zoukankan      html  css  js  c++  java
  • 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 
    ", argv[0]);
            return 1;
        }
        double base = atof(argv[1]);
        int exponent = atoi(argv[2]);
        double result = power(base, exponent);
        printf("%g ^ %d is %g
    ", 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

  • 相关阅读:
    波形相加
    2003-2011电赛题目
    个人课程总结
    程序员的修炼之道:从小工到专家阅读笔记03
    程序员修炼之道:从小工到专家阅读笔记02
    计算最长英语单词链
    学习进度十五
    程序员修炼之道:从小工到专家阅读笔记01
    学习进度十四
    用户体验评价
  • 原文地址:https://www.cnblogs.com/qwj-sysu/p/12076648.html
Copyright © 2011-2022 走看看