• [CMAKE] 详解CMakeLists.txt文件


    【快速查询】https://cmake.org/cmake/help/v2.8.8/cmake.html#section_Commands

    1、CMake简介

      CMake是跨平台编译工具,比make更高级一些。其编译的主要工作是生成CMakeLists.txt文件,然后根据该文件生成Makefile,最后调用make来生成可执行程序或者动态库。所以基本步骤就只有两步:(1)cmake生成CMakeLists.txt文件;(2)make执行编译工作。

      下面一张图对比一下AutoTools与CMake的工作流程(可见CMake比较清晰简洁):

     

    2、CMakeLists.txt文件

    详情参考:http://wiki.ros.org/catkin/CMakeLists.txt

    1、Required CMake Version (cmake_minimum_required)
    2、Package Name (project())
    3、Find other CMake/Catkin packages needed for build (find_package())
    4、Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())
    5、Invoke message/service/action generation (generate_messages())
    6、Specify package build info export (catkin_package())
    7、Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())
    8、Tests to build (catkin_add_gtest())
    9、Install rules (install())

    (1)CMake Version: 
    每一个 catkin CMakeLists.txt 必须以 CMake 需要的版本开始,Catkin 需要版本 2.8.3 或者更高

    cmake_minimum_required(VERSION 2.8.3)

    (2)Package name: 
    CMake project function 指定的文件名。

    project(robot_brain)

    在 CMake script 文件中,引用 CMake package 可以使用变量 ${PROJECT_NAME}

    (3)依赖功能包:

    寻找需要用到的其他 CMake packages,用函数 find_package。 
    至少依赖一个关于 catkin 的功能包

    find_package(catkin REQUIRED)

    如果要使用 C++ 和 Boost,则需要引用 find_package 包含 Boost,并且指明 Boost 的类型,如使用 Boost threads,则:

    find_package(Boost REQUIRED COMPONENTS thread)

     (4)catkin_package() 

    catkin_package() 是 catkin 支持的 CMake 宏指令。用来向编译系统指明 catkin-specific 的信息,而编译系统来生成 pkg-config and CMake files。

    该函数必须用在用 add_library() or add_executable() 声明之前。 
    有5个可选参数:

    INCLUDE_DIRS - The exported include paths (i.e. cflags) for the package
    LIBRARIES - The exported libraries from the project
    CATKIN_DEPENDS - Other catkin projects that this project depends on
    DEPENDS - Non-catkin CMake projects that this project depends on
    CFG_EXTRAS - Additional configuration options

     例如:

    catkin_package(
       INCLUDE_DIRS include
       LIBRARIES ${PROJECT_NAME}
       CATKIN_DEPENDS roscpp nodelet
       DEPENDS eigen opencv)

     (5)Specifying Build Targets

    3、一个简单的CMakeLists.txt入门示例

      外部编译:单独建立一个空目录专门用于cmake编译,便于管理编译中间文件。在空目录中用 cmake ../(CMakeLists.txt所在目录)就行了,中间文件生成在当前目录。

      工程结构:

    .
    ├── build
    ├── CMakeLists.txt
    ├── include
    │   └── math_lib.h
    └── src
        ├── main.cpp
        └── math_lib.cpp
    
    3 directories, 4 files

      CMakeLists.txt示例(借鉴网友配置)

    # 1.cmake verson,指定cmake版本 
    cmake_minimum_required(VERSION 3.4.1)
    
    # 2.project name,指定项目的名称,一般和项目的文件夹名称对应
    PROJECT(test_math_lib)
    
    # 3.head file path,头文件目录
    INCLUDE_DIRECTORIES(include)
    
    # 4.source directory,源文件目录
    AUX_SOURCE_DIRECTORY(src DIR_SRCS)
    
    # 5.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
    SET(TEST_MATH ${DIR_SRCS})
    
    # 6.add executable file,添加要编译的可执行文件
    ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_MATH})
    
    # 7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)

       编译方法(直接生成目标程序):

    kuliuheng@ubuntu:~/_8GB_EXT/workspace/cpp/testCmake$ cd build/
    kuliuheng@ubuntu:~/_8GB_EXT/workspace/cpp/testCmake/build$ cmake ../
    -- The C compiler identification is GNU 7.4.0
    -- The CXX compiler identification is GNU 7.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
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/kuliuheng/_8GB_EXT/workspace/cpp/testCmake/build

    4、示例:如何给动态库添加三方库依赖

    方法一:用LINK_DIRECTORIES 来指定三方库路径,然后通过库名称去链接。需要注意一个坑就是LINK_DIRECTORIES 要放到 ADD_LIBRARY 前面才行。

    file(GLOB_RECURSE header1_files "src/main/cpp/3rd/*.h")
    file(GLOB_RECURSE source1_files "src/main/cpp/3rd/*.cpp")
    
    LINK_DIRECTORIES("libs/${ANDROID_ABI}")    # 添加三方库的绝对/相对路径,用于搜索三方库。但是千万要注意一点:要放到ADD_LIBRARY之前,否则不生效!
    
    ADD_LIBRARY (
                 my_lib  # 设置生成动态库的名称
                 SHARED  # 设置库类型,STATIC 或 SHARED
    
                 # 需要编译的c/c++ 文件
                 ${source1_files}
                 src/main/cpp/jni_main.cpp
                 )
    
    target_link_libraries(
                           my_lib  # 链接目标
     
                           # Links the target library to the log library included in the NDK
                           ${log-lib}
    
                    plug_ins_project        # 这个就是对应libplug_ins_project.so库文件
            )    

     方法二:通过ADD_LIBRARY 结合 SET_TARGET_PROPERTIER 来指定第三方库绝对路径信息,然后连接库名即可。

    TIPS:可以用MESSAGE打印调试日志—— MESSAGE(WARNING "${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}")

    # 通过add_library 可以引入三方库,通过set_target_properties 指定具体三方库的属性
    add_library(plug_ins
            SHARED
            IMPORTED)
    set_target_properties( plug_ins
            PROPERTIES IMPORTED_LOCATION
            ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI}/libplug_ins_project.so)
    
    target_link_libraries( # Specifies the target library.
                           # 指定链接的目标库
                           my_lib
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib}
            plug_ins
            )
  • 相关阅读:
    数据库设计准则(第一、第二、第三范式说明)
    Linux之chmod使用
    数据备份——PHP
    PHP语言性能优化——少使用魔术方法
    PHP性能之语言性能优化:安装VLD扩展——检测性能
    PHP性能之语言性能优化:安装VLD扩展——检测性能
    PHP性能之语言性能优化:安装VLD扩展——检测性能
    socket、fsockopen、curl、stream 区别
    iOS 下 Podfile 使用方法
    使用 NVM 管理不同的 Node.js 版本
  • 原文地址:https://www.cnblogs.com/kuliuheng/p/9431275.html
Copyright © 2020-2023  润新知