Aller au contenu | Aller au menu | Aller à la recherche

How to build qgis on OSX with MacPort

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:

  1. You switch to python 2.7 as default when building QGIS (sudo port select --set python python2.7)
  2. 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... )