You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CMake中获取适配不同IDE的目标输出文件目录?

问题
  • 在Visual Studio 2022中打开CMake项目,选择x64-Debug配置时,构建目录为<project_directory>\out\build\x64-Debug,可执行文件及依赖DLL直接存放在该目录下。
  • 在Visual Studio Code中,CMake扩展默认在<project_directory>\build创建构建目录,执行cmake --build后,输出文件存放在<project_directory>\build\Debug。

需要添加自定义目标将源目录中的文件复制到输出目录或其子目录,但遇到以下问题:

  • 使用CMAKE_CURRENT_BINARY_DIR时,在VS2022中正常工作,但在cmake --build构建场景下失效。
  • 尝试追加$<CONFIG>后,cmake --build场景可用,但VS2022中失效。

请问是否存在能通用获取构建输出路径的变量或表达式?


当前CMakeLists.txt代码
cmake_minimum_required(VERSION 3.10)

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
  CACHE STRING "Vcpkg toolchain file")

# set the project name
project(sdl2-gl-project-template)

# add the executable
add_executable(main 
    "main.cpp" 
    "scene.hpp" "scene.cpp" 
    "io_util.hpp"
    "shader.hpp" "shader.cpp")

find_package(SDL2 CONFIG REQUIRED)
find_package(OpenGL REQUIRED)
find_package(imgui CONFIG REQUIRED)
find_package(gl3w CONFIG REQUIRED)
find_package(glm CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED)
find_package(imguizmo CONFIG REQUIRED)

target_link_libraries(main PRIVATE 
    SDL2::SDL2 
    SDL2::SDL2main 
    OpenGL::GL
    imgui::imgui
    imguizmo::imguizmo
    unofficial::gl3w::gl3w 
    spdlog::spdlog 
    spdlog::spdlog_header_only
    fmt::fmt
    fmt::fmt-header-only)

target_compile_features(main PRIVATE cxx_std_20)
set_property(TARGET main PROPERTY CXX_STANDARD 20)
set_property(TARGET main PROPERTY CXX_STANDARD_REQUIRED ON)

if (MSVC)
    # set_property(TARGET main PROPERTY WIN32_EXECUTABLE ON)
    target_compile_options(main PRIVATE /Zc:__cplusplus)
endif()

function(compile_shaders)
    set(oneValueArgs TARGET TARGET)
    set(multiValueArgs TARGET INPUT)
    set(oneValueArgs DESTINATION DESTINATION)

    cmake_parse_arguments(COMPILE_SHADERS "${options}" "${oneValueArgs}"
            "${multiValueArgs}" ${ARGN}
            )

    file(GLOB GLSL_SOURCE_FILES ${COMPILE_SHADERS_INPUT})

    add_custom_target(${COMPILE_SHADERS_TARGET}
            COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_SHADERS_DESTINATION}/"
            COMMAND ${CMAKE_COMMAND} -E copy ${GLSL_SOURCE_FILES} "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_SHADERS_DESTINATION}/"
            )
    add_dependencies(main ${COMPILE_SHADERS_TARGET})
endfunction()

compile_shaders(
        TARGET CompileBasicShader
        DESTINATION "shaders/frag"
        INPUT "shaders/shader.vert" "shaders/shader.frag"
)   

解决方案

使用CMake的生成器表达式 $<TARGET_FILE_DIR:main>,它能直接获取目标main的可执行文件所在的输出目录,无论你是在VS2022还是VSCode中构建,这个表达式都会自动适配正确的路径。

修改后的compile_shaders函数如下:

function(compile_shaders)
    set(oneValueArgs TARGET DESTINATION)
    set(multiValueArgs INPUT)

    cmake_parse_arguments(COMPILE_SHADERS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

    file(GLOB GLSL_SOURCE_FILES ${COMPILE_SHADERS_INPUT})

    # 获取目标可执行文件的输出目录
    set(OUTPUT_DIR "$<TARGET_FILE_DIR:main>/${COMPILE_SHADERS_DESTINATION}")

    add_custom_target(${COMPILE_SHADERS_TARGET}
            COMMAND ${CMAKE_COMMAND} -E make_directory "${OUTPUT_DIR}"
            COMMAND ${CMAKE_COMMAND} -E copy ${GLSL_SOURCE_FILES} "${OUTPUT_DIR}"
            )
    add_dependencies(main ${COMPILE_SHADERS_TARGET})
endfunction()

关键说明

  • $<TARGET_FILE_DIR:main> 是CMake生成器表达式,会在构建阶段动态解析为main可执行文件的实际存放目录,完美适配VS2022的<project_directory>\out\build\x64-Debug和VSCode的<project_directory>\build\Debug两种场景。
  • 同时修复了原函数中cmake_parse_arguments的参数定义错误(重复定义TARGET参数类型),确保参数解析逻辑正确。

内容的提问来源于stack exchange,提问作者Wutipong Wongsakuldej

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 20:05:02