c - 使用 CMake 获取链接错误

标签 c build build-process cmake

在有条件地编译特定于平台的代码后,我遇到了多重定义 链接错误。

我的项目布局如下:

/
|__+ 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 中的代码 #included 以及各个 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/

相关文章:

c++ - 不受主存储器约束的函数所需的复杂性是多少?

c - 在 C 中,为什么 (int*)&x[k] 对于二维数组 x 和 (int*)x[k] 一样好用?

c - 给定一个点和一个正方形面积值作为输入参数的函数返回四个正方形

Android 4 ICS 构建源代码 - 最低系统要求

android - 加快 Android Studio 中的运行过程

build-process - 发布流程改进

c - 如何使用 C 在 Ubuntu 上获取 WIFI 参数(带宽、延迟)

caching - 将环境状态显式附加到 SCons Builder 依赖项 MD5 指纹

msbuild - 使用MSBuild或NAnt相对于从命令行运行DevEnv.exe的优势