【CMake实战】CMake获取子目录并add_subdirectory加入到构建体系中来的方法

文章介绍了如何在CMake中使用find命令和自定义宏glob遍历查找子目录,特别强调了如何查找包含CMakeLists.txt的目录,以及在Windows环境下可能遇到的问题和解决方案。
摘要由CSDN通过智能技术生成

1. find查找简单办法

  • 假定场景, 子目录都以 problem 开头, 所以查找时候用了 problem* 只查找一层目录;
  • 劣势: 在Windows下可能失效, 因为find命令不一样;
message("CMAKE_CURRENT_SOURCE_DIR=: ${CMAKE_CURRENT_SOURCE_DIR}")
execute_process(
    COMMAND find ${CMAKE_CURRENT_SOURCE_DIR} -type d -name problem* -maxdepth 1 -exec basename {} \;
    OUTPUT_VARIABLE dirs)

message("Found sub directories:\n${dirs}")
string(REPLACE "\n" ";" sub_dirs_list ${dirs})
foreach(d ${sub_dirs_list})
    add_subdirectory(${d})
endforeach(d)

2. 使用自定义宏glob进行遍历查找

2.1 获取子目录的宏定义

  • 宏定义, 得到的 子目录列表用 分号隔开, 类似于 abc;ccb 这种;
cmake_minimum_required(VERSION 3.0)
project(tc)

MACRO(SUBDIRLIST result currdir)
  FILE(GLOB children RELATIVE ${currdir} ${currdir}/*)
  SET(dirlist "")
  FOREACH(child ${children})
    IF(IS_DIRECTORY ${currdir}/${child})
      LIST(APPEND dirlist ${child})
    ENDIF()
  ENDFOREACH()
  SET(${result} ${dirlist})
ENDMACRO()

add_subdirectory(tc)
  • 示例
message("CMAKE_CURRENT_SOURCE_DIR=: ${CMAKE_CURRENT_SOURCE_DIR}")
SUBDIRLIST(dirs ${CMAKE_CURRENT_SOURCE_DIR})
message("Found sub directories:\n${dirs}")
# 下面这个替换在find命令时才需要; 使用宏时不需要;
string(REPLACE "\n" ";" sub_dirs_list ${dirs})
message("after replace sub directories:\n${sub_dirs_list}")
#foreach(d ${sub_dirs_list})
foreach(d ${dirs})
	message("dir is :${d}")
    add_subdirectory(${d})
endforeach(d)

  • 效果
$ cmake ..
CMAKE_CURRENT_SOURCE_DIR=: /home/neo/fast-dev/t-cmake-prj/tc
Found sub directories:
abc;cbb
after replace sub directories:
abccbb
dir is :abc
dir is :cbb
-- Configuring done
-- Generating done
-- Build files have been written to: /home/neo/t-cmake-prj/build

3. 改进的宏定义

3.1 查找CMake编译路径子目录(包含CMakeLists.txt文件)

  • 基础宏定义类似之前查找子目录的方式, 得到的 子目录列表用 分号隔开, 类似于 abc;ccb 这种;
  • 增加判定子目录下是否有CMakeLists.txt文件的功能
cmake_minimum_required(VERSION 3.0)
project(tc)

MACRO(SUBDIRLIST result currdir)
	FILE(GLOB children RELATIVE ${currdir} ${currdir}/*)
	SET(dirlist "")
	FOREACH(child ${children})
		IF((IS_DIRECTORY ${currdir}/${child}) AND (EXISTS ${currdir}/${child}/CMakeLists.txt))
			LIST(APPEND dirlist ${child})
		ENDIF()
	ENDFOREACH()
	SET(${result} ${dirlist})
ENDMACRO()

add_subdirectory(tc)

4. 常见问题

  • does not contain a CMakeLists.txt file. 如果使用本文开头非增强版本的宏定义, 由于扫描出来的目录可能是其他用途, 里面没有 CMakeLists.txt 文件, 直接使用 add_subdirectory(dir) 就会报这个错误;
  • 解决办法参考上面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逸云沙鸥のIHave@Dream

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

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

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

打赏作者

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

抵扣说明:

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

余额充值