CMake基础

基础知识与命令

1.一些指令

#添加头文件搜索目录,对于纯头文件组成的eigen就可以使用了

  • target_link_directories(${PROJECT_NAME} PUBLIC /usr/include/eigen3)
    #添加要链接的库
  • target_link_libraries(myapp PUBLIC hellolib)
    #添加一个宏定义
  • target_add_definitions(myapp PUBLIC MY_MACRO=1)
  • target_add_definitions(myapp PUBLIC -DMY_MACRO=1) # 与 MY_MACRO=1 等价
    #添加编译器命令行选项
  • arget_compile_options(myapp PUBLIC -fopenmp)
    #添加要编译的源文件
  • target_sources(myapp PUBLIC hello.cpp other.cpp)
    以及可以通过下列指令(不推荐使用),把选项加到所有接下来的目标去:
  • include_directories(/opt/cuda/include) # 添加头文件搜索目录
  • link_directories(/opt/cuda) # 添加库文件的搜索路径
  • add_definitions(MY_MACRO=1) # 添加一个宏定义
  • add_compile_options(-fopenmp) # 添加编译器命令行选项
    例如,windows中,在文件头部加入add_definitions(-DNOMINMAX),以屏蔽<windows.h>中min

2.通常一个库一个模块(对应主CMakeLists.txt中的add_subdirectory),即子模块
在子模块的CMakeLists.txt中

add_library(xxxlib STATIC xxx.cpp)
#.是指这个CMakeLists.txt所在的目录,PUBILC修饰符使得目标可执行文件在链接link这个xxxlib将得到这个xxlib的头文件目录.
target_inlcude_directories(xxxlib PUBLIC .)

3.除了像eigen这种纯头文件的,有以源文件的方式加入工程,比如ORB-SLAM2中的DBOW2
在这里插入图片描述

cmake_minimum_required(VERSION 2.8)
project(DBoW2)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall  -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall  -O3 -march=native")
#定义一些变量
set(HDRS_DBOW2
  DBoW2/BowVector.h
...)
set(SRCS_DBOW2
  DBoW2/BowVector.cpp
...)
set(HDRS_DUTILS
  DUtils/Random.h
...)

find_package(OpenCV 3.0 QUIET)
if(NOT OpenCV_FOUND)
   find_package(OpenCV 2.4.3 QUIET)
   if(NOT OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
   endif()
endif()
#设置lib输出目录
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
#添加头文件搜索目录
include_directories(${OpenCV_INCLUDE_DIRS})
#用源文件来编译库
add_library(DBoW2 SHARED ${SRCS_DBOW2} ${SRCS_DUTILS})
#为目标链接库
target_link_libraries(DBoW2 ${OpenCV_LIBS})

4还有一些要提前安装的库
需要用,如 find_package(fmt REQUIRED)找到现代 CMake 认为一个包 (package) 可以提供多个库,又称组件 (components),比如 target_link_libraries(myexec PUBLIC fmt::fmt),为避免冲突,每个包都享有一个独立的名字空间,以 :: 分割。你可以指定要用哪几个组件:

find_package(TBB REQUIRED COMPONENTS tbb tbbmalloc REQUIRED)
target_link_libraries(myexec PUBLIC TBB::tbb TBB::tbbmalloc)

5.例子
以cmake-examples-02为例
在这里插入图片描述

#basic/CMakeLists.txt
cmake_minimum_required (VERSION 3.5)

project(subprojects)
#CMakeLists.txt文件可以包含和调用包含CMakeLists.txt文件的子目录
# Add sub directories
add_subdirectory(sublibrary1)
add_subdirectory(sublibrary2)
add_subdirectory(subbinary)

在这里插入图片描述
/sublibrary1 源码编译了一个库文件

#生成静态库的CMakeLists.txt
# Set the project name
project (sublibrary1)

# Add a library with the above sources
#此处${PROJECT_NAME}是当前project的名字,sublibrary1
add_library(${PROJECT_NAME} src/sublib1.cpp)
add_library(sub::lib1 ALIAS ${PROJECT_NAME})
#将头文件移至每个项目include目录下的子文件夹,而将目标include保留为根include文件夹。 这是防止文件名冲突的一个好主意,因为您必须包括以下文件:#include "sublib1/sublib1.h"
target_include_directories( ${PROJECT_NAME}
    PUBLIC ${PROJECT_SOURCE_DIR}/include
)

在这里插入图片描述
\sublibrary2

#生成仅有头文件的库的CMakeLists.txt
# Set the project name
project (sublibrary2)
#如果您有一个库被创建为仅头文件的库,则cmake支持INTERFACE目标,以允许创建没有任何构建输出的目标
add_library(${PROJECT_NAME} INTERFACE)
add_library(sub::lib2 ALIAS ${PROJECT_NAME})

#此处INTERFACE的作用是:使用INTERFACE范围包含该目标的目录。 INTERFACE范围用于制定在链接此目标的任何库中使用的目标需求,但在目标本身的编译中不使用
target_include_directories(${PROJECT_NAME}
    INTERFACE
        ${PROJECT_SOURCE_DIR}/include
)

\subbianry

project(subbinary)

# Create the executable
add_executable(${PROJECT_NAME} main.cpp)

#使用别名sub :: lib1从subproject1链接静态库
#使用别名sub :: lib2从subproject2链接仅标头的库
#这将导致该目标的包含目录添加到该项目中即lib1,lib2中的target_include_directories()语句
target_link_libraries(${PROJECT_NAME}
    sub::lib1
    sub::lib2
)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值