如何用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的用途。现咨询两个问题:
- 是否可通过CMakeLists.txt中的命令实现我想要的项目布局?
- 我想要的这种布局是否存在不合理之处?
回答
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
相关产品推荐
相关产品推荐

