cmake 基本入門(編譯可執行文件和動態庫)


編譯可執行文件

單文件

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

執行以下命令

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


免責聲明!

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



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