CMAKE如何编译具有不同标志的静态/对象库
Posted
技术标签:
【中文标题】CMAKE如何编译具有不同标志的静态/对象库【英文标题】:CMAKE How to compile static/object library with different flags 【发布时间】: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
)。您实际使用哪种类型的库?
“共享”我的意思是,代码是共享的。静态或对象,我不知道,什么会起作用。很抱歉造成混乱
【参考方案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_options 和target_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)等。以上是关于CMAKE如何编译具有不同标志的静态/对象库的主要内容,如果未能解决你的问题,请参考以下文章