Docker配置C++环境
前提准备
配置 Docker
预定义容器构建
创建容器步骤
- 点击 VSCode 左下角「打开远程窗口」
- 点击「打开容器配置文件」
- 点击「在工作区级别添加配置文件」
- 选择
来自预定义的容器配置定义创建容器 - 选择
c++,ubuntu22.04,cmake:3.22.2 - 选择插件(不会被包含在 Dockerfile 中)
- 点击 VSCode 左下角「打开远程窗口」
- 点击「在容器中重新打开」
自定义容器构建
容器配置
文件目录:
.
├── dockerfiles
│ └── Dockerfile # 镜像构建文件
│ └── reinstall-cmake.sh # cmake构建文件
└── docker-compose.yml # 镜像启动文件
Dockerfile文件:
基于 Ubuntu 22.04 的 C++ 开发环境,提供了一个可选的机制来安装特定版本的 CMake
FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-22.04
ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="3.22.2"
# Optionally install the cmake for vcpkg
COPY dockerfiles/reinstall-cmake.sh /tmp/
RUN if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then \
chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE}; \
fi \
&& rm -f /tmp/reinstall-cmake.sh
# [Optional] Uncomment this section to install additional vcpkg ports.
# RUN su vscode -c "${VCPKG_ROOT}/vcpkg install <your-port-name-here>"
# [Optional] Uncomment this section to install additional packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
reinstall-cmake.sh文件:
下载、安装并配置指定版本的 CMake
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
set -e
CMAKE_VERSION=${1:-"none"}
if [ "${CMAKE_VERSION}" = "none" ]; then
echo "No CMake version specified, skipping CMake reinstallation"
exit 0
fi
# Cleanup temporary directory and associated files when exiting the script.
cleanup() {
EXIT_CODE=$?
set +e
if [[ -n "${TMP_DIR}" ]]; then
echo "Executing cleanup of tmp files"
rm -Rf "${TMP_DIR}"
fi
exit $EXIT_CODE
}
trap cleanup EXIT
echo "Installing CMake..."
apt-get -y purge --auto-remove cmake
mkdir -p /opt/cmake
architecture=$(dpkg --print-architecture)
case "${architecture}" in
arm64)
ARCH=aarch64 ;;
amd64)
ARCH=x86_64 ;;
*)
echo "Unsupported architecture ${architecture}."
exit 1
;;
esac
CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh"
CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt"
TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX)
echo "${TMP_DIR}"
cd "${TMP_DIR}"
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O
sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}"
sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license
ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest
docker-compose.yml文件:
定义和配置一个基于 Docker 的 C++ 开发环境服务,为与 Visual Studio Code 的 Dev Containers 扩展配合使用而设计。
version: '3.8' # 推荐使用较新的版本
services:
# 服务名称,您可以根据项目更改
devcontainer:
# 告诉 Compose 构建当前目录下的 dockerfiles/Dockerfile
build:
context: .
dockerfile: dockerfiles/Dockerfile
# 使用 build-args 来设置 Dockerfile 中的 ARGs,例如 CMake 版本
args:
REINSTALL_CMAKE_VERSION_FROM_SOURCE: "3.22.2" # 确保此值与 Dockerfile 中的默认值一致或设置为您需要的版本
# 容器名称
container_name: cpp-dev-env
# 挂载卷。将主机当前目录 (./) 挂载到容器的 /workspaces/cpp-dev-env
# 这是 Dev Container 约定俗成的挂载路径,方便 VS Code/Devcontainers 扩展识别
volumes:
- .:/workspaces/cpp-dev-env:cached
# 设置容器内的工作目录
working_dir: /workspaces/cpp-dev-env
# [可选] 保持容器运行,即使没有在执行命令
# 这样可以方便地 attach 到一个运行中的容器
# command: sleep infinity
# [可选] 运行时的用户,与基础镜像中的 `vscode` 用户保持一致
# 基础镜像 `mcr.microsoft.com/devcontainers/cpp` 默认用户是 `vscode`
user: vscode
# [可选] 端口映射,如果您有在容器中运行的应用程序(如 Web 服务器、调试器等)
# ports:
# - "8080:8080"
# [可选] 重启策略
# restart: unless-stopped
创建容器
创建容器步骤
- 点击 VSCode 左下角「打开远程窗口」
- 点击「打开容器配置文件」
- 点击「在工作区级别添加配置文件」
- 选择
From docker-compose.yml创建容器 - 选择插件(不会被包含在 Dockerfile 中)
- 点击 VSCode 左下角「打开远程窗口」
- 点击「在容器中重新打开」
CMake
CMake 配置
文件目录:
.
├── build
└── main.cpp # 测试文件
└── CMakeLists.txt # CMake构建
build 作为 项目构建的输出目录,将所有生成的文件与源代码文件隔离开来
CMakeLists.txt 定义、配置和控制一个软件项目应该如何被编译和构建
# 最小要求的 CMake 版本
cmake_minimum_required(VERSION 3.10)
# 1. 定义项目名称
project(MyCppProject VERSION 1.0)
# 2. 【关键步骤】设置 C++ 标准为 C++20
# 这会告诉编译器(如 g++)使用 -std=c++20 标志
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 3. 添加您的可执行文件
# 假设您的主源文件是 main.cpp
add_executable(main main.cpp)
main.cpp 测试文件
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>
#include <cmath>
#include <numeric>
#include <cassert>
// --- 假设被测试的库代码 ---
// (在实际项目中,这些函数将定义在单独的头文件和源文件中)
namespace MyMathLib {
// 假设函数 1: 计算两个数的和
int Add(int a, int b) {
return a + b;
}
// 假设函数 2: 计算数组中所有元素的平均值
double Average(const std::vector<int>& data) {
if (data.empty()) {
// 抛出异常或返回特定值处理空向量
return 0.0;
}
long long sum = 0;
for (int n : data) {
sum += n;
}
return static_cast<double>(sum) / data.size();
}
// 假设函数 3: 检查一个数是否为素数
bool IsPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i = i + 6) {
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}
} // namespace MyMathLib
// --- 测试框架代码 ---
static int tests_run = 0;
static int tests_failed = 0;
// 自定义断言函数,用于替代 GTest 的宏
#define RUN_TEST(test_func) \
do { \
tests_run++; \
if (test_func()) { \
std::cout << "[PASS] " << #test_func << "\n"; \
} else { \
std::cout << "[FAIL] " << #test_func << "\n"; \
tests_failed++; \
} \
} while (0)
// --- 测试函数定义 ---
bool test_addition_positive() {
// 基础测试
assert(MyMathLib::Add(2, 3) == 5);
// 较大数值
assert(MyMathLib::Add(50, 50) == 100);
return true;
}
bool test_addition_negative() {
// 全负数
assert(MyMathLib::Add(-2, -3) == -5);
// 零求和
assert(MyMathLib::Add(5, -5) == 0);
return true;
}
bool test_average_empty() {
std::vector<int> empty_data = {};
// 期望空向量的平均值为 0.0
assert(MyMathLib::Average(empty_data) == 0.0);
return true;
}
bool test_average_positive() {
std::vector<int> data = {1, 2, 3, 4, 5};
// 15 / 5 = 3.0
assert(std::fabs(MyMathLib::Average(data) - 3.0) < 0.0001);
return true;
}
bool test_average_mixed() {
std::vector<int> data = {-10, 20, 30};
// 40 / 3 ≈ 13.333333
double expected = 40.0 / 3.0;
assert(std::fabs(MyMathLib::Average(data) - expected) < 0.0001);
return true;
}
bool test_prime_small() {
assert(MyMathLib::IsPrime(2) == true);
assert(MyMathLib::IsPrime(3) == true);
assert(MyMathLib::IsPrime(5) == true);
assert(MyMathLib::IsPrime(4) == false);
return true;
}
bool test_prime_large() {
assert(MyMathLib::IsPrime(97) == true);
assert(MyMathLib::IsPrime(100) == false);
return true;
}
// --- 主函数:运行所有测试 ---
int main() {
std::cout << "--- Running Basic Math Tests ---\n";
// 运行所有的测试函数
RUN_TEST(test_addition_positive);
RUN_TEST(test_addition_negative);
RUN_TEST(test_average_empty);
RUN_TEST(test_average_positive);
RUN_TEST(test_average_mixed);
RUN_TEST(test_prime_small);
RUN_TEST(test_prime_large);
std::cout << "--- Test Summary ---\n";
std::cout << "Total tests run: " << tests_run << "\n";
std::cout << "Total tests failed: " << tests_failed << "\n";
if (tests_failed == 0) {
std::cout << "RESULT: All tests passed successfully.\n";
return 0; // 成功退出
} else {
std::cout << "RESULT: Some tests failed. Check logs.\n";
return 1; // 失败退出
}
}
CMake 使用
在 ./build 目录下
使用 cmake .. 配置编译和代码的构建环境。
cmake ..
使用 make 执行由构建系统( CMake)生成的构建脚本。
make
这样就可以生成可执行文件,运行文件 main ,观察输出即可知道是否安装成功
./main

浙公网安备 33010602011771号