< /ul>
Серия событий заставила меня хотеть попробовать Создайте приложение C ++ в контейнере Docker, при использовании VCPKG .
Вот серия операторов, которые должны помочь обеспечить контекст:
- Я использую сервер Debian для разработки приложения C ++ < /li>
Приложение записано с использованием C ++ 23. Это относительно недавняя версия стандарта C ++, и как таковой, это только относительно недавние выбросы компиляторов, которые поддерживают эту версию стандарта - Я использую GCC /для составления кода C ++
Код: Выделить всё
g++ - Система Debian, которую я использую, имеет более старую версию GCC . Это что -то вроде версии 12. Он не поддерживает (по крайней мере, некоторые из) функций C ++ 23, которые мне нужны < /li>
Я не хочу заменять компилятор системы по умолчанию другим. Как правило, не очень хорошая идея, чтобы поменять компилятор, который поставляется с вашей ОС. Это один из способов, которым вы можете сломать Debian. (См. не сломайте Debian ) - I мог бы установить вторую версию GCC , но Я не решаюсь сделать это, потому что это включает либо временное изменение компилятора по умолчанию с помощью альтернатив обновления apt или настройки версии компилятора для выбранной системы сборки вручную . Это не кажется хорошим подходом, и у меня не было хорошего опыта с этим в прошлом. Я бы посоветовал использовать контейнер Docker - это более простой подход. < /p>
У меня есть одно решение, которое работает, но это не хорошее решение. Следующие шаги описаны ниже.
сначала установить vcpkg на хостево -вторых, инициализируйте новый проект C ++ с VcpkgКод: Выделить всё
git clone https://github.com/microsoft/vcpkg.git cd vcpkg && ./bootstrap-vcpkg.sh -disableMetrics export VCPKG_ROOT=/path/to/vcpkg export PATH=$VCPKG_ROOT:$PATHВ -третьих, создайте cmakelists.txtКод: Выделить всё
mkdir myproject && cd myproject vcpkg new --application # created `vcpkg-configuration.json` and `vcpkg.json` # example: add dependencies using vcpkg vcpkg add port fmt
Существуют другие доступные системы сборки. Насколько я понимаю, VCPKG совместима с диапазоном систем сборки. Я использую cmake по умолчанию, а не по какой -либо конкретной причине.Четвертый шаг: create main.cppКод: Выделить всё
# CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(myproject) find_package(fmt CONFIG REQUIRED) add_executable(myproject main.cpp) target_link_libraries(myproject PRIVATE fmt::fmt)может содержать минимальный пример «Hello World». >Код: Выделить всё
main.cpp) отличается от примера файла, представленного в документации, показанного ниже:Код: Выделить всё
# CMakePresets.json { "version": 2, "configurePresets": [ { "name": "vcpkg", "generator": "Ninja", "binaryDir": "${sourceDir}/build", "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" } } ] } < /code> # CMakeUserPresets.json { "version": 2, "configurePresets": [ { "name": "default", "inherits": "vcpkg" } ] } < /code> Note that this file (CMakeUserPresets.json, и обнаружил, что он, кажется, работает.Код: Выделить всё
# CMakeUserPresets.json (example from documentation) { "version": 2, "configurePresets": [ { "name": "default", "inherits": "vcpkg", "environment": { "VCPKG_ROOT": " " } } ] } < /code> I tried changing "VCPKG_ROOT": " " < /code> to "VCPKG_ROOT": "$env{VCPKG_ROOT}" < /code> however, this resulted in an error when trying to run $ cmake --preset=default CMake Error: Could not read presets from /home/user/myproject: Invalid macro expansion < /code> Therefore I removed "environment".Код: Выделить всё
CMake was unable to find a build program corresponding to "Ninja". < /code> Therefore I changed "generator": "Ninja" < /code> to "generator": "Unix Makefiles" < /code> in CMakePresets.json
Тогда команда выполняется OK: cmake - -preset = default .
Наконец, для создания: < /p>, который должен быть сделан внутри контейнера Docker, потому что вряд ли мы находим существующее изображение, которое содержит все, что мы хотим.Код: Выделить всё
cmake --build build < /code> Note that if we were to repeat these steps inside a Docker container, the first step would be required, but none of the remaining steps are required. In the first step, we installed vcpkg
Однако оставшиеся шаги не нужны повторять. Мы просто копируем необходимые файлы в изображение контейнера. < /P>
Есть две проблемы с этим подходом: < /p>
Процесс занимает много времени и очень неэффективен. Каждый раз, когда исходный код меняется, VCPKG идет и загружает файл из GitHub. Это вызвано командой cmake - -preset = default . - Процесс сборки работает только, выполняя некоторые работы извне.
< /ul>
, чтобы объяснить вторую точку в более подробном детеальном: сборка изображения контейнера Docker зависит от некоторых команд vcpkg < /code>, которые были выполнены до того, как контейнер будет построен. Это связано с тем, что контейнер зависит от файлов vcpkg-configuration.json и vcpkg.json . Они генерируются путем запуска некоторых команд vcpkg . Чтобы их генерировать, хост -система требует установки vcpkg .
она чувствует себя немного "курицей и яйцом".
это Было бы возможно запустить эти команды внутри контейнера как часть процесса сборки, однако тогда vcpkg-configuration.json и vcpkg.json будет сгенерирован, а не файлы, хранящиеся под управлением источника. /p>
Вот копия Dockerfile < /code>. < /p>Файл также необходим для предотвращения копирования каталога Build . Без этого сборка ошибся. < /P>Код: Выделить всё
FROM gcc:latest WORKDIR /root RUN apt update && apt install curl zip unzip tar cmake -y RUN git clone https://github.com/microsoft/vcpkg.git RUN cd vcpkg && ./bootstrap-vcpkg.sh -disableMetrics ENV VCPKG_ROOT=/root/vcpkg ENV PATH=$VCPKG_ROOT:$PATH RUN mkdir /app WORKDIR /app COPY ./myproject ./myproject WORKDIR /app/myproject RUN cmake --preset=default RUN cmake --build build < /code> A .dockerignore
#.dockerignore
**/build
< /code>
To run it
$ docker build -t myproject/myprojectbuild .
$ docker run --rm myproject/myprojectbuild
< /code>
There is one final problem: How to get the build artifact out of the (temporary) container, and copy it to the host.
To summarize: - It should be possible for someone with a system with a C++23 compiler to build the C++ source code without needing to use Docker to obtain access to a C++ 23 compiler
- Therefore, dependencies probably should not be generated inside the Docker container? (Let me know your thoughts on this?)
- If someone (such as myself) does not have a C++ 23 compiler, then it should be possible to use a Docker container to build the application, and run it
- Or better yet, one container to Build, and another container to Run the application, for separation of environments. (Deployment does not need to have all the dependencies for compiling)
Подробнее здесь: https://stackoverflow.com/questions/793 ... sing-vcpkg