0

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.

starball
  • 20,030
  • 7
  • 43
  • 238
DocDriven
  • 3,726
  • 6
  • 24
  • 53
  • Note: the fact that this happens inside a dockerfile is not a crucial detail to this question- just the fact that the platform is a linux/unix platform. – starball Feb 27 '23 at 08:19
  • 1
    That is true. The reasoning why I included it in the question was that using the built library in the Dockerfile makes modifying the CMake configuration file a less viable solution. If I just pull the sources and modify the right variable, I would be able to directly create the output file in the desired location. Maybe I should have included this thought in the question. – DocDriven Feb 27 '23 at 09:12

1 Answers1

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 What is the LD_PRELOAD trick?), 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.

starball
  • 20,030
  • 7
  • 43
  • 238
  • Thanks, I was afraid that this was out of my control. I decided against patching the file as this solution is probably the most error-prone approach in the long run. It seems that the issue can be resolved by adding the additional directory to `LD_LIBRARY_PATH`. – DocDriven Feb 27 '23 at 03:03