cmake使用方法(详细)
cmake使用方法(詳細)
- cmake
- 幫助文檔
- 技巧
- 命令行選項
- -D
- 編譯選項
- add_compile_options
- add_compile_definition
- option & add_definition
- 使用方法
- 語法說明
- 列表和字符串
- 變量
- 控制流
- 引號,字符串和轉義
- 正則表達式
- 常用命令
- cmake_minimum_required
- project
- set
- message
- mode關鍵字
- aux_source_directory 查找源文件
- add_library
- add_subdirectory
- include_directories 添加頭文件目錄
- link_directories 添加需要鏈接的庫文件目錄
- find_library 查找庫所在目錄
- link_libraries 添加需要鏈接的庫文件路徑
- target_link_libraries 設置要鏈接的庫文件的名稱
- add_executable 為工程生成目標文件
幫助文檔
技巧
cmake命令是不區分大小寫的,但是變量區分。
判斷編譯器類型
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")MESSAGE("Clang")elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")MESSAGE("GNU")elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")MESSAGE("Intel")elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")MESSAGE("MSVC")endif()命令行選項
-D
例子
cmake -DCMAKE_BUILD_TYPE=Debug編譯選項
在cmake腳本中,設置編譯選項可以通過add_compile_options命令,也可以通過set命令修改CMAKE_CXX_FLAGS或CMAKE_C_FLAGS。 使用這兩種方式在有的情況下效果是一樣的,但請注意它們還是有區別的:
例子
#判斷編譯器類型,如果是gcc編譯器,則在編譯選項中加入c++11支持 if(CMAKE_COMPILER_IS_GNUCXX)set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")message(STATUS "optional:-std=c++11") endif(CMAKE_COMPILER_IS_GNUCXX)add_compile_options
語法
add_compile_options(<option> ...)# 例子add_compile_options(-Wall -Wextra -pedantic -Werror -g)add_compile_definition
待補充
option & add_definition
語法
# Provides an option for the user to select as ON or OFF. If no initial <value> is provided, OFF is used. If <variable> is already set as a normal variable then the command does nothing option(<variable> "<help_text>" [value])# Add -D define flags to the compilation of source files. add_definitions(-DFOO -DBAR ...)使用方法
首先在CMakeList.txt中增加選項
option(TEST_DEBUG "option for debug" OFF) if (TEST_DEBUG) add_definitions(-DTEST_DEBUG) endif()在cmake構造makefile的時候輸入想要的參數
cmake -DTEST_DEBUG=ON ..源碼中使用該定義
// test.cpp #include "test.h"#ifdef TEST_DEBUG ... #endif語法說明
列表和字符串
在CMake中基礎的數據形式是字符串。CMake也支持字符串列表。
列表通過分號分隔。譬如兩個聲明給變量VAR設同樣的值:
set(VAR a;b;c) set(VAR a b c)字符串列表可以通過foreach命令迭代或直接操控列表命令。
變量
CMake 支持簡單的變量可以是字符串也可以是字符串列表。變量參考使用${VAR}語法。多參數可以使用set命令組合到一個列表中。所有其他的命令
通過空白分隔符傳遞命令來擴展列表,例如
set(Foo a b c) # 將 變量 Foo 設為 a b c, 并且如果Foo 傳遞給另一個命令 command(${Foo}) # 等同于 command(a b c)# 如果要把參數列表傳遞給一個命令,且它是一個簡單的參數只要加一個雙引號就可以。例如 command("${Foo}") # 等價于 command("a b c")控制流
像大多數語言一樣,Cmake 提供了控制流結構。Cmake提供了三中控制流:
條件控制流 if
# some_command will be called if the variable's value is not: # empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND. if(var) some_command(...) endif(var)循環結構: foreach 和 while
set(VAR a b c) # loop over a, b,c with the variable f foreach(f ${VAR})message(${f}) endforeach(f)過程定義 宏和函數(函數在2.6及更高的版本中有效)。函數對變量局部有效,宏是全局有效。
# define a macro hello macro(hello MESSAGE)message(${MESSAGE}) endmacro(hello) # call the macro with the string "hello world" hello("hello world") # define a function hello function(hello MESSAGE)message(${MESSAGE}) endfunction(hello)更多控制流信息參見命令 if,while,foreach,macro,function文檔。
引號,字符串和轉義
在CMake中原義字符串用雙引號括起來。字符串可以是多行字符串,并在其中嵌入新的行。例如
set(MY_STRING "this is a string with anewline init")也可以在一個字符串中轉義字符和使用變量
set(VAR "helloworld")message("\${VAR}= ${VAR}")# prints out${VAR}=helloworld同樣支持標準C中的轉義
message("\n\thello world")#prints outhello world如果字符在引號之前是空格則原義字符串只是原義字符串。但是引號必須成對,例如
message(hell"o") -> prints hell"o" message(hell\"o\") -> prints hello"o"正則表達式
cmake可以使用正則表達式
常用命令
cmake_minimum_required
cmake project 頭文件必須存在這行命令, 例如cmake_minimum_required(VERSION 3.10)
project
設置項目名稱project(Tutorial)
set
語法
# Set Normal Variable set(<variable> <value>... [PARENT_SCOPE])# Set Environment Variable # 這個環境變量只對當前cmake工程有效,對外界是無效的。 set(ENV{<variable>} [<value>])例子
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -Wall -Wl,-rpath=/tools/lib64 -Wl,--dynamic-linker=/tools/lib/ld-2.17.so")message
語法
message([<mode>] "message to display" ...)mode關鍵字
The optional <mode> keyword determines the type of message:
| FATAL_ERROR | CMake Error, stop processing and generation. |
| SEND_ERROR | CMake Error, continue processing, but skip generation. |
| WARNING | CMake Warning, continue processing. |
| AUTHOR_WARNING | CMake Warning (dev), continue processing. |
| DEPRECATION | CMake Deprecation Error or Warning if variable CMAKE_ERROR_DEPRECATED or CMAKE_WARN_DEPRECATED is enabled, respectively, else no message. |
| (none) or NOTICE | Important message printed to stderr to attract user’s attention. |
| STATUS | 一般就用這個,Ideally these should be concise, no more than a single line, but still informative. |
| VERBOSE | Detailed informational messages intended for project users. These messages should provide additional details that won’t be of interest in most cases, but which may be useful to those building the project when they want deeper insight into what’s happening. |
| DEBUG | Detailed informational messages intended for developers working on the project itself as opposed to users who just want to build it. These messages will not typically be of interest to other users building the project and will often be closely related to internal implementation details. |
| TRACE | Fine-grained messages with very low-level implementation details. Messages using this log level would normally only be temporary and would expect to be removed before releasing the project, packaging up the files, etc. |
aux_source_directory 查找源文件
# 找到所有dir目錄下的源文件(不會遞歸遍歷子文件夾),源文件是.c文件(也就是makefile中可以生成.o的文件) aux_source_directory(<dir> <variable>)add_library
將指定的源文件(CPP文件)生成鏈接文件,然后添加到工程中去。
語法
add_library(<name> [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL][source1] [source2 ...])其中<name>表示庫文件的名字,該庫文件會根據命令里列出的源文件來創建。而STATIC、SHARED和MODULE的作用是指定生成的庫文件的類型。
例子
add_library(roland_pb CreateUDiskRequest.pb.cc) add_executable(echo_client echo_client.cc) target_link_libraries(echo_client uevent event uevent_base pthread roland_pb protobuf)add_subdirectory
在子文件夾添加了library或者executable之后,在上層目錄添加subdirectory, 也可以在同一個CMakeList.txt中使用
include_directories 添加頭文件目錄
它相當于g++選項中的-I參數的作用,也相當于環境變量中增加路徑到CPLUS_INCLUDE_PATH變量的作用。
語法:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...]) # 例子 include_directories(../../../thirdparty/comm/include)link_directories 添加需要鏈接的庫文件目錄
它相當于g++命令的-L選項的作用,也相當于環境變量中增加LD_LIBRARY_PATH的路徑的作用。 語法:
`link_directories(directory1 directory2 ...)` # 例子 `link_directories("/home/server/third/lib")`find_library 查找庫所在目錄
語法:
# A short-hand signature is: find_library (<VAR> name1 [path1 path2 ...])# The general signature is: find_library (<VAR>name | NAMES name1 [name2 ...] [NAMES_PER_DIR][HINTS path1 [path2 ... ENV var]][PATHS path1 [path2 ... ENV var]][PATH_SUFFIXES suffix1 [suffix2 ...]][DOC "cache documentation string"][NO_DEFAULT_PATH][NO_CMAKE_ENVIRONMENT_PATH][NO_CMAKE_PATH][NO_SYSTEM_ENVIRONMENT_PATH][NO_CMAKE_SYSTEM_PATH][CMAKE_FIND_ROOT_PATH_BOTH |ONLY_CMAKE_FIND_ROOT_PATH |NO_CMAKE_FIND_ROOT_PATH])# 例子如下 FIND_LIBRARY(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH) cmake會在目錄中查找,如果所有目錄中都沒有,值RUNTIME_LIB就會被賦為NO_DEFAULT_PATHlink_libraries 添加需要鏈接的庫文件路徑
該指令的作用主要是指定要鏈接的庫文件的路徑,該指令有時候不一定需要。因為find_package和find_library指令可以得到庫文件的絕對路徑。不過你自己寫的動態庫文件放在自己新建的目錄下時,可以用該指令指定該目錄的路徑以便工程能夠找到。
語法:
link_libraries(library1 <debug | optimized> library2 ...)
# 直接是全路徑 link_libraries(“/home/server/third/lib/libcommon.a”) # 下面的例子,只有庫名,cmake會自動去所包含的目錄搜索 link_libraries(iconv)# 傳入變量 link_libraries(${RUNTIME_LIB}) # 也可以鏈接多個 link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")可以鏈接一個,也可以多個,中間使用空格分隔.
target_link_libraries 設置要鏈接的庫文件的名稱
語法:
target_link_libraries(<target> [item1 [item2 [...]]][[debug|optimized|general] <item>] ...)# 以下寫法都可以: target_link_libraries(myProject comm) # 連接libhello.so庫,默認優先鏈接動態庫 target_link_libraries(myProject libcomm.a) # 顯示指定鏈接靜態庫 target_link_libraries(myProject libcomm.so) # 顯示指定鏈接動態庫# 再如: target_link_libraries(myProject libcomm.so) #這些庫名寫法都可以。 target_link_libraries(myProject comm) target_link_libraries(myProject -lcomm)add_executable 為工程生成目標文件
語法:
add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL]source1 [source2 ...])簡單的例子如下:
add_executable(demo main.cpp) add_executable(echo_client echo_client.cc CreateUDiskRequest.pb.cc)
本篇文章由一文多發平臺ArtiPub自動發布
總結
以上是生活随笔為你收集整理的cmake使用方法(详细)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java面试必学-吐血推荐
- 下一篇: linux网络编程--select/po