C++ 正确使用CMAKE_*\u输出目录

C++ 正确使用CMAKE_*\u输出目录,c++,cmake,C++,Cmake,前言:我只谈论本地编译,而不是安装项目。这是因为我没有用CMake对正确的install进行足够的研究,但如果我的问题与install实践直接相关(似乎有可能),请插话 TL;博士 在哪些情况下,您不希望将所有构建到同一目录中的项目库收集到一起?为什么没有人缓存CMAKE\u*\ u OUTPUT\u目录路径 是否需要直接执行$级别规范 一般默认值是CMAKE\u BINARY\u DIR,CMAKE\u CURRENT\u BINARY\u DIR,还是PROJECT\u BINARY\u D

前言:我只谈论本地编译,而不是安装项目。这是因为我没有用CMake对正确的
install
进行足够的研究,但如果我的问题与
install
实践直接相关(似乎有可能),请插话

TL;博士
  • 在哪些情况下,您希望将所有构建到同一目录中的项目库收集到一起?为什么没有人
    缓存
    CMAKE\u*\ u OUTPUT\u目录
    路径

  • 是否需要直接执行
    $
    级别规范

  • 一般默认值是
    CMAKE\u BINARY\u DIR
    CMAKE\u CURRENT\u BINARY\u DIR
    ,还是
    PROJECT\u BINARY\u DIR

  • 1.缓存还是不缓存? 从

    你可以在网络上的许多项目中看到这一点

    • 父级
      CMakeLists.txt
      无法覆盖这些
    • 如果父项目希望/需要更改这些内容,例如将所有内容放在同一文件夹中,则不可能
    因此,建议的修订将是始终
    缓存路径“描述”

    • 是否有任何理由缓存
    2.
    $
    构建的处理 这应该总是留给发电机,是吗?我的理解(和经验)是,通过设置非配置生成器,在每个配置构建中使用文件夹的生成器(VisualStudio、XCode,…)仍然满足于将内容放在它们通常需要的地方。AKA通过不设置配置级别
    CMAKE\u*\ u OUTPUT\u DIRECTORY\u*
    我将控制权传递给生成器,由其决定

    3. <代码>二进制目录
    当前二进制目录
    ,或
    项目二进制目录
    ? 另一方面,假设开发人员不希望他们正在构建的其他项目最终位于同一目录中。我是否应该进一步使用
    CMAKE\u CURRENT\u BINARY\u DIR
    ?如果只使用原始的
    CMAKE_BINARY_DIR
    ,而没有
    缓存
    ,那么我绝对无法阻止我正在构建的子项目在我的子项目旁边结束

    通过使用
    CMAKE\u CURRENT\u BINARY\u DIR
    PROJECT\u BINARY\u DIR
    ,如果用户不希望此库结束在父项目旁边,他们只需在配置此库后设置
    CMAKE\u*\u OUTPUT\u目录
    变量

    总结
    基本上,对于如何使用这些变量,似乎没有任何标准。我对CMake的多才多艺感到兴奋,我并不是说他们应该在这里进行任何默认操作——这将由项目决定。我正在努力理解什么是最合适的默认选择,如果开发者愿意,他们也可以绕过我的默认设置。

    我支持@Tsyvarev。我没有看到启用CMake的项目的用户想要更改构建工件的输出路径,只有安装路径

    1.缓存还是不缓存? 只是不要将
    CMAKE_*\u OUTPUT_目录
    变量设置为缓存,因为如果另一个CMAKE项目将您的作为子项目使用,您在某些情况下会覆盖父项目的设置(缓存的变量是全局的)

    2.
    $
    构建的处理 对。仅当生成器的默认值不合适时才会给出(“配置名称”=“子文件夹名称”)

    3.
    CMAKE\u BINARY\u DIR
    CMAKE\u CURRENT\u BINARY\u DIR
    ,或
    PROJECT\u BINARY\u DIR
    ? 因此,我想说,save变量将首先使用
    if()
    语句检查其他人是否已经设置了变量,并使用:


    然后,项目的用户仍然可以从外部设置变量,或者父项目可以设置变量,如果未设置,则您有一个默认值。

    正如您在开始时正确猜测的,用户只希望选择安装位置。所以构建树的布局只由项目的开发人员选择。另一方面,一些项目(通常是简单的项目)不需要安装。但是这样做主要是为了项目的简单性,所以这样的项目很少允许用户选择目录。这是一个很好的观点。我需要更仔细地考虑我将如何处理这件事。最初的想法是,由于我的库(可选)能够构建其所有依赖项,因此设置一个结构,使用户只需
    安装
    我的库,而我的安装将创建必要的
    包含
    目录结构,但为了方便,只需将所有库放在一个文件夹中即可。我必须对安装实践做更多的研究!很好。我偶然发现了一个项目,该项目也构建了python绑定,并且在windows上有配置级别的设置,但它似乎确实像预期的那样正常工作:)在检查值方面,如果父级缓存了它(而不是仅仅设置它),是否有理由更改行为?例如,通过检查
    get\u属性(runtimeCached CACHE CMAKE\u RUNTIME\u OUTPUT\u目录属性值集)
    ?我认为最好的做法是只在
    未设置的情况下设置它。这不是为了用户,而是为了开发者;)如果我想移动它,请让我!Hehe@sjm324我会说,通常情况下,子项目的输出——可能是中间构建产品——不需要最终到达用户选择的最终构建输出目的地。但如果你愿意,这也在中讨论过。您可以考虑添加一个特定于项目的用户可定义变量,如“代码> MyLabyLogyOutPuxObjult,然后您可以在代码中查询。我认为第二个选项是最好的方法,如果父母希望如此,则允许在另一个位置输出。我
    
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE PATH "Where to place compiled static libraries.")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib CACHE PATH "Where to place compiled shared libraries.")
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin CACHE PATH "Where to place compiled executables.")
    
    if (NOT CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
        set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
    endif()