1## 2# osgeo/gdal:alpine-normal 3 4# This file is available at the option of the licensee under: 5# Public domain 6# or licensed under X/MIT (LICENSE.TXT) Copyright 2019 Even Rouault <even.rouault@spatialys.com> 7 8ARG ALPINE_VERSION=3.13 9FROM alpine:${ALPINE_VERSION} as builder 10 11# Derived from osgeo/proj by Howard Butler <howard@hobu.co> 12LABEL maintainer="Even Rouault <even.rouault@spatialys.com>" 13 14# Setup build env for PROJ 15RUN apk add --no-cache wget curl unzip make libtool autoconf automake pkgconfig g++ sqlite sqlite-dev 16 17ARG PROJ_DATUMGRID_LATEST_LAST_MODIFIED 18RUN \ 19 mkdir -p /build_projgrids/usr/share/proj \ 20 && curl -LOs http://download.osgeo.org/proj/proj-datumgrid-latest.zip \ 21 && unzip -q -j -u -o proj-datumgrid-latest.zip -d /build_projgrids/usr/share/proj \ 22 && rm -f *.zip 23 24# For PROJ and GDAL 25ARG POPPLER_DEV=poppler-dev 26RUN apk add --no-cache \ 27 linux-headers \ 28 curl-dev tiff-dev \ 29 zlib-dev zstd-dev \ 30 libjpeg-turbo-dev libpng-dev openjpeg-dev libwebp-dev expat-dev \ 31 py3-numpy-dev python3-dev py3-numpy \ 32 ${POPPLER_DEV} postgresql-dev \ 33 openexr-dev libheif-dev xerces-c-dev geos-dev cfitsio-dev \ 34 netcdf-dev hdf5-dev freexl-dev \ 35 # For spatialite (and GDAL) 36 libxml2-dev \ 37 && mkdir -p /build_thirdparty/usr/lib 38 39# Build szip 40ARG SZIP_VERSION=2.1.1 41RUN if test "${SZIP_VERSION}" != ""; then ( \ 42 wget -q https://support.hdfgroup.org/ftp/lib-external/szip/${SZIP_VERSION}/src/szip-${SZIP_VERSION}.tar.gz \ 43 && tar xzf szip-${SZIP_VERSION}.tar.gz \ 44 && rm -f szip-${SZIP_VERSION}.tar.gz \ 45 && cd szip-${SZIP_VERSION} \ 46 && CFLAGS=-O2 ./configure --prefix=/usr --disable-static \ 47 && make -j$(nproc) \ 48 && make install \ 49 && cp -P /usr/lib/libsz*.so* /build_thirdparty/usr/lib \ 50 && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 51 && cd .. \ 52 && rm -rf szip-${SZIP_VERSION} \ 53 ); fi 54 55# Build hdf4 56ARG HDF4_VERSION=4.2.15 57RUN if test "${HDF4_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ 58 apk add --no-cache byacc flex portablexdr-dev \ 59 && mkdir hdf4 \ 60 && wget -q https://support.hdfgroup.org/ftp/HDF/releases/HDF${HDF4_VERSION}/src/hdf-${HDF4_VERSION}.tar.gz -O - \ 61 | tar xz -C hdf4 --strip-components=1 \ 62 && cd hdf4 \ 63 && LDFLAGS=-lportablexdr ./configure --prefix=/usr --enable-shared --disable-static \ 64 --with-szlib=/usr --disable-fortran --disable-netcdf \ 65 && make -j$(nproc) \ 66 && make install \ 67 && cp -P /usr/lib/libdf*.so* /build_thirdparty/usr/lib \ 68 && cp -P /usr/lib/libmfhdf*.so* /build_thirdparty/usr/lib \ 69 && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 70 && cd .. \ 71 && rm -rf hdf4 \ 72 && apk del byacc flex portablexdr-dev \ 73 ); fi 74 75# Build likbkea 76ARG KEA_VERSION=1.4.13 77RUN if test "${KEA_VERSION}" != ""; then ( \ 78 apk add --no-cache cmake \ 79 && wget -q https://github.com/ubarsc/kealib/archive/kealib-${KEA_VERSION}.zip \ 80 && unzip -q kealib-${KEA_VERSION}.zip \ 81 && rm -f kealib-${KEA_VERSION}.zip \ 82 && cd kealib-kealib-${KEA_VERSION} \ 83 && cmake . -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release \ 84 -DCMAKE_INSTALL_PREFIX=/usr -DHDF5_INCLUDE_DIR=/usr/include/hdf5 \ 85 -DHDF5_LIB_PATH=/usr/lib -DLIBKEA_WITH_GDAL=OFF \ 86 && make -j$(nproc) \ 87 && make install \ 88 && cd .. \ 89 && rm -rf kealib-kealib-${KEA_VERSION} \ 90 && cp -P /usr/lib/libkea*.so* /build_thirdparty/usr/lib \ 91 && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 92 && apk del cmake \ 93 ); fi 94 95# Build openjpeg 96# ARG OPENJPEG_VERSION=2.3.1 97RUN if test "${OPENJPEG_VERSION}" != ""; then ( \ 98 apk add --no-cache cmake \ 99 && wget -q https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz \ 100 && tar xzf v${OPENJPEG_VERSION}.tar.gz \ 101 && rm -f v${OPENJPEG_VERSION}.tar.gz \ 102 && cd openjpeg-${OPENJPEG_VERSION} \ 103 && cmake . -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -DCMAKE_BUILD_TYPE=Release \ 104 -DCMAKE_INSTALL_PREFIX=/usr \ 105 && make -j$(nproc) \ 106 && make install \ 107 && rm -f /usr/lib/libopenjp2.so.2.3.0 \ 108 && cp -P /usr/lib/libopenjp2*.so* /build_thirdparty/usr/lib \ 109 && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 110 && cd .. \ 111 && rm -rf openjpeg-${OPENJPEG_VERSION} \ 112 && apk del cmake \ 113 ); fi 114 115# Build libdeflate 116ARG LIBDEFLATE_VERSION=1.7 117RUN if test "${LIBDEFLATE_VERSION}" != ""; then ( \ 118 mkdir libdeflate \ 119 && wget -q https://github.com/ebiggers/libdeflate/archive/v${LIBDEFLATE_VERSION}.tar.gz -O - \ 120 | tar xz -C libdeflate --strip-components=1 \ 121 && cd libdeflate \ 122 && make -j$(nproc) PREFIX=/usr install \ 123 && cp -P /usr/lib/libdeflate.so* /build_thirdparty/usr/lib \ 124 && for i in /build_thirdparty/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 125 && cd .. \ 126 && rm -rf libdeflate \ 127 ); fi 128 129RUN apk add --no-cache rsync ccache 130ARG RSYNC_REMOTE 131 132# Build PROJ 133ARG PROJ_VERSION=master 134RUN mkdir proj \ 135 && wget -q https://github.com/OSGeo/PROJ/archive/${PROJ_VERSION}.tar.gz -O - \ 136 | tar xz -C proj --strip-components=1 \ 137 && cd proj \ 138 && ./autogen.sh \ 139 && if test "${RSYNC_REMOTE}" != ""; then \ 140 echo "Downloading cache..."; \ 141 rsync -ra ${RSYNC_REMOTE}/proj/ $HOME/; \ 142 echo "Finished"; \ 143 export CC="ccache gcc"; \ 144 export CXX="ccache g++"; \ 145 export PROJ_DB_CACHE_DIR="$HOME/.ccache"; \ 146 ccache -M 100M; \ 147 fi \ 148 && ./configure --prefix=/usr --disable-static --enable-lto \ 149 && make -j$(nproc) \ 150 && make install \ 151 && make install DESTDIR="/build_proj" \ 152 && if test "${RSYNC_REMOTE}" != ""; then \ 153 ccache -s; \ 154 echo "Uploading cache..."; \ 155 rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/proj/; \ 156 echo "Finished"; \ 157 rm -rf $HOME/.ccache; \ 158 unset CC; \ 159 unset CXX; \ 160 fi \ 161 && cd .. \ 162 && rm -rf proj \ 163 && for i in /build_proj/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 164 && for i in /build_proj/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done 165 166# Build spatialite 167ARG SPATIALITE_VERSION=5.0.1 168RUN if test "${SPATIALITE_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then ( \ 169 wget -q http://www.gaia-gis.it/gaia-sins/libspatialite-${SPATIALITE_VERSION}.tar.gz \ 170 && tar xzf libspatialite-${SPATIALITE_VERSION}.tar.gz \ 171 && rm -f libspatialite-${SPATIALITE_VERSION}.tar.gz \ 172 && cd libspatialite-${SPATIALITE_VERSION} \ 173 && apk add --no-cache minizip-dev \ 174 && if test "${RSYNC_REMOTE}" != ""; then \ 175 echo "Downloading cache..."; \ 176 rsync -ra ${RSYNC_REMOTE}/spatialite/ $HOME/; \ 177 echo "Finished"; \ 178 export CC="ccache gcc"; \ 179 export CXX="ccache g++"; \ 180 ccache -M 100M; \ 181 fi \ 182 && ./configure --prefix=/usr --disable-static --disable-rttopo \ 183 && make -j$(nproc) \ 184 && make install \ 185 && if test "${RSYNC_REMOTE}" != ""; then \ 186 ccache -s; \ 187 echo "Uploading cache..."; \ 188 rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/spatialite/; \ 189 echo "Finished"; \ 190 rm -rf $HOME/.ccache; \ 191 unset CC; \ 192 unset CXX; \ 193 fi \ 194 && mkdir -p /build_spatialite/usr/lib \ 195 && cp -P /usr/lib/libspatialite*.so* /build_spatialite/usr/lib \ 196 && for i in /build_spatialite/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 197 && cd .. \ 198 && rm -rf libspatialite-${SPATIALITE_VERSION} \ 199 ); else \ 200 mkdir -p /build_spatialite/usr/lib; \ 201 fi 202 203# Build GDAL 204ARG GDAL_VERSION=master 205ARG GDAL_RELEASE_DATE 206ARG GDAL_BUILD_IS_RELEASE 207RUN if test "${GDAL_VERSION}" = "master"; then \ 208 export GDAL_VERSION=$(curl -Ls https://api.github.com/repos/OSGeo/gdal/commits/HEAD -H "Accept: application/vnd.github.VERSION.sha"); \ 209 export GDAL_RELEASE_DATE=$(date "+%Y%m%d"); \ 210 fi \ 211 && if test "x${GDAL_BUILD_IS_RELEASE}" = "x"; then \ 212 export GDAL_SHA1SUM=${GDAL_VERSION}; \ 213 fi \ 214 && export GDAL_EXTRA_ARGS="" \ 215 && export GDAL_EXTRA_ARGS="--with-geos ${GDAL_EXTRA_ARGS}" \ 216 && if test "${XERCESC_VERSION}" != ""; then \ 217 export GDAL_EXTRA_ARGS="--with-xerces ${GDAL_EXTRA_ARGS}"; \ 218 fi \ 219 && if test "${HDF4_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then \ 220 apk add --no-cache portablexdr-dev \ 221 && export LDFLAGS="-lportablexdr ${LDFLAGS}" \ 222 && export GDAL_EXTRA_ARGS="--with-hdf4 ${GDAL_EXTRA_ARGS}"; \ 223 fi \ 224 && export GDAL_EXTRA_ARGS="--with-hdf5 ${GDAL_EXTRA_ARGS}" \ 225 && export GDAL_EXTRA_ARGS="--with-netcdf ${GDAL_EXTRA_ARGS}" \ 226 && if test "${SPATIALITE_VERSION}" != "" -a "$(uname -m)" = "x86_64"; then \ 227 export GDAL_EXTRA_ARGS="--with-spatialite ${GDAL_EXTRA_ARGS}"; \ 228 fi \ 229 && if test "${POPPLER_DEV}" != ""; then \ 230 export GDAL_EXTRA_ARGS="--with-poppler ${GDAL_EXTRA_ARGS}"; \ 231 fi \ 232 && echo ${GDAL_EXTRA_ARGS} \ 233 && mkdir gdal \ 234 && wget -q https://github.com/OSGeo/gdal/archive/${GDAL_VERSION}.tar.gz -O - \ 235 | tar xz -C gdal --strip-components=1 \ 236 && cd gdal/gdal \ 237 && if test "${RSYNC_REMOTE}" != ""; then \ 238 echo "Downloading cache..."; \ 239 rsync -ra ${RSYNC_REMOTE}/gdal/ $HOME/; \ 240 echo "Finished"; \ 241 # Little trick to avoid issues with Python bindings 242 printf "#!/bin/sh\nccache gcc \$*" > ccache_gcc.sh; \ 243 chmod +x ccache_gcc.sh; \ 244 printf "#!/bin/sh\nccache g++ \$*" > ccache_g++.sh; \ 245 chmod +x ccache_g++.sh; \ 246 export CC=$PWD/ccache_gcc.sh; \ 247 export CXX=$PWD/ccache_g++.sh; \ 248 ccache -M 1G; \ 249 fi \ 250 && ./configure --prefix=/usr --without-libtool \ 251 --with-hide-internal-symbols \ 252 --with-proj=/usr \ 253 --with-libtiff=internal --with-rename-internal-libtiff-symbols \ 254 --with-geotiff=internal --with-rename-internal-libgeotiff-symbols \ 255 # --enable-lto 256 ${GDAL_EXTRA_ARGS} \ 257 --with-python \ 258 && make -j$(nproc) \ 259 && make install DESTDIR="/build" \ 260 && (cd apps && make -j$(nproc) multireadtest && cp multireadtest /build/usr/bin) \ 261 && if test "${RSYNC_REMOTE}" != ""; then \ 262 ccache -s; \ 263 echo "Uploading cache..."; \ 264 rsync -ra --delete $HOME/.ccache ${RSYNC_REMOTE}/gdal/; \ 265 echo "Finished"; \ 266 rm -rf $HOME/.ccache; \ 267 unset CC; \ 268 unset CXX; \ 269 fi \ 270 && cd ../.. \ 271 && rm -rf gdal \ 272 && mkdir -p /build_gdal_python/usr/lib \ 273 && mkdir -p /build_gdal_python/usr/bin \ 274 && mkdir -p /build_gdal_version_changing/usr/include \ 275 && mv /build/usr/lib/python3.8 /build_gdal_python/usr/lib \ 276 && mv /build/usr/lib /build_gdal_version_changing/usr \ 277 && mv /build/usr/include/gdal_version.h /build_gdal_version_changing/usr/include \ 278 && mv /build/usr/bin/*.py /build_gdal_python/usr/bin \ 279 && mv /build/usr/bin /build_gdal_version_changing/usr \ 280 && for i in /build_gdal_version_changing/usr/lib/*; do strip -s $i 2>/dev/null || /bin/true; done \ 281 && for i in /build_gdal_python/usr/lib/python3.8/site-packages/osgeo/*.so; do strip -s $i 2>/dev/null || /bin/true; done \ 282 && for i in /build_gdal_version_changing/usr/bin/*; do strip -s $i 2>/dev/null || /bin/true; done \ 283 # Remove resource files of uncompiled drivers 284 && (for i in \ 285 # unused 286 /build/usr/share/gdal/*.svg \ 287 # unused 288 /build/usr/share/gdal/*.png \ 289 ;do rm $i; done) 290 291# Build final image 292FROM alpine:${ALPINE_VERSION} as runner 293 294RUN date 295 296ARG POPPLER=poppler 297RUN apk add --no-cache \ 298 libstdc++ \ 299 sqlite-libs \ 300 libcurl tiff \ 301 zlib zstd-libs\ 302 libjpeg-turbo libpng libwebp expat \ 303 icu-libs \ 304 python3 py3-numpy ${POPPLER} pcre libpq libxml2 portablexdr openjpeg \ 305 netcdf hdf5 freexl \ 306 openexr libheif xerces-c geos cfitsio minizip \ 307 # Remove /usr/lib/libopenjp2.so.2.3.0 since we are building v2.3.1 manually 308 # && rm -f /usr/lib/libopenjp2.so.2.3.0 \ 309 # libturbojpeg.so is not used by GDAL. Only libjpeg.so* 310 && rm -f /usr/lib/libturbojpeg.so* \ 311 # libpoppler-cpp.so is not used by GDAL. Only libpoppler.so* 312 && rm -f /usr/lib/libpoppler-cpp.so* \ 313 # Only libwebp.so is used by GDAL 314 && rm -f /usr/lib/libwebpmux.so* /usr/lib/libwebpdemux.so* /usr/lib/libwebpdecoder.so* \ 315 && ln -s /usr/bin/python3 /usr/bin/python 316 317# Order layers starting with less frequently varying ones 318COPY --from=builder /build_thirdparty/usr/ /usr/ 319 320COPY --from=builder /build_projgrids/usr/ /usr/ 321 322COPY --from=builder /build_spatialite/usr/ /usr/ 323 324COPY --from=builder /build_proj/usr/share/proj/ /usr/share/proj/ 325COPY --from=builder /build_proj/usr/include/ /usr/include/ 326COPY --from=builder /build_proj/usr/bin/ /usr/bin/ 327COPY --from=builder /build_proj/usr/lib/ /usr/lib/ 328 329COPY --from=builder /build/usr/share/gdal/ /usr/share/gdal/ 330COPY --from=builder /build/usr/include/ /usr/include/ 331COPY --from=builder /build_gdal_python/usr/ /usr/ 332COPY --from=builder /build_gdal_version_changing/usr/ /usr/ 333