Skip to content
Permalink
Browse files

mxe -> fedora mingw64 from Sourcepole

Replace MXE with fedora mingw64 cross build recipe with python.

Thanks to Sandro Mani!
  • Loading branch information
elpaso committed Feb 19, 2021
1 parent ce4ce5d commit faed480a736046c0a19727c203b9ca64ad7320a5
@@ -0,0 +1,255 @@
#!/bin/bash
# Script to build QGIS inside the qgis-build-deps-mingw.dockerfile Docker container
# Run from QGIS root dirctory 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 \
-DZSTD_INCLUDE_DIR=/usr/x86_64-w64-mingw32/sys-root/mingw/include/zstd/ \
-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

@@ -0,0 +1,97 @@
# MinGW build environment for QGIS / KADAS Albireo

FROM fedora:rawhide

MAINTAINER Sandro Mani <manisandro@gmail.com>

RUN \
echo all > /etc/rpm/macros.image-language-conf && \
rm -f /etc/yum.repos.d/*modular* && \
dnf install -y 'dnf-command(config-manager)' && \
dnf config-manager --add-repo https://copr.fedorainfracloud.org/coprs/smani/mingw-extras/repo/fedora-rawhide/smani-mingw-extras-fedora-rawhide.repo && \
dnf install -y --nogpgcheck \
mingw64-dlfcn \
mingw64-exiv2 \
mingw64-gcc-c++ \
mingw64-gdal \
mingw64-gdb \
mingw64-GdbCrashHandler \
mingw64-GeographicLib \
mingw64-geos \
mingw64-gsl \
mingw64-libgomp \
mingw64-libzip \
mingw64-osgearth-qt5 \
mingw64-pacparser \
mingw64-postgresql \
mingw64-proj \
mingw64-python3 \
mingw64-python3-affine \
mingw64-python3-chardet \
mingw64-python3-flask \
mingw64-python3-gdal \
mingw64-python3-GeographicLib \
mingw64-python3-homography \
mingw64-python3-idna \
mingw64-python3-lxml \
mingw64-python3-markupsafe \
mingw64-python3-numpy \
mingw64-python3-opencv \
mingw64-python3-OWSLib \
mingw64-python3-pillow \
mingw64-python3-psycopg2 \
mingw64-python3-pygments \
mingw64-python3-pytz \
mingw64-python3-pyyaml \
mingw64-python3-qscintilla-qt5 \
mingw64-python3-qt5 \
mingw64-python3-requests \
mingw64-python3-shapely \
mingw64-python3-six \
mingw64-python3-urllib3 \
mingw64-qca-qt5 \
mingw64-qscintilla-qt5 \
mingw64-qt5-qmake \
mingw64-qt5-qtactiveqt \
mingw64-qt5-qtbase \
mingw64-qt5-qtimageformats \
mingw64-qt5-qtlocation \
mingw64-qt5-qtmultimedia \
mingw64-qt5-qtscript \
mingw64-qt5-qtserialport \
mingw64-qt5-qtsvg \
mingw64-qt5-qttools \
mingw64-qt5-qttools-tools \
mingw64-qt5-qttranslations \
mingw64-qt5-qtwebkit \
mingw64-qt5-qtxmlpatterns \
mingw64-qtkeychain-qt5 \
mingw64-quazip-qt5 \
mingw64-qwt-qt5 \
mingw64-sip \
mingw64-spatialindex \
mingw64-sqlite \
mingw64-svg2svgt \
mingw64-zstd \
bison \
cmake \
findutils \
flex \
gcc-c++ \
gdal-devel \
git \
make \
proj-devel \
python-qt5 \
qt5-linguist \
qt5-qtbase-devel \
sqlite-devel \
wget \
xorg-x11-server-Xvfb \
zip

RUN wget https://pkg.sourcepole.ch/kadas/mingw64-librsvg2-2.40.11-1.fc28.noarch.rpm
RUN dnf install -y mingw64-librsvg2-2.40.11-1.fc28.noarch.rpm

WORKDIR /workspace
VOLUME ["/workspace"]

0 comments on commit faed480

Please sign in to comment.