如何在Dockerfile中更改MariaDB的C++连接器的CMake安装路径?

huangapple go评论66阅读模式
英文:

How can I change the CMake install path inside Dockerfile for the C++ connector for MariaDB?

问题

我正在尝试将MariaDB的C++连接器集成到Dockerfile中。我的Dockerfile如下所示:

# syntax=docker/dockerfile:1

FROM alpine:3.16 AS base

RUN apk update && apk add \
    libstdc++ \
    mariadb-connector-c

FROM base AS builder

RUN apk update && apk add \
    alpine-sdk \
    cmake \
    git \
    curl \
    musl-dev \
    openssl-dev; \
    cd /; \
    git clone https://github.com/MariaDB-Corporation/mariadb-connector-cpp.git; \
    cd mariadb-connector-cpp; \
    mkdir build; \
    cd build; \
    cmake ../ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONC_WITH_UNIT_TESTS=Off -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_SSL=OPENSSL; \
    cmake --build . --config RelWithDebInfo; \
    make install

COPY ./myapp /usr/src/myapp

RUN cd /usr/src/myapp; \
    make; make install

FROM base AS runtime

COPY --from=builder /usr/local/bin /usr/local/bin

COPY --from=builder /usr/local/lib /usr/local/lib

// 定义入口点等等

我以前成功地使用过类似的Dockerfile,用于其他自建的库。所有这些其他共享库都会自行安装到/usr/local/lib/libexample.so,并且在运行应用程序时可以找到它们,没有问题。然而,MariaDB连接器会创建一个子目录,并将其共享库放在那里,例如/usr/local/lib/mariadb/libmariadbcpp.so

随后,我的应用程序在运行时无法找到共享对象。我对使用CMake不太熟悉,我想知道是否有一种优雅的方法来通过修改安装路径使我的应用程序找到这些库?我可以将文件复制到父目录,但一定有更好的方法。

英文:

I am trying to integrate the C++ connector for MariaDB into a Dockerfile. My Dockerfile looks like this:

# syntax=docker/dockerfile:1

FROM alpine:3.16 AS base

RUN apk update && apk add \
    libstdc++ \
    mariadb-connector-c

FROM base AS builder

RUN apk update && apk add \
    alpine-sdk \
    cmake \
    git \
    curl \
    musl-dev \
    openssl-dev; \
    cd /; \
    git clone https://github.com/MariaDB-Corporation/mariadb-connector-cpp.git; \
    cd mariadb-connector-cpp; \
    mkdir build; \
    cd build; \
    cmake ../ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONC_WITH_UNIT_TESTS=Off -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_SSL=OPENSSL; \
    cmake --build . --config RelWithDebInfo; \
    make install

COPY ./myapp /usr/src/myapp

RUN cd /usr/src/myapp; \
    make; make install


FROM base AS runtime

COPY --from=builder /usr/local/bin /usr/local/bin

COPY --from=builder /usr/local/lib /usr/local/lib

// define entrypoints, etc.

I have successfully used Dockerfiles like this before with other self-built libraries. All these other shared libraries installed themselves into /usr/local/lib/libexample.so and were found without issues when running the application. However, the MariaDB connector creates a subdirectory and puts its shared libraries there, e.g. /usr/local/lib/mariadb/libmariadbcpp.so.

Subsequently, my application cannot find the shared object during runtime. I am not very experienced using cmake and I wonder if there is an elegant way to make my application find the libraries by modifying the install path? I could copy the files to the parent directory, but there must be a better way.

答案1

得分: 1

这部分内容不需要翻译。

英文:

It seems like you don't have much control over this install subdirectory without modifying the CMake script files of mariadb-connector-cpp itself.

In mariadb-corporation/mariadb-connector-odbc's CMakeLists.txt

########## Packaging ##########

# MSI
IF(WIN32)
  ...
ELSE()
  IF(APPLE)
    ...
  ENDIF()
  INSTALL(TARGETS
          ${LIBRARY_NAME}
          LIBRARY DESTINATION ${INSTALL_LIB_SUFFIX}/mariadb
          COMPONENT CppLibs)

In mariadb-corporation/mariadb-connector-odbc's cmake/install.cmake:

# This has been done before C/C cmake scripts are included
IF(NOT DEFINED INSTALL_LIB_SUFFIX)
  SET(INSTALL_LIB_SUFFIX "lib" CACHE STRING "Directory, under which to install libraries, e.g. lib or lib64")
  IF("${CMAKE_SIZEOF_VOID_P}" EQUAL "8" AND EXISTS "/usr/lib64/" AND "${INSTALL_LAYOUT}" EQUAL "RPM")
    SET(INSTALL_LIB_SUFFIX "lib64")
  ENDIF()
ENDIF()

So you could set the value of INSTALL_LIB_SUFFIX to an empty string, but that still wouldn't change the fact that it hardcodes an additional mariadb/ subdirectory to whatever the value of INSTALL_LIB_SUFFIX is. If you really really wanted to change that, you'd need to patch the CMake scripts after the git clone and before running the CMake configuration command.

You could add that directory to the system search path before running your application, or look into using the LD_PRELOAD or similar environment variables in the environment of your application at runtime (see https://stackoverflow.com/q/426230/11107541), or you could use the RPATH mechanism. For more info on how shared libraries are searched for on unix systems, see https://unix.stackexchange.com/q/22926/550426.

huangapple
  • 本文由 发表于 2023年2月27日 09:56:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75576207.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定