如何在CMakeLists.txt中判断它是否与add_subdirectory()一起使用?

ein*_*ica 3 build cmake subdirectory subrepos

我有此代码项目可以独立构建,也可以作为较大存储库的子项目构建(将其作为子存储库检查)。在后一种情况下,我CMakeLists.txt在主项目中拥有一个顶层

add_subdirectory(${MY_SUBPROJ_SUBDIR})
Run Code Online (Sandbox Code Playgroud)

现在,我希望子项目在通过中使用时,其行为有所不同the add_directory()。显然,我会使用一条大if指令。但是我要检查什么情况?当运行某些命令时CMakeLists.txt,CMake如何“告诉” 它是子目录文件还是主文件?

Tsy*_*rev 7

  1. project()在项目的CMakeLists.txt和项目的子目录中调用之后,您可以使用:

    if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
        # I am top-level project.
    else()
        # I am called from other project with add_subdirectory().
    endif()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 替代使用project()电话:

    if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
        # I am top-level project.
    else()
        # I am called from other project with add_subdirectory().
    endif()
    
    Run Code Online (Sandbox Code Playgroud)

    也可以在项目的任何地方CMakeLists.txt(但不能在子目录中)使用此替代方法。


假设您有一个项目ACMakeLists.txt其中有两个:一个在项目目录中,一个在子目录中src/。上述使用方法方案:

CMakeLists.txt

cmake_minimum_required(...)
...
<only approach *2* can be used there>
...
project(A)
...
<approach *1* or *2* can be used there>
...
add_subdirectory(src)
...
Run Code Online (Sandbox Code Playgroud)

src / CMakeLists.txt

...
<only approach *1* can be used there>
...
Run Code Online (Sandbox Code Playgroud)

使用给定的方案,项目A可以检测它是独立构建(顶层项目)还是作为另一个项目B的一部分。

  • 在Windows上不起作用。`CMAKE_SOURCE_DIR`扩展为`c:/ users / ...`,而`PROJECT_SOURCE_DIR`扩展为`C:/ Users / ...`。代替“ STREQUAL”,必须进行不区分大小写的比较(将两个字符串都转换为小写,然后进行“ STREQUAL”)。 (2认同)