Ce post expliquera comment créer un projet C ++ à l'aide de GTest et Boost à l'aide de Docker. L'article est une recette avec quelques commentaires explicatifs; la solution présentée dans l'article ne prétend pas être prête pour la production.
Pourquoi et qui pourrait en avoir besoin?
Supposons que vous, comme moi, appréciez vraiment le concept de Python venv , lorsque toutes les dépendances nécessaires sont situées dans un répertoire distinct et strictement défini; ou vous devez fournir une portabilité simple de l'environnement d'assemblage et de test pour le projet en cours de développement, ce qui est très pratique, par exemple, lorsque vous joignez un nouveau développeur à l'équipe.
Cet article sera particulièrement utile pour les développeurs débutants qui doivent effectuer des paramètres d'environnement de base pour créer et exécuter un projet C ++.
L'environnement présenté dans l'article peut être utilisé comme cadre pour des tâches de test ou des travaux de laboratoire.
Installer Docker
Tout ce dont vous avez besoin pour implémenter le projet présenté dans cet article est Docker et l'accès Internet.
Docker est disponible pour les plates-formes Windows, Linux et Mac. La documentation officielle .
Puisque j'utilise une machine Windows à bord, je n'ai eu qu'à télécharger le programme d'installation et l'exécuter.
Veuillez noter qu'en ce moment, Docker pour Windows utilise Hyper-V pour son travail.
Projet
En tant que projet, nous entendons une application CommandLine qui affiche la chaîne "Hello World!" au flux de sortie standard.
Le projet utilisera les bibliothèques minimales requises, ainsi que CMake comme système de construction.
La structure de notre projet sera la suivante:
project | Dockerfile | \---src CMakeLists.txt main.cpp sample_hello_world.h test.cpp
Le fichier CMakeLists.txt contient une description du projet.
Code source du fichier:
cmake_minimum_required(VERSION 3.2) project(HelloWorldProject)
Le fichier sample_hello_world.h contient une description de la classe HelloWorld, en envoyant une instance au flux, la chaîne "Hello World!" Sera affichée. Cette complexité est due à la nécessité de tester le code de notre application.
Code source du fichier:
#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
Le fichier main.cpp contient le point d'entrée de notre application, nous ajouterons également Boost.Program_options pour simuler un vrai projet.
Code source du fichier:
#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; }
Le fichier test.cpp contient le minimum nécessaire - un test de la fonctionnalité de la classe HelloWorld. Pour les tests, nous utilisons GoogleTest .
Code source du fichier:
#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(); }
Ensuite, passons à la partie la plus intéressante - configurer votre environnement de construction à l'aide de Dockerfile!
Dockerfile
Pour l'assemblage, nous utiliserons gcc de la dernière version.
Dockerfile contient deux étapes: la création et le lancement de notre application.
Pour exécuter, utilisez la dernière version d'Ubuntu.
Contenu 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"]
Je suppose que pour l'instant, continuez à construire et exécuter l'application!
Assemblage et lancement
Pour construire notre application et créer une image Docker, il suffira d'exécuter la commande suivante:
Pour démarrer l'application, utilisez la commande:
> docker run docker-cpp-sample
Nous verrons les mots chéris:
Hello World!
Pour passer un paramètre, il suffira de l'ajouter à la commande ci-dessus:
> docker run docker-cpp-sample --help Allowed options: -h [ --help ] Produce this message
Pour résumer
En conséquence, nous avons créé une application C ++ à part entière, configuré l'environnement pour sa création et son exécution sous Linux, et l'avons enveloppé dans un conteneur Docker. Ainsi, libérant les développeurs suivants de la nécessité de passer du temps à configurer un assembly local.