这篇文章将讨论如何使用GTest和使用Docker的Boost构建C ++项目。 这篇文章是一个食谱,上面有一些解释性的评论;该文章中提供的解决方案并不伪装成可立即投入生产的。
为什么以及谁可能需要它?
假设您和我一样,非常喜欢Python venv的概念,并且所有必要的依赖项都位于一个单独的严格定义的目录中; 或者您需要为正在开发的项目提供组装和测试环境的简单可移植性,这非常方便,例如,在将新开发人员加入团队时。
本文对于需要执行基本环境设置以构建和运行C ++项目的新手开发人员特别有用。
本文中介绍的环境可以用作测试任务或实验室工作的框架。
安装Docker
实现本文介绍的项目所需要做的就是Docker和Internet访问。
Docker适用于Windows,Linux和Mac平台。 官方文件 。
由于我在船上使用Windows计算机,因此我只需要下载安装程序并运行它。
请注意,目前,Docker for Windows使用Hyper-V进行工作。
专案
作为一个项目,我们将指一个命令行应用程序,该程序显示字符串“ Hello World!”。 到标准输出流。
该项目将使用所需的最小库以及CMake作为构建系统。
我们的项目结构如下:
project | Dockerfile | \---src CMakeLists.txt main.cpp sample_hello_world.h test.cpp
CMakeLists.txt文件包含项目的描述。
该文件的源代码:
cmake_minimum_required(VERSION 3.2) project(HelloWorldProject)
sample_hello_world.h文件包含HelloWorld类的描述,该类的实例发送到流中,将显示字符串“ Hello World!”。 这种复杂性是由于需要测试我们的应用程序的代码。
该文件的源代码:
#ifndef SAMPLE_HELLO_WORLD_H #define SAMPLE_HELLO_WORLD_H namespace sample { struct HelloWorld { template<class OS> friend OS& operator<<(OS& os, const HelloWorld&) { os << "Hello World!"; return os; } }; } // sample #endif // SAMPLE_HELLO_WORLD_H
main.cpp文件包含我们应用程序的入口点,我们还将添加Boost.Program_options来模拟真实项目。
该文件的源代码:
#include "sample_hello_world.h" #include <boost/program_options.hpp> #include <iostream> // - "--help" auto parseArgs(int argc, char* argv[]) { namespace po = boost::program_options; po::options_description desc("Allowed options"); desc.add_options() ("help,h", "Produce this message"); auto parsed = po::command_line_parser(argc, argv) .options(desc) .allow_unregistered() .run(); po::variables_map vm; po::store(parsed, vm); po::notify(vm); // C++17 std::make_pair return std::pair(vm, desc); } int main(int argc, char* argv[]) try { auto [vm, desc] = parseArgs(argc, argv); if (vm.count("help")) { std::cout << desc << std::endl; return 0; } std::cout << sample::HelloWorld{} << std::endl; return 0; } catch (std::exception& e) { std::cerr << "Unhandled exception: " << e.what() << std::endl; return -1; }
test.cpp文件包含必需的最小值-对HelloWorld类的功能的测试。 为了进行测试,我们使用GoogleTest 。
该文件的源代码:
#include "sample_hello_world.h" #include <sstream> #include <gtest/gtest.h> // , HelloWorld , TEST(HelloWorld, Test) { std::ostringstream oss; oss << sample::HelloWorld{}; ASSERT_EQ("Hello World!", oss.str()); } // int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
接下来,让我们继续进行最有趣的部分-使用Dockerfile设置构建环境!
Docker文件
对于组装,我们将使用最新版本的gcc 。
Dockerfile包含两个阶段:构建和启动我们的应用程序。
要运行,请使用最新版本的Ubuntu。
Dockerfile内容:
# --------------------------------------- # gcc:latest FROM gcc:latest as build # GoogleTest WORKDIR /gtest_build # GoogleTest # , # Docker RUN , # , , RUN apt-get update && \ apt-get install -y \ libboost-dev libboost-program-options-dev \ libgtest-dev \ cmake \ && \ cmake -DCMAKE_BUILD_TYPE=Release /usr/src/gtest && \ cmake --build . && \ mv lib*.a /usr/lib # /src ADD ./src /app/src # WORKDIR /app/build # , RUN cmake ../src && \ cmake --build . && \ CTEST_OUTPUT_ON_FAILURE=TRUE cmake --build . --target test # --------------------------------------- # ubuntu:latest FROM ubuntu:latest # , Docker root # root' :) RUN groupadd -r sample && useradd -r -g sample sample USER sample # WORKDIR /app # COPY --from=build /app/build/hello_world_app . # ENTRYPOINT ["./hello_world_app"]
我想现在,继续构建并运行该应用程序!
组装和发射
要构建我们的应用程序并创建一个Docker映像,只需运行以下命令即可:
要启动该应用程序,请使用以下命令:
> docker run docker-cpp-sample
我们将看到珍惜的话:
Hello World!
要传递参数,将其添加到上面的命令中就足够了:
> docker run docker-cpp-sample --help Allowed options: -h [ --help ] Produce this message
总结一下
结果,我们创建了一个成熟的C ++应用程序,配置了在Linux下构建和运行它的环境,并将其包装在Docker容器中。 因此,使后续的开发人员摆脱了花费时间来建立本地程序集的需求。