C++ 与 Crow、CMake 和 Docker

标签 c++ docker cmake crow

目标

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

代码

到目前为止,我在 Visual Studio 中编译并通过 VCPKG 安装了 Crow,类似于 Tutorial 。 来自 Crow website 的示例 ma​​in.cpp :

#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

感谢您的帮助:)

最佳答案

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

在 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 容器.

Crow 项目在 Docker 容器中使用 g++ 命令和仅 header 库编译

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

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

我使用与上面相同的命令构建并运行 Docker 镜像/容器。 Dockerfile (project 目录中的全部内容被复制到 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" ]

其他问题

  • 我仍然不知道这是否可能。
  • 通过这样一个(仍然)简单的文件结构,没有出现严重的冲突。
  • 关于C++ 与 Crow、CMake 和 Docker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73332642/

    相关文章:

    linux - 如何使用 json 数组格式为 Docker ENTRYPOINT 运行多个语句?

    c++ - 用cmake构建比特币

    linux - ROS-Indigo Collada DOM 安装对 libpcrecpp 包的依赖无法检测到已安装的 libpcrecpp 包

    c++ - 自定义类构造中的段错误

    c++ - 如何知道启动应用程序的可执行文件名称?

    javascript - 将 C++ 代码连接到 Electron 应用程序中的 HTML Canvas ?

    bash - 在 docker 入口点脚本中使用 exec 有什么作用?

    c++ - 近似字符串匹配的概率预选

    amazon-web-services - 适用于 AWS 的 Docker 与 EC2 上的纯 Docker 部署

    c++ - 使用CMake而不是g++链接GDAL库