在有条件地编译特定于平台的代码后,我遇到了多重定义
链接错误。
我的项目布局如下:
/
|__+ include/
| |__+ native/
| | |__ impl.h
| |
| |__ general.h
|
|__+ src/
|__+ native/
| |__ impl.linux.c
| |__ impl.win32.c
|
|__ general.c
在 general.c
文件的顶部:
#if defined(LIBRARY_PLATFORM_LINUX)
#include "native/impl.linux.c"
#elsif defined(LIBRARY_PLATFORM_WIN32)
#include "native/impl.win32.c"
#endif
我在 CMake 中设置了内省(introspection)以检测操作系统并定义相应的常量。问题是,我不想在每个目录中维护一个 CMakeLists.txt
文件,所以我简单地遍历了所有 .c
文件 as suggested in this answer :
file(GLOB_RECURSE LIBRARY_SOURCE_FILES "${PROJECT_SOURCE_DIR}/src/*.c")
显然,这就是导致问题的原因。它似乎正在编译 general.c
中的代码 #include
d 以及各个 src/native/impl.*.c
文件.
CMakeFiles/lib.dir/src/native/impl.linux.c.o: In function `declared_in_impl_h':
impl.linux.c:(.text+0x0): multiple definition of `declared_in_impl_h'
CMakeFiles/lib.dir/src/general.c.o:general.c:(.text+0x0): first defined here
我该如何解决这个问题?
最佳答案
对于这种跨平台情况,最佳做法是创建两个库,一个用于 linux,一个用于 windows,并停止执行条件包含。每个平台只编译和链接相关的库。
使用 cmake 执行此操作的推荐方法是停止通配并仅包含每个文件。在某些情况下,它可能会感到困惑并且没有意识到它需要重新编译。您可以论证不更改的遗留代码不会有这个问题。
如果您真的想避免做这些事情中的任何一个,我会将包含的代码放在 header 中而不是 c 文件中。你真的不想要 include 守卫,这样人们就不会混淆应该像常规标题一样使用的东西。在文件中添加一堆评论,以警告他们不要进行上述行为。
关于c - 使用 CMake 获取链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9756025/