【发布时间】:2021-01-15 22:33:26
【问题描述】:
我有一个包含多个目标 release 和 test 的项目,该项目链接到一个静态库,该库可以使用 TEST 宏进行编译。
假设我希望构建我的 release 目标而不使用 TEST 宏,并且使用定义的宏构建 test 目标,但该宏必须传播到链接的反对库。
在我的主要CMakeLists.txt 中,我创建了目标并使用target_compile_definitions(mytest PUBLIC TEST) 定义了该宏,但显然库core 无法识别它。
项目树如下:
.
├── CMakeLists.txt
├── core
│ ├── CMakeLists.txt
│ ├── inc
│ │ ├── core_comp1.h
│ │ └── core_comp2.h
│ └── src
│ ├── core_comp1.c
│ └── core_comp2.c
├── lib
│ ├── CMakeLists.txt
│ ├── inc
│ │ ├── ext_comp1.h
│ │ └── ext_comp2.h
│ └── src
│ ├── ext_comp1.c
│ └── ext_comp2.c
├── main.c
├── README.md
└── test.c
根./CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.10)
# set the project name
project(cmake_test)
# add the subdirectories
add_subdirectory(core)
add_subdirectory(lib)
# define my targets
set(MY_TARGETS myexe mytest)
# create and link against the libs
foreach(target ${MY_TARGETS})
add_executable(${target})
target_link_libraries(${target} PRIVATE core ext)
endforeach(target ${MY_TARGETS})
# add target specific sources
target_sources(myexe PRIVATE main.c)
target_sources(mytest PRIVATE test.c)
# define the TEST macro for mytest
target_compile_definitions(mytest PUBLIC TEST)
./core/CMakeLists.txt 库文件夹有:
add_library(core
${CMAKE_CURRENT_SOURCE_DIR}/src/core_comp1.c
${CMAKE_CURRENT_SOURCE_DIR}/src/core_comp2.c
)
target_include_directories(core PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/inc
)
target_link_libraries(core PRIVATE ext)
myexe的输出,release target是正确的:
Running the release executable
Original core_comp1_display
虽然mytest 不正确:
Running the test executable
Original core_comp1_display
应该是:
Running the test executable
Test core_comp1_display
我已将项目推送到 GitLab,cmake-library-test
myexe 目标的编译给出如下:
[build] [9/12 8% :: 0.032] /usr/bin/gcc -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/myexe.dir/lib/src/ext_comp2.c.o -MF CMakeFiles/myexe.dir/lib/src/ext_comp2.c.o.d -o CMakeFiles/myexe.dir/lib/src/ext_comp2.c.o -c ../../lib/src/ext_comp2.c
[build] [9/12 16% :: 0.034] /usr/bin/gcc -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/myexe.dir/core/src/core_comp2.c.o -MF CMakeFiles/myexe.dir/core/src/core_comp2.c.o.d -o CMakeFiles/myexe.dir/core/src/core_comp2.c.o -c ../../core/src/core_comp2.c
[build] [9/12 25% :: 0.039] /usr/bin/gcc -I../../lib/inc -g -MD -MT lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o -MF lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o.d -o lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o -c ../../lib/src/ext_comp2.c
[build] [9/12 33% :: 0.041] /usr/bin/gcc -I../../lib/inc -g -MD -MT lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o -MF lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o.d -o lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o -c ../../lib/src/ext_comp1.c
[build] [10/12 41% :: 0.043] /usr/bin/gcc -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/myexe.dir/lib/src/ext_comp1.c.o -MF CMakeFiles/myexe.dir/lib/src/ext_comp1.c.o.d -o CMakeFiles/myexe.dir/lib/src/ext_comp1.c.o -c ../../lib/src/ext_comp1.c
[build] [10/12 50% :: 0.046] /usr/bin/gcc -I../../core/inc -g -MD -MT core/CMakeFiles/core.dir/src/core_comp2.c.o -MF core/CMakeFiles/core.dir/src/core_comp2.c.o.d -o core/CMakeFiles/core.dir/src/core_comp2.c.o -c ../../core/src/core_comp2.c
[build] [10/12 58% :: 0.049] /usr/bin/gcc -I../../core/inc -g -MD -MT core/CMakeFiles/core.dir/src/core_comp1.c.o -MF core/CMakeFiles/core.dir/src/core_comp1.c.o.d -o core/CMakeFiles/core.dir/src/core_comp1.c.o -c ../../core/src/core_comp1.c
[build] [11/12 66% :: 0.054] /usr/bin/gcc -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/myexe.dir/main.c.o -MF CMakeFiles/myexe.dir/main.c.o.d -o CMakeFiles/myexe.dir/main.c.o -c ../../main.c
[build] [11/12 75% :: 0.058] /usr/bin/gcc -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/myexe.dir/core/src/core_comp1.c.o -MF CMakeFiles/myexe.dir/core/src/core_comp1.c.o.d -o CMakeFiles/myexe.dir/core/src/core_comp1.c.o -c ../../core/src/core_comp1.c
[build] [11/12 83% :: 0.110] : && /usr/bin/cmake -E rm -f lib/libmylib.a && /usr/bin/ar qc lib/libmylib.a lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o && /usr/bin/ranlib lib/libmylib.a && :
[build] [11/12 91% :: 0.119] : && /usr/bin/cmake -E rm -f core/libcore.a && /usr/bin/ar qc core/libcore.a core/CMakeFiles/core.dir/src/core_comp1.c.o core/CMakeFiles/core.dir/src/core_comp2.c.o && /usr/bin/ranlib core/libcore.a && :
[build] [12/12 100% :: 0.147] : && /usr/bin/gcc -g CMakeFiles/myexe.dir/main.c.o CMakeFiles/myexe.dir/core/src/core_comp1.c.o CMakeFiles/myexe.dir/core/src/core_comp2.c.o CMakeFiles/myexe.dir/lib/src/ext_comp1.c.o CMakeFiles/myexe.dir/lib/src/ext_comp2.c.o -o myexe core/libcore.a lib/libmylib.a && :
[build] Build finished with exit code 0
而mytest的编译给:
[build] [9/12 8% :: 0.035] /usr/bin/gcc -I../../core/inc -g -MD -MT core/CMakeFiles/core.dir/src/core_comp2.c.o -MF core/CMakeFiles/core.dir/src/core_comp2.c.o.d -o core/CMakeFiles/core.dir/src/core_comp2.c.o -c ../../core/src/core_comp2.c
[build] [9/12 16% :: 0.045] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o -MF CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o.d -o CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o -c ../../lib/src/ext_comp1.c
[build] [9/12 25% :: 0.047] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -MF CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o.d -o CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -c ../../lib/src/ext_comp2.c
[build] [9/12 33% :: 0.049] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/core/src/core_comp2.c.o -MF CMakeFiles/mytest.dir/core/src/core_comp2.c.o.d -o CMakeFiles/mytest.dir/core/src/core_comp2.c.o -c ../../core/src/core_comp2.c
[build] [9/12 41% :: 0.049] /usr/bin/gcc -I../../core/inc -g -MD -MT core/CMakeFiles/core.dir/src/core_comp1.c.o -MF core/CMakeFiles/core.dir/src/core_comp1.c.o.d -o core/CMakeFiles/core.dir/src/core_comp1.c.o -c ../../core/src/core_comp1.c
[build] [10/12 50% :: 0.052] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/test.c.o -MF CMakeFiles/mytest.dir/test.c.o.d -o CMakeFiles/mytest.dir/test.c.o -c ../../test.c
[build] [10/12 58% :: 0.056] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/core/src/core_comp1.c.o -MF CMakeFiles/mytest.dir/core/src/core_comp1.c.o.d -o CMakeFiles/mytest.dir/core/src/core_comp1.c.o -c ../../core/src/core_comp1.c
[build] [10/12 66% :: 0.065] /usr/bin/gcc -I../../lib/inc -g -MD -MT lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o -MF lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o.d -o lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o -c ../../lib/src/ext_comp2.c
[build] [10/12 75% :: 0.069] /usr/bin/gcc -I../../lib/inc -g -MD -MT lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o -MF lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o.d -o lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o -c ../../lib/src/ext_comp1.c
[build] [11/12 83% :: 0.127] : && /usr/bin/cmake -E rm -f core/libcore.a && /usr/bin/ar qc core/libcore.a core/CMakeFiles/core.dir/src/core_comp1.c.o core/CMakeFiles/core.dir/src/core_comp2.c.o && /usr/bin/ranlib core/libcore.a && :
[build] [11/12 91% :: 0.139] : && /usr/bin/cmake -E rm -f lib/libmylib.a && /usr/bin/ar qc lib/libmylib.a lib/CMakeFiles/mylib.dir/src/ext_comp1.c.o lib/CMakeFiles/mylib.dir/src/ext_comp2.c.o && /usr/bin/ranlib lib/libmylib.a && :
[build] [12/12 100% :: 0.168] : && /usr/bin/gcc -g CMakeFiles/mytest.dir/test.c.o CMakeFiles/mytest.dir/core/src/core_comp1.c.o CMakeFiles/mytest.dir/core/src/core_comp2.c.o CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -o mytest core/libcore.a lib/libmylib.a && :
[build] Build finished with exit code 0
很明显core_comp*.c和ext_comp*.c是在没有-DTEST的情况下编译的
使用建议的INTERFACE关键字,将标志-DTEST传入所有文件,编译如下:
[build] [5/6 16% :: 0.024] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/core/src/core_comp2.c.o -MF CMakeFiles/mytest.dir/core/src/core_comp2.c.o.d -o CMakeFiles/mytest.dir/core/src/core_comp2.c.o -c ../../core/src/core_comp2.c
[build] [5/6 33% :: 0.025] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -MF CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o.d -o CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -c ../../lib/src/ext_comp2.c
[build] [5/6 50% :: 0.038] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o -MF CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o.d -o CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o -c ../../lib/src/ext_comp1.c
[build] [5/6 66% :: 0.041] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/core/src/core_comp1.c.o -MF CMakeFiles/mytest.dir/core/src/core_comp1.c.o.d -o CMakeFiles/mytest.dir/core/src/core_comp1.c.o -c ../../core/src/core_comp1.c
[build] [5/6 83% :: 0.058] /usr/bin/gcc -DTEST -I../../core/inc -I../../lib/inc -g -MD -MT CMakeFiles/mytest.dir/test.c.o -MF CMakeFiles/mytest.dir/test.c.o.d -o CMakeFiles/mytest.dir/test.c.o -c ../../test.c
[build] [6/6 100% :: 0.134] : && /usr/bin/gcc -g CMakeFiles/mytest.dir/test.c.o CMakeFiles/mytest.dir/core/src/core_comp1.c.o CMakeFiles/mytest.dir/core/src/core_comp2.c.o CMakeFiles/mytest.dir/lib/src/ext_comp1.c.o CMakeFiles/mytest.dir/lib/src/ext_comp2.c.o -o mytest && :
[build] Build finished with exit code 0
core 和 mylib 库现在是透明的,目标 myexe 和 mytest 实际上认为库源是“他们的”
【问题讨论】:
-
@KamilCuk 使用
target_link_libraries(core PRIVATE mytest)将导致错误Attempt to add link library "mytest" to target "core" which is not built in this directory -
堆栈溢出的要求相关代码应该包含到问题帖子中,而不仅仅是链接。请将您的代码(至少
CMakeLists.txt)添加到问题帖子中。另请参阅How to Ask。 -
@Tsyvarev 指出,我添加了 2 个主要的
CMakeLists.txt -
好吧,您显示的代码绝对不足以理解问题,但是根据链接的 repo,
Original core_comp1_display和Test core_comp1_display行是由依赖于的core库输出的TEST宏的值。您将core库链接到test和release可执行文件,并希望库输出不同 行。这根本不可能:您的core库构建一次,因此只有单个输出 是可能的。此输出是在您构建库本身时确定的,而不是在您与它链接时确定的。 -
您可以创建单独的库(例如
core_test和core_release)并将它们相应地链接到test和release。或者您可以在打印行的core_comp1_display函数中添加一个参数,因此test和release可执行文件可以使用不同的参数调用此函数。您可以在core库中创建一些变量,而不是函数的参数,并为test和release提供一种为此变量设置值的方法。
标签: cmake