CMake笔记 3-结构更优的项目结构

  上一个笔记中,从内部构建转向了外部构建,自此之后,将会一直采用外部构建方式,设定构建目录是工程目录下的build目录;
  上一个笔记中,工程目录下只有build文件夹、源文件和CMakeLists.txt文件;在简单项目中,这样的目录结构还合适,在以后实际项目中,会有更多源文件,更多依赖的外部第三方库文件等等,目录结构就会更为复杂,先将之前例子进行优化,为以后复杂项目构建打好基础;
  之前的目录结构如下:
在这里插入图片描述
  处理Hello例子的步骤:
    1.增加src文件夹,用来存放工程源代码;
    2.增加doc文件夹,用来存放这个工程的文档hello.txt;
    3.在项目根目录中增加文本文件COPYRIGHT,README;
    4.在项目根目录中增加runhello.sh脚本,用来执行hello二进制文件;
    5.在cmake后会自动增加build/bin文件夹,用于存放构建后的目标文件;
    6.安装可执行文件和.sh文件;
      将 hello 二进制与 runhello.sh 安装至/usr/bin;
      将doc目录的内容以及COPYRIGHT/README 安装到/usr/share/doc/cmake/t1
  更改后的目录结构;
在这里插入图片描述
  src文件夹下的CMakeLists.txt内容

ADD_EXECUTABLE(hello main.c)

  项目根目录下的CMakeLists.txt内容

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

  在build目录下,执行cmake …/
在这里插入图片描述
  执行make后,在bin目录出现hello文件;
在这里插入图片描述
  bin目录结构如下:
在这里插入图片描述

新增指令

ADD_SUBDIRECTORY

  ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUE_FROM_ALL])
  该指令用于向当前项目工程中添加源文件目录,指定中间二进制文件目录以及目标二进制文件存放的目录;
  EXCLUE_FROM_ALL参数的含义是将这个目录从编译过程中排除;

ADD_SUBDIRECTORY(src bin)

  意思是:将src源文件目录加入工程中,指定编译输出(包含编译中间结果)路径为bin目标,如果bin目录不存在,则自动生成bin目录,如果不指定binary_dir目录,则将使用源文件目录名字,在当前的例子下是build/src/,指定binary_dir目录后,相当于在编译时将src重命名为bin。

SET重定义

  cmake中使用EXECUTABLE_OUTPUT_PATH 定义目标二进制可执行文件的存放位置,使用LIBRARY_OUTPUT_PATH 定义目标链接库文件的存放位置;
  可以通过SET指令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量来指定最终的目标二进制的位置(指最终生成的hello或者最终的共享库,不包含编译生成 的中间文件);

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

  EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH同ADD_EXECUTABLE或ADD_LIBRARY一起写入同一个CMakeLists.txt中。

INSTALL

  INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及文件、目录、脚本等;

目标文件以及库安装

INSTALL(TARGETS targets...
	[[ARCHIVE|LIBRARY|RUNTIME] 
	 [DESTINATION <dir>]
	 [PERMISSIONS permissions...]
	 [CONFIGURATIONS [Debug|Release|...]]
	 [COMPONENT <component>]
	 [OPTIONAL]]
	[...]) 

  TARGETS后面跟的就是被ADD_EXECUTABLE或ADD_LIBRARY定义的输出目标文件,可能是可执行二进制、动态库或者静态库;
  之后是目标类型,分为三种:ARCHIVE 特指静态库,LIBRARY 特指动态库,RUNTIME 特指可执行目标二进制。
  之后的DESTINATION是安装的路径,如果路径是以/开头,那么指的是绝对路径,这时候CMAKE_INSTALL_PREFIX就无效了;只有使用相对路径,CMAKE_INSTALL_PREFIX才会有效,安装后的路径就是${CMAKE_INSTALL_PREFIX}/<DESTINATION定义的路径>
  举例:

INSTALL(TARGETS myrun mylib mystaticlib
		RUNTIME DESTINATION bin
		LIBRARY DESTINATION lib
		ARCHIVE DESTINATION libstatic)

  可执行二进制myrun安装到${CMAKE_INSTALL_PREFIX}/bin 目录;
  动态库libmylib安装到${CMAKE_INSTALL_PREFIX}/lib目录;
  静态库libmystaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic 目录;
  注意:不需要关系TARGETS具体生成的路径,只需要写上TARGETS名称即可;

一般文件安装

普通文件的安装:

INSTALL(FILES files... DESTINATION <dir>
		[PERMISSIONS permissions...]
		[CONFIGURATIONS [Debug|Release|...]]
		[COMPONENT <component>]
		[RENAME <name>]
		[OPTIONAL])

  上面的INSTALL格式可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。
  如果默认不定义权限PERMISSIONS,安装后文件的权限为:    OWNER_WRITE|OWNER_READ|GROUP_READ|WORLD_READ,即644权限(110100100);

非目标文件的可执行程序安装

非目标文件的可执行程序(脚本类文件)安装:

INSTALL(PROGRAMS files... DESTINATION <dir>
		[PERMISSIONS permissions...]
		[CONFIGURATIONS [Debug|Release|...]]
		[COMPONENT <component>]
		[RENAME <name>]
		[OPTIONAL])

  与之前的FILES指令使用方法一样,唯一的不同是安装后权限为:
    OWNER_EXECUTE|GROUP_EXECUTE|WORLD_EXECUTE,即755权限(111101101)

目录的安装

INSTALL(DIRECTORY dirs... DESTINATION <dir>
		[FILE_PERMISSIONS permissions...]
		[USE_SOURCE_PERMISSIONS]
		[CONFIGURATIONS [Debug|Release|...]]
		[COMPONENT <component>]
		[[PATTERN <pattern> | REGEX <regex>] 
		 [EXCLUDE]
		 [PERMISSIONS permissions...]]
		[...]
		)

  DIRECTORY后面连接的是所在Source 目录的相对路径;
  注意:abc与abc/有很大的区别;
  如果目录名不以/结尾,那么这个目录将被安装为目标路径下的abc,如果目录名以/结尾,代表将这个目录中的内容安装的目标路径,但不包括这个目标本身;
  PATTERN用于使用正则表达式进行过滤,紧跟其后的PERMISSIONS用于指定PATTERN过滤后的文件权限;
  举例学习:

INSTALL(DIRECTORY icons scripts/ DESTIONATION share/myproj
		PATTERN "CVS" EXCLUDE
		PATTERN "scripts/*"
		PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)

  执行后的结果:将icons目录安装到<prefix>/share/myproj,将scripts/中的内容安装到<prefix>/share/myproj;不包含目录名为CVS的目录,对于scripts/*文件指定权限为OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ;

安装时 CMAKE 脚本的执行

INSTALL([[SCRIPT <file>] [CODE <code>]] [...])

  SCRIPT 参数用于在安装时调用 cmake 脚本文件(也就是.cmake 文件)
  CODE 参数用于执行 CMAKE 指令,必须以双引号括起来。比如:
  INSTALL(CODE “MESSAGE(“Sample install message.”)”)

新项目结构

  在项目目录t1中增加doc文件夹,doc内随便来一个txt;
  增加COPYRIGHT和README文件;
  增加runhello.sh,内部写入./hello
在这里插入图片描述
  更改t1目录下的CMakeLists.txt文件内容:

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t1)
INSTALL(PROGRAMS runhello.sh DESTINATION bin)
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t1)
INSTALL(TARGETS hello RUNTIME DESTINATION bin) 

  1.拷贝COPYRIGHT和README文件到<prefix>/share/doc/cmake/t1目录下;
  2.拷贝runhello.sh到<prefix>bin目录下;
  3.拷贝doc文件夹内的所有文件到<prefix>/share/doc/cmake/t1目录下;
  4.拷贝hello可执行文件到<prefix>bin目录下;
  注意:CMAKE_INSTALL_PREFIX默认定义是/usr/local;
  在build目录下执行cmake DCMAKE_INSTALL_PREFIX=/tmp/t1/usr …/
在这里插入图片描述
  执行make
在这里插入图片描述
  执行make install
在这里插入图片描述
  在/tmp/t1/usr/bin/下执行runhello.sh
在这里插入图片描述

参考资料

1.《cmake 实践》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑山老妖的笔记本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值