Linux与Windows平台下C++工程开发环境的搭建问题

发布于 2025-07-15
更新于 2026-03-08

问题描述:为了更好地满足不同场景下的开发需求,我们需要弄清楚如何在不同的平台上开发C++项目。要求使用cmake构建工具和conan包管理工具。

Linux下的c++开发环境搭建

  • 🟢 1️⃣ 安装 C++ 编译器

Ubuntu 自带 gcc 或 g++,但一般建议先更新到较新版本。

bash
sudo apt update
sudo apt install build-essential
  • build-essential 包含 gcc、g++、make 等基本编译工具。

  • 🟠 2️⃣ 安装 CMake

bash
sudo apt install cmake
  • 🔵 3️⃣ 安装 Conan(C++ 包管理器)

Conan 推荐使用 Python 的 pip 安装:

bash
# Python 3.11 起 使用虚拟环境
# 安装 venv(如果没有)
sudo apt install python3-venv
# 创建一个新的虚拟环境
python3 -m venv ~/.venvs/conan-env
# 激活虚拟环境
source ~/.venvs/conan-env/bin/activate
# 在虚拟环境中安装 conan ,注意到国内可能存在的网络环境问题
pip install conan -i https://pypi.tuna.tsinghua.edu.cn/simple
# 确认安装
conan --version

# 旧的python版本下可用
sudo apt install -y python3-pip
pip3 install conan -i https://pypi.tuna.tsinghua.edu.cn/simple
conan --version
  • 初始化 Conan 的配置文件(profile)
    执行以下命令,Conan 会自动根据你当前系统生成一个默认 profile
bash
conan profile detect

执行完毕后会自动在 ~/.conan2/profiles/ 下生成一个 default 文件,可以根据实际需求进行手动修改。

  • 配置 Conan远程仓库(可选步骤)

Conan 默认使用本地缓存,但可以配置远程仓库(如 conan-center):

bash
# 添加远程仓库
conan remote add conan-center https://center.conan.io
# 查看已配置的远程仓库
conan remote list
  • 🟣 4️⃣ 创建项目文件夹结构(示例)
bash
mkdir MyCppProject
cd MyCppProject

mkdir src include build
touch src/main.cpp
touch CMakeLists.txt
  • 🟤 5️⃣ 示例代码和配置
cpp
// src/main.cpp
#include <fmt/core.h>

int main() {
    fmt::print("Hello, C++ with Conan and CMake!\n");
    return 0;
}
  • CMakeLists.txt 示例
cmake
cmake_minimum_required(VERSION 3.15)
project(MyCppProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

find_package(fmt CONFIG REQUIRED)  # 例如你的依赖是 fmt
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt)cmake_minimum_required(VERSION 3.15)
project(MyCppProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 只需要 find_package 即可

find_package(fmt CONFIG REQUIRED)  # 例如你的依赖是 fmt
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt)
  • 🟢 6️⃣ 配置 Conan

创建 conanfile.txt

txt
[requires]
# 假设项目需要 `fmt` 库(一个流行的 C++ 格式化库)
fmt/10.2.1
eigen/3.4.0

[generators]
CMakeDeps
CMakeToolchain
  • 安装依赖
bash
cd build
conan install .. --build=missing
  • 🟠 7️⃣ 配置并构建项目
bash
cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build .

构建成功后运行

bash
./MyCppProject

如果一切正常,应该输出:

plaintext
Hello, C++ with CMake & Conan!

一个完整小项目演示

要求:现在请利用上面的环境(在 Ubuntu 系统下搭建 C++ 开发环境,并且使用 CMake 作为构建工具、Conan 作为包管理工具),完成一个小任务:矩阵数据的序列化与反序列化。要求包括:

  • 编写C++ 代码,实现Eigen::MatrixXd矩阵数据的序列化与反序列化。
  • 需要写单元测试用例
  • 通过 CMake 构建项目
  • 可使用的三方库以及版本:eigen/3.4.0nlohmann/3.11.3gtest/1.14.0

示例方案:
其中 CMakeLists.txt 内容为

cmake
cmake_minimum_required(VERSION 3.15)
project(MyCppProject)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 头文件目录
include_directories(${PROJECT_SOURCE_DIR}/include)

# 查找依赖
find_package(Eigen3 REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(GTest REQUIRED)

# 主程序
add_executable(MyCppProject src/main.cpp src/matrix_serializer.cpp)
target_link_libraries(MyCppProject PRIVATE nlohmann_json::nlohmann_json Eigen3::Eigen)

# 单元测试
enable_testing()
add_executable(tests test/test_matrix_serializer.cpp src/matrix_serializer.cpp)
target_link_libraries(tests PRIVATE GTest::gtest GTest::gtest_main nlohmann_json::nlohmann_json Eigen3::Eigen)

add_test(NAME MatrixSerializerTests COMMAND tests)

conanfile.txt

txt
[requires]
eigen/3.4.0
nlohmann_json/3.11.3
gtest/1.14.0

[generators]
CMakeDeps
CMakeToolchain

Windows平台下开发C++项目

使用CMake预设

在Windows平台下开发C++项目,主流的方式是VS。打开VS,选择新建CMake项目后,项目文件夹下会生成CMakePresets.json文件和CMakeSettings.json,这里有必要先弄清楚这些设置文件的含义。

  1. CMakeSettings.jsonVisual Studio 特有的配置文件,在 CMake 官方推出预设机制前,VS 为了更好地支持 CMake 项目而设计的配置方式。它用于定义 VS 中 CMake 项目的构建配置,包括指定编译器、构建目录、构建类型(Debug/Release)、环境变量等等。它仅在 Visual Studio 中生效,不被其他 IDE(如 CLion、VS Code)或 CMake 官方工具识别。它的格式和语法是 VS 自定义的,与 CMake 官方标准无关。适合纯 VS 环境下的开发,无需考虑跨平台兼容性。

  2. CMakePresets.jsonCMake 官方推出的标准化配置文件(CMake 3.19+ 支持),旨在统一不同 IDE/工具对 CMake 项目的配置方式。它用于定义项目的通用构建预设,包括构建类型(Debug/Release)、生成器(如 Ninja、Visual Studio)、工具链路径、缓存变量等,可被所有支持 CMake 预设的工具识别。它能跨平台、跨工具兼容(支持 VS、VS Code、CLion、CMake 命令行等),是项目级的配置文件,通常包含团队共用的基础配置,需要提交到版本控制(如 Git)中,语法遵循 CMake 官方规范。CMakePresets.json的内容分为几类 preset: configurePresets 用于定义 CMake 配置(生成器、编译器、选项等);buildPresets定义构建参数(并行度、目标等);testPresets定义测试运行方式。

  3. CMakeUserPresets.json同样是 CMake 官方预设机制的一部分,用于补充 CMakePresets.json。它用于存储用户个人的自定义配置(如本地路径、个人偏好的编译选项等),不会影响团队其他成员的配置,属于用户级配置文件,通常 不提交到版本控制(需加入 .gitignore),避免覆盖他人配置,继承或扩展 CMakePresets.json 中的预设,添加个人化修改(如本地工具链路径)。它必须继承于 CMakePresets.json 中的配置,并覆盖CMakePresets.json中的相同项。

维度 CMakeSettings.json CMakePresets.json CMakeUserPresets.json
来源 Visual Studio 特有 CMake 官方标准 CMake 官方标准
适用范围 仅 VS 环境 跨 IDE/工具(通用) 跨 IDE/工具(用户个人)
版本控制 可提交(团队共享) 必须提交(团队共享) 不提交(个人使用)
兼容性 非标准,仅 VS 识别 标准,所有支持 CMake 预设的工具都识别 同左

在VS中打开:工具--选项--CMake--常规,第一项有三个选项:

VS中的cmake配置VS中的cmake配置

  1. 始终使用 CMake 预设,VS2022 会 完全依赖 CMakePresets.json / CMakeUserPresets.json 作为配置来源。如果项目里没有 CMakePresets.json,那么配置会失败,VS 不会回退到 CMakeSettings.json

  2. 如果可用请使用 CMake 预设,否则使用 CMakeSettings.json 这是 VS 的默认策略,优先检查项目中是否存在 CMakePresets.json/CMakeUserPresets.json。若存在预设文件,则使用其配置;若不存在,则回退到使用 VS 特有的CMakeSettings.json文件。这种方式兼顾了跨平台标准化(CMake 预设)和 VS 传统工作流(CMakeSettings.json),适合需要兼容旧项目的场景。

  3. 从不使用 CMake 预设 强制 VS 忽略任何 CMakePresets.json/CMakeUserPresets.json 文件,仅使用 VS 特有的CMakeSettings.json进行配置。适合的场景:项目比较老,还没有采用 CMake Presets,或者只打算在 Visual Studio 里开发,不考虑跨 IDE 的配置一致性。

当项目中同时存在 CMakePresets.jsonCMakeSettings.json 时,VS 会根据CMake 项目属性的配置决定优先使用哪一个。而CMakeUserPresets.json 则始终用于覆盖或补充 CMakePresets.json,不影响 CMakeSettings.json

优先推荐使用 CMakePresets.json + CMakeUserPresets.json 的组合,尤其适合跨平台、多工具协作的项目。

使用conan

Conan 是一个开源的C/C++包管理器,用于管理和构建C/C++项目所需的依赖库。它是去中心化的 C/C++ 包管理器,它借鉴了像 npm、pip、cargo 等现代语言包管理器的理念,但针对 C++ 的复杂性(平台、编译器、架构、标准库、构建系统等)做了深度适配。

sh
# 安装conan
pip install conan
conan --version
conan profile detect

配置远程仓库,conancenter是官方远程仓库,在安装时已经默认添加,可以在国内的网络下正常访问,个人开发者使用它即可。可以在C盘user/.conan2文件夹下查看配置。

sh
conan remote add conancenter https://center.conan.io

conan install 官方文档 https://docs.conan.org.cn/2/reference/commands/install.html
摘取部分内容如下:
--build 参数决定缺失的二进制包(或者匹配不到的)是否从源码构建,以及在什么情况下构建。

bash
conan install . --build=missing

常见值(参考conan install — conan 2.20.1 文档 - Conan 文档): | 值 | 含义 | | ---------------------- | ----------------------------------------------------------------------------------- | | never | 全部使用二进制包;如果二进制包不存在就报错。 | | missing | 对于那些没有合适的二进制包的包,从源代码构建。 | | cascade | 如果一个包有依赖被构建,那么这些依赖也可能被构建。详见文档。 | | [pattern] | 对匹配 pattern 的包强制从源码构建,例如 --build="pkg/*"。 | | ~[pattern] | 排除匹配 pattern 的包不从源码构建。 | | missing:[pattern] | 类似 missing,但仅对匹配 pattern 的包。 | | compatible:[pattern] | 实验性选项。如果没有兼容的二进制包,并且按照某些兼容策略允许,那么对匹配 pattern 的依赖使用可兼容的包构建。|

在早期版本的conan 1 中,推荐的配置是将conan_toolchain.cmake手动指定到专门的 generators文件夹中,而在conan 2中官方现在推荐的做法是,在conanfile.py或者 conanfile.txt文件中使用自动的layout配置。
参阅 使用 layout() 方法

py
from conan import ConanFile
from conan.tools.cmake import cmake_layout

class CompressorRecipe(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    generators = "CMakeToolchain", "CMakeDeps"
    def layout(self):
        cmake_layout(self)
    def requirements(self):
        self.requires("gtest/1.14.0")

在此文件的基础上,运行下面的命令

bash
conan install . --build=never -r=conancenter --update

即可看到build目录下有了generators文件夹,文件夹中包含一系列配置文件。

CMake结合conan的示例方式(VS生成器)

下面举一个最简单的CMake配合conan的使用示例,注意是在Windows环境下,其他操作系统的指令稍有不同!

文件层级:

bash
CPP_Demo_Example/
├── src/
│   └── main.cpp
│
├── CMakeLists.txt
│
├── conanfile.py
│
└── CMakePresets.json

首先写一个简单的主程序:

cpp
// src/main.cpp
#include <fmt/core.h>
#include <fmt/color.h>

int main() {
    fmt::print(fmt::fg(fmt::color::cyan) | fmt::emphasis::bold, 
               "Conan is a MIT-licensed, Open Source. This is an example.");
    fmt::print(fmt::fg(fmt::color::white), 
               "package manager for C and C++ development\n");
    return 0;
}

CMake预设:

json
{
  "version": 4,
  "configurePresets": [
    {
      "name": "VS2022_x64-Base",
      "hidden": true,
      "generator": "Visual Studio 17 2022",
      "architecture": {
        "value": "x64",
        "strategy": "external"
      },
      "cacheVariables": {
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/install",
        "CMAKE_GENERATOR_PLATFORM": "x64"
      },
      "vendor": {
        "microsoft.com/VisualStudioSettings/CMake/1.0": {
          "clangTidyChecks": "-format-style='file'",
          "enableMicrosoftCodeAnalysis": true,
          "enableClangTidyCodeAnalysis": true
        }
      }
    },
    {
      "name": "VS2022_x64-Debug",
      "inherits": "VS2022_x64-Base",
      "binaryDir": "${sourceDir}/build/Debug",
      "cacheVariables": {
        "BUILD_TYPE_FOR_CONAN": "Debug"
      }
    },
    {
      "name": "VS2022_x64-Release",
      "inherits": "VS2022_x64-Base",
      "binaryDir": "${sourceDir}/build/Release",
      "cacheVariables": {
        "BUILD_TYPE_FOR_CONAN": "Release"
      }
    },
    {
      "name": "VS2022_x64-RelWithDebInfo",
      "inherits": "VS2022_x64-Base",
      "binaryDir": "${sourceDir}/build/RelWithDebInfo",
      "cacheVariables": {
        "BUILD_TYPE_FOR_CONAN": "RelWithDebInfo"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "Debug",
      "configurePreset": "VS2022_x64-Debug",
      "configuration": "Debug"
    },
    {
      "name": "Release",
      "configurePreset": "VS2022_x64-Release",
      "configuration": "Release"
    },
    {
      "name": "RelWithDebInfo",
      "configurePreset": "VS2022_x64-RelWithDebInfo",
      "configuration": "RelWithDebInfo"
    }
  ]
}

对应CMake配置

CMake
# CMakeLists.txt
cmake_minimum_required(VERSION 3.31)
project(Demo_example CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# 设置 Conan 工具链文件路径 输出目录为build/generators(在conan配置中使用cmake_layout后默认的路径)
set(CONAN_TOOLCHAIN_PATH "${CMAKE_SOURCE_DIR}/build/generators/conan_toolchain.cmake")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
    set(CONAN_ARCH "x86_64")
else()
    set(CONAN_ARCH "x86")
endif()
set(CONAN_OS ${CMAKE_SYSTEM_NAME})
execute_process(
    COMMAND
        conan install ${CMAKE&#95;SOURCE&#95;DIR} --output=${CMAKE_SOURCE_DIR}
        --build=missing --update --settings os=${CONAN&#95;OS} --settings arch=${CONAN_ARCH}
        --settings build_type=${BUILD_TYPE_FOR_CONAN} 
    RESULT_VARIABLE result
)

if(result)
    message(FATAL_ERROR "Failed to execute conan install command")
endif()

# 加载 Conan 工具链文件
include(${CONAN_TOOLCHAIN_PATH})
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/build/generators)
list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/build/generators)

find_package(fmt REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt)

和conan的配置

python
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout,CMakeToolchain, CMakeDeps

class MyRecipe(ConanFile):
    name = "CPP_Template_Project"
    user = "JohnJi"
    channel = "develop"
    description = "This is an example to explain how to use conan with cmake. By JohnJi"
    settings = "os", "compiler", "build_type", "arch"

    # The cmake_layout() sets the folders and cpp attributes to follow the structure of a typical CMake project.
    # https://docs.conan.io/2.0/reference/tools/cmake/cmake_layout.html 
    # https://docs.conan.org.cn/2/tutorial/consuming_packages/the_flexibility_of_conanfile_py.html#consuming-packages-flexibility-of-conanfile-py-use-layout
    def layout(self):
        cmake_layout(self)

    # The requirements() method is used to specify the dependencie_s of a package.
    # https://docs.conan.io/2.0/reference/conanfile/methods/requirements.html
    def requirements(self):
        # self.requires("eigen/3.4.0")
        self.requires("fmt/11.2.0")

    # The purpose of generate() is to prepare the build, generating the necessary files.
    # https://docs.conan.io/2.0/reference/conanfile/methods/generate.html
    def generate(self):
        tc = CMakeToolchain(self)
        tc.user_presets_path = False # 禁用 Conan 生成的 user-presets.json
        deps = CMakeDeps(self)
        deps.generate()

        # 生成最终的 toolchain 文件(默认是 conan_toolchain.cmake)
        tc.generate()

    # The build() method is used to define the build from source of the package.
    # https://docs.conan.io/2.0/reference/conanfile/methods/build.html
    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    # The package() method is in charge of copying files from the source_folder and the temporary build_folder to the package_folder
    ## https://docs.conan.io/2/reference/conanfile/methods/package.html#
    def package(self):
        cmake = CMake(self)
        cmake.install()

在根目录下运行:

bash
cmake --preset=VS2022_x64-Debug
cmake --build --preset Debug

即可生成Demo_example.exe
解释一下
这个示例匹配的具体要求为:要求在windows系统下搭建c++开发环境,c++项目使用cmake构建工具和conan包管理工具,而且使用vscode编辑器。系统中已经安装了vs 2022,要求使用Visual Studio 17 2022生成器。CMake预设中还开启了在VS中的clang-tidy 静态检查。
预设文件中写了一个 BUILD_TYPE_FOR_CONAN这是为了将 build_type 参数传给 conan ,conan必须获得正确的build_type才能最终生成正确的产物。而这里指定了"Visual Studio 17 2022"这种多配置生成器,cmake中的CMAKE_BUILD_TYPE参数对它不起作用,因此只能另外手动指定一个名称传递给它。

CMake结合conan的示例方式(Ninja生成器)

实际上,Ninja生成器才是目前被广泛推荐的,包括微软官方也更倾向于推荐Ninja生成器而不是VS生成器。
下面在上文中示例项目的基础上进行修改,首先是简化CMake预设文件:

json
{
  "version": 4,
  "configurePresets": [
    {
      "name": "Ninja_x64-Base",
      "hidden": true,
      "generator": "Ninja",
      "cacheVariables": {
        "CMAKE_INSTALL_PREFIX": "${sourceDir}/install"
      }
    },
    {
      "name": "Ninja_x64",
      "inherits": "Ninja_x64-Base",
      "binaryDir": "${sourceDir}/build/${presetName}"
    }
  ],
  "buildPresets": [
    {
      "name": "Debug",
      "configurePreset": "Ninja_x64",
      "configuration": "Debug"
    },
    {
      "name": "Release",
      "configurePreset": "Ninja_x64",
      "configuration": "Release"
    },
    {
      "name": "RelWithDebInfo",
      "configurePreset": "Ninja_x64",
      "configuration": "RelWithDebInfo"
    }
  ]
}

随后修改CMakeLists.txt

CMake
cmake_minimum_required(VERSION 3.31)
project(Demo_example CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CONAN_TOOLCHAIN_PATH "${CMAKE_SOURCE_DIR}/build/generators/conan_toolchain.cmake")
# 使用ninja生成器时,可以使用CMAKE_BUILD_TYPE变量
execute_process(
    COMMAND
        conan install ${CMAKE&#95;SOURCE&#95;DIR} --output=${CMAKE_SOURCE_DIR}
        --build=missing --update
        --settings build_type=${CMAKE_BUILD_TYPE} 
    RESULT_VARIABLE result
)

if(result)
    message(FATAL_ERROR "Failed to execute conan install command")
endif()

# 加载 Conan 工具链文件
include(${CONAN_TOOLCHAIN_PATH})
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/build/generators)
list(PREPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/build/generators)

find_package(fmt REQUIRED)
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt)

和conan的配置

python
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout,CMakeToolchain, CMakeDeps

class MyRecipe(ConanFile):
    name = "CPP_Template_Project"
    user = "JohnJi"
    channel = "develop"
    description = "This is an example to explain how to use conan with cmake. By JohnJi"
    settings = "os", "compiler", "build_type", "arch"

    def layout(self):
        cmake_layout(self)

    def requirements(self):
        self.requires("fmt/11.2.0")

    def generate(self):
        tc = CMakeToolchain(self)
        tc.user_presets_path = False
        # 重要:在这里指定Ninja生成器
        # 参考 https://docs.conan.org.cn/2/examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html
        tc.generator = "Ninja"
        deps = CMakeDeps(self)
        deps.generate()
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

推荐在VS中打开、开发项目,如果要使用 VScode 则必须在x64 Native Tools Command Prompt for VS 2022控制台中打开(开始菜单 → Visual Studio 2022 → x64 Native Tools Command Prompt)。在控制台中输入命令 code即可打开vscode。这样做的原因是这个控制台已经预先配置好了cl.exe等一系列工具链,不会报错找不到生成器、编译器等。如果不使用这个预先配置好的控制台且还要使用VS Code,则必须在环境变量中配置一系列东西。
在 Developer Command Prompt 环境下的控制台中,可以输入 code来打开VS code,也可以输入命令:

bash
cmake --preset Ninja_x64
cmake --build --preset Debug

可以看到顺利可执行文件被正确生成了,且速度确实更快。

归根到底,Windows平台下最推荐的C++开发方案仍然是VS,或者Clion这样的IDE。VSCode对大型C++项目的支持还是不能和专业的IDE相比。

参考阅读