• Makefile与CMakeLists.txt


    make与Makefile,cmake与CMakeLists.txt

    make用来编译c++项目,make命令根据Makefile中配置的编译链接关系;由于Makefile文件的制作是个大工程,因此出现了cmake工具cmake根据CMakeLists.txt来执行cmake命令;

    使用CMake编写跨平台工程的流程如下:

    (1)编写源文件

    (2)编写CMakeLists.txt

    (3)由CMake根据CMakeLists.txt来生成相应的makefile文件

    (4)使用make并根据makefile调用gcc来生成相应的可执行文件

    CMake是一个可以跨平台的编译工具,可以用简单的语句来描述所有平台的编译过程。他能够输出各种各样的 makefile 或者工程文件。和make与makefile类似,我们在使用CMake时同样也需要一个文件来提供规则,这个文件就是CMakeLists

    CMakeLists.txt

    编写CMakeLists.txt最常用的功能就是调用其他的.h头文件和.so/.a库文件,将.cpp/.c/.cc文件编译成可执行文件或者新的库文件。

    # 指定cmake最小版本
    cmake_minimun_version(VERSION 3.4.1)
    
    # 本CMakeLists.txt的project名称
    # 会自动创建两个变量,PROJECT_SOURCE_DIR和PROJECT_NAME 
    # ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的文件夹路径
    # ${PROJECT_NAME}:本CMakeLists.txt的project名称
    # CMAKE_BINART_DIR, PROJECT_BINARY_DIR, _BINARY_DIR:这三个变量的含义一样。
    project(xxx)
    
    # 获取路径下所有的.cpp/.c/.cc文件,并赋值给变量中
    aux_source_directory(路径 变量)
    
    # 给文件名/路径名或其他字符串起别名,用${变量}获取变量内容
    set(变量 文件名/路径/...)
    
    # 添加编译选项
    add_definitions(编译选项)
    
    # 打印消息
    message(消息)
    
    # 编译子文件夹的CMakeLists.txt
    add_subdirectory(子文件夹名称) 
    
    # 将.cpp/.c/.cc文件生成可执行文件
    add_executable(可执行文件名称 文件)
    
    # 将.cpp/.c/.cc文件生成.a静态库 // add_library(库文件名称 STATIC 文件)
    # 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
    # 生成静态库(默认) 
    add_library(myCommonLib STATIC util.cpp)
    # 生成动态库
    add_library(myCommonLib SHARED util.cpp)
    
    # 规定.h头文件路径
    include_directories(路径)
    
    # 规定.so/.a库文件路径
    link_directories(路径)
    
    # 对add_library或add_executable生成的文件进行链接操作
    # 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
    target_link_libraries(库文件名称/可执行文件名称 链接的库文件名称)
    # 如果是链接的库,则运行的时候需要把它拷贝到可执行文件名称同目录下
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    如何设置DGB调试模式请看这里

    CMakeLists设置源文件的方法

    1.明确制定包含的源文件

    add_library(demo demo.cpp test.cpp util.cpp)
    
    • 1

    2.搜索所有cpp文件

    # 发现一个目录下所有的源代码文件,并将列表存储再一个变量中(不会递归遍历目录)
    aux_source_directory(. SRC_LIST)
    add_library(demo ${SRC_LIST})
    
    • 1
    • 2
    • 3

    3.自定义搜索规则

    file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
    add_library(demo ${SRC_LIST})
    #或者
    file(GLOB SRC_LIST "*.cpp")
    file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
    add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
    #或者
    aux_source_directory(. SRC_LIST)
    aux_source_directory(protocol SRC_PROTOCOL_LIST)
    add_library(demo ${SRC_LIST) ${SRC_PROTOCOL_LIST)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    添加编译选项

    功能1

    add_definitions的功能和C/C++中的#define是一样的

    # 添加一个宏定义,设置后,代码中即可使用 `TEST_DEBUG`这个宏,等同在代码中增加 #define TEST_DEBUG
    add_definitions(-DTEST_DEBUG)
    
    • 1
    • 2

    于是cpp代码中,就可以使用TEST_DEBUG这个宏了

    #ifdef TEST_DEBUG
    ...
    #else 
    ...
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5

    问题是,由谁来驱动定义这个宏呢?通过结合options指令可以实现

    # 设置一个宏选项默认值ON,
    # option选项 不会影响到cpp代码(不会添加#define宏)
    option(TEST_DEBUG "test"  ON)
    if(TEST_DEBUG )
    	message("itis" ${TEST_IT_CMAKE})
    	add_definitions(-DTEST_DEBUG )
    endif()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    最后,在执行cmake时,就可以设置该选项了,并传递该值下去;

    cmake .. -DTEST_DEBUG=1
    
    • 1

    通过cmake-gui也可以很方便的配置选项,如下:
    在这里插入图片描述

    功能2
    add_definitions("-Wall -g")
    
    • 1
    #没加之前
    gcc -c main.c -o test
    
    • 1
    • 2
    #添加之后,相当于
    gcc -g -Wall -c main.c -o tes
    
    • 1
    • 2

    CMakeLists 查找so库的方法

    #在指定目录下搜索一个库, 保存在变量MY_LIB中
    find_library(MY_LIB "usr/lib/libmylib.so" )
    
    #链接这个库
    target_link_libraries(${PROJECT_NAME}  ${MY_LIB})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 常用的预定义变量
    变量说明
    PROJECT_SOURCE_DIR工程根目录
    PROJECT_BINARY_DIR运行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build
    PROJECT_NAME返回通过project命令定义的项目名称
    CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在的路径
    CMAKE_CURRENT_BINARY_DIRtarget 编译目录
    CMAKE_CURRENT_LIST_DIRCMakeLists.txt的完整路径
    CMAKE_CURRENT_LIST_LINE当前所在的行
    CMAKE_MODULE_PATH定义自己cmake模块所在的路径。SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
    EXECUTABLE_OUTPUT_PATH重新定义目标二进制可执行文件的存放位置
    LIBRARY_OUTPUT_PATH重新定义目标链接库的存放位置
    1. 环境变量
      1. 使用环境变量$ENV{name}
      2. 写入环境变量 set(ENV{name} value)

    如何使用CMakeLists.txt 完成一次编译过程

    创建如下目录结构

    - /myCpp
     - CMakeLists.txt 
     - /build
     - /src
       - myHello.cpp 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    myHello.cpp

    #include 
    int main() {
        std::cout<<"Hello world!"<<std::endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.0)
    project(Hello)
    MESSAGE(STATUS"This is BINARY_dir" ${PROJECT_BINARY_DIR})
    MESSAGE(STATUS"This is SOURCE_dir"${PROJECT_SOURCE_DIR})
    aux_source_directory(./src DIR_SRCS)
    add_executable(${PROJECT_NAME} ${DIR_SRCS})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    编译过程

    $ cd build
    $ cmake ..
    -- The C compiler identification is GNU 5.4.0
    -- The CXX compiler identification is GNU 5.4.0
    -- Check for working C compiler: /usr/bin/cc
    -- Check for working C compiler: /usr/bin/cc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    STATUS"This is BINARY_dir"/home/bing/bingCpp/myDemo/build
    STATUS"This is SOURCE_dir"/home/bing/bingCpp/myDemo
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/bing/bingCpp/myDemo/build
    $ make
    Scanning dependencies of target Hello
    [ 50%] Building CXX object CMakeFiles/Hello.dir/src/main.cpp.o
    [100%] Linking CXX executable Hello
    [100%] Built target Hello
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    DragGAN部署全流程
    逻辑回归预测瘀血阻络证||LogRegression 二分类 python3
    axios的两种请求方法
    不知道HTTPS的加密原理,相信我,看这一篇就够了!
    多线程系列(二十) -CompletableFuture使用详解
    二进制部署kubernetes集群的推荐方式
    获取手机位置信息
    LeetCode算法二叉树—108. 将有序数组转换为二叉搜索树
    Flutter实践二:repository模式
    LVGL Animations(动画)的简单使用
  • 原文地址:https://blog.csdn.net/youlinhuanyan/article/details/126079321