C++ CMake 构建错误“未定义的参考”
Posted
技术标签:
【中文标题】C++ CMake 构建错误“未定义的参考”【英文标题】:C++ CMake Build Errors "Undefined Reference" 【发布时间】:2018-04-13 17:14:43 【问题描述】:我对 CMake 很陌生,我正在尝试使用 VS2017 和 WSL(Linux 子系统)构建一个跨平台的 c++ 项目。不幸的是,我仍在尝试了解 CMake 如何处理依赖项和链接,因此我遇到了很多“未解析的外部符号”和“未定义的对...的引用”错误。
为了更容易理解,我创建了以下项目,我可以在其中复制我遇到的错误类型。需要一些帮助来更好地了解如何配置 CMake。
注意:我刚刚在其中包含了 opencv 文件夹,以展示我如何尝试使用 CMake 包含外部依赖项,尽管在此示例中我并没有真正使用任何 opencv 代码。
/CMakeLists.txtcmake_minimum_required(VERSION 3.9)
project(WslSample) set (CMAKE_CXX_STANDARD 11)
include_directories(
$PROJECT_BINARY_DIR
$PROJECT_SOURCE_DIR/ext/opencv/include )
add_subdirectory(src)
/src/CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project (SampleApp)
set (CMAKE_CXX_STANDARD 11)
file(GLOB_RECURSE SOURCES RELATIVE $PROJECT_SOURCE_DIR "src/*.cpp")
file(GLOB_RECURSE HEADERS RELATIVE $PROJECT_SOURCE_DIR "src/*.hpp")
add_executable($PROJECT_NAME main.cpp $HEADERS $SOURCES)
target_include_directories($PROJECT_NAME PUBLIC utils)
/src/main.cpp
#include <iostream>
#include <string>
#include <log.hpp>
int main()
log(LEVEL_INFO, "Sample App running...");
return 0;
/utils/log.hpp
#pragma once
typedef enum
LEVEL_DEBUG = 0,
LEVEL_INFO = 1,
LEVEL_WARNING = 2,
LEVEL_ERROR = 3,
LogLevel;
void log(const LogLevel& level, const char* str);
/utils/log.cpp
#include <iostream>
#include <log.hpp>
std::string getLogStr(const LogLevel& level)
switch (level)
case LEVEL_INFO:
return "INFO";
case LEVEL_DEBUG:
return "DEBUG";
case LEVEL_ERROR:
return "ERROR";
case LEVEL_WARNING:
return "WARNING";
default:
return "n/a";
void log(const LogLevel& level, const char* str)
std::cout << getLogStr(level) << " " << str << std::endl;
构建输出日志
18:06:55: Copying files to remote machine...
18:06:55: Finished copying files (elapsed time 00h:00m:00s:009ms).
cd '/var/tmp/build/3df28527-45dd-1335-b3fd-743d2a9ed7dd/build/Linux-Debug';/usr/local/bin/cmake --build "/var/tmp/build/3df28527-45dd-1335-b3fd-743d2a9ed7dd/build/Linux-Debug" --target SampleApp ;
[ 50%] Linking CXX executable SampleApp
CMakeFiles/SampleApp.dir/main.cpp.o: In function `main':
/var/tmp/src/3df28527-45dd-1335-b3fd-743d2a9ed7dd/Linux-Debug/src/main.cpp:7: undefined reference to `log(LogLevel const&, char const*)'
collect2: error: ld returned 1 exit status
src/CMakeFiles/SampleApp.dir/build.make:94: recipe for target 'src/SampleApp' failed
make[3]: *** [src/SampleApp] Error 1
CMakeFiles/Makefile2:85: recipe for target 'src/CMakeFiles/SampleApp.dir/all' failed
make[2]: *** [src/CMakeFiles/SampleApp.dir/all] Error 2
CMakeFiles/Makefile2:97: recipe for target 'src/CMakeFiles/SampleApp.dir/rule' failed
make[1]: *** [src/CMakeFiles/SampleApp.dir/rule] Error 2
Makefile:118: recipe for target 'SampleApp' failed
make: *** [SampleApp] Error 2
Build failed.
【问题讨论】:
看起来您的SOURCES
变量没有选择 /utils/log.cpp
。试试打印出来(我喜欢用message(FATAL_ERROR "$SOURCES")
@Justin 这确实是与我查找文件的方式有关的错误。您的提示对我的调试帮助很大。谢谢。
【参考方案1】:
发现问题...我查找文件的方式错误,并且我使用了错误的 CMake 变量。在此特定案例的解决方案下方:
/src/CMakeLists.txt
file(GLOB_RECURSE SOURCES RELATIVE $PROJECT_SOURCE_DIR "*.cpp")
file(GLOB_RECURSE HEADERS RELATIVE $PROJECT_SOURCE_DIR "*.hpp")
【讨论】:
以上是关于C++ CMake 构建错误“未定义的参考”的主要内容,如果未能解决你的问题,请参考以下文章
使用 autotools 生成未定义的参考错误,而自定义 Makefile 工作正常