mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-23 00:02:38 -05:00
258 lines
8.8 KiB
Bash
Executable File
258 lines
8.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Script to build QGIS inside the qgis-build-deps-mingw.dockerfile Docker container
|
|
# Run from QGIS root directory with:
|
|
# docker run --rm -w /QGIS -v $(pwd):/QGIS elpaso/qgis-deps-mingw:latest /QGIS/ms-windows/mingw/build.sh
|
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
arch=${1:-x86_64}
|
|
DEBUG=false
|
|
if [ "$2" == "debug" ]; then
|
|
DEBUG=true
|
|
fi
|
|
|
|
njobs=${3:-$(($(grep -c ^processor /proc/cpuinfo) * 3 / 2))}
|
|
|
|
|
|
if [ "$arch" == "i686" ]; then
|
|
bits=32
|
|
elif [ "$arch" == "x86_64" ]; then
|
|
bits=64
|
|
else
|
|
echo "Error: unrecognized architecture $arch"
|
|
exit 1
|
|
fi
|
|
|
|
# Do copies instead of links if building inside container
|
|
if [ -f /.dockerenv ]; then
|
|
lnk() {
|
|
cp -aL "$1" "$2"
|
|
}
|
|
else
|
|
lnk() {
|
|
ln -sf "$1" "$2"
|
|
}
|
|
fi
|
|
|
|
# Note: This script is written to be used with the Fedora mingw environment
|
|
MINGWROOT=/usr/$arch-w64-mingw32/sys-root/mingw
|
|
|
|
if $DEBUG; then
|
|
optflags="-O0 -g1 -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -fno-omit-frame-pointer"
|
|
buildtype="Debug"
|
|
else
|
|
optflags="-O2 -g1 -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -fno-omit-frame-pointer"
|
|
buildtype="RelWithDebugInfo"
|
|
fi
|
|
pyver=$(mingw${bits}-python3 -c "import sys; print('.'.join(list(map(str, sys.version_info))[0:2]))")
|
|
|
|
# Halt on errors
|
|
set -e
|
|
|
|
export MINGW32_CFLAGS="$optflags"
|
|
export MINGW32_CXXFLAGS="$optflags"
|
|
export MINGW64_CFLAGS="$optflags"
|
|
export MINGW64_CXXFLAGS="$optflags"
|
|
|
|
SRCDIR="$(readlink -f "$(dirname "$(readlink -f "$0")")/../..")"
|
|
|
|
if $DEBUG; then
|
|
BUILDDIR="$SRCDIR/build_mingw${bits}_debug"
|
|
else
|
|
BUILDDIR="$SRCDIR/build_mingw${bits}"
|
|
fi
|
|
installroot="$BUILDDIR/dist"
|
|
installprefix="$installroot/usr/$arch-w64-mingw32/sys-root/mingw"
|
|
|
|
# Cleanup
|
|
rm -rf "$installroot"
|
|
|
|
# Build
|
|
mkdir -p $BUILDDIR
|
|
(
|
|
cd $BUILDDIR
|
|
qsci_ver=$(grep -Eo '\s*([0-9]+\.[0-9]+\.[0-9]+)' $MINGWROOT/include/qt5/Qsci/qsciglobal.h)
|
|
mingw$bits-cmake \
|
|
-DCMAKE_CROSS_COMPILING=1 \
|
|
-DCMAKE_BUILD_TYPE=$buildtype \
|
|
-DNATIVE_CRSSYNC_BIN=$(readlink -f $SRCDIR)/build/output/bin/crssync \
|
|
-DQSCINTILLA_VERSION_STR=$qsci_ver \
|
|
-DQSCINTILLA_LIBRARY=$MINGWROOT/lib/libqscintilla2_qt5.dll.a \
|
|
-DQSCI_MOD_VERSION_STR=$qsci_ver \
|
|
-DQWT_INCLUDE_DIR=$MINGWROOT/include/qt5/qwt \
|
|
-DQSCI_SIP_DIR=$MINGWROOT/share/sip/PyQt5/Qsci/ \
|
|
-DBUILD_TESTING=OFF \
|
|
-DENABLE_TESTS=OFF \
|
|
-DQGIS_BIN_SUBDIR=bin \
|
|
-DQGIS_CGIBIN_SUBDIR=bin \
|
|
-DQGIS_LIB_SUBDIR=lib \
|
|
-DQGIS_LIBEXEC_SUBDIR=lib/qgis \
|
|
-DQGIS_DATA_SUBDIR=share/qgis \
|
|
-DQGIS_PLUGIN_SUBDIR=lib/qgis/plugins \
|
|
-DQGIS_INCLUDE_SUBDIR=include/qgis \
|
|
-DQGIS_SERVER_MODULE_SUBDIR=lib/qgis/server \
|
|
-DQGIS_QML_SUBDIR=lib/qt5/qml \
|
|
-DBINDINGS_GLOBAL_INSTALL=ON \
|
|
-DWITH_SERVER=OFF \
|
|
-DTXT2TAGS_EXECUTABLE= \
|
|
..
|
|
)
|
|
|
|
# Compile native crssync
|
|
# mkdir -p $BUILDDIR/native_crssync
|
|
# (
|
|
# cd $BUILDDIR/native_crssync
|
|
# echo "Building native crssync..."
|
|
# moc-qt5 $SRCDIR/src/core/qgsapplication.h > moc_qgsapplication.cpp
|
|
# g++ $optflags -fPIC -o crssync $SRCDIR/src/crssync/main.cpp $SRCDIR/src/crssync/qgscrssync.cpp moc_qgsapplication.cpp $SRCDIR/src/core/qgsapplication.cpp -DCORE_EXPORT= -DCOMPILING_CRSSYNC -I$SRCDIR/src/core/ -I$SRCDIR/src/core/geometry -I$BUILDDIR $(pkg-config --cflags --libs Qt5Widgets gdal sqlite3 proj)
|
|
# )
|
|
# crssync needs X at runtime
|
|
# Xvfb :99 &
|
|
# export DISPLAY=:99
|
|
|
|
mingw$bits-make -C$BUILDDIR -j$njobs DESTDIR="${installroot}" install VERBOSE=1
|
|
|
|
# Remove plugins with missing dependencies
|
|
rm -rf ${installroot}/share/qgis/python/plugins/{MetaSearch,processing}
|
|
|
|
# Strip debuginfo
|
|
binaries=$(find $installprefix -name '*.exe' -or -name '*.dll' -or -name '*.pyd')
|
|
for f in $binaries
|
|
do
|
|
case $(mingw-objdump -h $f 2>/dev/null | egrep -o '(debug[\.a-z_]*|gnu.version)') in
|
|
*debuglink*) continue ;;
|
|
*debug*) ;;
|
|
*gnu.version*)
|
|
echo "WARNING: $(basename $f) is already stripped!"
|
|
continue
|
|
;;
|
|
*) continue ;;
|
|
esac
|
|
|
|
echo extracting debug info from $f
|
|
mingw-objcopy --only-keep-debug $f $f.debug || :
|
|
pushd $(dirname $f)
|
|
keep_symbols=`mktemp`
|
|
mingw-nm $f.debug --format=sysv --defined-only | awk -F \| '{ if ($4 ~ "Function") print $1 }' | sort > "$keep_symbols"
|
|
mingw-objcopy --add-gnu-debuglink=`basename $f.debug` --strip-unneeded `basename $f` --keep-symbols="$keep_symbols" || :
|
|
rm -f "$keep_symbols"
|
|
popd
|
|
done
|
|
|
|
# Collect dependencies
|
|
function isnativedll {
|
|
# If the import library exists but not the dynamic library, the dll ist most likely a native one
|
|
local lower=${1,,}
|
|
[ ! -e $MINGWROOT/bin/$1 ] && [ -f $MINGWROOT/lib/lib${lower/%.*/.a} ] && return 0;
|
|
return 1;
|
|
}
|
|
|
|
function linkDep {
|
|
# Link the specified binary dependency and it's dependencies
|
|
local indent=$3
|
|
local destdir="$installprefix/${2:-bin}"
|
|
local name="$(basename $1)"
|
|
test -e "$destdir/$name" && return 0
|
|
test -e "$destdir/qgisplugins/$name" && return 0
|
|
echo "${indent}${1}"
|
|
[ ! -e "$MINGWROOT/$1" ] && echo "Error: missing $MINGWROOT/$1" && return 1
|
|
mkdir -p "$destdir" || return 1
|
|
lnk "$MINGWROOT/$1" "$destdir/$name" || return 1
|
|
echo "${2:-bin}/$name: $(rpm -qf "$MINGWROOT/$1")" >> $installprefix/origins.txt
|
|
autoLinkDeps "$destdir/$name" "${indent} " || return 1
|
|
[ -e "$MINGWROOT/$1.debug" ] && lnk "$MINGWROOT/$1.debug" "$destdir/$name.debug" || ($debug && echo "Warning: missing $name.debug" || :)
|
|
return 0
|
|
}
|
|
|
|
function autoLinkDeps {
|
|
# Collects and links the dependencies of the specified binary
|
|
for dep in $(mingw-objdump -p "$1" | grep "DLL Name" | awk '{print $3}'); do
|
|
if ! isnativedll "$dep"; then
|
|
# HACK fix incorrect libpq case
|
|
dep=${dep/LIBPQ/libpq}
|
|
linkDep bin/$dep bin "$2" || return 1
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
# Install python libs
|
|
(
|
|
cd $MINGWROOT
|
|
SAVEIFS=$IFS
|
|
IFS=$(echo -en "\n\b")
|
|
for file in $(find lib/python${pyver} -type f); do
|
|
mkdir -p "$installprefix/$(dirname $file)"
|
|
lnk "$MINGWROOT/$file" "$installprefix/$file"
|
|
done
|
|
IFS=$SAVEIFS
|
|
)
|
|
|
|
echo "Linking dependencies..."
|
|
binaries=$(find $installprefix -name '*.exe' -or -name '*.dll' -or -name '*.pyd')
|
|
for binary in $binaries; do
|
|
autoLinkDeps $binary
|
|
done
|
|
linkDep bin/gdb.exe
|
|
linkDep bin/python3.exe
|
|
linkDep bin/python3w.exe
|
|
|
|
linkDep $(ls $MINGWROOT/bin/libssl-*.dll | sed "s|$MINGWROOT/||")
|
|
linkDep $(ls $MINGWROOT/bin/libcrypto-*.dll | sed "s|$MINGWROOT/||")
|
|
linkDep lib/mod_spatialite.dll bin
|
|
|
|
# Additional dependencies
|
|
linkDep lib/qt5/plugins/imageformats/qgif.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qicns.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qico.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qjp2.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qjpeg.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qtga.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qtiff.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qwbmp.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qwebp.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/imageformats/qsvg.dll bin/imageformats
|
|
linkDep lib/qt5/plugins/platforms/qwindows.dll bin/platforms
|
|
linkDep lib/qt5/plugins/printsupport/windowsprintersupport.dll bin/printsupport
|
|
linkDep lib/qt5/plugins/styles/qwindowsvistastyle.dll bin/styles
|
|
linkDep lib/qt5/plugins/audio/qtaudio_windows.dll bin/audio
|
|
linkDep lib/qt5/plugins/mediaservice/dsengine.dll bin/mediaservice
|
|
linkDep lib/qt5/plugins/mediaservice/qtmedia_audioengine.dll bin/mediaservice
|
|
linkDep lib/qt5/plugins/sqldrivers/qsqlite.dll bin/sqldrivers
|
|
linkDep lib/qt5/plugins/sqldrivers/qsqlodbc.dll bin/sqldrivers
|
|
linkDep lib/qt5/plugins/sqldrivers/qsqlpsql.dll bin/sqldrivers
|
|
|
|
linkDep lib/qt5/plugins/crypto/libqca-gcrypt.dll bin/crypto
|
|
linkDep lib/qt5/plugins/crypto/libqca-logger.dll bin/crypto
|
|
linkDep lib/qt5/plugins/crypto/libqca-softstore.dll bin/crypto
|
|
linkDep lib/qt5/plugins/crypto/libqca-gnupg.dll bin/crypto
|
|
linkDep lib/qt5/plugins/crypto/libqca-ossl.dll bin/crypto
|
|
|
|
mkdir -p $installprefix/share/qt5/translations/
|
|
cp -a $MINGWROOT/share/qt5/translations/qt_*.qm $installprefix/share/qt5/translations
|
|
cp -a $MINGWROOT/share/qt5/translations/qtbase_*.qm $installprefix/share/qt5/translations
|
|
|
|
# Data files
|
|
mkdir -p $installprefix/share/
|
|
cp -a /usr/share/gdal $installprefix/share/gdal
|
|
cp -a /usr/share/proj $installprefix/share/proj
|
|
|
|
# Sort origins file
|
|
cat $installprefix/origins.txt | sort | uniq > $installprefix/origins.new && mv $installprefix/origins.new $installprefix/origins.txt
|
|
|
|
# Create package
|
|
DISTROOT=build_mingw64/dist/usr/x86_64-w64-mingw32/sys-root/mingw
|
|
DEBUGROOT=dist_debug
|
|
for file in $(find $DISTROOT -name '*.debug' \( -type l -or -type f \)); do
|
|
dest=${file/$DISTROOT/$DEBUGROOT}
|
|
mkdir -p "$(dirname $dest)"
|
|
sudo mv "$file" "$dest"
|
|
done
|
|
|
|
sudo mv $DISTROOT QGIS-Portable
|
|
zip -r qgis-portable-win64.zip QGIS-Portable
|
|
(cd $DEBUGROOT && zip -r - *) > qgis-portable-win64-debugsym.zip
|
|
|