Esta publicación hablará sobre cómo construir un proyecto C ++ usando GTest y Boost usando Docker. El artículo es una receta con algunos comentarios explicativos; la solución presentada en el artículo no pretende estar lista para producción.
¿Por qué y quién podría necesitarlo?
Supongamos que, como yo, realmente le gusta el concepto de Python venv , cuando todas las dependencias necesarias se encuentran en un directorio separado, estrictamente definido; o debe proporcionar una portabilidad simple del entorno de ensamblaje y prueba para el proyecto en desarrollo, lo cual es muy conveniente, por ejemplo, cuando se une un nuevo desarrollador al equipo.
Este artículo será especialmente útil para los desarrolladores principiantes que necesitan realizar configuraciones de entorno básicas para crear y ejecutar un proyecto C ++.
El entorno presentado en el artículo puede usarse como marco para tareas de prueba o trabajo de laboratorio.
Instalar Docker
Todo lo que necesita para implementar el proyecto presentado en este artículo es Docker y acceso a Internet.
Docker está disponible para plataformas Windows, Linux y Mac. La documentación oficial .
Como uso una máquina Windows a bordo, solo tuve que descargar el instalador y ejecutarlo.
Tenga en cuenta que en este momento, Docker para Windows utiliza Hyper-V para su trabajo.
Proyecto
Como proyecto, nos referiremos a una aplicación CommandLine que muestra la cadena "¡Hola Mundo!" a flujo de salida estándar.
El proyecto utilizará las bibliotecas mínimas requeridas, así como CMake como sistema de compilación.
La estructura de nuestro proyecto será la siguiente:
project | Dockerfile | \---src CMakeLists.txt main.cpp sample_hello_world.h test.cpp
El archivo CMakeLists.txt contiene una descripción del proyecto.
Código fuente del archivo:
cmake_minimum_required(VERSION 3.2) project(HelloWorldProject)
El archivo sample_hello_world.h contiene una descripción de la clase HelloWorld, enviando una instancia de la cual a la secuencia, se mostrará la cadena "Hello World!". Esta complejidad se debe a la necesidad de probar el código de nuestra aplicación.
Código fuente del archivo:
#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
El archivo main.cpp contiene el punto de entrada de nuestra aplicación, también agregaremos Boost.Program_options para simular un proyecto real.
Código fuente del archivo:
#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; }
El archivo test.cpp contiene el mínimo necesario: una prueba de la funcionalidad de la clase HelloWorld. Para las pruebas usamos GoogleTest .
Código fuente del archivo:
#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(); }
A continuación, pasemos a la parte más interesante: ¡configurar su entorno de compilación usando Dockerfile!
Dockerfile
Para el montaje usaremos gcc de la última versión.
Dockerfile contiene dos etapas: construcción y lanzamiento de nuestra aplicación.
Para ejecutar, use la última versión de Ubuntu.
Contenido de 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"]
Supongo que por ahora, ¡vaya a construir y ejecutar la aplicación!
Montaje y lanzamiento
Para construir nuestra aplicación y crear una imagen Docker, será suficiente ejecutar el siguiente comando:
Para iniciar la aplicación, use el comando:
> docker run docker-cpp-sample
Veremos las queridas palabras:
Hello World!
Para pasar un parámetro, será suficiente agregarlo al comando anterior:
> docker run docker-cpp-sample --help Allowed options: -h [ --help ] Produce this message
Para resumir
Como resultado, creamos una aplicación C ++ completa, configuramos el entorno para compilarla y ejecutarla en Linux, y la envolvimos en un contenedor Docker. Por lo tanto, libera a los desarrolladores posteriores de la necesidad de pasar tiempo configurando un ensamblaje local.