C++ CMake目录层次结构,独立构建子目录

C++ CMake目录层次结构,独立构建子目录,c++,cmake,C++,Cmake,我目前正在处理一个不太理想的CMake设置,我正试图纠正它。顶级CMakeListsMain.txt包含编译器设置,包括所有项目都依赖和使用的目录、宏等。我的源代码树包含许多项目,但我在这里缩小了它的规模 src/ CMakeListsMain.txt project1/ -->CMakeLists.txt project2/ -->CMakeLists.txt headers/ -->source headers

我目前正在处理一个不太理想的CMake设置,我正试图纠正它。顶级CMakeListsMain.txt包含编译器设置,包括所有项目都依赖和使用的目录、宏等。我的源代码树包含许多项目,但我在这里缩小了它的规模

src/ 
  CMakeListsMain.txt  
  project1/  
    -->CMakeLists.txt  
  project2/  
    -->CMakeLists.txt  
  headers/
    -->source headers for every project  
例如,CMakeListsMain.txt看起来像这样,但要复杂得多:

MACRO(USE_BOOST target)  
   target_link_libraries(${target} boost_thread-mt boost_filesystem-mt boost_regex-mt boost_system-mt)  
ENDMACRO(USE_BOOST)  

MACRO(USE_PTHREAD target)  
   target_link_libraries(${target} pthread)  
ENDMACRO(USE_PTHREAD)

add_subdirectory(project1)
add_subdirectory(project2)
项目1和项目2都使用顶级CMakeListsTop.txt中的宏和其他设置

以前,如果我想构建一个项目,CMake必须在每个目录上运行,这是不好的

我的问题是,如果我想分别构建每个项目,我将如何访问这些宏和其他设置。目前,我已将宏抽象为一个不同的文件,并已将该文件包含在每个项目的CMakeLists.txt中。这样做,我还必须使用绝对路径来引用源代码树中的头文件,而不是使用
CMAKE\u source\u DIR/headers


未经批准,我无法真正更改源代码树的布局,但是否有更简单的方法来执行此操作或我忽略了什么?

您可以将宏和设置移动到模块中。然后,您可以将模块包装在包含保护中,以确保它只执行一次,并从需要独立构建的每个CMakeLists.txt中包含它

因此,对于您的示例,模块文件如下所示:

IF(NOT DEFINED MAIN_SETTINGS_INCLUDED)
   SET(MAIN_SETTINGS_INCLUDED ON)
   MACRO(USE_BOOST target)  
       target_link_libraries(${target} boost_thread-mt boost_filesystem-mt boost_regex-mt boost_system-mt)  
   ENDMACRO(USE_BOOST)  

   MACRO(USE_PTHREAD target)  
       target_link_libraries(${target} pthread)  
   ENDMACRO(USE_PTHREAD)
ENDIF()
添加此宏

MACRO(ADD_PROJECT PROJECT)
  IF(${PROJECT} OR ALL)
    add_subdirectory(${PROJECT})
  ENDIF()
ENDMACRO()
将所有出现的
add_子目录
替换为

ADD_PROJECT(project1)
ADD_PROJECT(project2)

等等。现在,您可以通过使用标志
-Dproject1=1
等调用cmake来构建任何单个项目,或者使用
-DALL=1

来构建整个项目。如果模块仅包含宏定义,则无需使用标题保护来保护模块。顺便说一句,为了避免整个模块缩进,您可以使用。