cmake自动添加源文件和头文件
一、背景
项目中需要不断新建源文件和头文件,每添加一个文件CMakeLists.txt中需要手动加入源文件和指定头文件路径,不胜其烦。突发奇想cmake能不能像IDE一样,指定一次源文件和头文件后即可。百度查找资料,耗费一天时间,最终实现,整理分享出来。鉴于水平有限,方法不一定最优,欢迎讨论。
二、基本原理
遍历指定路径下的*.cpp *.c文件,将得到的文件列表使用add_library()加入工程。
遍历指定路径下的*.hpp *.h文件,将得到的文件列表使用include_directories()指定头文件路径。
三、CMakeLists.txt文件
1.自动添加源文件
# 查找source目录下的所有*.cpp,*.c源文件,并将文件列表保存到 DIR_LIB_SRCS 变量
file(GLOB_RECURSE SRC_DIR_LIST "source/*.cpp" "source/*.c") //遍历获取source/路径下所有的*.cpp和*.c文件列表
#将DIR_LIB_SRCS中文件列表以静态库的方式加入工程
add_library(
${PROJECT_NAME} STATIC
${SRC_DIR_LIST} //将DIR_LIB_SRCS中文件列表以静态库的方式加入工程
)
message(STATUS "SRC_DIR_LIST = ${SRC_DIR_LIST}") //打印SRC_DIR_LIST中列表信息
2.自动添加头文件路径
#自动查找头文件路径函数(没有去重)
macro(FIND_INCLUDE_DIR result curdir) //定义函数,2个参数:存放结果result;指定路径curdir;
file(GLOB_RECURSE children "${curdir}/*.hpp" "${curdir}/*.h" ) //遍历获取{curdir}中*.hpp和*.h文件列表
message(STATUS "children= ${children}") //打印*.hpp和*.h的文件列表
set(dirlist "") //定义dirlist中间变量,并初始化
foreach(child ${children}) //for循环
string(REGEX REPLACE "(.*)/.*" "\\1" LIB_NAME ${child}) //字符串替换,用/前的字符替换/*h
if(IS_DIRECTORY ${LIB_NAME}) //判断是否为路径
LIST(APPEND dirlist ${LIB_NAME}) //将合法的路径加入dirlist变量中
endif() //结束判断
endforeach() //结束for循环
set(${result} ${dirlist}) //dirlist结果放入result变量中
endmacro() //函数结束
#查找include目录下的所有*.hpp,*.h头文件,并路径列表保存到 INCLUDE_DIR_LIST 变量中
FIND_INCLUDE_DIR(INCLUDE_DIR_LIST ${PROJECT_SOURCE_DIR}/source) //调用函数,指定参数
#将INCLUDE_DIR_LIST中路径列表加入工程
include_directories( //INCLUDE_DIR_LIST路径列表加入工程
${INCLUDE_DIR_LIST}
)
message(STATUS "INCLUDE_DIR_LIST = ${INCLUDE_DIR_LIST}") //打印INCLUDE_DIR_LIST中列表信息
四、build信息
1.源文件列表build信息
-- SRC_DIR_LIST =
/home/root/project/source/backlight/main.cpp;
/home/root/project/source/backlight/moc_mainwindow.cpp;
/home/root/project/source/backlight/mainwindow.cpp;
/home/root/project/source/main.cpp;
/home/root/project/source/3g/main.cpp;
/home/root/project/source/3g/moc_mainwindow.cpp;
/home/root/project/source/3g/mainwindow.cpp;
/home/root/project/source/4g/main.cpp;
/home/root/project/source/4g/moc_mainwindow.cpp;
/home/root/project/source/4g/mainwindow.cpp;
/home/root/project/source/audio/main.cpp;
/home/root/project/source/audio/moc_mainwindow.cpp;
/home/root/project/source/audio/mainwindow.cpp
2.头文件列表build信息
-- children=
/home/root/project/source/backlight/ui_mainwindow.h;
/home/root/project/source/backlight/mainwindow.h;
/home/root/project/source/3g/ui_mainwindow.h;
/home/root/project/source/3g/mainwindow.h;
/home/root/project/source/4g/ui_mainwindow.h;
/home/root/project/source/4g/mainwindow.h;
/home/root/project/source/audio/ui_mainwindow.h;
/home/root/project/source/audio/mainwindow.h
-- INCLUDE_DIR_LIST =
/home/root/project/source/backlight;
/home/root/project/source/backlight;
/home/root/project/source/3g;
/home/root/project/source/3g;
/home/root/project/source/4g;
/home/root/project/source/4g;
/home/root/project/source/audio;
/home/root/project/source/audio;
五、调试总结
1.FIND_INCLUDE_DIR()调用时要指定绝对路径
六、todo
- 头文件列表中没有去重