CMake與MSVC工程化實踐

CMake與MSVC工程化實踐

CMake基礎

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

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

# 指明當前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工程,同時它也包含了咱們工程最關注的一些東西,包括生成庫文件,生成可執行文件,如何連接庫等等。ide

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_directoriesui

生成MSVC工程

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

# 在執行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工程的麻煩了,同時還能保留設置的斷點、書籤等等。調試

設置Target Platform Version

有時須要指定winsdk的版本,例如設置爲8.1:code

set(CMAKE_SYSTEM_VERSION 8.1 CACHE TYPE INTERNAL FORCE)

設置Platform Toolset

有時須要指定工具集的版本,例如生成vs2017工程可是使用vs2015的編譯鏈:orm

cmake -G "Visual Studio 15 2017" -T v140

結束語

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

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

相關文章
相關標籤/搜索