网上一般的教程都是手写C++源码进CMakeList
例如:
add_executable (main a.cpp b.cpp a/c.cpp ... )
这种写法太蠢了,不适合项目多层级目录使用
遍历所有文件夹
下面的代码是Cmake代码,一开始看到的时候我也是震惊的,但事实就是它可以运行
把下面的代码粘贴到CMakeList.txt中,然后在源码的目录执行 cmake,或者在源码的文件夹创建个build文件夹,CD到build中执行cmake .. 这种方式叫外部构建,创建的的文件都会放到build中。
#启动遍历方法,从根目录开始遍历文件夹以及编译CPP
function(makeAll)
# 遍历项目根目录和子目录下所有的 .cpp 文件
makeDir(*)
# 当前目录的cpp文件编译
makeCpp(.)
endfunction()
# 遍历文件夹
function(makeDir dir)
# 判断字符串是否包含 cmake-build-debug ,将结果输出到indexOfStr变量,若包含返回 > -1的值,若不包含返回-1
STRING(FIND ${dir} cmake-build-debug indexOfStr)
if(NOT indexOfStr MATCHES -1)
# 和 cpp的 return; 一样用法
return()
endif()
file (GLOB dirs ${dir}) # 创建变量files
foreach(item ${dirs})
if(${item} EQUAL cmake-build-debug)
# 和 cpp的 continue; 一样用法
continue()
endif()
if(IS_DIRECTORY ${item}) # 判断是否目录,必须加上${} ,如果不加 ${} 就是字符串,无法判断是否目录
makeDir(${item}/*) # 递归
makeCpp(${item}) # 编译cpp
endif()
# message(STATUS ${item})
endforeach()
endfunction()
# 编译单个目录下的所有cpp文件
function(makeCpp dir)
file (GLOB cpp_files ${dir}/*.cpp) # 创建变量files
foreach(item ${cpp_files})
message("make cpp file ->" ${item})
string(REGEX REPLACE ".+/(.+)/(.+)\\..*" "\\1-\\2" exe ${item})
add_executable (${exe} ${item} )
endforeach()
endfunction()
# 启动
makeAll()
红框里是执行cmake,以及执行后编译源码的样子
没编译成功!!!!有报错
看提示:fatal error: 'google/protobuf/stubs/common.h' file not found
报错原因,我们没有先编译被依赖代码,导致找不到文件报错。
如何解决,修改一下编译顺序就可以了
# 定义函数,函数名为 makeAll
function(makeAll)
# 遍历项目根目录和子目录下所有的 .cpp 文件
# makeDir(*) 这是老的代码,注释掉
# 由于gtest被google,因此先编译gtest
makeDir("/Users/hailong/Documents/CMakeProject/src/gtest")
#goolgle被下面的4个引用,第二个编译
makeDir("/Users/hailong/Documents/CMakeProject/src/google")
#core被后面3个引用,第三个编译
makeDir("/Users/hailong/Documents/CMakeProject/src/core")
#后面的三个没有互相引用,编译顺序随意
makeDir("/Users/hailong/Documents/CMakeProject/src/gamed")
makeDir("/Users/hailong/Documents/CMakeProject/src/cmn")
makeDir("/Users/hailong/Documents/CMakeProject/src/events")
endfunction()
修改CMakeList.txt代码后,再次执行cmake 。。
没有报错证明成功了,看一下build文件夹