使用cmake构建C/C++项目和动态库

作者: QxQx | 来源:发表于2021-03-13 17:45 被阅读0次

    编译C/C++文件时,很多时候都是直接使用像 gcc main.c 或者 g++ main.cpp 这样的命令编译的。但是代码文件多了后,这样编译就很困难了。这时候 就出现了MakeFile 这个工具。

    MakeFile 解决了多个文件编译难的问题,有了MakeFile,只需要在MakeFile的目录中 运行一下make 命令, 编译就会自动完成。但是编写MakeFile又很啰嗦,于是聪明的程序员们有开发了一个工具,自动生成MakeFile 文件,cmake 的作用就是自动生成MakeFile。毕竟写cmake要比写MakeFile要简单很多

    也许你会说,现在都是用IDE写代码,IDE都会自动自动编译和运行,我还学这些干啥。但是有时候需要服务器上编译项目,或者在没有IDE的机器上编译项目,这时候MakeFile就很有用了。其实很多IDE也是使用cmake完成编译的,比如 clion

    cmake 安装

    在linux上可以使用源码安装和包管理安装,一般直接用包管理安装就好了
    Ubuntu和Debian
    sudo apt-get install cmake

    CentOS
    sudo yum install cmake

    因为cmake只是生成MakeFile,最终组织编译的还是MakeFile,所以还有安装make

    make 一般都会预装,为了保险,还是装一下

    Ubuntu和Debian
    sudo apt-get install make

    CentOS
    sudo yum install make

    cmake基本规则

    cmake 也没啥神秘的,本质上也是根据一定的规则自动生成MakeFile的,也是有语法的

    # 是注释符号

    预定义变量

    PROJECT_NAME项目名称
    PROJECT_SOURCE_DIR工程的根目录
    PROJECT_BINARY_DIR 执行cmake命令的目录
    PROJECT_BINARY_DIR 执行cmake命令的目录
    CMAKE_CURRENT_SOURCE_DIR当前CMakeLists.txt文件所在目录
    CMAKE_C_FLAGS设置C编译选项
    CMAKE_CXX_FLAGS设置C++编译选项
    CMAKE_C_COMPILER设置C编译器
    CMAKE_CXX_COMPILER设置C++编译器
    EXECUTABLE_OUTPUT_PATH设置编译后可执行文件目录
    LIBRARY_OUTPUT_PATH设置生成的库文件目录

    常用规则

    cmake_minimum_required(VERSION 3.16) 指令cmake 版本
    project(hello_world) 设置工程名
    include_directories(${PROJECT_SOURCE_DIR}/include) 添加头文件路径
    link_directories(${PROJECT_SOURCE_DIR}/lib) 添加链接库的路径
    add_subdirectory(module)添加 module 子目录, 此目录下也要有CMakeLists.txt文件
    add_executable(project1 main.c)指定编译的可执行文件
    add_library(lib1 SHARED library.c library.h)指定生成的库文件,SHARED是生成动态库,STATIC后生成静态库
    add_compile_options() 添加编译选项
    target_link_libraries()指定动态链接库
    install()指定make install的目录

    set(XXXX YYYYYY)用于设置和修改变量
    ${XXXX} 使用变量

    构建一个简单的项目

    只有一个 main.c 文件

    CMakeList.txt

    cmake_minimum_required(VERSION 3.15)
    project(project1 C)
    
    set(CMAKE_C_STANDARD 99)
    
    add_executable(project1 main.c)
    

    main.c

    #include <stdio.h>
    
    int main() {
        printf("Hello, CMakeList!\n");
        return 0;
    }
    
    编译一个debug版本
    1. mkdir debug 新建debug目录
    2. cd debug 进入debug目录
    3. cmake -DCMAKE_BUILD_TYPR=debug .. 指定编译模式为debug
    4. make 生成可执行文件

    此时会生成project1文件

    步骤 3 中 cmake -DCMAKE_BUILD_TYPE=release .. 指定编译模式为release

    构建一个生成动态库的项目

    有两个文件library.hlibrary.c
    CMakeList.txt

    cmake_minimum_required(VERSION 3.15)
    project(shared C)
    
    set(CMAKE_C_STANDARD 99)
    
    add_library(shared SHARED library.c library.h)
    

    library.h

    int add(int a, int b);
    

    library.c

    int add(int a, int b) {
        return a + b;
    }
    
    生成动态库
    1. mkdir lib 新建lib目录
    2. cd lib 进入lib目录
    3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
    4. make 生成可执行文件
      此时会生成 libshared.so文件

    在第一个项目中使用动态库

    首先把 libshared.so文件和library.h文件复制到第一个项目中

    修改 CMakeList.txt

    cmake_minimum_required(VERSION 3.15)
    project(project1 C)
    
    set(CMAKE_C_STANDARD 99)
    
    add_executable(project1 main.c)
    
    target_link_libraries(project1 ${PROJECT_SOURCE_DIR}/libshared.so)#指定动态库文件
    
    1. mkdir debug 新建debug目录
    2. cd debug 进入debug目录
    3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
    4. make 生成可执行文件

    最终目录如图


    把两个项目合成一个

    能不能在一个项目中生成动态库并在这个项目中使用呢,当然是可以的。

    也就是在这个项目中部分文件编译成动态库 .so 文件, 部分文件编译成 可执行文件

    修改 CMakeList.txt

    cmake_minimum_required(VERSION 3.13.3)
    project(project1 C)
    
    set(CMAKE_C_STANDARD 99)
    
    add_library(shared SHARED library.h library.c)
    
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)#设置动态库输出目录
    
    add_executable(project1 main.c)
    
    target_link_libraries(project1 shared)
    
    1. mkdir debug 新建debug目录
    2. cd debug 进入debug目录
    3. cmake -DCMAKE_BUILD_TYPE=debug .. 指定编译模式为debug
    4. make 生成可执行文件

    最终目录如图

    最后

    通过几个简单的例子,介绍了一下cmake的基本使用,文中是使用cmake构建的C项目,换成C++基本没什么区别,就不展示了

    cmake的功能远不止这些,还需要在实战中多学习,多总结

    2021-03-06 补充
    通过上面的方式可以编译运行,但是会有一个问题,就是 .so 文件不能更改目录,一旦动态库目录变了,程序就没法加载,程序也就没法运行了。为此又找资料学习一番,另写了一篇,传送门

    相关文章

      网友评论

        本文标题:使用cmake构建C/C++项目和动态库

        本文链接:https://www.haomeiwen.com/subject/bzixcltx.html