【问题标题】:C++ with Crow, CMake, and DockerC++ 与 Crow、CMake 和 Docker
【发布时间】:2022-08-15 05:39:21
【问题描述】:

目标

我想用 CMake 编译一个 Crow 项目并将其部署在 docker 容器中。

代码

到目前为止,我在 Visual Studio 中编译并通过 VCPKG 安装了 Crow,类似于 Tutorial。 例子主文件来自Crow website

#include \"crow.h\"
//#include \"crow_all.h\"

int main()
{
    crow::SimpleApp app; //define your crow application

    //define your endpoint at the root directory
    CROW_ROUTE(app, \"/\")([](){
        return \"Hello world\";
    });

    //set the port, set the app to run on multiple threads, and run the app
    app.port(18080).multithreaded().run();
}

我想用docker build -t main_app:1 . 构建我的docker 映像,然后用docker run -d -it -p 443:18080 --name app main_app:1 运行一个容器。 因此,我考虑了类似的事情:

Dockerfile

FROM ubuntu:latest

RUN apt-get update -y
RUN apt-get upgrade -y

# is it necessary to install all of them?
RUN apt-get install -y g++ gcc cmake make git gdb pkg-config

RUN git clone --depth 1 https://github.com/microsoft/vcpkg
RUN ./vcpkg/bootstrap-vcpkg.sh

RUN /vcpkg/vcpkg install crow

CMakeLists.txt

cmake_minimum_required(VERSION 3.8)

project(project_name)

include(/vcpkg/scripts/buildsystems/vcpkg.cmake)

find_package(Crow CONFIG REQUIRED)

add_executable(exe_name \"main.cpp\")

target_link_libraries(exe_name PUBLIC Crow::Crow)

问题

  1. 但是,显然这并不完整,因此不会起作用。因此,我想知道这个 main.cpp 的正确(简单)Dockerfile 和 CMakeLists.txt 会是什么样子?
  2. 是否可以在没有 VCPKG 的情况下创建我的图像?我有点担心我的图像和容器大小,在这里。
  3. 它如何与crow_all.h 仅标头文件一起使用?
  4. 是否也可以从已编译的 name.exe 构建映像 - 这样我在构建映像时就不必编译任何东西了?
  5. 既然这应该是一个最小的例子,那么这样的文件结构会不会有任何冲突:
    docker_project
      |__Dockerfile
      |__CMakeLists.txt
      |__header.hpp
      |__class.cpp
      |__main.cpp
    

    谢谢你的帮助 :)

    标签: c++ docker cmake crow


    【解决方案1】:

    经过进一步的研究和测试,我可以通过两种方式解决这个问题:

    在 Docker 容器中使用 CMake 编译的 Crow.h 项目

    Dockerfile

    # get baseimage
    FROM ubuntu:latest
    
    RUN apt-get update -y
    RUN apt-get upgrade -y
    # reinstall certificates, otherwise git clone command might result in an error
    RUN apt-get install --reinstall ca-certificates -y
    
    # install developer dependencies
    RUN apt-get install -y git build-essential cmake --no-install-recommends
    
    # install vcpkg package manager
    RUN git clone https://github.com/microsoft/vcpkg
    RUN apt-get install -y curl zip
    RUN vcpkg/bootstrap-vcpkg.sh
    
    # install crow package
    RUN /vcpkg/vcpkg install crow
    
    # copy files from local directory to container
    COPY . /project
    
    # define working directory from container
    WORKDIR /build
    
    # compile with CMake 
    RUN bash -c "cmake ../project && cmake --build ."
    
    # run executable (name has to match with CMakeLists.txt file)
    CMD [ "./app" ]
    

    Docker 目录如下所示:

    Docker
      |__vcpkg
        |__ ...
      |__project
        |__CMakeLists.txt
        |__main.cpp
      |__build
        |__app
        |__ ...
    

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.8)
    
    project(project)
    
    # full path from root directory
    include(/vcpkg/scripts/buildsystems/vcpkg.cmake)
    
    find_package(Crow CONFIG REQUIRED)
    
    add_executable(
        app
        main.cpp
    )
    
    target_link_libraries(app PUBLIC Crow::Crow)
    

    在本地目录中构建 Docker 映像

    project
      |__Dockerfile
      |__CMakeLists.txt
      |__main.cpp
    

    导航到 shell 中的项目文件夹并运行 docker build -t image_name:1 . 以构建 Docker 映像并使用 docker run -d -it --rm --name container_name -p 443:18080 image_name:1 运行 Docker 容器。

    使用 Docker 容器中的 g++ 命令和仅标头库编译的 Crow 项目

    我从 Crow Github repository 创建了 crow_all.h 仅头文件,并通过我的 PC 上的 VCPKG 下载了 asio 包,并将头文件 (C:\vcpkg\packages\asio_x64-windows\include) 复制到我的项目文件夹中名为asio 的子目录。因此,我的项目目录如下所示:

    project
      |__asio
        |__asio.hpp
        |__asio
          |__ ...
      |__crow_all.h
      |__Dockerfile
      |__main.cpp
    

    我使用与上述相同的命令构建并运行 Docker 映像/容器。Dockerfileproject 目录中的全部内容被复制到 Docker 容器的 /usr/src/ 目录中)

    # get baseimage
    FROM gcc:12
    
    # copy files from local folder to destination
    COPY . /usr/src
    
    # define working directory in container
    WORKDIR /usr/src
    
    # compile main.cpp (-I/usr/src/asio/ link path starting from root)
    RUN g++ -I/usr/src/asio/ main.cpp -lpthread -o app
    
    # run executable
    CMD [ "./app" ]
    

    对其他问题

    1. 我仍然不知道,这是否可能。
    2. 使用这种(仍然)简单的文件结构,不会出现严重的冲突。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 1970-01-01
      • 2020-10-17
      • 2013-01-06
      • 1970-01-01
      • 2016-06-25
      • 2015-01-08
      相关资源
      最近更新 更多