ستتحدث هذه المشاركة عن كيفية إنشاء مشروع C ++ باستخدام GTest و Boost باستخدام Docker. المقالة عبارة عن وصفة تحتوي على بعض التعليقات التوضيحية ؛ والحل المقدم في المقالة لا يدعي أنه جاهز للإنتاج.
لماذا ومن الذي قد يحتاجها؟
لنفترض أنك ، مثلي ، تعجبك حقًا مفهوم Python venv ، عندما توجد كل التبعيات الضرورية في دليل منفصل ومحدّد بدقة ؛ أو تحتاج إلى توفير سهولة النقل لبيئة التجميع والاختبار للمشروع قيد التطوير ، وهو أمر مريح للغاية ، على سبيل المثال ، عند الانضمام إلى مطور جديد في الفريق.
ستكون هذه المقالة مفيدة بشكل خاص للمبتدئين الذين يحتاجون إلى تنفيذ إعدادات البيئة الأساسية لإنشاء مشروع C ++ وتشغيله.
يمكن استخدام البيئة الواردة في المقالة كإطار لمهام الاختبار أو العمل المختبري.
تثبيت Docker
كل ما تحتاجه لتنفيذ المشروع المعروض في هذه المقالة هو Docker والوصول إلى الإنترنت.
Docker متاح لأنظمة التشغيل Windows و Linux و Mac. الوثائق الرسمية .
نظرًا لأنني أستخدم جهاز Windows على متن الطائرة ، كان علي فقط تنزيل المثبت وتشغيله.
يرجى ملاحظة أنه في الوقت الحالي ، يستخدم Docker لـ Windows Hyper-V لعمله.
المشروع
كمشروع ، سنعني تطبيق CommandLine الذي يعرض السلسلة "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!
ملف Dockerfile
للتجميع سوف نستخدم دول مجلس التعاون الخليجي من أحدث إصدار.
يحتوي 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. وبالتالي ، تحرير المطورين اللاحقين من الحاجة إلى قضاء بعض الوقت في إنشاء مجلس محلي.