【问题标题】:CMAKE How to compile static/object library with different flagsCMAKE如何编译具有不同标志的静态/对象库
【发布时间】:2018-04-23 11:15:04
【问题描述】:

问题:2 个可执行文件,1 个带有 if/defs 的核心库

UPD2 在 Ľubomír Carik 的帮助下

每个可执行文件都设置自己的预处理器标志 一开始,创建库的目标

add_library(common_library STATIC ${__SOURCES} ${__HEADERS})

common_library 代码(即静态库,自带cmake文件)有预处理条件

#if defined(MY_DEFINE_1)
// specific code #1 
#elif defined (MY_DEFINE_2)
// specific code #2 
#else
// error
#endif

我在使用 CMake 来准备这样的配置时遇到问题。库没有看到定义。 第一个可执行文件(自己的 cmake):

target_compile_definitions(common_library PRIVATE -DMY_DEFINE_1)
add_executable(BINARY_1  ${bin1_sources}   )
add_dependencies(BINARY_1 common_library)

第二个可执行文件(自己的 cmake):

target_compile_definitions(common_library PRIVATE -DMY_DEFINE_2)
add_executable(BINARY_2  ${bin2_sources}   )
add_dependencies(BINARY_2 common_library)

但是 common_library 只构建一次,有 2 个定义。它应该为每个二进制文件单独构建。

【问题讨论】:

  • 您的标题是关于 STATIC 库的,您的代码是指 OBJECT 库(TARGET_OBJECTS 属性),而您的文字说明 SHARED 库 (... which will build shared library 2 times)。您实际使用哪种类型的库?
  • “共享”我的意思是,代码是共享的。静态或对象,我不知道,什么会起作用。很抱歉造成混乱

标签: cmake


【解决方案1】:

由于您尝试更改库上的编译器标志,因此您需要多次构建该库。您现在正在做的是多次更改库上的标志,这就是为什么您在构建中看到两组编译器定义的原因。

解决问题的最简单方法是创建两个库条目,每个条目都有自己的标志。这是我能想到的最小的例子:

project("sample"
    LANGUAGES
        C
)

add_library(lib1 STATIC foo.c)
target_compile_definitions(lib1
    PRIVATE -DCOND=1
)
add_library(lib2 STATIC foo.c)
target_compile_definitions(lib2
      PRIVATE -DCOND=0
)

我的foo.c 看起来像这样:

#if COND
#warning "case 1"
#else
#warning "case 2"
#endif

void foo() { }

构建看起来像这样:

$ make
Scanning dependencies of target lib1
[ 25%] Building C object CMakeFiles/lib1.dir/foo.o
/tmp/so/static-lib/foo.c:2:2: warning: #warning "case 1" [-Wcpp]
 #warning "case 1"
  ^~~~~~~
[ 50%] Linking C static library liblib1.a
[ 50%] Built target lib1
Scanning dependencies of target lib2
[ 75%] Building C object CMakeFiles/lib2.dir/foo.o
/tmp/so/static-lib/foo.c:4:2: warning: #warning "case 2" [-Wcpp]
 #warning "case 2"
  ^~~~~~~
[100%] Linking C static library liblib2.a
[100%] Built target lib2

如果大部分库代码都相同,您可以通过使用三个库来限制编译时间(例如,真正通用的代码,然后是只包含条件编译内容的库)。

【讨论】:

  • 谢谢,我终于找到了相同的解决方案。
【解决方案2】:

您应该使用target_compile_optionstarget_compile_definitions 而不是全局“add_definitions”。并为 library_1 和 library_2 设置不同的定义。

【讨论】:

  • 好的,它有帮助,我只需将 OBJECT 更改为 STATIC
  • 我必须取消标记答案,因为它有效,但是......奇怪。最后,我在库中都有定义。它只构建了 1 次,带有两个标志。
  • 是的,我现在看到了,您的更改。当您将下一个定义添加到同一个目标时,它就像添加一样。您需要 2 个目标,即 2 个具有不同目标名称的库(又名 common_library1 和 common_library2)。请不要将 CMakeList.txt 文件作为命令序列。 CMake 将生成项目文件,这些文件过着自己的生活。
  • 你应该创建 lib1 和 lib2,然后是 binary1 和 binary2 目标,然后你可以使用“target_link_libraries”将 lib1 链接到 app1(而不是冗余的 add_dependencies)等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多