英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论