【问题标题】:CMake multi-config generators use wrong build directoryCMake 多配置生成器使用错误的构建目录
【发布时间】:2021-01-08 17:55:15
【问题描述】:

我遇到了与 CMake 中的多配置生成器相关的问题。 任务很简单:我只想将一些文件(glsl 着色器)复制到运行时目录中(以便在运行时读取可执行文件)。

我有以下目标层次结构:我有(DLL)目标和可执行文件,将由用户创建。然后库与可执行文件链接。这就是问题所在。 我使用了以下代码:

configure_file("${SHADER_SRC}" "${CMAKE_RUNTIME_OUTPUT_DIR}/shaders/${SHADER_OUTPUT_FILENAME}" COPYONLY)

它会产生类似的构建树:

  • 二进制目录
    • BUILD_TYPE(例如,调试)
        • 着色器
          • 我的文件在这里。工作正常
        • 其他目标

它适用于单一配置生成器。 但是当我开始使用Visual Studio 16 2019 多配置生成器时,会发生以下情况:

  • 二进制目录
    • BUILD_TYPE
        • 着色器
          • 我的文件在这里。工作正常
        • BUILD_TYPE
          • 其他目标 可执行文件不再看到着色器,因为它们位于错误的目录中。 如何解决这个问题?

附: 我也用过add_custom_command 版本:

set(SHADER_OUTPUT_FILENAME "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/shaders/${SHADER_FILENAME}")
    
add_custom_command(
            TARGET ${LIBRARY_TARGET_NAME} PRE_BUILD
            WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
            COMMENT "Copying shader (${SHADER_FILENAME}) to build directory..."
            BYPRODUCTS "${SHADER_OUTPUT_FILENAME}"

            COMMAND ${CMAKE_COMMAND} -E copy
                    ${SHADER_SRC} # Shader file in source directory
                    ${SHADER_OUTPUT_FILENAME} # Shader file that I need in build directory

            VERBATIM
    )

【问题讨论】:

  • 请创建一个minimal reproducible example,即一个完整的最小CmakeLists.txt,可用于与所需(最小)输入文件一起重现问题。

标签: cmake build msbuild


【解决方案1】:
if(UNIX)
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
  # for multi-config build system (e.g. xcode, ninja-multiconfig)
  foreach(OUTPUTCONFIG IN LISTS CMAKE_CONFIGURATION_TYPES)
    string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_LIBDIR})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_LIBDIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_BINDIR})
  endforeach()
else()
  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
  # for multi-config builds (e.g. msvc)
  foreach(OUTPUTCONFIG IN LISTS CMAKE_CONFIGURATION_TYPES)
    string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_BINDIR})
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_BINDIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OUTPUTCONFIG}/${CMAKE_INSTALL_BINDIR})
  endforeach()
endif()

【讨论】:

  • 没有这个“ifs”有没有办法做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2022-07-12
  • 2015-05-16
  • 1970-01-01
  • 1970-01-01
  • 2019-12-26
  • 1970-01-01
相关资源
最近更新 更多