1 簡單的可執行文件生成工程
1.1 源文件
main.cpp
#include <stdio.h> int main(int argc, char *argv[]) { printf("Hello CMake!/n"); return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
1.2 CMakeLists.txt文件
CMakeLists.txt
# 版本限定 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 項目名稱 PROJECT(Test1) # 添加源文件列表變量 SET(SRC_LIST main.cpp) # 打印編譯目錄和項目目錄路徑 MESSAGE(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR}) MESSAGE(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR}) # 生成可執行文件 ADD_EXECUTABLE(HelloCMake ${SRC_LIST})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2 只單獨生成靜態庫和動態庫
2.1 工程目錄
.
├── build
├── CMakeLists.txt ├── include │ └── mymath.h └── src └── mymath.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2.2 工程文件
mymath.h
#ifndef _MYMATH_H_ #define _MYMATH_h_ int add(int a, int b); int sub(int a, int b); #endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
mymath.c
#include "mymath.h" int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2.3 CMakeLists.txt
# 版本限定 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 項目名稱 PROJECT(Test2) # 設置編譯器選項:O3優化,顯示所有警告 SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O3 -Wall") # 定義頭文件的路徑變量 SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/include) MESSAGE(STATUS "Include Path, ${INCLUDE_PATH}") # 定義源文件路徑變量 SET(SOURCE_PATH ${PROJECT_SOURCE_DIR}/src) MESSAGE(STATUS "Source Path , ${SOURCE_PATH}") # 包含頭文件路徑 INCLUDE_DIRECTORIES(${INCLUDE_PATH}) # 添加源文件路徑下所有源文件存放到變量中(*.c && *.cpp),當然也可以手動一個個文件添加進來 AUX_SOURCE_DIRECTORY(${SOURCE_PATH} SRC_LIST) # 設置動態庫輸出路徑 SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) MESSAGE(STATUS "Library Output Path, " ${PROJECT_BINARY_DIR/lib}) # 生成動態庫(libmymath.so) ADD_LIBRARY(mymath SHARED ${SRC_LIST}) # 生成靜態庫(libmymath.a,target名字只能有一個,所以不能與動態庫的名字一樣) ADD_LIBRARY(mymath_static STATIC ${SRC_LIST}) # 但是可以通過下面的命令更改靜態庫target生成的庫名,這樣就和動態庫的名字一樣的了 SET_TARGET_PROPERTIES(mymath_static PROPERTIES OUTPUT_NAME "mymath")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
3 外鏈接動態庫和靜態庫生成可執行文件
3.1 工程目錄
.
├── build
├── CMakeLists.txt ├── include │ └── mymath.h ├── libs │ ├── libmymath.a │ └── libmymath.so └── src └── main.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3.2 工程文件
mymath.h
#ifndef _MYMATH_H_ #define _MYMATH_h_ int add(int a, int b); int sub(int a, int b); #endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
main.c(注意:因為編譯的動/靜態庫是采用的C語言,所以只能寫為main.c,而不是main.cpp,否則在鏈接的時候出問題,當然比較好的做法就是在生成庫的時候加入extern "C"關鍵字,增加兼容性)
#include <stdio.h> #include "mymath.h" int main() { printf("Hello CMake!\n"); printf("1 + 5 = %d\n", add(1, 5)); return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3.3 CMakeLists.txt
# 版本限定 CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 項目名稱 PROJECT(Test3) # 設置編譯器選項:O3優化,顯示所有警告 SET(CMAKE_C_FLAGS "$ENV{CFLAGS} -O3 -Wall") # 定義頭文件的路徑變量 SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/include) MESSAGE(STATUS "Include Path, ${INCLUDE_PATH}") # 定義庫文件路徑 SET(LIB_PATH ${PROJECT_SOURCE_DIR}/libs) MESSAGE(STATUS "Libs Path, ${LIB_PATH}") # 定義源文件路徑變量 SET(SOURCE_PATH ${PROJECT_SOURCE_DIR}/src) MESSAGE(STATUS "Source Path , ${SOURCE_PATH}") # 包含頭文件搜索路徑 INCLUDE_DIRECTORIES(${INCLUDE_PATH}) # 包含庫搜索路徑 LINK_DIRECTORIES(${LIB_PATH}) # 定義待鏈接庫名字 # 鏈接靜態庫 SET(LIBS_LIST libmymath.a) # 鏈接動態庫 #SET(LIBS_LIST libmymath.so) # 添加源文件路徑下所有源文件存放到變量中(*.c && *.cpp) AUX_SOURCE_DIRECTORY(${SOURCE_PATH} SRC_LIST) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) # 設置生成可執行文件的名稱 SET(EXECUTABLE_FILE_NAME mymath.exe) # 生成可執行文件 ADD_EXECUTABLE(${EXECUTABLE_FILE_NAME} ${SRC_LIST}) # 設置可執行文件鏈接的庫名稱 TARGET_LINK_LIBRARIES(${EXECUTABLE_FILE_NAME} ${LIBS_LIST})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
4 CMake常用系統變量
# 編譯目錄路徑,下面三個變量均是同樣的值 CMAKE_BINARY_DIR PROJECT_BINARY_DIR <projectname>_BINARY_DIR # 工程頂層路徑,三個均是同樣的值 CMAKE_SOURCE_DIR PROJECT_SOURCE_DIR <projectname>_SOURCE_DIR # 當前CMakeLists.txt的路徑,如果子目錄下有CMakeLists.txt,那么該值與CMAKE_SOURCE_DIR不一樣 CMAKE_CURRENT_SOURCE_DIR # 當前CMakeLists.txt的目標文件輸出路徑,意義同上 CMAKE_CURRRENT_BINARY_DIR ADD_SUBDIRECTORY(src "更改為子目錄新的目標文件輸出路徑") # 設置目標文件的存放路徑 EXECUTABLE_OUTPUT_PATH # 設置庫文件的存放路徑 LIBRARY_OUTPUT_PATH # 設置工程名 PROJECT_NAME # 主版本號,比如2.4.6中的2,通過SET命令來設置 CMAKE_MAJOR_VERSION,CMAKE # 次版本號,比如2.4.6中的4 CMAKE_MINOR_VERSION,CMAKE # 補丁等級,比如2.4.6 中的6 CMAKE_PATCH_VERSION,CMAKE # 系統名稱,比如Linux-2.6.22 CMAKE_SYSTEM # 不包含版本的系統名,比如Linux CMAKE_SYSTEM_NAME # 系統版本,比如2.6.22 CMAKE_SYSTEM_VERSION # 處理器名稱,比如i686 CMAKE_SYSTEM_PROCESSOR # 在所有的類UNIX平台為TRUE,包括OS X和cygwin UNIX # 在所有的win32平台為TRUE,包括cygwin WIN32 # 動/靜態庫生成全局控制 BUILD_SHARED_LIBS # C編譯器選項(ADD_DEFINITIONS也可以添加選項) CMAKE_C_FLAGS/CMAKE_C_FLAGS_DEBUG/CMAKE_C_FLAGS_RELEASE SET(CMAKE_C_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") # C++編譯器選項 CMAKE_CXX_FLAGS/CMAKE_CXX_FLAGS_DEBUG/CMAKE_CXX_FLAGS_RELEASE SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -lpthread -lm")
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
5 CMake常用的指令說明
add_definitions(-DXXX1 -DXXX2 ...)
remove_definitions(-DXXX1 -DXXX2 ...)
# 添加/移出宏定義
- 1
- 1
aux_source_directory(dir variable)
# 作用是發現一個目錄下所有的源代碼文件並將列表存儲在一個變量中,這個指令臨時被用來自動構建源文件列表。如將當前文件夾中所有源文件放入一個變量中: AUX_SOURCE_DIRECTORY(. DIR_SRCS)
- 1
- 2
- 3
- 1
- 2
- 3
include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
# 添加編譯所需的頭文件 INCLUDE_DIRECTORIES(${XXX_INCLUDE_PATH} ${Other_INCLUDE_PATH} ${PROJECT_INCLUDE_PATH})
- 1
- 2
- 1
- 2
link_directories(directory1 directory2 ...)
# 添加庫搜索文件夾 LINK_DIRECTORIES(${XX1_LIB_PATH} ${XX2_LIB_PATH})
- 1
- 2
- 1
- 2
target_link_libraries(<target> [item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
# 指明可執行文件或者庫文件需要連接的鏈接庫(靜態or動態) add_library(A STATIC a.c) add_library(B STATIC b.c) target_link_libraries(A B) target_link_libraries(B A) add_executable(main main.c) target_link_libraries(main A)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED [GLOBAL])
# 參數 name 為欲生成的庫名稱,默認不加修飾為靜態庫,但是最后會受BUILD_SHARED_LIBS全局變量的影響,此變量默認為OFF,生成庫文件是,不需要加前綴lib add_library(calc calc.c) add_library(mylib ${mylib_sources})
- 1
- 2
- 3
- 1
- 2
- 3
get_filename_component(<VAR> <FileName> <COMP> [CACHE])
# 獲取一個完整名的特定部分 # 獲取PROJECT_SOURCE_DIR路徑中去除項目名稱的路徑部分 # 保存到變量WORKSPACE_DIR中(當cmake版本低於2.8.11時,component的值取PATH與大於2.8.11版本中的DIRECTORY的效果是一樣的) # <= 2.8.11 get_filename_component(WORKSPACE_DIR ${PROJECT_SOURCE_DIR} PATH) # > 2.8.11 get_filename_component(WORKSPACE_DIR ${PROJECT_SOURCE_DIR} DIRECTORY) # 各component說明如下 DIRECTORY = Directory without file name NAME = File name without directory EXT = File name longest extension (.b.c from d/a.b.c) NAME_WE = File name without directory or longest extension ABSOLUTE = Full path to file REALPATH = Full path to existing file with symlinks resolved PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
參考資料和擴展閱讀
https://cmake.org/cmake/help/v2.8.12/cmake.html
http://blog.csdn.net/freeape/article/details/52567087

