使用 CMake 的自定义 .h 和 cpp 的未定义符号 [关闭]

Posted

技术标签:

【中文标题】使用 CMake 的自定义 .h 和 cpp 的未定义符号 [关闭]【英文标题】:Undefined symbol for custom .h and cpp using CMake [closed] 【发布时间】:2020-03-23 01:44:19 【问题描述】:

我使用 C++ 已经十多年了,整个 CMake 对我来说是全新的。我的问题具体是如何配置 CMake 项目,以便它不会出现这个未定义的符号错误。

错误信息如下:

====================[ Build | glfw_template | Debug ]===========================
"/Users/brianyeh/Library/Application Support/JetBrains/Toolbox/apps/CLion/ch-0/193.6911.21/CLion.app/Contents/bin/cmake/mac/bin/cmake" --build /Users/brianyeh/CLionProjects/glfw_template/cmake-build-debug --target glfw_template -- -j 4
[ 50%] Linking CXX executable bin/glfw_template
Undefined symbols for architecture x86_64:
  "_LoadShaders", referenced from:
      init() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [bin/glfw_template] Error 1
make[2]: *** [CMakeFiles/glfw_template.dir/all] Error 2
make[1]: *** [CMakeFiles/glfw_template.dir/rule] Error 2
make: *** [glfw_template] Error 2

请参考此链接查看项目:https://github.com/crimsonalucard/glfw_template

期望的行为是项目在 CMake 下编译。

【问题讨论】:

看起来您实际上还没有创建一个名为 LoadShaders 的函数,LoadShaders 的 cpp 是空的。你忘记实现了吗? @NathanWride 我的错,这是来自 opengl 红皮书的示例代码。我复制了一些东西并复制了原始错误以作为 Stack Overflow 的示例。我已经更正了错误,但问题仍然存在。 堆栈溢出要求有代码,重现问题,在问题帖子中本身,而不是链接。拥有超过 2k 的声誉,您应该知道...请修复问题帖子。 【参考方案1】:

您需要使用项目中使用的所有 .cpp 文件构建可执行文件。

来自这些链接的示例:

http://derekmolloy.ie/hello-world-introductions-to-cmake/

Adding header and .cpp files in a project built with cmake

建议在你的 cmakelists 中做这样的事情:

file(GLOB SOURCES
    lib/*.cpp
    include/*.h
    main.cpp
)

add_executable(glfw_template $SOURCES)

编辑:根据 cmets GLOB 不推荐,首选方法是手动将所有来源添加到培养列表:

set(SOURCES lib/LoadShaders.cpp lib/vgl.cpp)
set(HEADERS include/LoadShaders.h include/vgl.h)

add_executable(glfw_template $SOURCES $HEADERS)

【讨论】:

在 CMake 文件中使用GLOB推荐的做法。最好单独列出所有源文件以避免将来出现依赖性问题。 @squareskittles 他的解决方案虽然有效。我现在正在检查它,但如果你有更好的解决方案,我很想听听。绝对不想不遵循最佳实践,但我也尊重他的解决方案有效这一事实。 我已经编辑了答案以提供 GLOB 的替代方案。我们实际上在工作中使用手动列表,所以我确信这是更好的做法,我只是认为 GLOB 非常适合这样的小项目。让我知道编辑是否适合您@BrianYeh @BrianYeh 是的,GLOB 在很多情况下都有效,尤其是对于小型项目。但它不会为您跟踪源文件更改,因此如果不手动重新运行 CMake,以后添加的源可能无法识别。这就是为什么它通常不被推荐,这在 CMake 文档中甚至很明显(参见 Note here)。 @NathanWride 成功了。谢谢你们俩。

以上是关于使用 CMake 的自定义 .h 和 cpp 的未定义符号 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从 CMake 中的自定义目标运行目标

使用 g++ 时 HDF5 的未定义符号

使用类标头对函数的未定义引用[重复]

我的Android进阶之旅NDK开发之CMake自定义搜索规则,减少每次都需要配置.cpp和.h的工作量

我的Android进阶之旅NDK开发之CMake自定义搜索规则,减少每次都需要配置.cpp和.h的工作量

在android NDK中包含本地头文件时的未定义引用