• CMake笔记


    CMake笔记

    1 工程项目一般形式

    1. 建立build文件夹
    mkdir build
    
    • 1
    1. 进入build文件
    cd build
    
    • 1
    1. cmake生成makefile文件
    cmake ..   # cmake是对CMakeLists.txt操作,操作命令要在同一文件夹
    
    • 1
    1. make编译
    make    # make是对Makefile操作
    
    • 1
    1. 调用
    ./useHello   # 这里是调用build文件夹下的helloSLAM
    
    • 1
    cmake会自己找.h文件  如果.h不在当前文件夹,需要加上include_directories(文件名)
    若.cpp也不在当前文件,在库文件哪里也加上路径
    
    • 1
    • 2
    # 声明要求的 cmake 最低版本
    cmake_minimum_required(VERSION 2.8)
    
    include_directories("include")
    # 声明一个 cmake 工程
    project(HelloSLAM)
    
    # 设置编译模式
    set(CMAKE_BUILD_TYPE "Debug")
    
    # 添加hello库   静态库
    add_library(hello_shared ./src/libHelloSLAM.cpp)
    # 共享库    动态库
    add_library(hello_shared SHARED ./src/libHelloSLAM.cpp)
    
    # 添加可执行程序调用hello库中函数
    # 语法:add_executable( 程序名 源代码文件 )
    add_executable(useHello ./src/useHello.cpp)
    
    # 将库文件链接到可执行程序上
    target_link_libraries(useHello hello_shared)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    在这里插入图片描述

    2 常见命令

    2.1 project

    PROJECT(projectname [CXX] [C] [Java])   #项目名 以及支持的语言   默认支持所有的语言
    
    • 1
    • 创建项目指令project默认创建了一下两个cmake变量
    _BINARY_DIR     # 内部编译!!!
    _SOURCE_DIR
    
    # 可以用message输出查看,在cmake在编译CMakeLists.txt时候就会输出对应的信息
    message(STATUS "this is a binary dir" _BINARY_DIR)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 系统预定义的两个变量,修改工程名不会影响这两个变量的值!
     PROJECT_BINARY_DIR    # (make)编译路径
     PROJECT_SOURCE_DIR    # 工程(源文件)路径
    
    • 1
    • 2
    • 实验
    project(Hello CXX)
    message(STATUS "this is binary dir" ${Hello_BINARY_DIR})
    # 等价 message(STATUS "this is binary dir" ${PORECT_BINARY_DIR})
    message(STATUS "this is source  dir" ${Hello_SOURCE_DIR})
    # 等价 message(STATUS "this is source  dir" ${PROJECT_SOURCE_DIR})
    add_executable(hello hello.cpp)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.2 set

    • 用来设置指定变量的一个替换变量
    SET(SRC_LIST main.cpp)     # SRC_LIST变量就代表了main.cpp
    SET(SRC_LIST main.cpp t1.cpp t2.cpp)   # SRC_LIST变量就代表了main.cpp  t1.cpp t2.cpp
    
    • 1
    • 2
    • 其它的一些变量设置
    # 设置CMake预定义的内建变量
    set(CMAKE_CXX_FLAGS "-O3")   # 优化选项,告诉编译器优化我们的代码
    set(CMAKE_CXX_FLAGS "-std = c++11")   # 设置为c++11标准
    
    
    # 设置编译模式
    set(CMAKE_BUILD_TYPE "Debug")   # 占用空间比较大,可以debug
    set(CMAKE_BUILD_TYPE "Release") # 占用空间比较小
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 实验1:利用变量cc来替换Hello.cpp
    project(Hello CXX)
    set(CC hello.cpp)
    add_executable(hello CC)
    
    • 1
    • 2
    • 3

    2.3 message

    MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR]  "message to display" ...)
    
    • 1
    • SEND_ERROR,产生错误,生成过程被跳过。
    • STATUS ,输出前缀是一个 — 的信息。
    • FATAL_ERROR,立即终止所有cmake 过程.

    上面三种选择一种,引号用来解释要输出的信息,三个点表示对应的变量

    MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
    
    MESSAGE(STATUS "This is SOURCE dir "${HELLO_SOURCE_DIR})
    
    • 1
    • 2
    • 3

    2.4 add_executable()

    ADD_EXECUTABLE(hello ${SRC_LIST})     # 生成的可执行文件名是hello
    									  # 源文件读取变量SRC_LIST中的内容
    ADD_EXECUTABLE(hello main.cpp)        # 这两句是等价的。									  
    
    • 1
    • 2
    • 3

    2.5 语法原则

    • 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名

    • 指令(参数 1 参数 2…) 参数使用括弧括起,参数之间使用空格或封号分开。

    • 指令是大小写无关的,参数和变量是大小写相关的。

    2.6 add_subdirectory

    ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
    
    # source_dir  用于向当前工程添加存放  源文件 的子目录
    # [binary_dir]   指定(子目录里面生成的可执行文件)中间二进制和目标二进制存放的位置
    # EXCLUDE_FROM_ALL 参数的含义是将这个目录从编译过程中排除
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 实验验证

    ​ 首先改写SLAM第三讲中的CMakeLists.txt文件,指定可执行文件的位置(build/…)。

    cmake_minimum_required(VERSION 2.8)
    project(chapter3)
    set(CMAKE_CXX_FLAGS "-std=c++11")
    
    add_subdirectory(useEigen useEigen)
    
    add_subdirectory(useGeometry useGeometry)
    
    add_subdirectory(visualizeGeometry visualizeGeometry) 
    
    add_subdirectory(examples examples)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    编译之后,其可执行文件都被保存在了build/…与定义的路径下面

    在这里插入图片描述

    比如

    在这里插入图片描述

    在这里插入图片描述

    相反,如果我们不设置其可执行文件的输出位置,默认在最外层build/建立和项目名一致的文件夹

    cmake_minimum_required(VERSION 2.8)
    project(chapter3)
    set(CMAKE_CXX_FLAGS "-std=c++11")
    
    add_subdirectory(useEigen ./cc)
    
    add_subdirectory(useGeometry)
    
    add_subdirectory(visualizeGeometry) 
    
    add_subdirectory(examples)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    2.7 add_library

    ADD_LIBRARY(hello  SHARED  ${LIBHELLO_SRC})
    
    • 1
    • hello:就是正常的库名,生成的名字前面会加上lib,最终产生的文件是libhello.so
    • SHARED,动态库 STATIC,静态库
    • ${LIBHELLO_SRC} :源文件,比如自己写的hello.cpp

    2.8 list

    set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" )
    list( APPEND CMAKE_MODULE_PATH "${CMAKE_ROOT}/Modules" ) 
    # 表示将后面的 "" 里面的内容添加到CMAKE_MODULE_PATH列表里
    
    • 1
    • 2
    • 3

    3 安装

    install安装可以包括:二进制、动态库、静态库以及文件、目录、脚本等。测试样例在主目录下CMake下面test1.

    .
    ├── build
    ├── CMakeLists.txt
    ├── COPYRIGHT    # 版权
    ├── doc          # 目录
    │   └── hello.txt
    ├── README       # 帮助文档
    ├── runhello.sh
    └── src
        ├── CMakeLists.txt
        └── hello.cpp
    
    3 directories : build,doc,src      7 files : ...
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.1 安装.h文件/文本文件

    project(Hello)
    add_subdirectory(src bin)
     
    # 安装文件FILES(上面创建的COPYRIGHT和README)    share/doc/cmake/是安装路径
    install(FILES COPYRIGHT README DESTINATION share/doc/cmake/)  
    
    # 也可以安装头文件.h   见4.2
    install(FILES hello.h DESTINATION include/hello)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    参数1:DESTINATION

    DESTINATION   # destination 目的地  即安装的路径
    1、写绝对路径
    2、可以写相对路径,相对路径实际路径是:${CMAKE_INSTALL_PREFIX}/
    
    CMAKE_INSTALL_PREFIX  默认是在 /usr/local/
    
    cmake -DCMAKE_INSTALL_PREFIX=/usr    在cmake的时候指定CMAKE_INSTALL_PREFIX变量的路径
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.2 安装工程脚本

    project(Hello)
    add_subdirectory(src bin)
    # 2.安装工程脚本PROGRAMS   实际路径: /usr/local/bin
    install(PROGRAMS test.sh DESTINATION bin)	
    
    • 1
    • 2
    • 3
    • 4

    参数2:PROGRAMS非目标文件的可执行程序安装(比如脚本之类)

    3.3 安装目录/目录下内容

    project(Hello)
    add_subdirectory(src bin)
    
    # DIRECTORY  3.安装目录下内容hello.txt			因为doc后面加了/
    # DIRECTORY 后面连接的是所在 Source 目录的相对路径
    install(DIRECTORY doc/ DESTINATION share/doc/cmake)	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参数3:doc/

    目录名不以/结尾:这个 目录 将被安装为目标路径下的

    目录名以/结尾:将这个 目录中的内容 安装到目标路径

    3.4 安装库文件

    project(Hello)
    add_subdirectory(src bin)
    # 4 安装库文件  见4.2
    # 二进制,静态库,动态库安装都用TARGETS
    # ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执行目标二进制。
    INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.5安装过程

    pj@p:~/slambook/CMake/build$ camke ..
    
    pj@p:~/slambook/CMake/build$ make -j4
    [ 50%] Building CXX object bin/CMakeFiles/hello.dir/main.o
    [100%] Linking CXX executable hello
    [100%] Built target hello
    
    pj@p:~/slambook/CMake/build$ sudo make install    # 这里才开始安装install
    [100%] Built target hello
    Install the project...
    -- Install configuration: ""
    -- Up-to-date: /usr/local/share/doc/cmake/COPYRIGHT
    -- Up-to-date: /usr/local/share/doc/cmake/README
    -- Installing: /usr/local/bin/test.sh
    -- Up-to-date: /usr/local/share/doc/cmake
    -- Installing: /usr/local/share/doc/cmake/test_cmake.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这里很重要,因为有些安装包你下载的地方不是默认的地方,把它cmake编译之后,还要将其加入的默认路径 /usr/local/...

    4 静态库和动态库

    静态库和动态库的区别

    • 静态库的扩展名一般为“.a”或“.lib”;动态库的扩展名一般为“.so”或“.dll”
    • 静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可独立运行
    • 动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行。

    测试样例于cmake/test2

    4.1 同时构建静态库和动态库

    ​ 先构建如下文件

    pj@p:~/CMake/test2$ tree
    .
    ├── build
    ├── CMakeLists.txt
    └── lib
        ├── CMakeLists.txt
        ├── hello.cpp
        └── hello.h
    
    2 directories, 4 files
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    hello.h中的内容

    #ifndef HELLO_H
    #define Hello_H
    
    void HelloFunc();
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    hello.cpp中的内容

    #include "hello.h"
    #include 
    void HelloFunc(){
        std::cout << "Hello World" << std::endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    项目中的cmake内容

    PROJECT(HELLO)
    ADD_SUBDIRECTORY(lib bin)
    
    • 1
    • 2

    ​ 下面这种方法不能同时构建,只会生成一中类型的库

    # 如果用这种方式,只会构建一个动态库,不会构建出静态库,虽然静态库的后缀是.a
    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
    ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
    
    # 修改静态库的名字,这样是可以的,但是我们往往希望他们的名字是相同的,只是后缀不同而已
    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
    ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • SET_TARGET_PROPERTIES

    ​ 这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和 API 版本,同时构建静态和动态库。lib下cmakelists.txt内容如下。

    SET(LIBHELLO_SRC hello.cpp)
    
    ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
    
    # 对hello_static的重名为hello
    SET_TARGET_PROPERTIES(hello_static PROPERTIES  OUTPUT_NAME "hello")
    # cmake 在构建一个新的target 时,会尝试清理掉其他使用这个名字的库,因为,在构建 libhello.so 时, 就会清理掉 libhello.a
    SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)  # 清除
    
    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
    
    SET_TARGET_PROPERTIES(hello PROPERTIES  OUTPUT_NAME "hello")
    SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4.2 安装头文件.h和库.a/.so

    ​ 我们将 hello 的共享库安装到/lib目录,将 hello.h 安装到/include/hello 目录

    SET(LIBHELLO_SRC hello.cpp)
    
    ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
    
    # 对hello_static的重名为hello
    SET_TARGET_PROPERTIES(hello_static PROPERTIES  OUTPUT_NAME "hello")
    # cmake 在构建一个新的target 时,会尝试清理掉其他使用这个名字的库,因为,在构建 libhello.so 时, 就会清理掉 libhello.a
    SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)  # 清除
    
    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
    
    SET_TARGET_PROPERTIES(hello PROPERTIES  OUTPUT_NAME "hello")
    SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    
    
    # 文件放到该目录下
    INSTALL(FILES hello.h DESTINATION include/hello)
    
    # 二进制,静态库,动态库安装都用TARGETS
    # ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执行目标二进制。
    INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.2.1 安装过程

    pj@p:~/CMake/test2/build$ cmake -D CMAKE_INSTALL_PREFIX=/usr .. 
    
    pj@p:~/CMake/test2/build$ make
    [ 25%] Building CXX object bin/CMakeFiles/hello_static.dir/hello.o
    [ 50%] Linking CXX static library libhello.a
    [ 50%] Built target hello_static
    [ 75%] Building CXX object bin/CMakeFiles/hello.dir/hello.o
    [100%] Linking CXX shared library libhello.so
    [100%] Built target hello
    
    pj@p:~/CMake/test2/build$ sudo make install   # 更改默认路径
    Consolidate compiler generated dependencies of target hello_static
    [ 50%] Built target hello_static
    Consolidate compiler generated dependencies of target hello
    [100%] Built target hello
    Install the project...
    -- Install configuration: ""
    -- Installing: /usr/include/hello/hello.h
    -- Installing: /usr/lib/libhello.so
    -- Installing: /usr/lib/libhello.a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    结果

    在这里插入图片描述

    4.2.2 使用外部共享库和头文件

    准备工作,新建一个目录来使用外部共享库和头文件(使用上面安装的库)

    [root@MiWiFi-R4CM-srv cmake3]# tree
    .
    ├── build
    ├── CMakeLists.txt
    └── src
        ├── CMakeLists.txt
        └── main.cpp
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • CMakeLists.txt
    project(hello)
    
    add_subdirectory(src bin)
    
    • 1
    • 2
    • 3
    • main.cpp
    #include 
    
    int main(){
    	HelloFunc();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • src下的CMakeLists.txt
    
    include_directories("/usr/include/hello")   # 链接头文件  .h
    add_executable(test main.cpp)
    
    target_link_libraries(test /usr/lib/libhello.so)  # 链接库文件  .cpp  libhello.so也可
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.2.3 使用find_package()来找到自定义库

    • FindHELLO.cmake
    find_path(HELLO_INCLUDE_DIR hello.h /usr/include/hello)
    find_library(HELLO_LIBRARY NAMES libhello.so PATHS /usr/lib )
    if (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
    
    	set(HELLO_FOUND TRUE)
    
    endif (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    写在最外层CMakeLists.txt

    在这里插入图片描述

    cmake_minimum_required(VERSION 3.22)
    
    project(hello)
    
    ## set(CMAKE_MODULE_PATH "../cmake")   这里可以写绝对路径,然后可以分子项目,具体见test4
    set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
    
    add_executable(test main.cpp)
    
    find_package(HELLO)
    
    message(STATUS "HELLO_INCLUDE_DIRS " ${HELLO_INCLUDE_DIR} )
    message(STATUS " HELLO_LIBRARY " ${HELLO_LIBRARY} )
    
    if(HELLO_FOUND)
    
        target_include_directories(test PRIVATE ${HELLO_INCLUDE_DIR})
        target_link_libraries(test ${HELLO_LIBRARY})  # 链接库文件  .cpp  libhello.so也可
    else(HELLO_FOUND)
        message(FATAL_ERROR "HELLO library not found")
    endif(HELLO_FOUND)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    如果分为子项目,即最外层只写

    cmake_minimum_required(VERSION 3.22)
    project(hello)
    add_subdirectory(src bin)
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    和上面的cmakelists相同,只需要改一句

    set(CMAKE_MODULE_PATH "../cmake")   # 这里可以写绝对路径,然后可以分子项目,具体见test4
    
    • 1

    在这里插入图片描述

    5 find_package()

    find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
                 [REQUIRED] [[COMPONENTS] [components...]]
                 [OPTIONAL_COMPONENTS components...]
                 [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
                 [GLOBAL]
                 [NO_POLICY_SCOPE]
                 [BYPASS_PROVIDER])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    ${XXX_INCLUDE_DIRS}    ## 一般要查找这两个变量,即头文件与源文件位置
    ${XXX_LIBRARIES}
    
    • 1
    • 2
    find_package(Pangolin REQUIRED)          # 查找Pangolin库,REQUIRED指找不到就在此停止程序。
    include_directories(${Pangolin_INCLUDE_DIRS})  # Pangolin库的头文件
    add_executable(plotTrajectory plotTrajectory.cpp)
    target_link_libraries(plotTrajectory ${Pangolin_LIBRARIES})   # 链接Pangolin的源文件,库
    
    • 1
    • 2
    • 3
    • 4

    5.1 find_package中的xxx是什么?

    # locate 库名 | grep cmake     xxx就是Config前面那个名字
    locate sophus | grep cmake
    locate Pangolin | grep cmake
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    5.2 使用find_package命令就是为了找到头文件和库文件位置

    include_directories(${XXX_INCLUDE_DIRS})   # 目的就是链接
    target_link_libraries(x ${XXX_LIBRARIES}) 
    
    # 这种方法是可行的,比如Pangolin库是没问题的
    
    find_package(Pangolin REQUIRED)          # 查找Pangolin库,REQUIRED指找不到就在此停止程序。
    include_directories(${Pangolin_INCLUDE_DIRS})  # Pangolin库的头文件
    add_executable(plotTrajectory plotTrajectory.cpp)
    target_link_libraries(plotTrajectory ${Pangolin_LIBRARIES})   # 链接Pangolin的源文件,库
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    但是,sophus这个库直接加这两个路径是不行的。我们可以载程序中使用message查看信息,它输出的是空白!

    message(STATUS "Sophus_INCLUDE_DIRS"  ${Sophus_INCLUDE_DIRS})
    message(STATUS "Sophus_INCLUDE_DIRS"  ${Sophus_LIBRARIES})
    
    • 1
    • 2

    在这里插入图片描述

    实际上我们已经安装了sophus的,并且它确实不能找到(以这种方式)

    在这里插入图片描述

    • 解决上述问题的办法
    # 1. 直接将绝对路径赋给它
    include_directories(/usr/local/include/sophus)
    # 2.  Sophus::Sophus 
    target_link_libraries(useSophus Sophus::Sophus)
    
    • 1
    • 2
    • 3
    • 4

    解释一下第二种方法的原因,

    在这里插入图片描述

    我们打开那个SophusTargets.cmake,里面有部分内容如下。就是可以把Sophus理解为一个类,对象,通过::来导入库。

    # Create imported target Sophus::Sophus
    add_library(Sophus::Sophus INTERFACE IMPORTED)
    
    • 1
    • 2

    之所以不能用${Sophus_INCLUDE_DIRS}),是因为在Config.cmake文件种没有这个东西。

    在这里插入图片描述

    但是eigen里面就有,所以eigen可以使用那种方式来链接库,eigen由头文件组成,没有库文件

    在这里插入图片描述

    5.3 find_path

    find_path(myCeres NAMES ceress.h PATHS /ceres/include/ceres NO_DEFAULT_PATH)
    include_directories(${myCeres})
    
    # eg   hello.h为要找的头文件    /usr/include/hello为绝对路径
    find_path(HELLO_INCLUDE_DIR hello.h /usr/include/hello)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.4 find_library

    find_library (<VAR> name [path1 path2 ...])    #<VAR> 找到的库的变量名(全路径)
    # eg   NAMES是指要找的动态库的名字  PATHS指我们为出现提供的路径,可以有多个
    find_library(HELLO_LIBRARY NAMES libhello.so PATHS /usr/lib )
    
    message(STATUS "HELLO_INCLUDE_DIRS " ${HELLO_INCLUDE_DIR} )
    message(STATUS " HELLO_LIBRARY " ${HELLO_LIBRARY} )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6 target_link_libraries(库文件LIBRARIES)

    # 这里要说的是,item可以库文件
    target_link_libraries(plotTrajectory ${Pangolin_LIBRARIES}) 
    
    # item可以是路径
    target_link_libraries(useHello ./src/libHelloSLAM.cpp) 
    
    # item可以是target,就是上面我们locate xx | grep cmake 找的东西
    # 而且,一旦有这个东西,那么用例如这样形式  Sophus::Sophus  我们就不需要include加头文件、库文件等
    target_link_libraries(useSophus Sophus::Sophus)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    7 include_directories()

    ​ 这里想补充以下关于include_directories()的用法,用于指定头文件的搜索路径,方便编译器查找相应的头文件。

    #include    // 比如说我们要调用eigen库和pangolin库
    #include 
    
    • 1
    • 2

    查看库的路径

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    Motor头文件和源文件解读
    【Python数据结构与判断7/7】数据结构小结
    spark—KV算子解析
    浅谈安科瑞ADL系列导轨式多功能仪表在迪拜楼宇EMS中的应用
    【比邻智选】M5310-E系列模组
    【面试题】绝对定位和相对定位
    (四)、基于 LangChain 实现大模型应用程序开发 | 基于知识库的个性化问答 (基本功能介绍)
    算法小讲堂之哈希表|散列表|考研笔记
    数字赋能 融链发展 ——2023工博会数字化赋能专精特新“小巨人”企业高质量发展论坛顺利举行
    java笔记38,JDBC
  • 原文地址:https://blog.csdn.net/qq_49561752/article/details/136354062