Как построить контейнер Docker для создания приложения C ++ с помощью VCPKG?Linux

Ответить
Anonymous
 Как построить контейнер Docker для создания приложения C ++ с помощью VCPKG?

Сообщение Anonymous »

Большая часть информации, содержащейся в этом вопросе get_started /get-farted? pivots = shell-bash < /li>
< /ul>

Серия событий заставила меня хотеть попробовать Создайте приложение C ++ в контейнере Docker, при использовании VCPKG .
Вот серия операторов, которые должны помочь обеспечить контекст:

[*] Я использую сервер Debian для разработки приложения C ++ < /li>
Приложение записано с использованием C ++ 23. Это относительно недавняя версия стандарта C ++, и как таковой, это только относительно недавние выбросы компиляторов, которые поддерживают эту версию стандарта
[*] Я использую GCC / для составления кода C ++
[*] Система Debian, которую я использую, имеет более старую версию GCC . Это что -то вроде версии 12. Он не поддерживает (по крайней мере, некоторые из) функций C ++ 23, которые мне нужны < /li>
Я не хочу заменять компилятор системы по умолчанию другим. Как правило, не очень хорошая идея, чтобы поменять компилятор, который поставляется с вашей ОС. Это один из способов, которым вы можете сломать Debian. (См. не сломайте Debian )
[*] I мог бы установить вторую версию GCC , но Я не решаюсь сделать это, потому что это включает либо временное изменение компилятора по умолчанию с помощью альтернатив обновления apt или настройки версии компилятора для выбранной системы сборки вручную . Это не кажется хорошим подходом, и у меня не было хорошего опыта с этим в прошлом. Я бы посоветовал использовать контейнер Docker - это более простой подход. < /p>
У меня есть одно решение, которое работает, но это не хорошее решение. Следующие шаги описаны ниже.
сначала установить 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
во -вторых, инициализируйте новый проект C ++ с 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 по умолчанию, а не по какой -либо конкретной причине.

Код: Выделить всё

# 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)
Четвертый шаг: create main.cpp

Код: Выделить всё

main.cpp
может содержать минимальный пример «Hello World». >

Код: Выделить всё

# 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>

Код: Выделить всё

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.

Подробнее здесь: https://stackoverflow.com/questions/793 ... sing-vcpkg
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»