我正在尝试使用CMake和gitsubmodules管理我的C ++项目依赖项。我遵循这里描述的布局:http://foonathan.net/blog/2016/07/07/cmake-dependency-handling.html并且它在小型项目上对我来说非常有效。但我已经开始在更大的项目中使用它,而且我在使用CMake遇到了一些问题。
我的所有外部构建依赖项都在我的主项目中的contrib/
子文件夹中。每个都是一个子模块,并有自己独立的目录。
/contrib
- /eigen
- /curl
- /leapserial
- /zlib
- /opencv
etc.
contrib/CMakeListst.txt
只是初始化子模块并为每个外部依赖项添加子目录
# EIGEN
execute_process(COMMAND git submodule update --recursive --init -- eigen
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# options..
add_subdirectory(eigen EXCLUDE_FROM_ALL)
# CURL
execute_process(COMMAND git submodule update --recursive --init -- curl
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(curl EXCLUDE_FROM_ALL)
# LEAP SERIAL
execute_process(COMMAND git submodule update --recursive --init -- leapserial
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(leapserial EXCLUDE_FROM_ALL)
# ZLIB
execute_process(COMMAND git submodule update --recursive --init -- zlib
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(zlib EXCLUDE_FROM_ALL)
# OPENCV
execute_process(COMMAND git submodule update --recursive --init -- opencv
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Initialize cache with CMake build options..
add_subdirectory(opencv EXCLUDE_FROM_ALL)
这个设置对我来说非常有用:
CMakeListst.txt
中将库添加到我的构建中是微不足道的。由于我有目标可用,我只是有类似的东西
add_executable(someProjectImWorkingOn
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp )
target_link_libraries(someProjectImWorkingOn
opencv_world
eigen
zlib
etc.)
子目录将定义具有相同名称的目标。在我给出的示例中,Eigen OpenCV以及另一个库都定义了“卸载”目标
我试图更新
add_subdirectory(blah)
到
add_subdirectory(blah EXCLUDE_FROM_ALL)
但由于某种原因,这并不能解决问题
启用变量ALLOW_DUPLICATE_CUSTOM_TARGETS
有点工作..但这是一个黑客攻击,只能使用Make文件,并且库基本上仍在“混合”,所以它仍然是一个问题
第二个问题出现在LeapSerial中,但说明了一个更大的问题。该项目不再知道它自己的名字。 LeapSerial试图确定LeapSerial的版本,但是当它要求项目版本时它会获得根项目版本。 IE浏览器。当子项目中的cmake代码询问“我在做什么项目”时,它会获得根项目,而不是它所在的直接项目。
所以,父级“命名空间”到处都在泄漏。这势必会产生越来越多的问题。我需要子模块是自包含的
是否有更清洁的解决方案?
ExternalProjectAdd可能会解决其中的一些问题,但很多会出现更多问题。这是一个真正的非首发b / c,它没有完成我列出的大部分内容。核心问题是它没有暴露子项目的目标 - 只是呕吐回变量,然后你必须耍弄