.. _installation-mac:

Installation on MacOS X
=======================

Preface: This information corresponds to building ufo using the `meson` build system and proposed by Serge cohen. It is based on the previous instruction for the Mac which were kindly provided by Andrey Shkarin and Roman Shkarin.

.. highlight:: bash

1. Install the MacPorts from http://macports.org

   .. note::

       If you previously installed MacPorts, and it can not be started after
       latest installation. `Error: port dlopen (...`
       You must download the tar.gz file and install it using a terminal::

           ./configure
           make
           sudo make install

2. Install the necessary packages through macports::

       sudo port install glib2-devel
       sudo port install gtk2
       sudo port install gtk-doc
       sudo port install json-glib
       sudo port install h5utils hdf5
       sudo port install clblast
       sudo port install opencv
       sudo port install zmq-devel
       sudo port install bash-completion
       sudo port install meson
       sudo port install cmake
       sudo port install pkgconfig
       sudo port select --set python3 python36
       sudo ln -s python-3.6.pc /opt/local/lib/pkgconfig/python3.pc

   If you want to also be making/building the documentation you will need those extra packages::

       sudo port install py36-sphinx
       sudo port install asciidoc
       sudo port select --set pygments py36-pygments
       sudo port select --set sphinx py36-sphinx

   **NB** It seems that the *mac port* of `hdf5` is not installing the pkgconfig file. This prevents `ufo-filters` from finding the `hdf5` library. The easiest solution found so far is to edit the pkgconfig file *yourself*::
     sudo -i
     cat - > /opt/local/lib/pkgconfig/hdf5.pc <<EOF
     Name: HDF5
     Description: Hierarchical Data Format 5 (HDF5)
     Version: 1.10.2
     Requires:
     Cflags: -I/opt/local/include
     Libs: -L/opt/local/lib -lhdf5
     EOF

   One has to be careful to make sure that the information corresponds exactly to the installed package, in particular in term of version, header location and library name.

3. Building `clFFT` (optional)
   `clFFT`  is a *standard* library providing FFT implementation in OpenCL. If it is present on the system it is used by `ufo`, otherwise `ufo` builds a workaround. Hence you will still have a working and *complete* `ufo` without `clFFT` installed, still you might get a bit of better performances with `clFFT` especially of the size of the processed images are not strictly power of two ?

   `clFFT` is not present in Mac ports. Hence you have to compile it from the source available on github `https://github.com/clMathLibraries/clFFT.git`::

     git clone https://github.com/clMathLibraries/clFFT
     cd clFFT
     mkdir build
     cd build/
     cmake -D CMAKE_INSTALL_PREFIX=$CENV ../src
     make
     make install

   **NB** You will need to have cmake to run the building. If you do not have it already, the easiest is to install using Mac ports : `sudo port install cmake`

   Then we still have to prepare the pkgconfig file for `clFFT`::

     mkdir -p $CENV/lib/pkgconfig
     cat - > $CENV/lib/pkgconfig/clFFT.pc <<EOF
     Name: clFFT
     Description: OpenCL implementation of FFT
     Version: 2.14.0
     Requires:
     prefix=$CENV
     libdir=\${prefix}/lib
     includedir=\${prefix}/include
     Cflags: -I\${includedir}
     Libs.private: -F/System/Library/Frameworks -framework OpenCL
     Libs: -L\${libdir} -lclFFT
     EOF

4. `Make ufo-core` and `ufo-filters`

   `ufo-core` may be built either using `cmake` or using `meson/ninja`. Currently it seems that the `cmake` method is working better and is more stable in time. Still here are the informations for both tool sets :

   1. Using `cmake`
      This is rather eassy and follow the exact same scheme as when using `cmake`to build `clFFT`. As for `clFFT`, one can perform the installation to a particular prefix by adding the `-D CMAKE_INSTALL_PREFIX=...` to the `cmake` command line (here we are installing with the default prefix of `/usr/local`)::

	export PKG_CONFIG_PATH=$CENV/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/local/lib/pkgconfig
	mkdir build
	cd build
	cmake ..
	
      Then the compilation itself is done using `make`::

	make

      Finally, `make` is also used to perform the installation::

	sudo make install

      Now that the `ufo-core` is installed, we should be able to go on building `ufo-filters`. Considering that `ufo-filters` and `ufo-core` are sibling in the file hierarchy we can simply to *nearly the same* for `ufo-filters` (the only difference is that one may request also compilation of contributed filters)::

	cd ../../ufo-filters
	mkdir build
	cd build
	cmake -D WITH_CONTRIB=true ..

      Then performing building and installation::

	make
	sudo make install
	make test

      Note that some tests may fail on macOS (*eg.* test-155 and test-177). These tests require the presence of the `tifffile` python package which is not installed on macOS.
	
	
   2. Using `meson` and `ninja`

      1. Got to the directory ufo-core and run::
	 
	   export PKG_CONFIG_PATH=$CENV/lib/pkgconfig:/usr/local/lib/pkgconfig:/opt/local/lib/pkgconfig
	   mkdir build-meson
	   cd build-meson
	   meson ..

      2. Run::

	   ninja
	   sudo ninja install

	 If you are using `cenv` or the like to install into a specific (non system-wise) directory you should instead configure directly `meson` this way::

	   meson --prefix $CENV ..
	   ninja
	   ninja install -k 1000

      3. Installation is complete, perhaps the last lines are as follows::

	   Installing /Users/serge/Projects/ufo-ipanema/ufo-core/bin/ufo-launch to /opt/local/share/bash-completion/completions
	   Installation failed due to insufficient permissions.
	   Attempting to use polkit to gain elevated privileges...
	   The value for environment variable DISPLAY contains suscipious content

	   This incident has been reported.
	   FAILED: meson-install
	   /opt/local/Library/Frameworks/Python.framework/Versions/3.7/bin/meson install --no-rebuild
	   ninja: build stopped: subcommand failed.

	 This is because the install was done without the sudo (likely to a specific prefix dir) but bash_completion has to go to the system-wise directory and hence is working only when running ninja using `sudo`. Indeed it is likely that part of the install is **not** done because of this error; in this case use `ninja -k 2 install`

      4. Go to ufo-filters directory. Now, if libufo was not installed in a *default* path, one has also to provide `pkgconfig` with the info as to where to find it::

        export PKG_CONFIG_PATH=$CENV/lib/pkgconfig

      Potentially later, add also `:/usr/local/lib/pkgconfig` at the end of the path (or any other necessary path to the list)

      5. Run::

	   mkdir build-meson
	   cd build-meson
	   meson --prefix $CENV -Dcontrib_filters=true ..
	   ninja
	   ninja install

	 Again, `ninja` might end-up with the error::
	   Installation failed due to insufficient permissions.
	   Attempting to use polkit to gain elevated privileges...
	   The value for environment variable DISPLAY contains suscipious content
	   
	   This incident has been reported.
	   FAILED: meson-install
	   /opt/local/Library/Frameworks/Python.framework/Versions/3.7/bin/meson install --no-rebuild
	   ninja: build stopped: subcommand failed.

	 This prevents `ufo` to be fully installed, in particular the `*.cl` kernel sources are not installed. If this happens, then the solution is to run the `ninja install` with root privileges::
	   sudo ninfa install

	 **Indeed** it looks like providing the large value of *ignored failed jobs* to `ninja` also does the trick without using root privileges::

	   ninja install -k 1000

      6. Quick fix
	 This is indeed not needed, the best is to make sure `meson` is always using `.so` extension for plugin/module.

	 If this problem happens, the best is indeed to make sure that `meson` is properly generating `.so` filenames for filter tasks. This is done by adding the `name_suffix: 'so'` in every `shared_module()` instance.


	 **DEPRECATED**: Indeed the sources of the plugin manager have been updated to use the `.dylib` extension when looking for plugins (which are *shared objects*) on MacOS.

	 Currently on macOS, `meson` produce *shared objects* as *dynamic libraries* (filename ending in `.dylib`) which prevents `dlopen` from finding them. Later on the `meson` build should adapt to MacOS to make sure it uses the proper extension for those, but in the short term the simpler is to make sure that `dlopen` finds the file by producing the correct softlinks::

           cd $CENV/lib/ufo
           for i in $(ls *.dylib) ; do ln -s $i $(basename $i .dylib).so; done

      7. Build the test project and verify that everything works.
