本文使用的相關(guān)軟件環(huán)境信息如下:
軟件名稱 | 軟件版本 |
---|---|
Linux操作系統(tǒng) | Ubuntu 22.04 LTS(X64) |
cmake | 3.22.1 |
g++ | 11.4.0 |
-
target_compile_definitions
命令格式
target_compile_definitions(<target> <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
該命令添加預(yù)編譯選項(xiàng)到編譯目標(biāo)中,與add_compile_definitions不同的是,target_compile_definitions針對(duì)構(gòu)建的目標(biāo)添加預(yù)編譯選項(xiàng)驶臊,而add_compile_definitions是針對(duì)源文件添加預(yù)編譯選項(xiàng)(實(shí)際上也隱含對(duì)當(dāng)前構(gòu)建目標(biāo)添加預(yù)編譯選項(xiàng))。
因此匿垄,target_compile_definitions要求構(gòu)建目標(biāo)已經(jīng)存在,也就是被add_executable()或add_library()等函數(shù)創(chuàng)建出來。此外验懊,target_compile_definitions還要求對(duì)每一個(gè)編譯選項(xiàng)指定范圍吭服,范圍有三個(gè)選項(xiàng):PUBLIC嚷堡、PRIVATE和INTERFACE。通過PUBLIC和PRIVATE范圍限定的預(yù)編譯選項(xiàng)會(huì)被添加到構(gòu)建目標(biāo)的COMPILE_DEFINITIONS屬性中艇棕,通過PUBLIC和INTERFACE范圍限定的預(yù)編譯選項(xiàng)會(huì)被添加到構(gòu)建目標(biāo)的INTERFACE_COMPILE_DEFINITIONS屬性中蝌戒。總結(jié)起來就是PUBLIC既給自己用欠肾,也給別人用瓶颠;PRIVATE只給自己用;INTERFACE只給別人用刺桃。
當(dāng)多個(gè)構(gòu)建目標(biāo)在一起鏈接的時(shí)粹淋,最終的可執(zhí)行文件會(huì)將各個(gè)構(gòu)建目標(biāo)的INTERFACE_COMPILE_DEFINITIONS屬性繼承過來。
對(duì)于-D的前導(dǎo)符和空字符串""會(huì)被CMake忽略瑟慈,例如下面命令完全等價(jià):
target_compile_definitions(target PUBLIC DEF_FLAG) target_compile_definitions(target PUBLIC -DDEF_FLAG) # -D 被移除 target_compile_definitions(target PUBLIC "" DEF_FLAG) # "" 被忽略 target_compile_definitions(target PUBLIC -D DEF_FLAG) # -D 變成 "" 然后被忽略
下面來看一個(gè)示例:
1桃移、對(duì)于CMakeLists.txt,通過構(gòu)建一個(gè)test庫和一個(gè)可執(zhí)行文件main葛碧,對(duì)test庫添加3個(gè)編譯選項(xiàng):一個(gè)是范圍為PRIVATE的PRIVATE_PRINT借杰,一個(gè)是范圍為PUBLIC的PUBLIC_PRINT,一個(gè)范圍是INTERFACE的INTERFACE_TEST_DEF进泼;對(duì)main可執(zhí)行文件添加范圍為PUBLIC的DEBUG_PRINT蔗衡。
2、對(duì)于源文件:test.cpp在定義PRIVATE_PRINT宏時(shí)會(huì)打印一條"show test private print..."乳绕,在定義PUBLIC_PRINT宏時(shí)候绞惦,會(huì)實(shí)現(xiàn)一個(gè)接口test_print()主胧,該接口打印一條"show test public print..."遏弱,該接口會(huì)在main.cpp中被調(diào)用(也會(huì)判斷宏定義PUBLIC_PRINT),而main.cpp在定義DEBUG_PRINT宏時(shí)會(huì)打印一條"In debug print mode..."肺然,在定義PRIVATE_PRINT宏時(shí)會(huì)打印"show test private print in main..."菠发。
文件目錄結(jié)構(gòu)為:
├── CMakeLists.txt ├── main.cpp ├── test.cpp └── test.h
CMakeLists.txt文件內(nèi)容:
CMAKE_MINIMUM_REQUIRED(VERSION 3.22) PROJECT(compiler_options) ADD_LIBRARY(test test.cpp) # 為test增加預(yù)編譯選項(xiàng) TARGET_COMPILE_DEFINITIONS(test PRIVATE PRIVATE_PRINT PUBLIC PUBLIC_PRINT INTERFACE INTERFACE_TEST_DEF) ADD_EXECUTABLE(main main.cpp) TARGET_COMPILE_DEFINITIONS(main PUBLIC DEBUG_PRINT) TARGET_LINK_LIBRARIES(main test)
test.h文件內(nèi)容:
#ifndef __TEST_TT__ #define __TEST_TT__ #ifdef PUBLIC_PRINT void test_print(); #endif #endif
test.cpp內(nèi)容:
#ifdef PUBLIC_PRINT #include "test.h" #include <iostream> void test_print() { std::cout << "test:show test public print..." << std::endl; #ifdef PRIVATE_PRINT std::cout << "test:show test private print..." << std::endl; #endif } #endif
main.cpp內(nèi)容:
#include "test.h" #include <iostream> int main(int argc, char** argv) { #ifdef DEBUG_PRINT std::cout << "main:In debug print mode..." << std::endl; #endif #ifdef PUBLIC_PRINT test_print(); #endif #ifdef PRIVATE_PRINT std::cout << "main:show test private print in main..." << std::endl; #endif return 0; }
運(yùn)行
cmake .
和make VERBOSE=1
王滤,關(guān)鍵信息輸出如下:…… [ 25%] Building CXX object CMakeFiles/test.dir/test.cpp.o /usr/bin/c++ -DPRIVATE_PRINT -DPUBLIC_PRINT -MD -MT CMakeFiles/test.dir/test.cpp.o -MF CMakeFiles/test.dir/test.cpp.o.d -o CMakeFiles/test.dir/test.cpp.o -c /XXX/test.cpp [ 50%] Linking CXX static library libtest.a …… [ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o /usr/bin/c++ -DDEBUG_PRINT -DINTERFACE_TEST_DEF -DPUBLIC_PRINT -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/shengyi/code/gitee_repo/projects/cmake/target_compile_definitions/main.cpp [100%] Linking CXX executable main
可以看到,在編譯test庫時(shí)滓鸠,使用了-DPRIVATE_PRINT -DPUBLIC_PRINT雁乡,說明INTERFACE預(yù)編譯選項(xiàng)test庫本身并不使用;在編譯main可執(zhí)行文件時(shí)候糜俗,使用了-DDEBUG_PRINT -DINTERFACE_TEST_DEF -DPUBLIC_PRINT 蔗怠,說明test庫的PUBLIC和INTERFACE預(yù)編譯選項(xiàng)傳遞給了main墩弯。