在有条件地编译特定于平台的代码后,我收到了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
我如何解决这种情况?
答案 0 :(得分:2)
这种跨平台情况的最佳实践是创建两个库,一个用于linux,一个用于Windows,并停止执行条件包含。每个平台仅编译和链接相关库。
使用cmake执行此操作的建议方法是停止globbing并仅包含每个文件。在某些情况下,可以混淆并且没有意识到它需要重新编译。您可以提出一个论据,即不变的遗留代码不会出现这个问题。
如果你真的想避免做这些事情,我会把包含的代码放在标题而不是c文件中。你真的不想要包含警卫,这样人们就不会因为像常规标题那样使用它而感到困惑。在文件中放入一堆注释,以警告他们不要使用这些行为。