背景 & 参考源
对于完整的CMakeList编写,很多大佬都有帖子,小白不班门弄斧,比如下边的链接飞向大佬,这个非常详实:
CMakeLists.txt 语法介绍与实例演练
具体问题:最近在工程中添加一些算法实现,发现编译报了link error,编译通过但是链接失败,基本能肯定是代码文件产生的.o文件找不到了,这方面没有know how所以搜搜大佬们都是怎么做的,总结下问题所在:
1.新增的算法导致文件夹结构变动了,具体:组件中的文件夹中添加了一层子文件夹——文件层级结构多了一层
2.原有的CMakeList文件,只检索到同级文件层——文件夹中若有子文件,则子文件夹中的.c、.h就找不到啦
粗暴描述就是uint_1中的.cc和.h都没问题,folder_1文件夹内的.cc和.h它不认,只认儿子不认孙子~
所以办法就是告诉CMake它除了儿子,还有孙子,甚至还有重孙子
多层文件的检索
我把planning模块中的lattice规划器的算法实现放在了第四层,报的link error就是这里。
工程结构大致如下:
解决这个问题有两种方法:
- 在planner(第3层)文件夹中再写一层CMakeList.txt,使.cc等生成对应的.o文件,在第二层的CMakeList.txt中通过
target_link_libraries
连接到该.o文件即可 - 在原有的CMakeList中,让其多检索一层,毕竟是一个组件内,不想写那么多CMakeList,简单无障碍,就是两层for循环…
改后对比:
代码实现
#组件名
project(planning_component)
#宏定义SUBDIRLIST,可看作一个函数使用,具体可参考文中链接
SUBDIRLIST(SUBDIRS ${PROJECT_SOURCE_DIR})
#检索planning的一级文件夹
FOREACH(subdir ${SUBDIRS})
include_directories (${subdir})
aux_source_directory(${subdir} SRC)
#search the deeper,检索并添加二级文件夹
SUBDIRLIST(SEC_SUBDIRS ${PROJECT_SOURCE_DIR}/${subdir})
FOREACH(Sec_Subdir ${SEC_SUBDIRS})
include_directories (${PROJECT_SOURCE_DIR}/${subdir}/${Sec_Subdir})
aux_source_directory(${PROJECT_SOURCE_DIR}/${subdir}/${Sec_Subdir} SRC)
ENDFOREACH()
ENDFOREACH()
aux_source_directory(. PLANNING_MAIN)
add_executable(${PROJECT_NAME}
${PLANNING_MAIN}
${SRC})
#SRC中包含了整个planning文件下以及子文件夹中的代码文件
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
message( ${PROJECT_SOURCE_DIR})
target_link_libraries (${PROJECT_NAME}
${GLOG}
${GFLAGS}
${Boost_FILE_SYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${ZMQ_LIBRARIES}
${JSON_LIBRARIES}
${LPTHREAD}
${DEMOSO_LIBRARY}
)
总结:
实现很简单,就是加了一层for循环,遍历模块文件夹下的文件+子文件夹中的文件,这样可以每个独立的组件使用一个CMakeList便可维护。Over~…每天进步一点点