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

如何让WSL环境下CMake构建的文件同步回Windows主机?

问题

接手一个基于STM32 MCU的固件项目,该项目已通过Docker定义构建流程,可生成.bin和.elf二进制文件。目前正在搭建Visual Studio 2022 + CMake的开发环境,目标是在WSL发行版中触发构建,并将生成的.elf和.bin文件同步回Windows主机,用于gdb server调试。

已编写简化版CMakeLists.txt(如下),能成功运行现有Docker镜像完成项目构建:

# CMakeList.txt : Top-level CMake project file, do global configuration
# and include sub-projects here.
#
cmake_minimum_required (VERSION 3.8)

# Enable Hot Reload for MSVC compilers if supported.
if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("firmware_cmake")

include(ExternalProject)

set(DOCKERFILE_DIR ${CMAKE_CURRENT_SOURCE_DIR})


ExternalProject_Add(
    build_image
    PREFIX build_image
    SOURCE_DIR ${DOCKERFILE_DIR}
    CONFIGURE_COMMAND rm -rf ${CMAKE_SOURCE_DIR}/build/ ${CMAKE_SOURCE_DIR}/Firmware/autogen ${CMAKE_SOURCE_DIR}/Firmware/build ${CMAKE_SOURCE_DIR}/Firmware/.tup
    BUILD_COMMAND docker build -t build-img .
    BUILD_IN_SOURCE 1
    INSTALL_COMMAND ""
    ALWAYS TRUE
)

ExternalProject_Add(
    build_cont
    DEPENDS build_image
    PREFIX build_cont
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
    CONFIGURE_COMMAND docker rm build-cont
    BUILD_COMMAND docker run -i -v ${CMAKE_CURRENT_SOURCE_DIR}:/FW --name build-cont build-img
    BUILD_IN_SOURCE 1
    INSTALL_COMMAND ""
    ALWAYS TRUE
)

add_custom_target(copy-runtime-files ALL
    COMMAND ${CMAKE_COMMAND} -E copy
            ${CMAKE_SOURCE_DIR}/Firmware/build/Firmware.bin
            ${CMAKE_BINARY_DIR}/Firmware.bin
    DEPENDS build_cont)

遇到的问题:生成的固件文件构建后未同步回Windows主机——WSL中可看到文件存在于~/.vs/firmware_cmake/out/build/linux-debug/,但Windows端的%path-to-my-project%\out\Ubuntu\build\linux-debug目录下无同步文件。

测试验证:创建cmake-test测试项目(仅含hello-world.cpp),add_executable生成的cmake-test-execute可正常同步,但自定义命令生成的test.txt无法同步。已在CMakePresets.json中配置copyBuildOutput为true。

需求:在不更改现有固件构建方式的前提下,让CMake将.bin/.elf文件标记为输出工件,实现和add_executable生成文件一致的Windows同步效果。


解决方案

方法1:用add_custom_command定义输出文件(推荐)

VS的WSL同步机制仅识别CMake标记为目标输出的文件,add_custom_target本身不关联输出,因此需要先通过add_custom_command明确定义生成的.bin/.elf为输出文件,再让自定义目标依赖这些输出:

# 定义要同步的输出文件路径
set(FIRMWARE_BIN ${CMAKE_BINARY_DIR}/Firmware.bin)
set(FIRMWARE_ELF ${CMAKE_BINARY_DIR}/Firmware.elf)

# 定义生成输出文件的命令
add_custom_command(
    OUTPUT ${FIRMWARE_BIN} ${FIRMWARE_ELF}
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Firmware/build/Firmware.bin ${FIRMWARE_BIN}
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Firmware/build/Firmware.elf ${FIRMWARE_ELF}
    DEPENDS build_cont  # 依赖Docker构建完成
    COMMENT "Copying firmware files to build directory"
)

# 创建自定义目标,关联上述输出文件
add_custom_target(copy-runtime-files ALL DEPENDS ${FIRMWARE_BIN} ${FIRMWARE_ELF})

# 标记为VS构建输出,确保同步机制识别
set_property(TARGET copy-runtime-files PROPERTY VS_GLOBAL_BuildOutput "${FIRMWARE_BIN};${FIRMWARE_ELF}")

这种方式让CMake明确识别这些文件为构建产物,VS的copyBuildOutput会自动同步它们到Windows主机。

方法2:直接标记目标的输出属性

如果不想修改现有add_custom_target结构,可在目标定义后添加属性,强制标记文件为输出:

add_custom_target(copy-runtime-files ALL
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Firmware/build/Firmware.bin ${CMAKE_BINARY_DIR}/Firmware.bin
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/Firmware/build/Firmware.elf ${CMAKE_BINARY_DIR}/Firmware.elf
    DEPENDS build_cont)

# 标记文件为目标的输出
set_property(TARGET copy-runtime-files APPEND PROPERTY
    OUTPUT "${CMAKE_BINARY_DIR}/Firmware.bin"
    OUTPUT "${CMAKE_BINARY_DIR}/Firmware.elf")

# 告诉VS这些是构建输出
set_property(TARGET copy-runtime-files PROPERTY VS_GLOBAL_BuildOutput "${CMAKE_BINARY_DIR}/Firmware.bin;${CMAKE_BINARY_DIR}/Firmware.elf")

方法3:构建后手动同步(备选)

若上述CMake配置仍不生效,可在CMakePresets.json的构建预设中添加postBuildCommand,直接执行WSL到Windows的复制:

{
  "version": 3,
  "buildPresets": [
    {
      "name": "linux-debug",
      "configurePreset": "linux-debug",
      "targets": ["all"],
      "postBuildCommand": "cp ${sourceDir}/Firmware/build/Firmware* ${sourceDir}/out/Ubuntu/build/linux-debug/"
    }
  ]
}

注意命令路径为WSL内路径,因构建命令在WSL环境执行,${sourceDir}会自动映射到WSL对应的项目目录。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:54:55