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

Build libvips with poppler from source #1749

Closed
asterikx opened this issue Jul 29, 2020 · 22 comments
Closed

Build libvips with poppler from source #1749

asterikx opened this issue Jul 29, 2020 · 22 comments
Labels

Comments

@asterikx
Copy link

asterikx commented Jul 29, 2020

I need to build libvips with poppler support for AWS Lambda. I need to build both libvips and poppler from source as they are not pre-installed on AWS Lambda (Amazon Linux 1).

I'm building all neceassry binaries and shared libraries to /opt (opt/bin, opt/lib, opt/include , etc.). Libvips picks up most packages such as libimagequant from there. However, I can't get libvips to see poppler and cairo.

Relevant parts of my Dockerfile:

ENV BUILD_DIR="/tmp/build"
ENV INSTALL_DIR="/opt"

ENV PATH="${INSTALL_DIR}/bin:${PATH}" \
  LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" \
  PKG_CONFIG_PATH="${INSTALL_DIR}/lib64/pkgconfig:${INSTALL_DIR}/lib/pkgconfig"


# Install Cairo (http://www.linuxfromscratch.org/blfs/view/svn/x/cairo.html)
#
ENV CAIRO_VERSION=1.17.2
ENV CAIRO_BUILD_DIR=${BUILD_DIR}/cairo

RUN set -Eeuxo pipefail \
  && mkdir -p ${CAIRO_BUILD_DIR} \
  && curl -L https://cairographics.org/snapshots/cairo-${CAIRO_VERSION}.tar.xz \
  | tar xJC ${CAIRO_BUILD_DIR} --strip-components=1

WORKDIR  ${CAIRO_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && autoreconf -fiv \
  && ./configure \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  --enable-tee \
  && make \
  && make install


# Install Poppler (http://www.linuxfromscratch.org/blfs/view/svn/general/poppler.html)
#
ENV POPPLER_VERSION=0.85.0
ENV POPPLER_BUILD_DIR=${BUILD_DIR}/poppler

RUN set -Eeuxo pipefail \
  && mkdir -p ${POPPLER_BUILD_DIR}/build \
  && curl -L https://poppler.freedesktop.org/poppler-${POPPLER_VERSION}.tar.xz \
  | tar xJC ${POPPLER_BUILD_DIR} --strip-components=1

WORKDIR ${POPPLER_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && CFLAGS="" \
  CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \
  LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \
  cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
  && make \
  && make install


# Install libvips (https://libvips.github.io/libvips/install.html)
#
ENV LIBVIPS_VERSION=8.9.2
ENV LIBVIPS_BUILD_DIR=${BUILD_DIR}/libvips

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBVIPS_BUILD_DIR} \
  && curl -L https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.gz \
  | tar xzC ${LIBVIPS_BUILD_DIR} --strip-components=1

WORKDIR ${LIBVIPS_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && ./configure \
  --prefix=${INSTALL_DIR} \
  --disable-gtk-doc \
  --without-magick \
  --without-giflib \
  && make \
  && make install \
  && echo /opt/lib > /etc/ld.so.conf.d/libvips.conf \
  && ldconfig
Complete Dockerfile
FROM lambci/lambda:build-go1.x AS compile-image
# FROM amazonlinux:2018.03 AS compile-image

# See here for more build examples: https://github.com/stechstudio/libvips-lambda/tree/master/build/dependencies
# https://github.com/jeylabs/aws-lambda-poppler-layer
# https://github.com/pjfoley/poppler-for-lambda

# SHELL ["/bin/bash", "-c"]

ENV BUILD_DIR="/tmp/build"
ENV INSTALL_DIR="/opt"

# Create all necessary build directories
#
RUN set -Eeuxo pipefail \
  && mkdir -p ${BUILD_DIR}/{bin,doc,include,lib,lib64,libexec,sbin,share}

# Install Development Tools
#
WORKDIR /tmp

RUN set -Eeuxo pipefail \
  && yum -y update \
  && yum -y install \
  gcc72-c++ \
  libuuid-devel \
  nasm \
  ninja-build \
  && yum -y clean all

RUN pip3 install meson

# Set GCC to 7.2.1-2 (default is 4.8.5-28 on lambci/lambda:build-go1.x image)
RUN update-alternatives --set gcc /usr/bin/gcc72

# Install CMake (http://www.linuxfromscratch.org/blfs/view/svn/general/cmake.html)
#
ENV CMAKE3_VERSION=3.18.0
ENV CMAKE3_BUILD_DIR=${BUILD_DIR}/cmake3

RUN set -Eeuxo pipefail \
  && mkdir -p ${CMAKE3_BUILD_DIR} \
  && curl -L https://github.com/Kitware/CMake/releases/download/v${CMAKE3_VERSION}/cmake-${CMAKE3_VERSION}.tar.gz \
  | tar xzC ${CMAKE3_BUILD_DIR} --strip-components=1 \
  && curl -L http://www.linuxfromscratch.org/patches/blfs/svn/cmake-${CMAKE3_VERSION}-regression_fix-1.patch -o ${CMAKE3_BUILD_DIR}/cmake-${CMAKE3_VERSION}-regression_fix-1.patch

WORKDIR  ${CMAKE3_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && patch -Np1 -i cmake-${CMAKE3_VERSION}-regression_fix-1.patch \
  && sed -i '/"lib64"/s/64//' Modules/GNUInstallDirs.cmake \
  && ./bootstrap \
  --parallel=4 \
  && make \
  && make install

# Configure Default Compiler Variables
#
ENV PATH="${INSTALL_DIR}/bin:${PATH}" \
  LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" \
  PKG_CONFIG_PATH="${INSTALL_DIR}/lib64/pkgconfig:${INSTALL_DIR}/lib/pkgconfig"

# Build libxml2 (http://www.linuxfromscratch.org/blfs/view/svn/general/libxml2.html)
#
ENV XML2_VERSION=2.9.10
ENV XML2_BUILD_DIR=${BUILD_DIR}/libxml2

RUN set -Eeuxo pipefail; \
  mkdir -p ${XML2_BUILD_DIR} \
  && curl -L http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz \
  | tar xzC ${XML2_BUILD_DIR} --strip-components=1

WORKDIR  ${XML2_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure \
  --prefix=${INSTALL_DIR} \
  --with-sysroot=${INSTALL_DIR} \
  --disable-static \
  --with-history \
  --with-icu \
  --without-python

RUN set -Eeuxo pipefail \
  && make install \
  && cp xml2-config ${INSTALL_DIR}/bin/xml2-config

# Install FreeType2 (http://www.linuxfromscratch.org/blfs/view/svn/general/freetype2.html)
#
ENV FREETYPE2_VERSION=2.10.2
ENV FREETYPE2_BUILD_DIR=${BUILD_DIR}/freetype2

RUN set -Eeuxo pipefail \
  && mkdir -p ${FREETYPE2_BUILD_DIR} \
  && curl -L https://download-mirror.savannah.gnu.org/releases/freetype/freetype-${FREETYPE2_VERSION}.tar.xz \
  | tar xJC ${FREETYPE2_BUILD_DIR} --strip-components=1

WORKDIR  ${FREETYPE2_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && sed -ri "s:.*(AUX_MODULES.*valid):\1:" modules.cfg

RUN set -Eeuxo pipefail \
  && sed -r "s:.*(#.*SUBPIXEL_RENDERING) .*:\1:" -i include/freetype/config/ftoption.h

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --with-sysroot=${INSTALL_DIR} \
  --enable-freetype-config  \
  --disable-static \
  && make \
  && make install

# Install Gperf (http://www.linuxfromscratch.org/blfs/view/7.4/general/gperf.html)
#
ENV GPERF_VERSION=3.1
ENV GPERF_BUILD_DIR=${BUILD_DIR}/gperf

RUN set -Eeuxo pipefail \
  && mkdir -p ${GPERF_BUILD_DIR} \
  && curl -L http://ftp.gnu.org/pub/gnu/gperf/gperf-${GPERF_VERSION}.tar.gz \
  | tar xzC ${GPERF_BUILD_DIR} --strip-components=1

WORKDIR  ${GPERF_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  && make \
  && make install

# Install Fontconfig (http://www.linuxfromscratch.org/blfs/view/svn/general/fontconfig.html)
#
# Requires: freetype and either expat or libxml2
#
ENV FONTCONFIG_VERSION=2.13.1
ENV FONTCONFIG_BUILD_DIR=${BUILD_DIR}/fontconfig

RUN set -Eeuxo pipefail \
  && mkdir -p ${FONTCONFIG_BUILD_DIR} \
  && curl -L https://www.freedesktop.org/software/fontconfig/release/fontconfig-${FONTCONFIG_VERSION}.tar.bz2 \
  | tar xjC ${FONTCONFIG_BUILD_DIR} --strip-components=1

WORKDIR  ${FONTCONFIG_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && rm -f src/fcobjshash.h

RUN set -Eeuxo pipefail \
  && FONTCONFIG_PATH=${INSTALL_DIR} \
  ./configure  \
  --sysconfdir=${INSTALL_DIR}/etc \
  --localstatedir=${INSTALL_DIR}/var \
  --prefix=${INSTALL_DIR} \
  --disable-docs \
  --enable-libxml2 \
  && make \
  && make install

# Install Libjpeg-Turbo (http://www.linuxfromscratch.org/blfs/view/svn/general/libjpeg.html)
#
ENV LIBJPEG_VERSION=2.0.5
ENV LIBJPEG_BUILD_DIR=${BUILD_DIR}/libjpeg

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBJPEG_BUILD_DIR}/build \
  && curl -L https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-${LIBJPEG_VERSION}.tar.gz \
  | tar xzC ${LIBJPEG_BUILD_DIR} --strip-components=1

WORKDIR  ${LIBJPEG_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && cmake .. \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DCMAKE_BUILD_TYPE=RELEASE \
  -DENABLE_STATIC=FALSE \
  -DCMAKE_INSTALL_DEFAULT_LIBDIR=lib \
  && make \
  && make install

# Install OpenJPEG (http://www.linuxfromscratch.org/blfs/view/svn/general/openjpeg2.html)
#
ENV OPENJPEG_VERSION=2.3.1
ENV OPENJPEG_BUILD_DIR=${BUILD_DIR}/openjpeg2

RUN set -Eeuxo pipefail \
  && mkdir -p ${OPENJPEG_BUILD_DIR}/build \
  && curl -L https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}/openjpeg-${OPENJPEG_VERSION}.tar.gz \
  | tar xzC ${OPENJPEG_BUILD_DIR} --strip-components=1

WORKDIR  ${OPENJPEG_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DBUILD_STATIC_LIBS=OFF \
  && make \
  && make install

# Install Libpng (http://www.linuxfromscratch.org/blfs/view/svn/general/openjpeg2.html)
#
ENV OPENPNG_VERSION=1.6.37
ENV OPENPNG_BUILD_DIR=${BUILD_DIR}/libpng

RUN set -Eeuxo pipefail \
  && mkdir -p ${OPENPNG_BUILD_DIR} \
  && curl -L https://downloads.sourceforge.net/libpng/libpng-${OPENPNG_VERSION}.tar.xz \
  | tar xJC ${OPENPNG_BUILD_DIR} --strip-components=1

WORKDIR  ${OPENPNG_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  # && CFLAGS="" \
  # CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \
  # LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  && make \
  && make install

# Install LibTIFF (http://www.linuxfromscratch.org/blfs/view/svn/general/libtiff.html)
#
ENV LIBTIFF_VERSION=4.1.0
ENV LIBTIFF_BUILD_DIR=${BUILD_DIR}/tiff

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBTIFF_BUILD_DIR} \
  && curl -L http://download.osgeo.org/libtiff/tiff-${LIBTIFF_VERSION}.tar.gz \
  | tar xzC ${LIBTIFF_BUILD_DIR} --strip-components=1

WORKDIR  ${LIBTIFF_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && mkdir -p libtiff-build \
  && cd libtiff-build \
  && cmake .. \
  -DCMAKE_INSTALL_DOCDIR=/usr/share/doc/libtiff-4.1.0 \
  -DCMAKE_INSTALL_PREFIX=/usr -G Ninja \
  && ninja \
  && ninja install

# Install Pixman (http://www.linuxfromscratch.org/blfs/view/svn/general/pixman.html)
#
ENV PIXMAN_VERSION=0.40.0
ENV PIXMAN_BUILD_DIR=${BUILD_DIR}/pixman

RUN set -Eeuxo pipefail \
  && mkdir -p ${PIXMAN_BUILD_DIR} \
  && curl -L https://www.cairographics.org/releases/pixman-${PIXMAN_VERSION}.tar.gz \
  | tar xzC ${PIXMAN_BUILD_DIR} --strip-components=1

WORKDIR ${PIXMAN_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ls -al ${PIXMAN_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && mkdir build \
  && cd build \
  && meson --prefix=${INSTALL_DIR} \
  && ninja \
  && ninja install

# Install Cairo (http://www.linuxfromscratch.org/blfs/view/svn/x/cairo.html)
#
ENV CAIRO_VERSION=1.17.2
ENV CAIRO_BUILD_DIR=${BUILD_DIR}/cairo

RUN set -Eeuxo pipefail \
  && mkdir -p ${CAIRO_BUILD_DIR} \
  && curl -L https://cairographics.org/snapshots/cairo-${CAIRO_VERSION}.tar.xz \
  | tar xJC ${CAIRO_BUILD_DIR} --strip-components=1

WORKDIR  ${CAIRO_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && autoreconf -fiv \
  && ./configure \
  --prefix=${INSTALL_DIR}    \
  --disable-static \
  --enable-tee \
  && make \
  && make install

# Install Little CMS (https://downloads.sourceforge.net/lcms)
#
ENV LCMS_VERSION=2.11
ENV LCMS_BUILD_DIR=${BUILD_DIR}/lcms

RUN set -Eeuxo pipefail \
  && mkdir -p ${LCMS_BUILD_DIR} \
  && curl -L https://downloads.sourceforge.net/lcms/lcms2-${LCMS_VERSION}.tar.gz \
  | tar xzC ${LCMS_BUILD_DIR} --strip-components=1

WORKDIR ${LCMS_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  && make \
  && make install

# Install Boost (http://www.linuxfromscratch.org/blfs/view/svn/general/boost.html)
#
ENV BOOST_VERSION=1.73.0
ENV BOOST_VERSION_UNDERSCORE=1_73_0
ENV BOOST_BUILD_DIR=${BUILD_DIR}/boost

RUN set -Eeuxo pipefail \
  && mkdir -p ${BOOST_BUILD_DIR} \
  && curl -L https://dl.bintray.com/boostorg/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_UNDERSCORE}.tar.bz2 | tar xjC ${BOOST_BUILD_DIR} --strip-components=1

WORKDIR ${BOOST_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./bootstrap.sh \
  --prefix=${INSTALL_DIR} \
  && ./b2 stage -j4 threading=multi link=shared \
  && ./b2 install threading=multi link=shared \
  && ln -svf detail/sha1.hpp ${INSTALL_DIR}/include/boost/uuid/sha1.hpp

# Install Poppler (http://www.linuxfromscratch.org/blfs/view/svn/general/poppler.html)
#
ENV POPPLER_VERSION=0.85.0
ENV POPPLER_BUILD_DIR=${BUILD_DIR}/poppler

RUN set -Eeuxo pipefail \
  && mkdir -p ${POPPLER_BUILD_DIR}/build \
  && curl -L https://poppler.freedesktop.org/poppler-${POPPLER_VERSION}.tar.xz \
  | tar xJC ${POPPLER_BUILD_DIR} --strip-components=1

WORKDIR ${POPPLER_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && CFLAGS="" \
  CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \
  LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \
  cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
  && make \
  && make install

# Install libimagequant
#
ENV LIBIMAGEQUANT_VERSION=2.12.6
ENV LIBIMAGEQUANT_BUILD_DIR=${BUILD_DIR}/libimagequant

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBIMAGEQUANT_BUILD_DIR} \
  && git clone https://github.com/ImageOptim/libimagequant.git ${LIBIMAGEQUANT_BUILD_DIR}

WORKDIR ${LIBIMAGEQUANT_BUILD_DIR}

RUN ./configure \
  --prefix=${INSTALL_DIR} && \
  make libimagequant.so && \
  make install

# Install libvips (https://libvips.github.io/libvips/install.html)
#
ENV LIBVIPS_VERSION=8.9.2
ENV LIBVIPS_BUILD_DIR=${BUILD_DIR}/libvips

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBVIPS_BUILD_DIR} \
  && curl -L https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.gz \
  | tar xzC ${LIBVIPS_BUILD_DIR} --strip-components=1

WORKDIR ${LIBVIPS_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && ./configure \
  --prefix=${INSTALL_DIR} \
  --disable-gtk-doc \
  --without-magick \
  --without-giflib \
  && make \
  && make install \
  && echo /opt/lib > /etc/ld.so.conf.d/libvips.conf \
  && ldconfig


FROM lambci/lambda:build-go1.x AS runtime-image

ENV SOURCE_DIR="/opt"
ENV INSTALL_DIR="/opt"

ENV PATH="/opt/bin:${PATH}" \
  LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib"

# Install zip
#
RUN set -Eeuxo pipefail \
  && yum update -y \
  && yum -y install zip \
  && yum -y clean all

# Copy all binaries/libaries
#
RUN set -Eeuxo pipefail \
  && mkdir -p ${BUILD_DIR}/{etc,bin,var,share,lib}

COPY --from=compile-image /lib64/libuuid.so.* ${INSTALL_DIR}/lib/
COPY --from=compile-image ${SOURCE_DIR}/share/ /tmp/share
COPY --from=compile-image ${SOURCE_DIR}/etc/ ${INSTALL_DIR}/etc/
COPY --from=compile-image ${SOURCE_DIR}/bin/ ${INSTALL_DIR}/bin/
COPY --from=compile-image ${SOURCE_DIR}/var/ ${INSTALL_DIR}/var/
COPY --from=compile-image ${SOURCE_DIR}/lib/ ${INSTALL_DIR}/lib/
COPY --from=compile-image ${SOURCE_DIR}/lib64/ ${INSTALL_DIR}/lib/

RUN set -Eeuxo pipefail \
  && cp -R /tmp/share/fontconfig ${INSTALL_DIR}/share/fontconfig
Libvips configure output
* build options
native win32:				no
native OS X:				no
open files in binary mode: 		no
enable debug:				no
enable deprecated library components:	yes
enable docs with gtkdoc:		no
gobject introspection: 			no
enable radiance support: 		yes
enable analyze support: 		yes
enable PPM support: 			yes

* optional dependencies
use fftw3 for FFT: 			no
Magick package: 			none
Magick API version: 			none
load with libMagick: 			no
save with libMagick: 			no
accelerate loops with orc: 		no
  (requires orc-0.4.11 or later)
ICC profile support with lcms: 		yes (lcms2)
file import with niftiio: 		no
file import with libheif: 		no
file import with OpenEXR: 		no
file import with OpenSlide:		no
  (requires openslide-3.3.0 or later)
file import with matio: 		no
PDF import with PDFium 			no
PDF import with poppler-glib: 		no
  (requires poppler-glib 0.16.0 or later)
SVG import with librsvg-2.0: 		no
  (requires librsvg-2.0 2.34.0 or later)
zlib: 					yes
file import with cfitsio: 		no
file import/export with libwebp:	no
  (requires libwebp, libwebpmux, libwebpdemux 0.6.0 or later)
text rendering with pangoft2: 		no
file import/export with libpng: 	yes (pkg-config libpng >= 1.2.9)
  (requires libpng-1.2.9 or later)
support 8bpp PNG quantisation:		yes
  (requires libimagequant)
file import/export with libtiff:	yes (pkg-config libtiff-4)
file import/export with giflib:		no
file import/export with libjpeg:	yes (pkg-config)
image pyramid export:			no
  (requires libgsf-1 1.14.26 or later)
use libexif to load/save JPEG metadata: no

While there are the flags --with-pdfium-includes and --with-pdfium-libraries for PDFium, there's no equivalent for poppler. I have rarely compiled libraries before, so I might miss something obvious.

Thanks for any help

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

Hello @asterikx,

I can't see anything obviously wrong. I'll try building your dockerfile.

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

libvips uses the poppler-glib interface, which isn't being built.

You'll need to enable it with something like:

cmake \
    -DENABLE_ZLIB=ON \
    -DENABLE_LIBTIFF=ON \
    -DENABLE_LIBPNG=ON \
    -DENABLE_GLIB=ON \
    -DENABLE_CMS='lcms2' \
    -DENABLE_LIBOPENJPEG='openjpeg2' \
    -DENABLE_DCTDECODER='libjpeg' \
    -DENABLE_SPLASH=OFF \
    -DENABLE_CPP=OFF

I noticed you are missing libexif -- it's needed to get metadata from JPEG files. I imagine the one in yum would be OK. I would add orc as well -- you'll see a dramatic speedup for things like convolution. I'd build libvips with V=0 to make it a bit less chatty.

@asterikx
Copy link
Author

Hi @jcupitt, thank you so much!

The version of CMake that comes with the image is too old and building takes very long, unfortunately ...

Off-topic: I'm building poppler version 0.85.0. Buiding the most recent version 0.90.1 fails with:

[ 64%] Linking CXX executable pdfimages
../libpoppler.so.101.0.0: undefined reference to `png_set_longjmp_fn'
collect2: error: ld returned 1 exit status
make[2]: *** [utils/pdfimages] Error 1
make[1]: *** [utils/CMakeFiles/pdfimages.dir/all] Error 2
make: *** [all] Error 2

This issue suggests that my version of libpng is corrupt, but since I'm building it from source, I can't think that's true.

It's probably an issue with picking the correct version of libpng (1.2.8 is pre-installed and I'm building 1.6.37), but I don't know how to point poppler to the correct version of libpng.

@asterikx
Copy link
Author

libvips uses the poppler-glib interface, which isn't being built.

Thank you! Sorry, I think I'm lacking a bit of general knowledge in "system-level" programming.

I noticed you are missing libexif -- it's needed to get metadata from JPEG files. I imagine the one in yum would be OK. I would add orc as well -- you'll see a dramatic speedup for things like convolution. I'd build libvips with V=0 to make it a bit less chatty.

Thanks for the tips! Would you recommend installing libboost for poppler? Since I'm building for Lambda I have to keep an eye on overall size. The concrete lambda in question should convert PDFs to PNG (and optionally resize them).

I'm also not sure if I only need the .so files at runtime or if .a and include files are needed as well. I don't expect an answer here, since it is largely off-topic. I am interested in learning more about this stuff, so if you can recommend any resources, I would appreciate it :)

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

We're staying 0.89 for now in the win32 build, if that's an option for you.

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

Yes, orc will help resize speed too.

You don't need the .a and .so files, you can pick one or the other. I would just use .so myself, but it doesn't matter much.

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

Oh, you never need .a at runtime.

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

I'm pressing Comment too quickly.

.a are old-fashioned static libraries, .so are more modern dynamic libraries.

Static libraries are very simple bundles of code that get copied into your program when you make an executable. They are only used during compilation and just by the linker. They have a range of problems (tricky to update, tricky to link to system services, inflexible) and have mostly vanished.

Dynamic libraries are used both at compile time and at runtime. Rather than copying code into your executable, the compiler just leaves a reference to the library. At run-time, the dynamic linker automatically finds and pull in the .sofile for you. The LD_LIBRARY_PATH env var controls this process, but there's usually a default path in the executable as well.

@asterikx
Copy link
Author

asterikx commented Jul 30, 2020

I understand now. Thank you for this very good explanation 🥇

but there's usually a default path in the executable as well.

Are these controlled using flags like

CFLAGS="" CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include"  LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" cmake ... 

(because I'm unsure when I need those and when not)

I'm still facing issues with the poppler build though. It does not recognize cairo correctly.

[ 79%] Linking CXX executable pdftocairo
/opt/lib/libcairo.so: undefined reference to `FT_Done_MM_Var'
/opt/lib/libcairo.so: undefined reference to `FT_Get_Var_Design_Coordinates'
/opt/lib/libcairo.so: undefined reference to `FT_Get_Var_Blend_Coordinates'
collect2: error: ld returned 1 exit status
make[2]: *** [utils/pdftocairo] Error 1
make[1]: *** [utils/CMakeFiles/pdftocairo.dir/all] Error 2
make: *** [all] Error 2
Dockerfile snippet
# Install Poppler (http://www.linuxfromscratch.org/blfs/view/svn/general/poppler.html)
#
ENV POPPLER_VERSION=0.89.0
ENV POPPLER_BUILD_DIR=${BUILD_DIR}/poppler

RUN set -Eeuxo pipefail \
  && mkdir -p ${POPPLER_BUILD_DIR}/build \
  && curl -L https://poppler.freedesktop.org/poppler-${POPPLER_VERSION}.tar.xz \
  | tar xJC ${POPPLER_BUILD_DIR} --strip-components=1

WORKDIR ${POPPLER_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
  -DENABLE_ZLIB=ON \
  -DENABLE_LIBTIFF=ON \
  -DENABLE_LIBPNG=ON \
  -DENABLE_GLIB=ON \
  -DENABLE_CMS='lcms2' \
  -DENABLE_LIBOPENJPEG='openjpeg2' \
  -DENABLE_DCTDECODER='libjpeg' \
  -DENABLE_SPLASH=OFF \
  -DENABLE_CPP=OFF \
  && make \
  && make install
poppler configuration output
Building Poppler with support for:
  font configuration:   fontconfig
  splash output:        no
  cairo output:         yes
  qt5 wrapper:          no
  glib wrapper:         no
    introspection:      no
    gtk-doc:            no
  cpp wrapper:          no
  use libjpeg:          yes
  use libpng:           yes
  use libtiff:          yes
  use zlib compress:    yes
  use zlib uncompress:  no
  use nss3:             no
  use curl:             yes
  use libopenjpeg2:     yes
  use lcms2:            yes
  use boost:            no
  command line utils:   yes
  fuzz target:          no
  test data dir:        /tmp/build/poppler/../test
-- Configuring done

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

FT_ is freetype, the font renderer. I would guess it's picking up the headers for your freetype, but trying to link against the system freetype, which is very old and missing these features.

You don't need to generate executables like pdftocairo, I'd just disable them in the cmake config for poppler.

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

Yes, the library path is set in three ways:

  • Automatically by the compiler. If you link against /some/path/libthing.so, the compiler will note the use of the library libthing, and set /some/path as the default search path for the runtime linker for that object.
  • You can use the -rpath compiler flag to override this.
  • At run-time, you can set LD_LIBRARY_PATH anbd the paths listed there will be searched first.

It's actually more complex than this, since libraries can be versioned, but that's the general idea.

@asterikx
Copy link
Author

asterikx commented Jul 30, 2020

Perfect, thanks. I just realized that libvips requires Poppler OR Cairo. So having both is probably not necessary.

I needed to add the compiler flag LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" to the Poppler build as the Lambda environment has an old version of Cairo pre-installed which messes up things.

Unfortunately, libvips did still not pickup Poppler. Only the libpoppler.so* files were present in /opt/lib/, but no libpoppler-glib.so* files.

configure: WARNING: poppler-glib >= 0.16.0 or cairo >= 1.2 not found; disabling PDF load via poppler
checking for RSVG... no

I had a look into Poppler's CMakeList.txt. By default ENABLE_GLIB is set to ON, but there are several conditions that may set it to OFF:

if(CAIRO_FOUND)
  ...
else()
  set(CAIRO_FEATURE "#undef POPPLER_HAS_CAIRO")
  set(ENABLE_GLIB OFF)
endif()
if(ENABLE_GLIB)
  macro_optional_find_package(GLIB)
  if(NOT GLIB_FOUND)
    set(ENABLE_GLIB OFF)
  endif()
endif()
Poppler output
-- Checking for module 'cairo>=1.10.0'
--   Found cairo, version 1.12.14
-- Found Cairo: /usr/lib64/libcairo.so (Required is at least version "1.10.0") 
-- Checking for modules 'glib-2.0>=2.41;gobject-2.0>=2.41;gio-2.0>=2.41'
--   Requested 'glib-2.0 >= 2.41' but version of GLib is 2.36.3
--   Requested 'gobject-2.0 >= 2.41' but version of GObject is 2.36.3
--   Requested 'gio-2.0 >= 2.41' but version of GIO is 2.36.3
CMake Warning (dev) at /usr/local/share/cmake-3.18/Modules/FindPackageHandleStandardArgs.cmake:273 (message):
  The package name passed to `find_package_handle_standard_args` (GLib) does
  not match the name of the calling package (GLIB).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  cmake/modules/FindGLIB.cmake:24 (find_package_handle_standard_args)
  cmake/modules/MacroOptionalFindPackage.cmake:32 (find_package)
  CMakeLists.txt:171 (macro_optional_find_package)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Could NOT find GLib (missing: GLIB2_LIBRARIES GLIB2_CFLAGS) 
-- Checking for module 'lcms2'
--   Found lcms2, version 2.11
-- Found lcms version 2.06, /usr/lib64/liblcms2.so

In my case, the installed version of GLib was too old. Poppler requests version >=2.41.0 but the Lambda environment has version 2.36.3. That's why GLIB_FOUND is set to false and GLib build is disabled ...

So I had to install GLib from source too. After that libvips did finally build with Poppler support 🎉

Dockerfile (for future reference)
FROM lambci/lambda:build-go1.x AS compile-image

# See here for more build examples: https://github.com/stechstudio/libvips-lambda/tree/master/build/dependencies
# https://github.com/jeylabs/aws-lambda-poppler-layer
# https://github.com/pjfoley/poppler-for-lambda

# SHELL ["/bin/bash", "-c"]

ENV BUILD_DIR="/tmp/build"
ENV INSTALL_DIR="/opt"

# Create all necessary build directories
#
RUN set -Eeuxo pipefail \
  && mkdir -p ${BUILD_DIR}/{etc,bin,doc,include,lib,lib64,libexec,sbin,share}

# Install Development Tools
#
WORKDIR /tmp

RUN set -Eeuxo pipefail \
  && yum -y update \
  && yum -y install \
  gcc72-c++ \
  # libuuid is required by Fontconfig
  libuuid-devel \
  nasm \
  ninja-build \
  && yum -y clean all

RUN pip3 install meson

# Set GCC to 7.2.1-2 (default is 4.8.5-28 on lambci/lambda:build-go1.x image)
RUN update-alternatives --set gcc /usr/bin/gcc72


# Install CMake (http://www.linuxfromscratch.org/blfs/view/svn/general/cmake.html)
#
# Pre-installed on Amazon Linux: 2.8.12.2
# Required by: Fontconfig (Poppler)
#
ENV CMAKE3_VERSION=3.18.0
ENV CMAKE3_BUILD_DIR=${BUILD_DIR}/cmake3

RUN set -Eeuxo pipefail \
  && mkdir -p ${CMAKE3_BUILD_DIR} \
  && curl -L https://github.com/Kitware/CMake/releases/download/v${CMAKE3_VERSION}/cmake-${CMAKE3_VERSION}.tar.gz \
  | tar xzC ${CMAKE3_BUILD_DIR} --strip-components=1 \
  && curl -L http://www.linuxfromscratch.org/patches/blfs/svn/cmake-${CMAKE3_VERSION}-regression_fix-1.patch -o ${CMAKE3_BUILD_DIR}/cmake-${CMAKE3_VERSION}-regression_fix-1.patch

WORKDIR ${CMAKE3_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && patch -Np1 -i cmake-${CMAKE3_VERSION}-regression_fix-1.patch \
  && sed -i '/"lib64"/s/64//' Modules/GNUInstallDirs.cmake \
  && ./bootstrap \
  #  --prefix=/usr/local \
  --parallel=4 \
  && make V=0 \
  && make install


# Configure Default Compiler Variables
#
ENV PATH="${INSTALL_DIR}/bin:${PATH}" \
  LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" \
  PKG_CONFIG_PATH="${INSTALL_DIR}/lib64/pkgconfig:${INSTALL_DIR}/lib/pkgconfig"


# Install GLib (http://www.linuxfromscratch.org/blfs/view/svn/general/cmake.html)
#
# Pre-installed on Amazon Linux: 2.36.3
# Required by: Poppler
# Note: Amazon Linux has GLib 2.36.3 but Poppler requires >=2.41.0
#
ENV GLIB_VERSION=2.64.4
ENV GLIB_MAJOR=2.64
ENV GLIB_BUILD_DIR=${BUILD_DIR}/glib

RUN set -Eeuxo pipefail \
  && mkdir -p ${GLIB_BUILD_DIR} \
  && curl -L http://ftp.gnome.org/pub/gnome/sources/glib/${GLIB_MAJOR}/glib-${GLIB_VERSION}.tar.xz \
  | tar xJC ${GLIB_BUILD_DIR} --strip-components=1

WORKDIR ${GLIB_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && mkdir build \
  && cd build \
  && meson \
  --prefix=${INSTALL_DIR} \
  -Dselinux=disabled \
  && ninja \
  && ninja install


# Install Libpng (http://www.linuxfromscratch.org/blfs/view/svn/general/openjpeg2.html)
#
# Pre-installed on Amazon Linux: 1.2.49
# Required by: Cairo (Poppler)
# Recommended dependency of: Poppler, FreeType (Poppler)
# Optional dependency of: libvips
#
ENV LIBPNG_VERSION=1.6.37
ENV LIBPNG_BUILD_DIR=${BUILD_DIR}/libpng

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBPNG_BUILD_DIR} \
  && curl -L https://downloads.sourceforge.net/libpng/libpng-${LIBPNG_VERSION}.tar.xz \
  | tar xJC ${LIBPNG_BUILD_DIR} --strip-components=1

WORKDIR ${LIBPNG_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  && make V=0 \
  && make install


# Install LibTIFF (http://www.linuxfromscratch.org/blfs/view/svn/general/libtiff.html)
#
# Pre-installed on Amazon Linux: 4.0.3
# Optional dependency of: libvips, Poppler
#
# ENV LIBTIFF_VERSION=4.1.0
# ENV LIBTIFF_BUILD_DIR=${BUILD_DIR}/tiff

# RUN set -Eeuxo pipefail \
#   && mkdir -p ${LIBTIFF_BUILD_DIR} \
#   && curl -L http://download.osgeo.org/libtiff/tiff-${LIBTIFF_VERSION}.tar.gz \
#   | tar xzC ${LIBTIFF_BUILD_DIR} --strip-components=1

# WORKDIR ${LIBTIFF_BUILD_DIR}/

# RUN set -Eeuxo pipefail \
#   && mkdir -p libtiff-build \
#   && cd libtiff-build \
#   && cmake .. \
#   -DCMAKE_INSTALL_DOCDIR=/usr/share/doc/libtiff-4.1.0 \
#   -DCMAKE_INSTALL_PREFIX=/usr -G Ninja \
#   && ninja \
#   && ninja install


# Install Libjpeg-Turbo (http://www.linuxfromscratch.org/blfs/view/svn/general/libjpeg.html)
#
# Pre-installed on Amazon Linux: no
# Recommended dependency of: Poppler
# Optional dependency of: libvips
#
ENV LIBJPEG_TURBO_VERSION=2.0.5
ENV LIBJPEG_TURBO_BUILD_DIR=${BUILD_DIR}/libjpeg

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBJPEG_TURBO_BUILD_DIR}/build \
  && curl -L https://downloads.sourceforge.net/libjpeg-turbo/libjpeg-turbo-${LIBJPEG_TURBO_VERSION}.tar.gz \
  | tar xzC ${LIBJPEG_TURBO_BUILD_DIR} --strip-components=1

WORKDIR ${LIBJPEG_TURBO_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && cmake .. \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DCMAKE_BUILD_TYPE=RELEASE \
  -DENABLE_STATIC=FALSE \
  -DCMAKE_INSTALL_DEFAULT_LIBDIR=lib \
  && make V=0 \
  && make install


# Install libexif (http://www.linuxfromscratch.org/blfs/view/svn/general/libexif.html)
#
# Pre-installed on Amazon Linux: 0.6.21
# Optional dependency of: libvips
#
# ENV LIBEXIF_VERSION=0.6.22
# ENV LIBEXIF_VERSION_URL=0_6_22
# ENV LIBEXIF_BUILD_DIR=${BUILD_DIR}/libexif

# RUN set -Eeuxo pipefail \
#   && mkdir -p ${LIBEXIF_BUILD_DIR} \
#   && curl -L https://github.com/libexif/libexif/releases/download/libexif-${LIBEXIF_VERSION_URL}-release/libexif-${LIBEXIF_VERSION}.tar.xz \
#   | tar xJC ${LIBEXIF_BUILD_DIR} --strip-components=1

# WORKDIR ${LIBEXIF_BUILD_DIR}

# RUN set -Eeuxo pipefail \
#   && ./configure  \
#   --prefix=${INSTALL_DIR} \
#   --disable-docs \
#   --disable-static \
#   && make V=0 \
#   && make install


# Install OpenJPEG (http://www.linuxfromscratch.org/blfs/view/svn/general/openjpeg2.html)
#
# Pre-installed on Amazon Linux: no
# Recommended dependency of: Poppler
#
ENV OPENJPEG_VERSION=2.3.1
ENV OPENJPEG_BUILD_DIR=${BUILD_DIR}/openjpeg2

RUN set -Eeuxo pipefail \
  && mkdir -p ${OPENJPEG_BUILD_DIR}/build \
  && curl -L https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}/openjpeg-${OPENJPEG_VERSION}.tar.gz \
  | tar xzC ${OPENJPEG_BUILD_DIR} --strip-components=1

WORKDIR ${OPENJPEG_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  -DBUILD_STATIC_LIBS=OFF \
  && make V=0 \
  && make install


# Build libxml2 (http://www.linuxfromscratch.org/blfs/view/svn/general/libxml2.html)
#
# Pre-installed on Amazon Linux: 2.9.1
# Optional dependency of: Fontconfig (Poppler)
#
# ENV XML2_VERSION=2.9.10
# ENV XML2_BUILD_DIR=${BUILD_DIR}/libxml2

#RUN set -Eeuxo pipefail; \
#  mkdir -p ${XML2_BUILD_DIR} \
#  && curl -L http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz \
#  | tar xzC ${XML2_BUILD_DIR} --strip-components=1

# WORKDIR ${XML2_BUILD_DIR}/

# RUN set -Eeuxo pipefail \
#   && ./configure \
#   --prefix=${INSTALL_DIR} \
#   --with-sysroot=${INSTALL_DIR} \
#   --disable-static \
#   --with-history \
#   --with-icu \
#   --without-python

# RUN set -Eeuxo pipefail \
#   && make install \
#   && cp xml2-config ${INSTALL_DIR}/bin/xml2-config


# Install FreeType (http://www.linuxfromscratch.org/blfs/view/svn/general/freetype2.html)
#
# Pre-installed on Amazon Linux: 2.3.11
# Required by: Fontconfig (Poppler)
#
ENV FREETYPE_VERSION=2.10.2
ENV FREETYPE_BUILD_DIR=${BUILD_DIR}/freetype

RUN set -Eeuxo pipefail \
  && mkdir -p ${FREETYPE_BUILD_DIR} \
  && curl -L https://download-mirror.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.xz \
  | tar xJC ${FREETYPE_BUILD_DIR} --strip-components=1

WORKDIR ${FREETYPE_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && sed -ri "s:.*(AUX_MODULES.*valid):\1:" modules.cfg

RUN set -Eeuxo pipefail \
  && sed -r "s:.*(#.*SUBPIXEL_RENDERING) .*:\1:" -i include/freetype/config/ftoption.h

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --with-sysroot=${INSTALL_DIR} \
  --enable-freetype-config  \
  --disable-static \
  && make V=0 \
  && make install


# Install Harfbuzz (http://www.linuxfromscratch.org/blfs/view/svn/general/harfbuzz.html)
#
# Pre-installed on Amazon Linux: no
# Recommended dependency of: FreeType
#
ENV HARZBUFF_VERSION=2.7.0
ENV HARZBUFF_BUILD_DIR=${BUILD_DIR}/harfbuzz

RUN set -Eeuxo pipefail \
  && mkdir -p ${HARZBUFF_BUILD_DIR} \
  && curl -L https://github.com/harfbuzz/harfbuzz/archive/${HARZBUFF_VERSION}.tar.gz \
  | tar xzC ${HARZBUFF_BUILD_DIR} --strip-components=1

WORKDIR ${HARZBUFF_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && mkdir build \
  && cd build \
  && meson \
  --prefix=${INSTALL_DIR} \
  && ninja \
  && ninja install

# Now re-install FreeType

WORKDIR ${FREETYPE_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --with-sysroot=${INSTALL_DIR} \
  --enable-freetype-config  \
  --disable-static \
  && make V=0 \
  && make install


# Install Gperf (http://www.linuxfromscratch.org/blfs/view/7.4/general/gperf.html)
#
# Pre-installed on Amazon Linux: no
# Required by: Fontconfig
#
ENV GPERF_VERSION=3.1
ENV GPERF_BUILD_DIR=${BUILD_DIR}/gperf

RUN set -Eeuxo pipefail \
  && mkdir -p ${GPERF_BUILD_DIR} \
  && curl -L http://ftp.gnu.org/pub/gnu/gperf/gperf-${GPERF_VERSION}.tar.gz \
  | tar xzC ${GPERF_BUILD_DIR} --strip-components=1

WORKDIR  ${GPERF_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  && make V=0 \
  && make install


# Install Fontconfig (http://www.linuxfromscratch.org/blfs/view/svn/general/fontconfig.html)
#
# Pre-installed on Amazon Linux: 2.8.0
# Required by: Poppler
# Requires: freetype and either expat or libxml2 (http://bio.gsi.de/DOCS/SOFTWARE/fontconfig.html) - not sure if that's still the case
#
ENV FONTCONFIG_VERSION=2.13.1
ENV FONTCONFIG_BUILD_DIR=${BUILD_DIR}/fontconfig

RUN set -Eeuxo pipefail \
  && mkdir -p ${FONTCONFIG_BUILD_DIR} \
  && curl -L https://www.freedesktop.org/software/fontconfig/release/fontconfig-${FONTCONFIG_VERSION}.tar.bz2 \
  | tar xjC ${FONTCONFIG_BUILD_DIR} --strip-components=1

WORKDIR ${FONTCONFIG_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && rm -f src/fcobjshash.h

RUN set -Eeuxo pipefail \
  && LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \
  FONTCONFIG_PATH=${INSTALL_DIR} \
  ./configure  \
  --sysconfdir=${INSTALL_DIR}/etc \
  --localstatedir=${INSTALL_DIR}/var \
  --prefix=${INSTALL_DIR} \
  --disable-docs \
  # --enable-libxml2 \
  && make V=0 \
  && make install


# Install Pixman (http://www.linuxfromscratch.org/blfs/view/svn/general/pixman.html)
#
# Pre-installed on Amazon Linux: 0.32.4
# Required by: Cairo (Poppler)
#
ENV PIXMAN_VERSION=0.40.0
ENV PIXMAN_BUILD_DIR=${BUILD_DIR}/pixman

RUN set -Eeuxo pipefail \
  && mkdir -p ${PIXMAN_BUILD_DIR} \
  && curl -L https://www.cairographics.org/releases/pixman-${PIXMAN_VERSION}.tar.gz \
  | tar xzC ${PIXMAN_BUILD_DIR} --strip-components=1

WORKDIR ${PIXMAN_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && mkdir build \
  && cd build \
  && meson --prefix=${INSTALL_DIR} \
  && ninja \
  && ninja install


# Install Cairo (http://www.linuxfromscratch.org/blfs/view/svn/x/cairo.html)
#
# Pre-installed on Amazon Linux: 1.12.14
# Recommend eddependency of: Poppler
#
ENV CAIRO_VERSION=1.17.2
ENV CAIRO_BUILD_DIR=${BUILD_DIR}/cairo

RUN set -Eeuxo pipefail \
  && mkdir -p ${CAIRO_BUILD_DIR} \
  && curl -L https://cairographics.org/snapshots/cairo-${CAIRO_VERSION}.tar.xz \
  | tar xJC ${CAIRO_BUILD_DIR} --strip-components=1

WORKDIR ${CAIRO_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && autoreconf -fiv \
  && ./configure \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  --enable-tee \
  && make \
  && make install


# Install Little CMS (http://www.linuxfromscratch.org/blfs/view/svn/general/lcms2.html)
#
# Pre-installed on Amazon Linux: 2.6
# Recommended dependency of: Poppler
# Optional dependency of: libvips
#
ENV LCMS2_VERSION=2.11
ENV LCMS2_BUILD_DIR=${BUILD_DIR}/lcms

RUN set -Eeuxo pipefail \
  && mkdir -p ${LCMS2_BUILD_DIR} \
  && curl -L https://downloads.sourceforge.net/lcms/lcms2-${LCMS2_VERSION}.tar.gz \
  | tar xzC ${LCMS2_BUILD_DIR} --strip-components=1

WORKDIR ${LCMS2_BUILD_DIR}/

RUN set -Eeuxo pipefail \
  && ./configure  \
  --prefix=${INSTALL_DIR} \
  --disable-static \
  && make V=0 \
  && make install


# Install Poppler (http://www.linuxfromscratch.org/blfs/view/svn/general/poppler.html)
#
# Pre-installed on Amazon Linux: no
#
ENV POPPLER_VERSION=0.89.0
ENV POPPLER_BUILD_DIR=${BUILD_DIR}/poppler
# ENV POPPLER_TEST_DIR=${BUILD_DIR}/poppler-test

# RUN set -Eeuxo pipefail \
#   && mkdir -p ${POPPLER_TEST_DIR} \
#   && git clone git://git.freedesktop.org/git/poppler/test ${POPPLER_TEST_DIR}

RUN set -Eeuxo pipefail \
  && mkdir -p ${POPPLER_BUILD_DIR}/build \
  && curl -L https://poppler.freedesktop.org/poppler-${POPPLER_VERSION}.tar.xz \
  | tar xJC ${POPPLER_BUILD_DIR} --strip-components=1

WORKDIR ${POPPLER_BUILD_DIR}/build/

RUN set -Eeuxo pipefail \
  && CFLAGS="" \
  CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \
  LDFLAGS="-L${INSTALL_DIR}/lib64 -L${INSTALL_DIR}/lib" \
  cmake .. \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
  # -DTESTDATADIR=${POPPLER_TEST_DIR} \
  -DENABLE_UNSTABLE_API_ABI_HEADERS=ON \
  -DENABLE_CPP=OFF \
  -DENABLE_QT5=OFF \
  -DENABLE_GLIB=ON \
  -DENABLE_SPLASH=OFF \
  && make V=0 \
  && make install


# Install libimagequant
#
# Pre-installed on Amazon Linux: no
# Optional dependency of: libvips
#
# ENV LIBIMAGEQUANT_VERSION=2.12.6
# ENV LIBIMAGEQUANT_BUILD_DIR=${BUILD_DIR}/libimagequant

# RUN set -Eeuxo pipefail \
#   && mkdir -p ${LIBIMAGEQUANT_BUILD_DIR} \
#   && git clone https://github.com/ImageOptim/libimagequant.git ${LIBIMAGEQUANT_BUILD_DIR}

# WORKDIR ${LIBIMAGEQUANT_BUILD_DIR}

# RUN set -Eeuxo pipefail \
#   && ./configure \
#   --prefix=${INSTALL_DIR} && \
#   make V=0 libimagequant.so && \
#   make install


# Install orc (https://gitlab.freedesktop.org/gstreamer/orc/-/blob/master/.gitlab-ci.yml#L15)
#
# Pre-installed on Amazon Linux: no
# Optional dependency of: libvips
#
ENV ORC_VERSION=0.4.31
ENV ORC_BUILD_DIR=${BUILD_DIR}/orc

RUN set -Eeuxo pipefail \
  && mkdir -p ${ORC_BUILD_DIR} \
  && curl -L https://gstreamer.freedesktop.org/src/orc/orc-${ORC_VERSION}.tar.xz \
  | tar xJC ${ORC_BUILD_DIR} --strip-components=1

WORKDIR ${ORC_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && mkdir build \
  && cd build \
  && meson --prefix=${INSTALL_DIR} --werror \
  && ninja \
  && ninja install


# Install libvips (https://libvips.github.io/libvips/install.html)
#
# Pre-installed on Amazon Linux: no
#
ENV LIBVIPS_VERSION=8.9.2
ENV LIBVIPS_BUILD_DIR=${BUILD_DIR}/libvips

RUN set -Eeuxo pipefail \
  && mkdir -p ${LIBVIPS_BUILD_DIR} \
  && curl -L https://github.com/libvips/libvips/releases/download/v${LIBVIPS_VERSION}/vips-${LIBVIPS_VERSION}.tar.gz \
  | tar xzC ${LIBVIPS_BUILD_DIR} --strip-components=1

WORKDIR ${LIBVIPS_BUILD_DIR}

RUN set -Eeuxo pipefail \
  && ./configure --prefix=${INSTALL_DIR} \
  --without-gsf \
  --without-fftw \
  --without-magick \
  --without-OpenEXR \
  --without-nifti \
  --without-heif \
  --without-pdfium \
  --without-rsvg \
  --without-openslide \
  --without-matio \
  --without-cfitsio \
  --without-libwebp \
  --without-pangoft2 \
  --without-tiff \
  --without-giflib \
  --without-imagequant \
  --without-libexif \
  --disable-gtk-doc \
  && make V=0 \
  && make install \
  && echo /opt/lib > /etc/ld.so.conf.d/libvips.conf \
  && ldconfig


FROM lambci/lambda:build-go1.x AS runtime-image

ENV SOURCE_DIR="/opt"
ENV INSTALL_DIR="/opt"

ENV PATH="/opt/bin:${PATH}" \
  LD_LIBRARY_PATH="${INSTALL_DIR}/lib64:${INSTALL_DIR}/lib"

# Install zip
#
RUN set -Eeuxo pipefail \
  && yum update -y \
  && yum -y install zip \
  && yum -y clean all

# Copy all binaries/libaries
#
RUN set -Eeuxo pipefail \
  && mkdir -p ${INSTALL_DIR}/{etc,bin,var,share,lib}

COPY --from=compile-image /lib64/libuuid.so.* ${INSTALL_DIR}/lib/
COPY --from=compile-image ${SOURCE_DIR}/share/ /tmp/share
COPY --from=compile-image ${SOURCE_DIR}/etc/ ${INSTALL_DIR}/etc/
COPY --from=compile-image ${SOURCE_DIR}/bin/ ${INSTALL_DIR}/bin/
COPY --from=compile-image ${SOURCE_DIR}/var/ ${INSTALL_DIR}/var/
COPY --from=compile-image ${SOURCE_DIR}/lib/ ${INSTALL_DIR}/lib/
# COPY --from=compile-image ${SOURCE_DIR}/lib64/ ${INSTALL_DIR}/lib/

RUN set -Eeuxo pipefail \
  && cp -R /tmp/share/fontconfig ${INSTALL_DIR}/share/fontconfig

I'm not sure if GLib is only needed at build time or if it's needed at runtime too and if I need to copy only the shared objects to my Lambda layer or the installed programs too.

@asterikx
Copy link
Author

asterikx commented Jul 30, 2020

I'm still left a bit confused about which (optional) dependencies I should consider installing, and whether an old, pre-installed version is fine, or whether I should install the latest version to get the best performance/results. Installing the latest version will increase the size of the lambda layer and thus increase the cold start times by a bit. So it's a trade-off.

@jcupitt I know I already asked you too much, but would you mind helping me and checking the boxes that you think are worth installing.

Optional dependencies of libvips:

  • libexif 0.6.22 (most recent is 2.13.1, Lambda runtime has 0.6.21) -- not sure why libvips has not found the pre-installed version)
    • should install 2.13.1 manually
  • libgsf-1
  • libtiff (most recent is 4.1.0, Lambda runtime has 4.0.3)
    • should install 4.1.0 manually
  • fftw3
  • lcms2 (most recent is 2.11, Lambda runtime has 2.6)
    • should install 2.11
  • libpng (most recent is 1.6.37, Lambda runtime has 1.2.49)
    • should install 1.6.37 manually
  • libimagequant
  • pangoft2

Required dependencies of Poppler:

  • FontConfig (most recent is 2.13.1, Lambda runtime has 2.8.0)
    • should install 2.13.1 manually

Recommended (transitive) dependencies of Poppler:

  • Cairo (most recent is 1.17.2, Lambda runtime has 1.12.14)
    • should install 1.17.2 manually
  • NSS (most recent is 3.55, Lambda runtime has 3.44.0)
    • should install 3.55 manually
  • HarfBuzz

Optional (transitive) dependencies of Poppler:

  • Boost
  • libxml2 (most recent is 2.9.10, Lambda runtime has 2.9.1)
    • should install 2.9.10 manually
  • GPerf (EDIT: required for Poppler to build)

@jcupitt
Copy link
Member

jcupitt commented Jul 30, 2020

It depends what features you need. If you don't need to read and write TIFFs, you don't need libtiff. You'll need cairo for poppler to work, I think. lcms2 is very useful.

The AWS versions of many of these packages are very old and have known security problems. You should probably build your own.

@asterikx
Copy link
Author

asterikx commented Jul 31, 2020

Thank you so much!

My Dockerfile builds fine now.

Unfortunately, Poppler picks up the old versions. It appears as if it looks into usr/ (where it finds the old AWS versions of jpeg, zlib, png, and tiff) before looking into opt/ (where it finds cairo for example).

FreeType should be at 2.10.2, and libpng at 1.6.37.

EDIT: Not sure if that's what's going on. It uses Fontconfig 2.13.1 although 2.8.0 is pre-installed

-- Found Freetype: /usr/lib64/libfreetype.so (found version "2.3.11") 
-- Checking for module 'fontconfig'
--   Found fontconfig, version 2.13.1
-- Found Fontconfig: /usr/lib64/libfontconfig.so  
-- Found JPEG: /usr/lib64/libjpeg.so (found version "62") 
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.8") 
-- Found PNG: /usr/lib64/libpng.so (found version "1.2.49") 
-- Found TIFF: /usr/lib64/libtiff.so (found version "4.0.3") 
-- Checking for module 'nss>=3.19'
--   No package 'nss' found
-- Could NOT find NSS3 (missing: NSS3_LIBRARIES NSS3_CFLAGS) 
-- Checking for module 'cairo>=1.10.0'
--   Found cairo, version 1.17.2
-- Found Cairo: /opt/lib/libcairo.so (Required is at least version "1.10.0") 
-- Checking for modules 'glib-2.0>=2.41;gobject-2.0>=2.41;gio-2.0>=2.41'
--   Found glib-2.0, version 2.64.4
--   Found gobject-2.0, version 2.64.4
--   Found gio-2.0, version 2.64.4

Interestingly, Poppler uses version 2.64.4 of GLib that is installed in /opt even though version 2.36.3 exists in usr/ but doesn't satisfy Poppler's minimum version requirement >=2.41.0 for GLib.

For libvips I can't really tell from the logs which version it uses:

file import/export with libpng: 	yes (pkg-config libpng >= 1.2.9)
  (requires libpng-1.2.9 or later)
support 8bpp PNG quantisation:		no
  (requires libimagequant)
file import/export with libtiff:	no
file import/export with giflib:		no
file import/export with libjpeg:	yes (pkg-config)

Do you know how I can specify the correct version/paths? (I have updated the Dockerfile in my previous comment)

@jcupitt
Copy link
Member

jcupitt commented Aug 2, 2020

I tried your dockerfile again -- there's a cmake 3.18.1 now, so you don't need the patch.

libvips uses pkg-config to locate dependencies, so it'll pick up the correct versions automatically.

You need to uncomment the final copy to get the lib64 stuff into your target.

You add /usr/include to the compiler search path for poppler here:

  CPPFLAGS="-I${INSTALL_DIR}/include -I/usr/include" \

This will cause a variety of severe confusion. As a rule, don't add standard search locations with -I.

I'm not sure you need to set any -I or -L args here. I'd just rely on pkg-config.

I don't know why poppler is pickup up the wrong fontconfig etc. I think you have the .pc files and it's just not using them. I'd ask poppler.

If I run a shell in your docker during poppler config, I see:

bash-4.2# yum list installed | grep fontconfig
fontconfig.x86_64                  2.8.0-5.8.amzn1                 @amzn-main   
fontconfig-devel.x86_64            2.8.0-5.8.amzn1                 @amzn-main  
bash-4.2# pkg-config fontconfig --modversion
2.13.1
bash-4.2# pkg-config fontconfig --libs
-L/opt/lib -lfontconfig -lfreetype  
bash-4.2# cmake .. -DCMAKE_INSTALL_PREFIX=/opt
-- The C compiler identification is GNU 7.2.1
-- The CXX compiler identification is GNU 7.2.1
...
-- Checking for module 'fontconfig'
--   Found fontconfig, version 2.13.1
-- Found Fontconfig: /usr/lib64/libfontconfig.so  
...

So it finds the correct headers for fontconfig in /opt (since the version is correct), but then picks completely the wrong library binary.

I wonder a bit about the way you've built cmake: I'd try a more vanilla build I think. Just install to /usr/local and don't touch anything.

@asterikx
Copy link
Author

asterikx commented Aug 2, 2020

Thanks for your continuous help.

I followed the instructions from Linux From Scratch for building cmake:

sed ... Modules/GNUInstallDirs.cmake: This command disables applications using cmake from attempting to install files in /usr/lib64/.

I'm not sure what is the motivation for not having applications install to lib64. Since I'm copying /opt/lib and /opt/lib64, I think I can safely omit that change.

If I omit the -I args, Poppler still picks up the old versions from /usr/lib64.

If I omit the -L args, Poppler still picks up the old versions from /usr/lib64, cmake generates a bunch of warnings, and linking fails:

CMake Warning at CMakeLists.txt:535 (add_library):
  Cannot generate a safe runtime search path for target poppler because files
  in some directories may conflict with libraries in implicit directories:

    runtime library [libfreetype.so.6] in /usr/lib64 may be hidden by files in:
      /opt/lib
    runtime library [libfontconfig.so.1] in /usr/lib64 may be hidden by files in:
      /opt/lib
    runtime library [libjpeg.so.62] in /usr/lib64 may be hidden by files in:
      /opt/lib
    runtime library [liblcms2.so.2] in /usr/lib64 may be hidden by files in:
      /opt/lib

  Some of these libraries may not be found correctly.


CMake Warning at utils/CMakeLists.txt:37 (add_executable):
  Cannot generate a safe runtime search path for target pdftocairo because
  files in some directories may conflict with libraries in implicit
  directories:

    runtime library [libfreetype.so.6] in /usr/lib64 may be hidden by files in:
      /opt/lib
    runtime library [liblcms2.so.2] in /usr/lib64 may be hidden by files in:
      /opt/lib

  Some of these libraries may not be found correctly.


CMake Warning at glib/CMakeLists.txt:89 (add_library):
  Cannot generate a safe runtime search path for target poppler-glib because
  files in some directories may conflict with libraries in implicit
  directories:

    runtime library [libfreetype.so.6] in /usr/lib64 may be hidden by files in:
      /opt/lib

  Some of these libraries may not be found correctly.
[ 70%] Linking CXX executable pdftocairo
/opt/lib64/libharfbuzz.so.0: undefined reference to `FT_Reference_Face'
/opt/lib/libcairo.so: undefined reference to `FT_Done_MM_Var'
/opt/lib/libcairo.so: undefined reference to `FT_Get_Var_Design_Coordinates'
/opt/lib/libcairo.so: undefined reference to `FT_Get_Var_Blend_Coordinates'
collect2: error: ld returned 1 exit status
make[2]: *** [utils/pdftocairo] Error 1
make[1]: *** [utils/CMakeFiles/pdftocairo.dir/all] Error 2
make: *** [all] Error 2

I have changed my cmake build to ./configure && make && make install so cmake should not be causing these issues.

@asterikx
Copy link
Author

asterikx commented Aug 3, 2020

@jcupitt FYI: I filed an issue at the Poppler repo: https://gitlab.freedesktop.org/poppler/poppler/-/issues/948#note_587049

I'm still confused. There, I'm told that libpng is not using pkg-config and that my problem is not related to Poppler but likely to cmake.

@jcupitt
Copy link
Member

jcupitt commented Aug 3, 2020

libpng has installed libpng.pc (the pkg-config file for finding libpng) for a long time, since 2002, I think. Before then, you had to search for it. Perhaps poppler is still using the old search method? libvips finds libpng using pkg-config first, then if that fails, falls back to searching.

@jcupitt
Copy link
Member

jcupitt commented Aug 3, 2020

I had a read, and cmake will not use pkg-config unless you explicitly ask it to. It's because it has to work on platforms like Windows where pkg-config is not always available.

Instead, it has a complex thing to find libpng:

https://github.com/Kitware/CMake/blob/master/Modules/FindPNG.cmake

You can set the path that these FindXXXX.cmake programs search with eg. -DCMAKE_PREFIX_PATH=/opt, so I would try adding that to your cmake line for poppler.

@asterikx
Copy link
Author

asterikx commented Aug 3, 2020

@jcupitt it works!!! Thank you so much!

I can even do away with the -L and -I flags that I needed before.

Do you take contributions somewhere? I would like to buy you a coffee.

@jcupitt
Copy link
Member

jcupitt commented Aug 3, 2020

Oh, that's great!

There's a "sponsor" button at the top of the page, if you're feeling generous.

@asterikx asterikx closed this as completed Aug 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants