Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Build With kleisauke/libvips-packaging? #338

Closed
dsimunic opened this issue Mar 30, 2022 · 3 comments
Closed

How to Build With kleisauke/libvips-packaging? #338

dsimunic opened this issue Mar 30, 2022 · 3 comments
Labels
question Further information is requested

Comments

@dsimunic
Copy link

I'm trying to build weserv module on Debian 11 and link it against the pre-built libvips-cpp.so from kleisauke/libvips-packaging.

The build succeeds, but linking fails with

[100%] Linking CXX executable ../../../bin/weserv-cli
/usr/bin/ld: ../../../lib/libweserv.so.5.0.0: undefined reference to `vips::VImage::new_from_buffer(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*, vips::VOption*)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/tools/CMakeFiles/weserv-cli.dir/build.make:104: ../bin/weserv-cli] Error 1
make[1]: *** [CMakeFiles/Makefile2:182: src/tools/CMakeFiles/weserv-cli.dir/all] Error 2
make: *** [Makefile:149: all] Error 2

A simple example .c file linked against that same libvips setup works, so I presume the library and paths are correct. Building against libvips-dev from apt also works, but that version depends on hundreds of files, not fun to copy around.

I made my own pkg-config for vips and vips-cpp, the files are here: https://gist.github.com/dsimunic/1d4bc350191505595071ebd7cdbc3d74, and the build script is here.

What do I need to change to successfully build weserv nginx module with the packaged libvips?

@kleisauke kleisauke added the question Further information is requested label Apr 6, 2022
@kleisauke
Copy link
Member

kleisauke commented Apr 6, 2022

Hi @dsimunic,

Sorry for the delay. The pre-built binaries in the kleisauke/libvips-packaging repository were compiled with the devtoolset packages on RHEL/CentOS 7 which forcefully disabled the -D_GLIBCXX_USE_CXX11_ABI=1 compiler flag, see: https://stackoverflow.com/a/52611576.

You can verify this with the readelf utility:

$ readelf -Ws libvips-cpp.so.42 | c++filt | grep -qF "::__cxx11::" && echo "C++11 ABI used" || echo "C++03 ABI used"
C++03 ABI used

So, to take advantage of these pre-built binaries, you should build this project with:

CFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0"
CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0"

This will fix the linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace.

Here is an sample Dockerfile that seems to work for me:

Details
FROM debian:bullseye

LABEL maintainer="Kleis Auke Wolthuizen <info@kleisauke.nl>"

ARG NGINX_VERSION=1.21.6
ARG VIPS_VERSION=8.12.2

# https://gist.github.com/kleisauke/91ef7315adbe1ca7455a38b24d28081e
ARG PKG_CONFIG_TARBALL=https://gist.github.com/kleisauke/91ef7315adbe1ca7455a38b24d28081e/archive/7f024426a686539b051d6239f84d9d5a6719394c.tar.gz

WORKDIR /opt/libvips

# Update packages
RUN apt-get update -q \
    # Install curl
    && apt-get install -qy --no-install-recommends \
        ca-certificates \
        curl \
    # Download pre-built libvips binaries
    && curl -Ls https://github.com/kleisauke/libvips-packaging/releases/download/v$VIPS_VERSION/libvips-$VIPS_VERSION-linux-x64.tar.gz | tar -xzC . \
    # Download pkgconfig files
    && mkdir -p lib/pkgconfig \
    && curl -Ls $PKG_CONFIG_TARBALL | tar -xzC lib/pkgconfig --strip-components=1

WORKDIR /var/www/imagesweserv

# Set default timezone (can be overridden with -e "TZ=Continent/City")
ENV TZ=Europe/Amsterdam \
    # Update the PKG_CONFIG_PATH environment variable,
    # since libvips is installed in a non-standard prefix
    PKG_CONFIG_PATH=/opt/libvips/lib/pkgconfig \
    # Ensure dynamic linker finds the pre-built libvips binaries
    LD_LIBRARY_PATH=/opt/libvips/lib

# Setup nginx user and group
RUN groupadd nginx \
    && useradd -r -g nginx -s /sbin/nologin -c "Nginx web server" nginx \
    # Install needed dependencies
    && apt-get install -qy --no-install-recommends \
        cmake \
        git \
        g++ \
        make \
        pkg-config \
        libpcre2-dev \
        libssl-dev \
        zlib1g-dev \
    # Clone the repository
    && git clone --depth=1 --recurse-submodules --shallow-submodules https://github.com/weserv/images.git . \
    # Build CMake-based project
    && cmake -S . -B _build \
        -DCMAKE_BUILD_TYPE=Release \
        -DBUILD_TOOLS=ON \
        -DNGX_VERSION=$NGINX_VERSION \
        -DCUSTOM_NGX_FLAGS="--prefix=/usr/share/nginx;\
--sbin-path=/usr/sbin/nginx;\
--modules-path=/usr/lib/nginx/modules;\
--conf-path=/etc/nginx/nginx.conf;\
--error-log-path=/var/log/nginx/error.log;\
--http-log-path=/var/log/nginx/access.log;\
--http-client-body-temp-path=/var/lib/nginx/tmp/client_body;\
--http-proxy-temp-path=/var/lib/nginx/tmp/proxy;\
--http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi;\
--http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi;\
--http-scgi-temp-path=/var/lib/nginx/tmp/scgi;\
--pid-path=/run/nginx.pid;\
--lock-path=/run/lock/subsys/nginx;\
--user=nginx;\
--group=nginx" \
    && cmake --build _build -- -j$(nproc) \
    && ldconfig \
    # Remove build directory and dependencies
    && rm -rf _build \
    && apt-get autoremove --purge -qy \
        libpcre2-dev \
        libssl-dev \
        zlib1g-dev \
    && rm -rf /var/lib/apt/lists/* \
    # Ensure nginx directories exist with the correct permissions
    && mkdir -m 700 /var/lib/nginx \
    && mkdir -m 700 /var/lib/nginx/tmp \
    && mkdir -m 700 /usr/lib/nginx \
    && mkdir -m 755 /usr/lib/nginx/modules \
    # Forward request and error logs to docker log collector
    && ln -sf /dev/stdout /var/log/nginx/weserv-access.log \
    && ln -sf /dev/stderr /var/log/nginx/weserv-error.log \
    # Copy nginx configuration to the appropriate location
    && cp ngx_conf/*.conf /etc/nginx

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

@kleisauke
Copy link
Member

Thinking about this further, we can also avoid calling the string overload of VImage::new_from_buffer, so that mixed C++ ABIs will work without any issues.

I just did this with commit 2b51dd8, so please ignore the above comment. Thanks for reporting this!

@dsimunic
Copy link
Author

dsimunic commented Apr 7, 2022

Didn't know that compilation output can differ between distributions. TIL a lot.

Thanks so much for taking the time to look into this and sorting it out. And thanks for the awesome plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Development

No branches or pull requests

2 participants