cmake使用筆記



cmake使用筆記

之前一直使用MakeFile,看過一些開源項目后,了解到了cmake,它是一個跨平台的編譯工具,不但能生成類unix系統下的makefile還能生成windows下project文件,這使得熟悉某個集成開發環境(IDE)的開發者可以用標准的方式建構他的軟件,這種可以使用各平台的原生建構系統的能力是 CMake 和 SCons 等其他類似系統的區別之處。

基本使用方法

cmake所的所有語句寫在CMakeLists.txt中,
因為cmake生成makefile或project然后在編譯時會生成很多中間文件,打亂項目文件結構,所以我們一般新建一個build目錄,在里面編譯。
基本操作只需要二步即可 :
1、cmake CMakeLists.txt文件目錄
2、make
3、如果配置了安裝路徑,還可以進行make install 等.
Alt text

相較於makefile的優點

目前個人體感上的優點。
1、跨平台。
2、語法相較於makefile簡潔不少,makefile有的,cmake基本都有。
3、編譯顯示自帶進度,顏色,看着很舒服,(當然makefile肯定也能實現,省了不少事罷了)。
Alt text

下面講講常用語句:

常用語法

cmake_minimum_required

CMake要求的最低版本

project

項目名稱

cmake_minimum_required (VERSION 2.8.7)
project (test_project)

PROJECT_SOURCE_DIR

項目根目錄,也就是CmakeLists.txt目錄的絕對路徑。

set

設置變量
例如

###
# variables
###
set(SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/sources)
set(OPEN_SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/open_sources)
set(INCLUDES_DIRECTORY ${PROJECT_SOURCE_DIR}/includes)

set(MUDUO_LOGGER_INCLUDES ${INCLUDES_DIRECTORY}/muduo_logger)
set(MUDUO_NETWORK_INCLUDES ${INCLUDES_DIRECTORY}/muduo_network)
set(CPP_REDIS_INCLUDES ${OPEN_SOURCES_DIRECTORY}/cpp_redis/includes)

include_directories

包含頭文件路徑,類似於makfilede的-I
例如

###
# includes
###
include_directories(${INCLUDES_DIRECTORY}
         ${MUDUO_LOGGER_INCLUDES} 
         ${MUDUO_NETWORK_INCLUDES}
         ${SOURCES_DIRECTORY}/sip_server
         ${CPP_REDIS_INCLUDES}
         ${OPEN_SOURCES_DIRECTORY}/includes
         ${OPEN_SOURCES_DIRECTORY}/includes/mysql++)

鏈接路徑,類似於makfilede的-L

###
# libraries
###
link_directories("${PROJECT_SOURCE_DIR}/library")
link_directories("${OPEN_SOURCES_DIRECTORY}/library")

常用變量

CMAKE_CURRENT_LIST_DIR

表示正在處理的CMakeLists.txt 文件的所在的目錄的絕對路徑(2.8.3 以及以后版本才支持)

CMAKE_ARCHIVE_OUTPUT_DIRECTORY

用於設置 ARCHIVE 目標的輸出路徑

CMAKE_LIBRARY_OUTPUT_DIRECTORY

用於設置 LIBRARY 目標的輸出路徑

CMAKE_RUNTIME_OUTPUT_DIRECTORY

用於設置 RUNTIME 目標的輸出路徑

LIBRARY_OUTPUT_PATH

用於設置 庫文件 的輸出路徑

EXECUTABLE_OUTPUT_PATH

用於設置 可執行文件的輸出路徑

例如

###
# outputs
###
#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_PKGCONFIG_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

編譯鏈接標志

CMAKE_C_FLAGS

CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

C 編譯標志相關變量。

CMAKE_CXX_FLAGS

CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

C++ 編譯標志相關變量。

CMAKE_C_FLAGS 或CMAKE_CXX_FLAGS 可以指定編譯標志
CMAKE_C_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]或 CMAKE_CXX_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO] 則指定特定構建類型的編譯標志,這些編譯標志將被加入到 CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS 中去,例如,如果構建類型為 DEBUG,那么 CMAKE_CXX_FLAGS_DEBUG 將被加入到 CMAKE_CXX_FLAGS中去

還有鏈接標志相關變量,作用類似
CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]
CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS_[DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO]

###
# compilation options
###
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g -W -Wall -Wextra -O3")

鏈接部分

add_library

添加要生成的庫文件
語法:add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)

用於指定從一組源文件 source1 source2 … sourceN 編譯出一個庫文件且命名為 name,默認是靜態庫.
例如

###
#library
###
add_library(async_logging ${muduo_logger_sources})

add_library(muduo_server ${muduo_network_sources})

add_executable

add_executable 命令
語法:add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)
用於指定從一組源文件 source1 source2 … sourceN 編譯出一個可執行文件且命名為 name

###
# executable
###
add_executable(sip_server ${test_excutable })
add_executable(mysql_use_test ${mysql_use_test_sources})

語法: target_link_libraries(<target> [item1 [item2 […]]][[debug|optimized|general] ] …)
用於指定 target 鏈接的依賴項 item1 item2 …。
例如:

###
# link librarys
###
target_link_libraries(async_logging pthread)

target_link_libraries(muduo_server async_logging)
target_link_libraries(muduo_server pthread)

target_link_libraries(test_excutable async_logging
                                 muduo_server
                                 pthread
                                 cpp_redis
                                 tacopie)

其他

add_subdirectory

如果想添加一個子項目或者模塊,可以用它進行構建的子目錄
語法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

add_subdirectory(${OPEN_SOURCES_DIRECTORY}/cpp_redis)

Debug和Release版本

暫不多詳述,簡單介紹一下。
debug 版的項目生成的可執行文件需要有調試信息並且不需要進行優化,、
release 版的不需要調試信息但需要優化。這些特性在 gcc/g++ 中是通過編譯時的參數來決定的,如果將優化程度調到最高需要設置參數-O3,最低是 -O0 即不做優化;添加調試信息的參數是 -g -ggdb ,如果不添加這個參數,調試信息就不會被包含在生成的二進制文件中。

PROJECT(main)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(CMAKE_SOURCE_DIR .)

SET(CMAKE_CXX_FLAGS_DEBUG"$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE"$ENV{CXXFLAGS} -O3 -Wall")

AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(main ${DIR_SRCS})

兩個變量 CMAKE_CXX_FLAGS_DEBUG 和CMAKE_CXX_FLAGS_RELEASE, 分別用於 debug 和 release 的編譯選項。編輯 CMakeList.txt 后需要執行 ccmake 命令生成 Makefile 。在進入項目的根目錄,輸入 "ccmake ." 進入一個圖形化界面。

調試手段

message

打印信息,類似於 echo/printf ,主要用於查cmake文件的語法錯誤。

set(mysql_use_test_sources ${SOURCES_DIRECTORY}/test_sources/mysql_user_accounts.cpp)
message("mysql_use_test_sources : ${mysql_use_test_sources}")

CMAKE_VERBOSE_MAKEFILE

顯示詳細的原始編譯信息,主要用於定位一些鏈接錯誤,看看庫路徑什么的是否配置對。

# print compile info
set(CMAKE_VERBOSE_MAKEFILE ON)

或者執行make時
$ make VERBOSE=1
或者
$ export VERBOSE=1
$ make
你講能看到如下所示詳細編譯信息
Alt text

cmake示例

cmake_minimum_required (VERSION 2.8.7)
project (ws_tcp_server)

###
# variables
###
set(SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/sources)
set(OPEN_SOURCES_DIRECTORY ${PROJECT_SOURCE_DIR}/open_sources)
set(INCLUDES_DIRECTORY ${PROJECT_SOURCE_DIR}/includes)

set(MUDUO_LOGGER_INCLUDES ${INCLUDES_DIRECTORY}/muduo_logger)
set(MUDUO_NETWORK_INCLUDES ${INCLUDES_DIRECTORY}/muduo_network)
set(CPP_REDIS_INCLUDES ${OPEN_SOURCES_DIRECTORY}/cpp_redis/includes)

###
# includes
###
include_directories(${INCLUDES_DIRECTORY}
         ${MUDUO_LOGGER_INCLUDES} 
         ${MUDUO_NETWORK_INCLUDES}
         ${CPP_REDIS_INCLUDES})

###
# libraries
###
link_directories("${PROJECT_SOURCE_DIR}/library")

###
# outputs
###
#set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
#set(CMAKE_PKGCONFIG_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pkgconfig)
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/library)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

###
# compilation options
###
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYSQLPP_MYSQL_HEADERS_BURIED -std=c++11 -g -W -Wall -Wextra -O3")

# print compile info
#set(CMAKE_VERBOSE_MAKEFILE ON)

###
# sources file
###
set(MUDUO_NETWORK_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/muduo_network)
set(MUDUO_LOGGER_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/muduo_logger)
set(TEST_EXUTE_SOURCES_DIRECTORY ${SOURCES_DIRECTORY}/test_exute)

foreach(dir ${MUDUO_LOGGER_SOURCES_DIRECTORY})
  # get directory sources and headers
  file(GLOB s_${dir} "${dir}/*.cpp")
  file(GLOB h_${dir} "${dir}/*.hpp")

  # set async_logger sources
  set(muduo_logger_sources ${s_${dir}} ${h_${dir}})
endforeach()

foreach(dir ${MUDUO_NETWORK_SOURCES_DIRECTORY})
  # get directory sources and headers
  file(GLOB s_${dir} "${dir}/*.cpp")
  file(GLOB h_${dir} "${dir}/*.hpp")

  # set muiduo_network sources
  set(muduo_network_sources ${s_${dir}} ${h_${dir}})
endforeach()

#message("muduo_network_sources: ${muduo_network_sources}")

set(test_exute_sources
    ${WS_SERVER_SOURCES_DIRECTORY}/test_exute.cpp
    ${WS_SERVER_SOURCES_DIRECTORY}/main.cpp)

#message("test_exute_sources : ${test_exute_sources}")

###
#library
###
add_library(async_logging ${muduo_logger_sources})
add_library(muduo_server ${muduo_network_sources})

###
# executable
###
add_executable(test_exute ${test_exute_sources})

小結

這些是到目前對cmake使用,所用到的一些基本語法,和基本編譯調試手段的一點筆記,后續如有新玩法另加。


免責聲明!

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



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