編譯可執行文件
單文件
cmake_minimum_required(VERSION 3.4.2) project(single) # 定義項目名稱 add_executable(single main.cc) # 添加可執行文件
main.cc 如下

#include <stdio.h> #include <stdlib.h> double power(double base, int exponent) { int result = base; int i; if (exponent == 0) { return 1; } for(i = 1; i < exponent; ++i){ result = result * base; } return result; } int main(int argc, char *argv[]) { if (argc < 3){ printf("Usage: %s base exponent \n", argv[0]); return 1; } double base = atof(argv[1]); int exponent = atoi(argv[2]); double result = power(base, exponent); printf("%g ^ %d is %g\n", base, exponent, result); return 0; }
執行以下命令
mkdir build && cd build && cmake .. && make
結果如下,就是這么簡單,不過對於單文件,沒有直接gcc或者g++來的直接
├── CMakeLists.txt ├── build │ ├── CMakeCache.txt │ ├── CMakeFiles │ ├── Makefile │ ├── cmake_install.cmake │ └── single └── main.cc
單目錄多文件
我們把main.cc里面的power函數的拆分到頭文件和cc文件,修改CMakeLists.txt如下
cmake_minimum_required(VERSION 3.4.2) project(single) aux_source_directory(. DIR_SRCS) # 遍歷目錄的所有文件,賦值給Dir_SRCS add_executable(single ${DIR_SRCS})
還是一樣執行以下命令
mkdir build && cd build && cmake .. && make
這個時候cmake比傳統的gcc和g++要好一點了
├── CMakeLists.txt ├── MathFunction.cc ├── MathFunctions.h ├── build │ ├── CMakeCache.txt │ ├── CMakeFiles │ ├── Makefile │ ├── cmake_install.cmake │ └── single └── main.cc
多目錄多文件
我們再折騰一下,把power函數相關的放入一個math文件夾,目錄結構如下
├── CMakeLists.txt ├── main.cc └── math ├── MathFunction.cc └── MathFunctions.h
同時修改CMakeLists.txt加入math目錄
cmake_minimum_required (VERSION 2.8) project (many) set(CMAKE_MACOSX_RPATH 1) aux_source_directory(. DIR_SRCS) aux_source_directory(./math MATH) list(APPEND DIR_SRCS ${MATH}) add_executable(many ${DIR_SRCS})
最后執行以下命令即可
mkdir build && cd build && cmake .. && make
多目錄+子目錄.a文件
我們稍作修改一下,我們想讓math先編譯成.a文件,這樣math的用途可以更廣
注意目錄結構中,math文件夾里多了一個CMakeLists.txt文件,這意味着math文件夾可以獨立編譯
├── CMakeLists.txt ├── main.cc └── math ├── CMakeLists.txt ├── MathFunction.cc └── MathFunctions.h
我們看下math的CMakeLists文件,很簡單,不同的是生成了一個靜態庫
aux_source_directory(. DIR_LIB_SRCS)
# 生成鏈接庫
add_library (math STATIC ${DIR_LIB_SRCS})
主目錄的CMakeLists文件也有小小的變動
cmake_minimum_required (VERSION 2.8) project (many) set(CMAKE_MACOSX_RPATH 1) aux_source_directory(. DIR_SRCS) # 添加 math 子目錄 add_subdirectory(./math math) add_executable(many ${DIR_SRCS}) target_link_libraries(many math)
最后的目錄結構如下(省略了一些重復的目錄文件),可以看到math目錄下面生成了一個.a文件
├── CMakeLists.txt ├── build │ ├── many │ └── math │ └── libmath.a ├── main.cc └── math ├── CMakeLists.txt ├── MathFunction.cc └── MathFunctions.h
最后看下這四種方式生成的可執行文件是否都能正常工作
$ cd ../../single_file/build/ $ ./single 2 3 2 ^ 3 is 8 $ cd ../../single_dir_many_file/build/ $ ./single 2 3 2 ^ 3 is 8 $ cd ../../many_dir_many_file/build/ $ ./many 2 3 2 ^ 3 is 8 $ cd ../../many_dir_many_file_a/build/ $ ./many 2 3 2 ^ 3 is 8
生成動態庫
也是很簡單的,改動CMakeLists文件的一行即可
cmake_minimum_required (VERSION 2.8) project (many) set(CMAKE_MACOSX_RPATH 1) aux_source_directory(. DIR_SRCS) # 添加 math 子目錄 add_subdirectory(./math math) # 就是下面這一行 add_library(many SHARED ${DIR_SRCS}) target_link_libraries(many math)
在mac上面生成的動態庫不是.so后綴,而是.dylib后綴(相同的代碼在Linux上生成的應該是so)
├── CMakeLists.txt ├── build │ ├── libmany.dylib │ └── math ├── main.cc └── math ├── CMakeLists.txt ├── MathFunction.cc └── MathFunctions.h
mac上生成so動態庫
如果是mac開發給Android或者Linux系統用,自然就有生成so動態庫的需求,以Android為例,修改CMakeLists如下(碰到的大坑:set 命令要放在project命令前面,否則可能不生效,因為命令行可以但CmakeLists不行所以發現了這個大坑)
cmake_minimum_required (VERSION 2.8) set(CMAKE_SYSTEM_NAME Android) # 如果沒有配置相關環境變量,可以參考下面的設置 # set(CMAKE_ANDROID_NDK "/Users/qiweijie/Tools/android-ndk-r15c") # set(CMAKE_TOOLCHAIN_FILE "/Users/qiweijie/Tools/android-ndk-r15c/build/cmake/android.toolchain.cmake") # set(ANDROID_TOOLCHAIN clang) # set(ANDROID_NATIVE_API_LEVEL 14) # set(ANDROID_ABI "armeabi-v7a") # set(CMAKE_BUILD_TYPE Release) # set(CMAKE_CROSSCOMPILING "TRUE") # set(CMAKE_CXX_STANDARD 11) #c++標准 project (many) aux_source_directory(. DIR_SRCS) # 添加 math 子目錄 add_subdirectory(./math math) add_library(many SHARED ${DIR_SRCS}) target_link_libraries(many math)
done