【问题标题】:How to detect if current scope has a parent in CMake?如何检测当前范围是否在 CMake 中有父级?
【发布时间】:2014-08-08 09:02:22
【问题描述】:

有没有办法检测当前作用域是否有父作用域?

我有一个项目,它既可以是独立项目,也可以是另一个项目的子项目。为了允许子项目案例,我使用 PARENT_SCOPE 标志来 set() 将事情推送到父项目。但是,当构建为独立项目时,我会收到“当前范围没有父级”警告。我想通过检测是否存在父级并将 set() 调用包含在 if 语句中来避免该错误。还是只有在有父级的情况下才能在父级范围内设置变量?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    我认为最可靠的方法是使用PARENT_DIRECTORY 目录属性。

    无论是在project 命令之前还是之后调用它,无论父子项目是否具有相同的项目名称,这都会产生正确的答案。

    get_directory_property(hasParent PARENT_DIRECTORY)
    if(hasParent)
      message(STATUS "Has a parent scope.")
    else()
      message(STATUS "Doesn't have a parent scope.")
    endif()
    

    【讨论】:

      【解决方案2】:

      CMake 3.21 版为此添加了PROJECT_IS_TOP_LEVEL 全局变量:

      一个布尔变量,指示是否最近调用 当前范围或以上范围内的 project() 命令位于顶层 CMakeLists.txt 文件。

      project(my_project)
      [...]
      
      if(PROJECT_IS_TOP_LEVEL)
        message(STATUS "Is a top-level project.")
      endif()
      

      【讨论】:

        【解决方案3】:

        扩展一点@ruslo 的想法 我不会使用PROJECT_SOURCE_DIR,而是使用CMAKE_PROJECT_NAME 变量(包含第一个定义的项目的名称)和PROJECT_NAME(包含当前项目的名称),因此您可以在@987654324 中执行类似的操作子项目的@:

        project(bar)
        
        if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
         #do stuff
        else()
         #do other stuff
        endif()
        

        【讨论】:

        • 您不能将if(... STREQUAL ...) 嵌套在set 命令中。
        • 好点,我没有想到也没有测试它。我将直接在 if 中移动测试。顺便说一句,PARENT_DIRECTORY 属性很好。我不知道它存在。
        猜你喜欢
        • 1970-01-01
        • 2020-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-20
        • 1970-01-01
        • 2012-12-30
        • 2012-06-04
        相关资源
        最近更新 更多