1. 程式人生 > >CMake與MSVC工程化實踐

CMake與MSVC工程化實踐

arc 解決 ID lis AD 根目錄 包括 prop postfix

CMake與MSVC工程化實踐

CMake基礎

cmake無疑是最流行的c++跨平臺構建工具之一,關於cmake入門指南這裏不再贅述,官方文檔是最好的參考,這裏通過一個例子簡述構建一個工程常用的函數和變量。

假設此項目有三個文件hello.h、hello.cpp、main.cpp,hello.h和hello.cpp導出一個void hello();的函數,在main.cpp中使用,CMakeList.txt如下:

# 指明當前CMake的版本不能小於指定版本
cmake_minimum_required (VERSION 3.4)
# 工程名稱,如果生成msvc工程,這個同樣是解決方案名稱
project
(MyProject) # 將hello.h、hello.cpp保存到${HELLO_SRC}變量中,作為文件列表 file(GLOB HELLO_SRC hello.h hello.cpp ) file(GLOB MAIN_SRC main.cpp ) # ${HELLO_SRC}生成為一個共享庫,在windows系統自然是dll模塊 add_library(hello SHARED ${HELLO_SRC}) # ${MAIN_SRC}生成一個可執行程序main.exe/main.out add_executable(main ${MAIN_SRC}) # 生產目標main的時候指定鏈接器鏈接hello模塊
target_link_libraries(main hello)

這樣便完成了一個非常簡單的CMake工程,同時它也包含了我們工程最關註的一些東西,包括生成庫文件,生成可執行文件,如何鏈接庫等等。

Debug與Release

有時候我們希望生成帶調試信息的庫或者可執行文件與正式發布的文件進行區分,最常見的就是把帶調試信息的文件後綴加‘d‘,同時為了目錄結構的整齊,需要把它們的生成目錄進行區分,那麽可以參考以下的CMake命令:

# 取消CMake默認生成的工程選項,僅保留Debug與Release(只對msvc這樣的多樣化構建ide有效)
if(CMAKE_CONFIGURATION_TYPES
) set(CMAKE_CONFIGURATION_TYPES Debug Release) set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "Reset the configurations to what we need" FORCE) endif() # 可執行文件生成目錄 # ${PROJECT_BINARY_DIR}運行CMake命令的所在目錄(用於CMake的分離式編譯) # ${PROJECT_SOURCE_DIR}是工程的根目錄(根CMakeList.txt的所在路徑) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/bin/Debug) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/bin/Release) # 庫文件生成目錄 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_BINARY_DIR}/lib) # 可執行文件後綴 set_target_properties(${TARGET_NAME} PROPERTIES DEBUG_POSTFIX "d") # 庫文件後綴 set(CMAKE_DEBUG_POSTFIX "d")

這時候會發現一些有爭議的地方,如果庫文件帶上了‘d‘後綴,那麽target_link_libraries鏈接庫的時候如何分別鏈接Debug的庫和Release的庫的呢。可以分兩種情況來說明,如果是上文中類似hello庫這種在工程內部‘聲明‘的庫,那麽我們可以不用考慮,仍然鏈接hello即可,在生成實際的msvc工程時cmake會為我們自動進行區分;如果使用第三方庫,就需要特別的選項去區分:

target_link_libraries(main 
    debug hello
    optimized hellod
)

簡單的理解debug選項後面表明帶調試信息的庫就去搜索hellod,而不帶調試信息的庫就去搜索hello,特別的對於第三方庫,需要註意聲明庫目錄,可以參考link_directories

生成MSVC工程

當編寫好一個基本的CMake工程後如何與Visual Studio結合使用呢,可以參考cmake -G命令:

# 在執行CMake命令的地方生成visual studio 2017的解決方案(32位構建選項)
cmake -G ‘Visual Studio 15 2017‘ ${PROJECT_SOURCE_DIR}
# 生成vs2015的64位構建方案
cmake -G ‘Visual Studio 14 2015 Win64‘ ${PROJECT_SOURCE_DIR}
# 根據你計算機內最新的visual studio版本生成解決方案
cmake ${PROJECT_SOURCE_DIR}

打開生成的解決方案會發現除了所有的庫的可執行文件對應一個project外,還有ALL_BUILD和一個ZERO_CHECK項目,ALL_BUILD顧名思義就是構建所有的項目了。而構建ZERO_CHECK會觸發cmake重新檢查CMakeList.txt並且重新加載解決方案,這樣就避免了修改CMakeList.txt後重新執行命令生成msvc工程的麻煩了,同時還能保留設置的斷點、書簽等等。

結束語

上文所述的僅僅是CMake的冰山一角,還有許許多多的功能和選項可以方便我們進行工程文件的管理。

CMake不僅僅是跨平臺構建工程的不二選擇,就是僅僅使用它來構建windows工程也提供了許多便利,尤其是鑒於visual studio更新比較頻繁,如果我們使用cmake管理我們的工程,同時使用標準的c++去開發,那麽visual studio版本的遷移也不是一件頭疼的事情了~

CMake與MSVC工程化實踐