1. 程式人生 > >cmake常用工程示例大集合

cmake常用工程示例大集合

1 簡單的可執行檔案生成工程

1.1 原始檔

  main.cpp

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello CMake!/n");

    return 0;
}

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})

2 只單獨生成靜態庫和動態庫

2.1 工程目錄

.
├── build
├── CMakeLists.txt
├── include
│   └── mymath.h
└── src
    └── mymath.c

2.2 工程檔案

  mymath.h

#ifndef _MYMATH_H_
#define _MYMATH_h_

int add(int a, int b);
int sub(int a, int b);

#endif

  mymath.c

#include "mymath.h"

int add(int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

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")

3 外連結動態庫和靜態庫生成可執行檔案

3.1 工程目錄

.
├── build
├── CMakeLists.txt
├── include
│   └── mymath.h
├── libs
│   ├── libmymath.a
│   └── libmymath.so
└── src
    └── main.c

3.2 工程檔案

  mymath.h

#ifndef _MYMATH_H_
#define _MYMATH_h_

int add(int a, int b);
int sub(int a, int b);

#endif

  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;
}

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})

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")

5 CMake常用的指令說明

  add_definitions(-DXXX1 -DXXX2 ...)
  remove_definitions(-DXXX1 -DXXX2 ...)

# 新增/移出巨集定義

  aux_source_directory(dir variable)

# 作用是發現一個目錄下所有的原始碼檔案並將列表儲存在一個變數中,這個指令臨時被用來自動構建原始檔列表。如將當前資料夾中所有原始檔放入一個變數中:
AUX_SOURCE_DIRECTORY(. DIR_SRCS)

  include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

# 新增編譯所需的標頭檔案
INCLUDE_DIRECTORIES(${XXX_INCLUDE_PATH} ${Other_INCLUDE_PATH} ${PROJECT_INCLUDE_PATH})

  link_directories(directory1 directory2 ...)

# 新增庫搜尋資料夾
LINK_DIRECTORIES(${XX1_LIB_PATH} ${XX2_LIB_PATH})

  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)

  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})

  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)

參考資料和擴充套件閱讀