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

Программы на C++. Форум разработчиков
Ответить
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.
    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
Ответить

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

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

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

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

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