Большая часть информации, содержащейся в этом вопросе get_started /get-farted? pivots = shell-bash < /li>
< /ul>
Серия событий заставила меня хотеть попробовать Создайте приложение C ++ в контейнере Docker, при использовании VCPKG .
Вот серия операторов, которые должны помочь обеспечить контекст:
Я использую сервер Debian для разработки приложения C ++ < /li>
Приложение записано с использованием C ++ 23. Это относительно недавняя версия стандарта C ++, и как таковой, это только относительно недавние выбросы компиляторов, которые поддерживают эту версию стандарта
Система Debian, которую я использую, имеет более старую версию GCC . Это что -то вроде версии 12. Он не поддерживает (по крайней мере, некоторые из) функций C ++ 23, которые мне нужны < /li>
Я не хочу заменять компилятор системы по умолчанию другим. Как правило, не очень хорошая идея, чтобы поменять компилятор, который поставляется с вашей ОС. Это один из способов, которым вы можете сломать Debian. (См. не сломайте Debian )
I мог бы установить вторую версию GCC , но Я не решаюсь сделать это, потому что это включает либо временное изменение компилятора по умолчанию с помощью альтернатив обновления apt или настройки версии компилятора для выбранной системы сборки вручную . Это не кажется хорошим подходом, и у меня не было хорошего опыта с этим в прошлом. Я бы посоветовал использовать контейнер Docker - это более простой подход. < /p>
У меня есть одно решение, которое работает, но это не хорошее решение. Следующие шаги описаны ниже.
сначала установить vcpkg на хосте
mkdir myproject && cd myproject
vcpkg new --application
# created `vcpkg-configuration.json` and `vcpkg.json`
# example: add dependencies using vcpkg
vcpkg add port fmt
В -третьих, создайте cmakelists.txt
Существуют другие доступные системы сборки. Насколько я понимаю, VCPKG совместима с диапазоном систем сборки. Я использую cmake по умолчанию, а не по какой -либо конкретной причине.
# 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>
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
, который должен быть сделан внутри контейнера Docker, потому что вряд ли мы находим существующее изображение, которое содержит все, что мы хотим.
Однако оставшиеся шаги не нужны повторять. Мы просто копируем необходимые файлы в изображение контейнера. < /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>
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
Файл также необходим для предотвращения копирования каталога Build . Без этого сборка ошибся. < /P>
#.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)
Большая часть информации, содержащейся в этом вопросе get_started /get-farted? pivots = shell-bash < /li> < /ul>
Серия событий заставила меня хотеть попробовать Создайте приложение C ++ в контейнере Docker, при использовании VCPKG . Вот серия операторов, которые должны помочь обеспечить контекст: [list] [*] Я использую сервер Debian для разработки приложения C ++ < /li> Приложение записано с использованием C ++ 23. Это относительно недавняя версия стандарта C ++, и как таковой, это только относительно недавние выбросы компиляторов, которые поддерживают эту версию стандарта [*] Я использую GCC /[code]g++[/code] для составления кода C ++ [*] Система Debian, которую я использую, имеет более старую версию GCC . Это что -то вроде версии 12. Он не поддерживает (по крайней мере, некоторые из) функций C ++ 23, которые мне нужны < /li> Я не хочу заменять компилятор системы по умолчанию другим. Как правило, не очень хорошая идея, чтобы поменять компилятор, который поставляется с вашей ОС. Это один из способов, которым вы можете сломать Debian. (См. не сломайте Debian ) [*] I мог бы установить вторую версию GCC , но Я не решаюсь сделать это, потому что это включает либо временное изменение компилятора по умолчанию с помощью альтернатив обновления apt или настройки версии компилятора для выбранной системы сборки вручную . Это не кажется хорошим подходом, и у меня не было хорошего опыта с этим в прошлом. Я бы посоветовал использовать контейнер Docker - это более простой подход. < /p> У меня есть одно решение, которое работает, но это не хорошее решение. Следующие шаги описаны ниже. сначала установить vcpkg на хосте [code]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 [/code] во -вторых, инициализируйте новый проект C ++ с Vcpkg [code]mkdir myproject && cd myproject vcpkg new --application # created `vcpkg-configuration.json` and `vcpkg.json`
# example: add dependencies using vcpkg vcpkg add port fmt [/code] В -третьих, создайте cmakelists.txt Существуют другие доступные системы сборки. Насколько я понимаю, VCPKG совместима с диапазоном систем сборки. Я использую cmake по умолчанию, а не по какой -либо конкретной причине. [code]# 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) [/code] Четвертый шаг: create main.cpp [code]main.cpp[/code] может содержать минимальный пример «Hello World». > [code]# 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[/code]) отличается от примера файла, представленного в документации, показанного ниже: [code]# 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"[/code], и обнаружил, что он, кажется, работает.[code]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[/code]. Тогда команда выполняется OK: cmake - -preset = default . Наконец, для создания: < /p> [code]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[/code], который должен быть сделан внутри контейнера Docker, потому что вряд ли мы находим существующее изображение, которое содержит все, что мы хотим. Однако оставшиеся шаги не нужны повторять. Мы просто копируем необходимые файлы в изображение контейнера. < /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> [code]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
RUN cmake --preset=default RUN cmake --build build < /code> A .dockerignore[/code] Файл также необходим для предотвращения копирования каталога Build . Без этого сборка ошибся. < /P> #.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) [/list]