Skip to content
Permalink
Browse files

[mxe] Add install instructions for mxe

  • Loading branch information
elpaso committed Feb 8, 2018
1 parent d19eef0 commit 1dd6db384ff9d20b9a7a8b4b51f8336d1402d000
Showing with 382 additions and 0 deletions.
  1. +35 −0 INSTALL
  2. +120 −0 ms-windows/mxe/README
  3. +104 −0 ms-windows/mxe/build-mxe.sh
  4. +123 −0 ms-windows/mxe/deploy.py
35 INSTALL
@@ -23,6 +23,7 @@ Last Change : Friday February 02, 2018
4.1. Building with Microsoft Visual Studio
4.2. Building using MinGW
4.3. Creation of MSYS environment for compilation of QGIS
4.4 Building on Linux with mxe
5. Building on MacOS X
5.1. Install Developer Tools
5.2. Install Qt4 from disk image
@@ -1027,6 +1028,40 @@ We're done with preparation of MSYS environment. Now you can delete all stuff in
of space and it's not necessary at all.



4.4. Building on Linux with mxe
===============================

With this approach you can build a windows binary on Linux using mxe MXE (M cross environment).
You can find the build script and a README file in the ms-windows/mxe directory.

For now, Python buildings cannot be built with mxe.

4.4.1. Initial setup
====================

Please follow the instructions on mxe website to setup your building toolchain http://mxe.cc/,
take note of the path where you have installed mxe.

4.4.2. Building the dependencies
================================

Please see the README under ms-windows/mxe for a list of the dependencies that needs to be
build in mxe before attempting to build QGIS.


4.4.3. Cross-Building QGIS
==========================

Edit the build-mxe.sh script and change the path where your mxe installation is located, you
can also change the build and release directory.

4.4.4. Testing QGIS
====================

Copy and unzip the release package ona a Windows machine and launch it!


5. Building on MacOS X
======================

@@ -0,0 +1,120 @@

Scripts to cross build a windows QGIS binary from Linux using MXE:
(M cross environment) http://mxe.cc/

For now, Python bindings cannot be built with mxe.

Follow the instructions on the website to prepare the mxe environment, you
will need to build all required dependencies for QGIS.

Note that someof the packages listed below are dependencies of other
packages, you will probably not need to build them all explicitely.


armadillo
bfd
bzip2
cairo
cmake
curl
dbus
dlfcn-win32
expat
fontconfig
freetds
freetype
freexl
gcc
gdal
gendef
geos
gettext
giflib
glib
gmp
gnutls
gsl
gta
harfbuzz
hdf4
hdf5
icu4c
isl
jasper
jpeg
json-c
lcms
libffi
libgcrypt
libgeotiff
libgnurx
libgpg_error
libiconv
libidn2
libmng
libmysqlclient
libpng
libspatialindex
libssh2
libunistring
libwebp
libxml2
libzip
lzo
mpc
mpfr
netcdf
nettle
openblas
openjpeg
openssl
pcre
pcre2
pixman
pkgconf
portablexdr
postgresql
proj
qca
qscintilla2
qt3d
qtactiveqt
qtbase
qtcanvas3d
qtcharts
qtconnectivity
qtdatavis3d
qtdeclarative
qtgamepad
qtgraphicaleffects
qtimageformats
qtkeychain
qtlocation
qtmultimedia
qtpurchasing
qtquickcontrols
qtquickcontrols2
qtscript
qtscxml
qtsensors
qtserialbus
qtserialport
qtspeech
qtsvg
qttools
qttranslations
qtvirtualkeyboard
qtwebchannel
qtwebkit
qtwebsockets
qtwebview
qtwinextras
qtxmlpatterns
qwt
spatialite
sqlite
tiff
xz
zlib

When done, you can edit the build-mxe.sh script to set the path to your mxe installation.
@@ -0,0 +1,104 @@
#!/bin/bash
###########################################################################
# build-mxe.sh
# ---------------------
# Date : February 2018
# Copyright : (C) 2018 by Alessandro Pasotti
# Email : elpaso at itopen dot it
###########################################################################
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
###########################################################################


set -e

# Usage: you can pass an optional "package" command to skip the build
# and directly go to the packaging
# This script needs to be called from the main QGIS directory, the
# one which contains CMakeLists.txt

COMMAND=$1

# Location of current script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PYDEPLOY=${DIR}/deploy.py

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# Configuration: change this!

# Location of mxe install dir
MXE=${HOME}/dev/mxe/

# Where the artifact will be saved

BUILD_DIR=`pwd`/build-mxe
RELEASE_DIR=`pwd`/release-mxe

# End configuration




if [[ "$COMMAND" != *"package"* ]]; then
[ -d $BUILD_DIR ] && rm -rf $BUILD_DIR
[ -d $RELEASE_DIR ] && rm -rf $RELEASE_DIR
# Make sure dirs exist

[ -d $BUILD_DIR ] || mkdir $BUILD_DIR
[ -d $RELEASE_DIR ] || mkdir $RELEASE_DIR

fi

pushd .

cd $BUILD_DIR

# Build

if [[ "$COMMAND" != *"package"* ]]; then

$MXE/usr/bin/i686-w64-mingw32.shared-cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=$RELEASE_DIR \
-DENABLE_TESTS=OFF \
-DWITH_QSPATIALITE=ON \
-DWITH_APIDOC=OFF \
-DWITH_QWTPOLAR=ON \
-DWITH_ASTYLE=OFF \
-DWITH_SERVER=OFF \
-DWITH_BINDINGS=FALSE \
-DQT_LRELEASE_EXECUTABLE=$MXE/usr/i686-w64-mingw32.shared/qt5/bin/lrelease \
$ARGS


make -j16 install

fi

# Collect deps

$PYDEPLOY --build=$RELEASE_DIR --objdump=$MXE/usr/bin/i686-w64-mingw32.shared-objdump ${RELEASE_DIR}/qgis.exe
for dll in $(ls ${RELEASE_DIR}/*.dll); do \
$PYDEPLOY --build=$RELEASE_DIR --objdump=$MXE/usr/bin/i686-w64-mingw32.shared-objdump $dll; \
done

cp -r $MXE/usr/i686-w64-mingw32.shared/qt5/plugins $RELEASE_DIR/qt5

cat <<__TXT__ > ${RELEASE_DIR}/qt.conf
[Paths]
Plugins = ./qt5/plugins
__TXT__


popd

ZIP_NAME=release-`date +%Y-%m-%d-%H-%I-%S`.zip

zip -r $ZIP_NAME $RELEASE_DIR

echo "Release in $ZIP_NAME ready."
@@ -0,0 +1,123 @@
#! /usr/bin/env python3
"""pyWindeployqt
This is a wrapper for mingw32 objdump replacing windeployqt which is missing from MXE
I don't know why they disabled it, but here it is.
Example:
./deploy.py --build=~/ClionProjects/project/build/ \
--objdump=/home/user/mxe/usr/bin/i686-w64-mingw32.shared-objdump \
~/ClionProjects/project/build/project.exe;
"""

__author__ = 'Alexey Elymanov (strangeqargo@gmail.com)'

import subprocess
import os
import sys
import re
import os.path

import argparse
parser = argparse.ArgumentParser()

parser.add_argument("--build", help="where to place libraries, optional, files will go to target location by default")
parser.add_argument("--objdump", help="objdump executable (/home/user/mxe/usr/bin/i686-w64-mingw32.shared-objdump)")
parser.add_argument("--libs", help="where to search for libraries (optional) infers from objdump")
parser.add_argument("target")

args = parser.parse_args()
if len(sys.argv) == 1 or not (args.libs or args.objdump):
parser.print_help()
sys.exit(1)

target = os.path.expanduser(args.target)
objdump_path = os.path.expanduser(args.objdump)

if not args.build:
build_path = os.path.expanduser(os.path.dirname(args.target)) + "/"
else:
build_path = os.path.expanduser(args.build)

libs = args.libs
if not args.libs:
libs = objdump_path.replace('/bin', '').replace('-objdump','')


# build_path = "/home/user/ClionProjects/project/build/"
# libs = "/home/user/mxe/usr/i686-w64-mingw32.shared"
# objdump_path = "/home/user/mxe/usr/bin/i686-w64-mingw32.shared-objdump"
# target = "project.exe"


def run_check():
return subprocess.getoutput("wine project.exe")


def find_dll(dll):
out = subprocess.getoutput("find " + libs + " | grep -i '" + dll+"$'")
return out.strip('\n')


def library_install_exe(out=''):
out = run_check().splitlines()
for line in out:
# err = re.search('(err:module:import_dll (Library |Loading library)) (.*?\.dll) ', line)
err = re.search('([^ ]+\.dll) \(which', line)
if err is not None:

dll = err.group(1)
dll = find_dll(dll)
if dll is not None:
copy_command = "cp " + dll + " " + build_path
print("copy: ", copy_command)
subprocess.getoutput(copy_command)
library_install_exe(out)


def library_install_objdump(path, level):
if path in skip_libs or path in done:
return

if level > 0:
lib = find_dll(path)
if lib == "": # not found
skip_libs.append(path)
print("Not found: " + path)
return
print(lib)
subprocess.getoutput("cp " + lib + " " + build_path)

else:
print("Processing target " + path)
lib = path

done.append(path)

command = objdump_path + " -p " + lib + " | grep -o ': .*\.dll$'"
res = subprocess.getstatusoutput(command)
if (res[0] > 0):
print("Error: objdump failed with " + lib)
else:
dlls = subprocess.getoutput(command).split("\n")
for line in dlls:
dll = (line.split(": "))[1]
if dll not in done and dll not in skip_libs:
level += 1
library_install_objdump(dll, level)

skip_libs = list()
done = list()


def main():

os.chdir(build_path)

#library_install_exe(target)
library_install_objdump(target, 0)

pass

main()

0 comments on commit 1dd6db3

Please sign in to comment.
You can’t perform that action at this time.