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

posted @ 2019-12-21 19:38  2BiTT  阅读(8017)  评论(0编辑  收藏  举报