Conan+CMake项目链接报错:undefined reference to company_name::square
链接错误排查:Conan+CMake自定义maths库未正确链接
错误信息
执行cmake --build时出现以下链接错误:
[ 50%] Building CXX object CMakeFiles/exp_proj.dir/main.cpp.o [100%] Linking CXX executable exp_proj CMakeFiles/exp_proj.dir/main.cpp.o: In function `main': main.cpp:(.text.startup+0x18d): undefined reference to `company_name::square(int)' collect2: error: ld returned 1 exit status gmake[2]: *** [CMakeFiles/exp_proj.dir/build.make:98: exp_proj] Error 1 gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/exp_proj.dir/all] Error 2 gmake: *** [Makefile:136: all] Error 2
项目代码与配置
主项目
main.cpp
#include <fmt/core.h> #include <fmt/color.h> #include <functions.h> #include <iostream> using namespace std; int main() { #ifdef NDEBUG { fmt::print(fmt::bg(fmt::color::crimson) | fmt::fg(fmt::color::black), "VERSION 1.0"); fmt::print(fmt::fg(fmt::color::crimson), "\n\nRELEASE BUILD..."); fmt::print(" the release build of the version 1.0 of the program runs with no issues!\nThe square of 5 is {}\n\n", company_name::square(5)); } #else fmt::print(fmt::bg(fmt::color::cornflower_blue) | fmt::fg(fmt::color::white), "VERSION 1.0"); fmt::print(fmt::fg(fmt::color::cornflower_blue), "\n\nDEBUG BUILD... "); fmt::print(" the debug build of version 1.0 of the program runs with no issues!\nThe square of 5 is {}\n\n", company_name::square(5)); #endif return 0; }
conanfile.py
from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, CMakeDeps, cmake_layout class project(ConanFile): name="exp_proj" version = "1.0" author = "SIGNORI Gianmario gianmario.signori@company_name.com" description = "IDK how many project I have done so far because of some unresolvable errors" topics = ("Conan", "Artifactory", "Libraries") exports_sources = "main.cpp", "CMakeLists.txt" settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} requires = ( "fmt/10.1.1", "maths/1.0" ) def config_options(self): if self.settings.os == "Windows": del self.options.fPIC def layout(self): cmake_layout(self) def generate(self): deps = CMakeDeps(self) deps.generate() tc = CMakeToolchain(self) tc.generate() def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): cmake = CMake(self) cmake.install()
CMakeLists.txt
cmake_minimum_required(VERSION 3.20) project(exp_proj) find_package(fmt REQUIRED) find_package(maths REQUIRED) set(CMAKE_CXX_STANDARD 20) add_executable(exp_proj main.cpp) target_link_libraries(exp_proj PRIVATE fmt::fmt maths::maths ) install(TARGETS exp_proj DESTINATION bin)
自定义maths库
functions.cpp
#include "functions.h" namespace company_name { int square(int x) { return x*x; } }
functions.h
#ifndef MATHS_FUNCTIONS_H #define MATHS_FUNCTIONS_H namespace company_name{ int square(int x); } #endif//MATHS_FUNCTIONS_H
CMakeLists.txt
cmake_minimum_required(VERSION 3.20) project(maths) set(CMAKE_CXX_STANDARD 20) add_library(maths STATIC functions.cpp) target_include_directories(maths PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) install(TARGETS maths ARCHIVE DESTINATION lib INCLUDES DESTINATION include ) install(FILES functions.h DESTINATION include) install(TARGETS maths DESTINATION lib)
conanfile.py
from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, CMakeDeps, cmake_layout from conan.tools.files import copy class maths(ConanFile): name="maths" version="1.0" author="SIGNORI GIANMARIO gianmario.signori@company_name.com" exports_sources="CMakeLists.txt", "functions.h", "functions.cpp" settings="os", "compiler", "build_type", "arch" options={"shared": [True, False]} default_options={"shared": False} def layout(self): cmake_layout(self) def generate(self): deps = CMakeDeps(self) deps.generate() tc=CMakeToolchain(self) tc.generate() def build(self): cmake=CMake(self) cmake.configure() cmake.build() def package(self): #copy(self, "*.h", dst="include", src=self.source_folder) #copy(self, "*.a", dst="lib", src=self.build_folder) #copy(self, "*.lib", dst="lib", src=self.build_folder) #copy(self, "*.cpp", self.source_folder, self.package_folder) #copy(self, "CMakeLists.txt", self.source_folder, self.package_folder) cmake = CMake(self) cmake.install() #def package_info(self): # self.cpp_info.libs = ["maths"]
执行命令
$ conan install . -s build_type=... $ cmake -S . -B build/... -DCMAKE_TOOLCHAIN_FILE=build/.../generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=... $ cmake --build build/... $ ./build/.../"exp_proj"
其中...为Release/Debug构建的占位符。
问题排查与解决方案
核心问题
链接错误提示undefined reference,说明主项目编译时能找到头文件,但链接阶段找不到maths库的二进制符号。原因是maths库的Conan包未正确导出库信息,导致主项目CMake无法正确关联到maths库文件。
修复步骤
启用maths库的
package_info方法
打开maths库的conanfile.py,取消注释package_info部分:def package_info(self): self.cpp_info.libs = ["maths"]这个方法告诉Conan将
maths库添加到依赖项目的链接路径中,确保CMake能找到并链接该库。重新打包并安装maths库
在maths库目录下执行:conan create . -s build_type=Release conan create . -s build_type=Debug这会重新生成包含正确库信息的Conan包,并安装到本地缓存。
清理主项目构建缓存并重新构建
删除主项目的build目录,重新执行:conan install . -s build_type=... cmake -S . -B build/... -DCMAKE_TOOLCHAIN_FILE=build/.../generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=... cmake --build build/...
额外验证点
- 检查maths库的安装包路径(通常在
~/.conan/data/maths/1.0/...),确认lib目录下存在libmaths.a(Linux/macOS)或maths.lib(Windows),include目录下存在functions.h。 - 主项目执行
cmake --build时,查看链接命令是否包含-lmaths(Linux/macOS)或maths.lib(Windows)。
内容的提问来源于stack exchange,提问作者Gianmario Signori
相关产品推荐
相关产品推荐

