使用CMake获取链接错误

时间:2012-03-18 04:36:35

标签: c build build-process cmake

在有条件地编译特定于平台的代码后,我收到了multiple definition个链接错误。

我的项目布局如下:

/
|__+ 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中设置了内省,以便检测操作系统并定义相应的常量。问题是,我不想在每个目录中维护一个CMakeLists.txt文件,因此我只是对所有.c个文件as suggested in this answer进行了整理:

file(GLOB_RECURSE LIBRARY_SOURCE_FILES "${PROJECT_SOURCE_DIR}/src/*.c")

显然,这是导致问题的原因。它似乎正在编译#include中的代码general.c以及各个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

我如何解决这种情况?

1 个答案:

答案 0 :(得分:2)

这种跨平台情况的最佳实践是创建两个库,一个用于linux,一个用于Windows,并停止执行条件包含。每个平台仅编译和链接相关库。

使用cmake执行此操作的建议方法是停止globbing并仅包含每个文件。在某些情况下,可以混淆并且没有意识到它需要重新编译。您可以提出一个论据,即不变的遗留代码不会出现这个问题。

如果你真的想避免做这些事情,我会把包含的代码放在标题而不是c文件中。你真的不想要包含警卫,这样人们就不会因为像常规标题那样使用它而感到困惑。在文件中放入一堆注释,以警告他们不要使用这些行为。