在CMake

时间:2017-08-15 07:59:48

标签: c++ cmake git-submodules

我正在尝试使用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)

这个设置对我来说非常有用:

  1. 这是system / packagemanager独立的。您无需安装任何库即可开始开发
  2. 我可以通过将子模块设置为特定提交来维护我的依赖项的确切版本。一些外部库打破你的构建没有意外
  3. 在根CMakeListst.txt中将库添加到我的构建中是微不足道的。由于我有目标可用,我只是有类似的东西 add_executable(someProjectImWorkingOn ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ) target_link_libraries(someProjectImWorkingOn opencv_world eigen zlib etc.)
  4. 当您将现有库目标连接到您自己的目标可执行文件/库时,CMake将自动(通过目标接口)向目标添加包含目录,并添加库目标所需的任何其他必要选项以供其使用
  5. 我可以在根CMakeLists.txt中选择一个工具链/编译器选项/构建类型,它将传播到所有子项目(我需要为多个系统构建。所以这是一个大问题)
  6. 由于它只在一个“大型项目”中,因此很容易连接rtags / kdevelop / clion来导航而不是你自己的代码,还有库代码
  7. 我无法解决的一些问题:

    1

    子目录将定义具有相同名称的目标。在我给出的示例中,Eigen OpenCV以及另一个库都定义了“卸载”目标

    我试图更新

    add_subdirectory(blah)
    

    add_subdirectory(blah EXCLUDE_FROM_ALL)
    

    但由于某种原因,这并不能解决问题

    启用变量ALLOW_DUPLICATE_CUSTOM_TARGETS有点工作..但这是一个黑客攻击,只能使用Make文件,并且库基本上仍在“混合”,所以它仍然是一个问题

    2

    第二个问题出现在LeapSerial中,但说明了一个更大的问题。该项目不再知道它自己的名字。 LeapSerial试图确定LeapSerial的版本,但是当它要求项目版本时它会获得根项目版本。 IE浏览器。当子项目中的cmake代码询问“我在做什么项目”时,它会获得根项目,而不是它所在的直接项目。

    所以,父级“命名空间”到处都在泄漏。这势必会产生越来越多的问题。我需要子模块是自包含的

    是否有更清洁的解决方案?

    ExternalProjectAdd可能会解决其中的一些问题,但很多会出现更多问题。这是一个真正的非首发b / c,它没有完成我列出的大部分内容。核心问题是它没有暴露子项目的目标 - 只是呕吐回变量,然后你必须耍弄

0 个答案:

没有答案