Post wrote by David Marteau
Building QGIS on OSX may be quite challenging, mostly because the major problem of building qgis on OSX is to gather all the needed and up to date dependencies.
I'm going to describe a method that use the MacPort packaging system: I use it since several years now and I tave been quite happy with it. By design MacPort provides insulation between installed bits and those natives to the system, and I'm more than ok with that.
There is no question of building a distributable package but, instead, the goal is to provide a set up for building, and install QGIS on your machine.
I won't go into the macport installation since all informations cat be found here: https://www.macports.org/
Support for building QGIS2 end QGIS3
Macport provides QT4 and QT5 packages than can be installed simultaneously as many of the qt tools that could depends on it (qscintilla, qca, qwt....). This is very handy if you have to deal with several versions of QGIS, which is our case.
Common dependencies
XCode 8 required
If you plan to build QGIS3 then you need XCode 8+ : QGIS3 use C++11 thread_local specifier which is not available in the clang compiler for version < 8. This also mean that you cannot build qgis3 on a pre 10.11 OSX version (you may always useanother compiler from those provided by MacPort, but I did not tried this).
Macport packages
These are macport packages needed for all versions:
cmake
fcgi
spatialindex
expat
bison
spatialite
gsl
gdal +curl+expat+geos+hdf4+hdf5+netcdf+openjpeg+perf+postgresql95+spatialite+sqlite3+xerces
These packages will pull many other things, and I there maybe other packages that I forgot to mention: just tell me, I will add them.
Building QGIS3 from master branch
I'm going to start with that story because it has been the easier to set up (see later).
Install dependencies:
I'm going to assume that your using python 3 as your default python installation (do not hesitate to use the
latest stable version, which is the 3.6 as this moment).
You will need, at least, the following packages:
boost +python36 (some qt5 dependencies depends on boost, force installation with python 3.6 supports)
qt5
qt5-qtwebkit
qscintilla2
qwt61
qca-qt5
qca-qt5-ossl
python36
py36-pyqt5
py36-sip
py36-owslib
py36-gdal
py36-matplotlib
py36-numpy
py36-qscintilla2
py36-jinja2
py36-future
py36-requests
py36-pygments
You will need to link /opt/local/bin/pyuic5-3.6
to /opt/local/bin/pyuic5
and /opt/local/bin/pyrcc5-3.6
to /opt/local/bin/pyrcc5
Install QTKeychain
QTKeychain is not provided by macport but it is very easy to build:
- Download source from https://github.com/frankosterfeld/qtkeychain
- configure using cmake, then make build, make install. QTKeychain library will install on
/usr/local.
Create missing pyQT5 sip folder
When installing py36-pyqt5, the installation forgot to add a entry to the Qt5 sip files at the default location: you need to add the following link:
cd /opt/local/share
sudo ln -s /opt/local/Library/Frameworks/Python.framework/Versions/3.6/share/sip py36-sip
Create Makefile
I use makefile to drive my builds.
.PHONY: build install clean clobber
INSTALL_PATH:=$(shell pwd)/dist
BUILDNAME:=build
JOBS:=-j6
ifeq ($(QGIS_DEBUG),1)
BUILDDIR=$(BUILDNAME)-debug
CMAKE_OPTS+=-DCMAKE_BUILD_TYPE=Debug
else
BUILDDIR=$(BUILDNAME)-release
endif
export PATH := $(PATH):/opt/local/libexec/qt5/bin
configure:
mkdir -p $(BUILDDIR)
rm -rf $(BUILDDIR)/CMakeCache.txt
cd $(BUILDDIR) && cmake $(CMAKE_OPTS) \
-DWITH_ASTYLE=ON \
-DCMAKE_INSTALL_PREFIX:PATH=$(INSTALL_PATH) \
-DWITH_SERVER=ON \
-DEXPAT_INCLUDE_DIR:PATH=/opt/local/include \
-DEXPAT_LIBRARY:FILEPATH=/opt/local/lib/libexpat.dylib \
-DSQLITE3_INCLUDE_DIR:PATH=/opt/local/include \
-DSQLITE3_LIBRARY:FILEPATH=/opt/local/lib/libsqlite3.dylib \
-DQT_QMAKE_EXECUTABLE:FILEPATH=/opt/local/libexec/qt5/bin/qmake \
-DQWT_INCLUDE_DIR:PATH=/opt/local/libexec/qt5/include/qwt \
-DQWT_LIBRARY:FILEPATH=/opt/local/libexec/qt5/lib/libqwt.dylib \
-DQCA_INCLUDE_DIR:PATH=/opt/local/libexec/qt5/include/QtCrypto \
-DQCA_LIBRARY:FILEPATH=/opt/local/libexec/qt5/lib/libqca-qt5.dylib \
-DQSCINTILLA_INCLUDE_DIR:PATH=/opt/local/libexec/qt5/include \
-DQSCINTILLA_LIBRARY:FILEPATH=/opt/local/libexec/qt5/lib/libqscintilla2_qt5.dylib \
-DQTKEYCHAIN_INCLUDE_DIR:PATH=/usr/local/include/qt5keychain \
-DQTKEYCHAIN_LIBRARY:FILEPATH=/usr/local/lib/libqt5keychain.dylib \
-DQT_LRELEASE_EXECUTABLE:FILEPATH=/opt/local/libexec/qt5/bin/lrelease \
..
build:
cd $(BUILDDIR) && $(MAKE) $(JOBS)
install:
mkdir -p $(INSTALL_PATH)
cd $(BUILDDIR) && $(MAKE) install
clean:
cd $(BUILDDIR) && $(MAKE) clean
clobber:
rm -rf $(BUILDDIR) $(INSTALL_PATH)
Build the beast
Doing make configure build
should do the job. If any problems occurs, look for a missing package.
Installing
Doing make install
will install the QGIS.app into INSTALL_DIR.
WARNING : If you are going to open the .app from the desktop it will crash unless the environment variable QT_QPA_PLATFORM_PLUGIN_PATH is defined as:
QT_QPA_PLATFORM_PLUGIN_PATH=/opt/local/libexec/qt5/plugins/platforms
This is a problem that affect all qt5 application and should be solved in some way. A quick and dirty solution would be to add thefollowing rule in your Makefile:
run:
QT_QPA_PLATFORM_PLUGIN_PATH=/opt/local/libexec/qt5/plugins/platforms \
open $(INSTALL_PATH)/QGIS.app
Building QGIS 2.18 with python2.7
Building QGIS 2.18 is a little bit tricky because of some deployment problems on mac
Install dependencies:
I'm going to assume that python2.7 IS NOT your default python installation
You will need, at least, the following packages:
qt4-mac
qt4-mac-sqlite3-plugin
qscintilla
qwt60 +qt4 (Use -f to force installation as it will say that it is incompatible with qwt61, but installed in its own qt4 directory with no side effects)
qca
qca-ossl
qjson
python27
py27-pyqt4
py27-sip
py27-gdal
py27-matplotlib
py27-numpy
py27-qscintilla
py27-jinja2
py27-requests
py27-future
py27-pygments
You will need to link /opt/local/bin/pyuic4-2.7
to /opt/local/bin/pyuic4
and /opt/local/bin/pyrcc4-2.7
to /opt/local/bin/pyrcc4
Fix cmake/FindPythonLibrary.cmake
As of version 2.18.9, the build use a custom cmake module to find python library. Unfortunately, this module is broken as it
force the variable PYTHON_LIBRARY to be set to the default python installation and ignore cmake defines.
There is two ways to deal with that:
- You switch to python 2.7 as default when building QGIS (
sudo port select --set python python2.7
)
- You fix the cmake module
Personally, I dont like 1. since you need to change your global settings for one task and the fix is very small:
--- a/cmake/FindPythonLibrary.cmake
+++ b/cmake/FindPythonLibrary.cmake
@ -78,7 +78,8 @@ else(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "
endif(python_config)
# adapted from cmake's builtin FindPythonLibs
- if(APPLE AND NOT _custom_python_fw)
+ # XXX Fix when PYTHON_LIBRARY defined
+ if(APPLE AND NOT _custom_python_fw AND NOT PYTHON_LIBRARY)
CMAKE_FIND_FRAMEWORKS(Python)
set(PYTHON_FRAMEWORK_INCLUDES)
if(Python_FRAMEWORKS)
@@ -93,7 +94,7 @@ else(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "
endif(NOT PYTHON_LIBRARY)
set(PYTHONLIBRARY_FOUND TRUE)
endif(Python_FRAMEWORKS)
- endif(APPLE AND NOT _custom_python_fw)
+ endif(APPLE AND NOT _custom_python_fw AND NOT PYTHON_LIBRARY)
endif(PYTHONINTERP_FOUND)
if(PYTHONLIBRARY_FOUND)
The Makefile
Very similar to the previous one:
.PHONY: build install clean clobber
INSTALL_PATH=/Applications
BUILDDIR:=build
JOBS:=-j6
export PATH := $(PATH):/opt/local/libexec/qt4/bin
configure:
mkdir -p $(BUILDDIR)
rm -rf $(BUILDDIR)/CMakeCache.txt
cd $(BUILDDIR) && cmake $(CMAKE_OPTS) \
-DCMAKE_INSTALL_PREFIX:PATH=$(INSTALL_PATH) \
-DCMAKE_INSTALL_PREFIX:PATH=/Applications \
-DWITH_SERVER=ON \
-DWITH_PYSPATIALITE=ON \
-DPYTHON_INCLUDE_PATH:PATH=/opt/local/include/python2.7 \
-DPYTHON_LIBRARY:FILEPATH=/opt/local/lib/libpython2.7.dylib \
-DEXPAT_INCLUDE_DIR:PATH=/opt/local/include \
-DEXPAT_LIBRARY:FILEPATH=/opt/local/lib/libexpat.dylib \
-DSQLITE3_INCLUDE_DIR:PATH=/opt/local/include \
-DSQLITE3_LIBRARY:FILEPATH=/opt/local/lib/libsqlite3.dylib \
-DQT_QMAKE_EXECUTABLE:FILEPATH=/opt/local/libexec/qt4/bin/qmake \
-DQWT_INCLUDE_DIR:PATH=/opt/local/libexec/qt4/include/qwt \
-DQWT_LIBRARY:FILEPATH=/opt/local/libexec/qt4/lib/libqwt.dylib \
-DQCA_INCLUDE_DIR:PATH=/opt/local/libexec/qt4/include/QtCrypto \
-DQCA_LIBRARY:FILEPATH=/opt/local/libexec/qt4/lib/libqca.dylib \
-DQSCINTILLA_INCLUDE_DIR:PATH=/opt/local/libexec/qt4/include \
-DQSCINTILLA_LIBRARY:FILEPATH=/opt/local/libexec/qt4/lib/libqscintilla2_qt4.dylib \
..
build:
cd $(BUILDDIR) && $(MAKE) $(JOBS)
install:
cd $(BUILDDIR) && $(MAKE) install
clean:
cd $(BUILDDIR) && $(MAKE) clean
clobber:
rm -rf $(BUILDDIR)
Building and installing
The commands for building and installing are the same as for qgis3.
Install problems
The Installation of $INSTALL_NAME/QGIS.app/Contents/Resources/python/PyQt4/Qsci.o
is broken - may be because of some rewrite of the install_name - and one must replace the fire with the original one /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/PyQt4/Qsci.so which has correct linking
Conclusion
There is some issues when compiling on mac, mostly because the system libraries are frozen and it is better not to temper with.
Using Macport (or Brew) should provide the requirements for building a fully running version of QGIS, while keeping your system clean.
It also gives you some of the problems that packaging will be facing: one of the major problem is that you cannot rely on the system defaults (especially on the default python which is frozen on python 2.7.10, so you can forget installing qgis3 on top of it... )