cmake自動添加宏定義


前言

一個大型的工程往往包含很多模塊,構建時候可以自主選擇需要使用的模塊,這里模擬一個任務,實現一個求指數的模塊,用戶可以在CMakeLists.txt文件中自由配制是否使用該模塊,如果使用該模塊,則需要在config.h配置文件中增加相應的宏定義

准備工作

創建sample8工程,新增Math目錄,Math.h和Math.cpp文件,實現求指數功能,新增main.cpp文件,當未引入Math模塊時使用系統求指數函數,否則使用Math模塊中的求指數函數
目錄如下:

./sample8 | +--- CMakeLists.txt | +--- build/ +--- src/ +--- CMakeLists.txt +--- main.cpp +--- Math/ +--- Math.h +--- Math.cpp 

main.cpp中內如下:

#include <stdio.h> #include <stdlib.h> #include "config.h" #ifdef USE_MYMATH #include "Math.h" #else #include <math.h> #endif int main(int argc, char *argv[]) { if (argc < 3){ printf("Usage: %s base exponent \n", argv[0]); return 1; } double base = atof(argv[1]); int exponent = atoi(argv[2]); #ifdef USE_MYMATH printf("Now we use our own Math library. \n"); double result = power(base, exponent); #else printf("Now we use the standard library. \n"); double result = pow(base, exponent); #endif printf("%g ^ %d is %g\n", base, exponent, result); return 0; } 

工程根目錄下CMakeLists.txt文件內容為:

# CMake 最低版本號要求 cmake_minimum_required (VERSION 2.8) if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) # CMake 3.0+ (2.8.12): MacOS "@rpath" in target's install name endif() # 項目工程名 project (sample8) message(STATUS "root This is BINARY dir " ${PROJECT_BINARY_DIR}) message(STATUS "root This is SOURCE dir " ${PROJECT_SOURCE_DIR}) # 添加子目錄 ADD_SUBDIRECTORY(src) 

src下CMakeLists.txt文件內容為:

# 打印信息
message(STATUS "src This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "src This is SOURCE dir " ${PROJECT_SOURCE_DIR})


# 定義工程根目錄; CMAKE_SOURCE_DIR為內建變量,表示工程根目錄的CMakeLists.txt文件路徑
SET(ROOT_DIR ${CMAKE_SOURCE_DIR})

# 是否使用自己的 Math庫
option (USE_MYMATH "Use provided math implementation" ON)
# 用於測試替換用的變量
set(TEST_ON 1)
set(TEST_OF 0)
set(VAR "VAR_NEW")

# 加入一個配置頭文件,用於處理 CMake 對源碼的設置
configure_file (
  "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
  "${CMAKE_CURRENT_BINARY_DIR}/config.h"
)

set(SRC_LIST main.cpp)

# 是否編譯Math函數
if (USE_MYMATH)
  set(SRC_LIST main.cpp Math.cpp)
endif (USE_MYMATH)

# 指定可執行文件存放目錄
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# 這樣可以找到config.h頭文件
include_directories("${CMAKE_CURRENT_BINARY_DIR}")

# 構建可執行程序
ADD_EXECUTABLE(sample8 ${SRC_LIST})

src新增 config.h.in文件,內容如下:

#cmakedefine USE_MYMATH // == 下面試測試用的 #cmakedefine01 TEST_ON #cmakedefine01 TEST_OF #ifndef __${VAR}___@VAR@ #endif 

進入build 開始構建,然后執行bin目錄下的./sample8 2 8 輸出:
Now we use our own Math library.
2 ^ 8 is 256

打開 build/src下的config.h文件,內容為:

#define USE_MYMATH // == 下面試測試用的 #define TEST_ON 1 #define TEST_OF 0 #ifndef __VAR_NEW___VAR_NEW #endif 

改寫前面src中的CMakeLists.txt,將option (USE_MYMATH "Use provided math implementation" ON)改成option (USE_MYMATH "Use provided math implementation" OFF),刪除build文件夾中內容,然后重新構建后,再執行 ./sample8 2 8 輸出:
Now we use the standard library.
2 ^ 8 is 256

打開 build/src下的config.h文件,內容為:

/* #undef USE_MYMATH */ // == 下面試測試用的 #define TEST_ON 1 #define TEST_OF 0 #ifndef __VAR_NEW___VAR_NEW #endif 

cmake新增語法解釋:

  • option (USE_MYMATH "Use provided math implementation" ON)指令
    給變量賦值 ON,代表真;OFF關鍵字則代表 假
  • configure_file(<input> <output> [COPYONLY] [ESCAPE_QUOTES] [@ONLY])
    對指定的輸入文件中的內容按照指定的規則進行替換,替換完成后輸出到output指定的輸出路徑
    替換規則為:
    1、在輸入文件中,凡是以${VAR}格式或@VAR@格式出現的地方都將用CMake中對應變量的值進行替換,如上例中VAR變量的值為VAR_NEW,config.h中全部替換成了這個值
    2、在輸入文件中,類似於#cmakedefine VAR的定義語句將會被替換為#define VAR或者/* #undef VAR /,如上例中USE_MYMATH當設定為ON的時候,config.h變成了#define USE_MYMATH,設定為OFF時,變成了/ #undef USE_MYMATH */;同理,類似於#cmakedefine01 VAR的定義語句將會被替換為#define VAR 1或#define VAR 0。

tips: 如果將CMakeLists.txt中的
@# 是否使用自己的 Math庫
option (USE_MYMATH "Use provided math implementation" ON)
@# 用於測試替換用的變量
set(TEST_ON 1)
set(TEST_OF 0)
set(VAR "VAR_NEW")
這一段寫到config_file指令的后面,會發生什么?
只有放到前面,config_file指令執行時這些變量才是有效的,切莫注意



from:https://www.jianshu.com/p/f0f71d36411a


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM