Docker配置C++环境

前提准备

配置 Docker

预定义容器构建

创建容器步骤

  1. 点击 VSCode 左下角「打开远程窗口」
  2. 点击「打开容器配置文件」
  3. 点击「在工作区级别添加配置文件」
  4. 选择 来自预定义的容器配置定义 创建容器
  5. 选择 c++ubuntu22.04cmake:3.22.2
  6. 选择插件(不会被包含在 Dockerfile 中)
  7. 点击 VSCode 左下角「打开远程窗口」
  8. 点击「在容器中重新打开」

自定义容器构建

容器配置

文件目录:

.
├── 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

创建容器

创建容器步骤

  1. 点击 VSCode 左下角「打开远程窗口」
  2. 点击「打开容器配置文件」
  3. 点击「在工作区级别添加配置文件」
  4. 选择 From docker-compose.yml 创建容器
  5. 选择插件(不会被包含在 Dockerfile 中)
  6. 点击 VSCode 左下角「打开远程窗口」
  7. 点击「在容器中重新打开」

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
posted @ 2025-11-26 17:07  半截山上的小猫  阅读(64)  评论(0)    收藏  举报