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

如何用CMake生成指定布局的Visual Studio项目文件?

CMake自定义Visual Studio项目布局问题解答

问题描述

我正在学习CMake,难以实现自己习惯的Visual Studio项目布局。我希望生成如下目录结构,其中.sln和.vcxproj文件由CMake生成:

Root
    CMakeLists.txt
    MySolution.sln

    ProjectOne
        CMakeLists.txt
        ProjectOne.vcxproj
        someSourceFile1.h
        someSourceFile1.cpp

    ProjectTwo
        CMakeLists.txt
        ProjectTwo.vcxproj
        someSourceFile2.h
        someSourceFile2.cpp

    Binaries
       Platform
          Debug
              ProjectOne.exe
              ProjectTwo.dll

          Release
             ProjectOne.exe
             ProjectTwo.dll

但我找到的教程示例多为如下结构:

Root
   Source
      CMakeLists.txt

      ProjectOne
        CMakeLists.txt
        someSourceFile1.h
        someSourceFile1.cpp

      ProjectTwo
        CMakeLists.txt
        someSourceFile2.h
        someSourceFile2.cpp

    Build
       MySolution.sln
       ProjectTwo.vcxproj
       ProjectOne.vcxproj
      
       Platform
          Debug
              ProjectOne.exe
              ProjectTwo.dll

          Release
              ProjectOne.exe
              ProjectTwo.dll

使用的命令为:

mkdir Build
cd build
CMake ..\Source
CMake --Build .

另外我暂未理解自动生成的ALL_BUILD.vcxproj和ZERO_CHECK.vcxproj的用途。现咨询两个问题:

  1. 是否可通过CMakeLists.txt中的命令实现我想要的项目布局?
  2. 我想要的这种布局是否存在不合理之处?

回答

1. 可以通过CMake配置实现目标布局

要实现你想要的目录结构,需要调整根目录和子项目的CMakeLists.txt配置,同时修改构建命令,具体步骤如下:

根目录Root/CMakeLists.txt配置

cmake_minimum_required(VERSION 3.15)

# 设置解决方案名称
project(MySolution LANGUAGES CXX)

# 指定.sln文件直接生成在根目录
set(CMAKE_VS_SOLUTION_FILE_NAME "MySolution.sln")

# 配置二进制文件输出路径,对应Binaries/Platform/Config结构
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/Binaries/$<PLATFORM_ID>/$<CONFIG>")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/Binaries/$<PLATFORM_ID>/$<CONFIG>")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/Binaries/$<PLATFORM_ID>/$<CONFIG>")

# 可选:禁用自动生成的ALL_BUILD和ZERO_CHECK项目
set(CMAKE_SUPPRESS_REGENERATION TRUE)
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD FALSE)

# 添加子项目
add_subdirectory(ProjectOne)
add_subdirectory(ProjectTwo)

子项目ProjectOne/CMakeLists.txt配置

project(ProjectOne LANGUAGES CXX)

# 生成可执行文件
add_executable(ProjectOne
    someSourceFile1.h
    someSourceFile1.cpp
)

# 指定.vcxproj文件生成在当前子项目目录
set_target_properties(ProjectOne PROPERTIES
    VS_PROJECT_FILE_NAME "${CMAKE_CURRENT_SOURCE_DIR}/ProjectOne.vcxproj"
)

子项目ProjectTwo/CMakeLists.txt配置

project(ProjectTwo LANGUAGES CXX)

# 生成动态链接库
add_library(ProjectTwo SHARED
    someSourceFile2.h
    someSourceFile2.cpp
)

# 指定.vcxproj文件生成在当前子项目目录
set_target_properties(ProjectTwo PROPERTIES
    VS_PROJECT_FILE_NAME "${CMAKE_CURRENT_SOURCE_DIR}/ProjectTwo.vcxproj"
)

构建命令

无需单独创建Build目录,直接在根目录执行:

cmake . -G "Visual Studio 17 2022"  # 根据你的VS版本调整生成器
cmake --build .

关于ALL_BUILD和ZERO_CHECK的用途

  • ZERO_CHECK.vcxproj:负责监测CMakeLists.txt文件的变更,一旦检测到修改,会自动重新运行CMake生成新的项目文件,保证项目配置与脚本同步。
  • ALL_BUILD.vcxproj:是一个虚拟聚合项目,依赖所有自定义子项目,构建它可以一次性编译整个解决方案的所有项目。

2. 目标布局的不合理之处

虽然可以通过配置实现,但这种布局存在几个明显的问题:

  • 源码与构建产物混合:.vcxproj、.sln属于构建生成文件,和源码放在同一目录下,会增加版本控制的复杂度(需额外配置忽略规则),也容易误修改生成的项目文件。
  • 多环境构建冲突:如果需要同时维护Debug/Release、x86/x64等不同配置,生成的.vcxproj文件会被覆盖,无法同时保留多套构建配置的项目文件。
  • 违背CMake设计思想:CMake的核心设计原则是源码目录与构建目录分离,这种分离可以避免构建产物污染源码树,也方便快速清理构建文件(直接删除Build目录即可)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:33:17