首页 > 其他分享 >CMake 菜鸟升级指南

CMake 菜鸟升级指南

时间:2023-01-16 10:34:57浏览次数:37  
标签:指南 BINARY CMake 菜鸟 PROJECT SOURCE cpp DIR



注!看参考资料一边学习一边整理的,只整理了自己能理解的部分,更详细的内容大家去挖官方的文档哈!

应知应会

  • 每一个要管理的目录都要包含一个CMakeLists.txt。(这个文件名不能有任何改动)
  • CMake获取变量值的语法是 ${变量名}。
  • CMake的指令可以大写、小写或大小混写,但是一般约定俗称都用大写。
  • CMake指令的参数用括号括起来,参数之间用空格隔开,参数是大小写相关的,不要乱写。
  • CMake参数也可以用分号“;”隔开,但不是约定俗成的用法,不建议使用。

CMake预定义变量


# 当前文件路径
${CMAKE_CURRENT_SOURCE_DIR}
# 安装路径
${CMAKE_INSTALL_PREFIX} # 默认值为 /usr/local
# 项目编译路径
${PROJECT_BINARY_DIR}
# 项目名
${PROJECT_NAME}
# 项目路径,值参照下面PROJECT指令说明
${PROJECT_SOURCE_DIR}


常用指令说明

ADD_EXECUTABLE


ADD_EXECUTABLE(name sourceFile)


用sourceFile源文件生成一个名为name的可执行文件。sourceFile可以是单个文件,也可以是定义的文件列表变量。见下面的例子:


# 单个文件
ADD_EXECUTABLE(${PROJECT_NAME} main.cpp)
# 多个文件
ADD_EXECUTABLE(${PROJECT_NAME} main.cpp pow.cpp)
# 源文件变量
ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILE} ${LIB_FILE})


ADD_LIBRARY


ADD_LIBRARY(<name> [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 [source2...])


  • [EXCLUDE_FROM_ALL] 这个库不会被默认构建,除非有其他的组件依赖或者手工构建。
  • 生成最终共享库的文件名为,libname.so。会自动在库名前加lib。

补充点有关静态库和动态库的背景知识:

  • 静态库的扩展名一般为".a"或".lib";动态库的扩展名一般为".so"或".dll";
  • 静态库在编译时会直接整合到目标程序中,编译成功的可执行文件即使没有静态库也可以独立运行。
  • 动态库在编译时不会放到链接的目标程序中,编译成功的可执行文件没有动态库无法独立运行。
  • (接上条,有时候玩游戏会出现缺少xxx.dll的提示,就是缺少动态库)


ADD_SUBDIRECTORY


ADD_SUBDIRECTORY(directory [BINARY_DIR] [EXCLUDE_FROM_ALL])


向当前项目添加存放源文件的子目录。

  • [BINARY_DIR] 指定生成的二进制文件的存放位置。
  • [EXCLUDE_FROM_ALL] 将这个目录从编译中排除。

AUX_SOURCE_DIRECTORY

扫描指定文件夹下的所有源文件,并将源文件以列表的形式存放在变量中。


# 扫描当前文件夹下的所有原文将并将其存放在变量SRC_FILES中。
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRC_FILES)


INSTALL


INSTALL(FILES|PROGRAM|DIRECTORY|TARGETS xxx DESTINATION xxx)


可以指定是安装文件、非目标文件的可执行程序、目录、可执行文件。

DESTINATION后可以写绝对路径,也可以写相对路径。相对路径是${CMAKE_INSTALL_PREFIX}/<相对路径>。

安装目录时,指定路径为directoryName是安装该文件夹到目标目录,指定路径为directoryName/是安装该文件夹中的所有文件到目标目录中。

MESSAGE


MESSAGE([SEND_ERROR|STATUS|FATAL_ERROR] "Content")


相当于编程中的打印指令(python的print、C++的std::cout)。

  • SEND_ERROR 报错误信息,不终止CMake构建过程。
  • STATUS 普通输出信息。
  • FATAL_ERROR 报错误信息,终止CMake构建过程。

PROJECT


PROJECT(projectname [CXX] [C] [JAVA])


[CXX] [C] [JAVA] 表示项目支持的语言,一般忽略这部分,默认情况下支持所有语言。

这个指令隐式地定义了两个CMake变量:

  • <projectname>_BINARY_DIR
  • <projectname>_SOURCE_DIR。

其中,SOURCE_DIR就是该指令所在CMakeLists.txt的文件夹路径。同时CMAKE也隐式地定义了另外两个变量:

  • PROJECT_BINARY_DIR
  • PROJECT_SOURCE_DIR

这两个变量的值和前面两个的值一样,区别在于上面两个变量在更改<projectname>后,所有使用了这两个变量的CMakeLists.txt脚本的相应位置都需要更改,而下面两个变量的更改是自动完成的。所以一般情况下使用下面两个可以降低后期调整的工作量。

SET


SET(VAR [VALUE])


SET 指令用来定义变量的值,相当于编程语言中的赋值操作(VAR=VALUE)。


# 定义SRC_LIST变量为三个cpp文件的列表。
SET(SRC_LIST main.cpp sqrt.cpp pow.cpp)


大型项目配置

指定二进制文件保存路径

指定最终二进制文件(可执行文件及库文件,不包含中间文件)的位置。


SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)


复制文件

将SOURCE目录文件or文件夹复制到BINARY目录。我自己理解的应用场景就是有一些资源文件需要拷贝什么的。


file(COPY ${PROJECT_SOURCE_DIR}/resource DESTINATION ${PROJECT_BINARY_DIR})


特殊情况处理

文件名带空格

因为CMake的参数是用空格隔开的,那文件名里面带空格怎么办?

处理办法是给文件名加引号。在CMake中写文件名带引号或不带引号都可以,但文件名包含空格的时候就必须加上引号。


# 例:将hello world.cpp文件赋值给HELLO_SRC_FILE变量
# 错误!!!
SET(HELLO_SRC_FILE hello world.cpp)
# 正确
SET(HELLO_SRC_FILE "hello world.cpp")


标签:指南,BINARY,CMake,菜鸟,PROJECT,SOURCE,cpp,DIR
From: https://blog.51cto.com/u_15202985/6010095

相关文章

  • cmake configure_file 评价
    cmakeconfigure_file大白话的意思就是:你可以用config.h.in模板自动生成config.h头文件,模板的参数在CMakeLists.txt里面这样我们下次直接只用修改CMakeLi......
  • 【避坑指南】快准狠!一键采购电子元器件
    在采购元器件的过程中,经常会出现一些或这或那的情况,比如遇到假货问题、不具备专业知识、工作经验不够丰富、采购型号错误等等,因此采购下单如赌注,每个订单都下得心惊肉跳。那......
  • 和菜鸟一起学linux之linux性能分析工具oprofile移植
    一、内核编译选项makemenuconfigGeneralsetup--->[*]Profilingsupport<*>OProfilesystemprofiling二、popt移植      下载源码:​​http://rpm5.org/files/p......
  • 和菜鸟一起学linux之upnp协议的学习记录
    UPnP全名是UniversalPlugandPlay,主要是微软在推行的一个标准。简单的来说,UPnP最大的愿景就是希望任何设备只要一接上网络,所有在网络上的设备马上就能知道有新设备加入,这......
  • 和菜鸟一起学linux之bluez学习记录1
    关于蓝牙协议栈体系结构 底层硬件模块 RF1、利用2400M~2483.5M频带2、采用调频方式传输数据,一共有79/EDR,40/BLE个hops,每秒3、采用GFSK(DQPSK和8DPSK)调制方式4、信道间隔(1......
  • 和菜鸟一起学android4.0.3源码之wifi direct的简单分析
    关于wifidirectWifidirect的连接 下面的图表示的是wifidirect的发现过程。 整个过程可以见下图。关于android上的wifidirect首先上层通过调用p2pmanager的接口来实现......
  • 和菜鸟一起学linux之bluez学习记录2
    这里主要摘取对于hci,l2cap,sdp和rfcomm的一些应用编程。 关于hci 一、HCI层协议概述 1、HCICommandPackets详见bluez源码:lib/hci.h/*LinkControl*/#defineOGF_LINK_......
  • 和菜鸟一起学linux内核源码之基础准备篇
        注:以下大部分内容摘自linux内核编程入门篇和linux内核完全注释       在工作的这段时间,发现我的visio画图熟悉了点点,总喜欢把什么源码啊,结构啊之类的就......
  • 和菜鸟一起学android4.0.3源码之wifi的简单分析
     关于wlan的组成 关于wifi应用层的接口的调用    首先从上层androidwifi的应用开始,首先会根据android的wifimanager的类,实例化一个mwifimanager的对象,这个对象处......
  • 和菜鸟一起学OK6410之ADC模块
    android上跑起来时也比较灵敏了,GPIO模拟的SPI也可以工作了,看了会书,修正了会,回到宿舍也已经9点多了。想想,OK6410上还有个AD模块呢。网上找了找资料,发现还是可以去尝试下可不......