# Building MyPaint from Source This guide is for developers, and testers who want the bleeding edge. Regular users might not need this guide. Most distributions already have a stable version of MyPaint. **Table of Contents** * [Install libmypaint and mypaint-brushes](#install-libmypaint-and-mypaint-brushes) * [Install third-party dependencies](#install-third-party-dependencies) - [Debian and derivatives](#debian-and-derivatives) - [Red Hat and derivatives](#red-hat-and-derivatives) - [OpenSUSE](#opensuse) - [Windows MSYS2](#windows-msys2) - [OSX MacPorts](#osx-macports) * [Fetch the source](#fetch-the-source) * [Migration from SCons](#migration-from-scons) * [Running the build script](#running-the-build-script) - [Demo mode](#demo-mode) - [Managed install and uninstall](#managed-install-and-uninstall) - [Installing locally](#building-and-installing-locally) * [Updating to the latest source](#updating-to-the-latest-source) ## Install libmypaint and mypaint-brushes MyPaint depends on its brushstroke rendering library, [**libmypaint**](https://github.com/mypaint/libmypaint). <details> <summary>Which version of libmypaint should I build against?</summary> When building the latest master, the rule of thumb is to build against the latest master of libmypaint. Stable releases should be built against a compatible stable releases of libmypaint. If you need to build a commit from the commit history, use `git log` after having checked out the commit, and search for libmypaint to infer which commit of libmypaint you should build against. This is not always specified explicitly, but should always be inferable by cross-referencing the commit log of libmypaint (by date or keyword search). </details> MyPaint also depends on the default brush collection [**mypaint-brushes**](https://github.com/mypaint/mypaint-brushes). These have to be built from scratch for most systems, see the links below for details on how to do this. * [Generic libmypaint build instructions][LIB] * [Generic mypaint-brushes build instructions][BRUSH] * [Debian-style package builder for libmypaint][LIBDEB] * [MyPaint's Ubuntu PPA (__not currently updated__)][PPA] Windows [MSYS2](http://msys2.org) users have pre-packaged options available for libmypaint-1.3.0 (newer versions currently have to be built from source): pacman -S mingw-w64-i686-libmypaint pacman -S mingw-w64-x86_64-libmypaint > ### Using optimization flags > MyPaint and libmypaint benefit dramatically from autovectorization and other > compiler optimizations. You may want to set your CFLAGS before compiling: > > ` export CFLAGS='-Ofast -ftree-vectorize -fopt-info-vec-optimized -march=native -mtune=native -funsafe-math-optimizations -funsafe-loop-optimizations' ` > > To avoid potential glitches, make sure to compile both libmypaint > and MyPaint using the same optimization flags. [LIBDEB]: https://github.com/mypaint/libmypaint.deb [LIB]: https://github.com/mypaint/libmypaint/blob/master/README.md [BRUSH]: https://github.com/mypaint/mypaint-brushes/blob/master/README.md [PPA]: https://launchpad.net/~achadwick/+archive/ubuntu/mypaint-testing ## Install third-party dependencies MyPaint has several third-party dependencies. They all need to be installed before you can build it. - setuptools - pygobject - gtk3 (>= 3.12) - python (>= 3.8) - swig (>= 3) - numpy - librsvg2 (and its svg gdk-pixbuf loader) - pycairo (>= 1.4) Some dependencies have specific versions for Python 2 and Python 3. Install the ones for the Python version you will use to build MyPaint. Apart from the use of disk space, there is usually no harm in installing both sets. ### Debian and derivatives For Debian, Mint, or Ubuntu, issue the following commands to install the external dependencies. sudo apt-get install -y \ git swig gettext g++ gir1.2-gtk-3.0 libgtk-3-dev \ libpng-dev liblcms2-dev libjson-c-dev python-gi-dev \ librsvg2-common # For python 2 sudo apt-get install -y \ python-setuptools python-dev python-numpy python-gi-cairo # For python 3 sudo apt-get install -y \ python3-setuptools python3-dev python3-numpy python3-gi-cairo If this doesn't work, try older names for the development packages, such as `libjson0-dev`, or `libpng12-dev`. ### Red Hat and derivatives For yum-enabled systems, the following should work. This has been tested on a minimal CentOS 7.3 install, and Fedora 30. sudo yum install -y git swig gettext gcc-c++ libpng-devel lcms2-devel \ json-c-devel gtk3 gtk3-devel gobject-introspection pygobject3-devel \ librsvg2 # For python 2 sudo yum install -y python-setuptools python-devel numpy # For python 3 sudo yum install -y python3-setuptools python3-devel python3-numpy ### OpenSUSE Issue the following commands to install the external dependencies. sudo zypper install \ git swig gcc-c++ gobject-introspection gtk3-devel \ libpng16-devel liblcms2-devel libjson-c-devel \ librsvg-2-2 gettext-tools # For python3 sudo zypper install \ python311-setuptools python311-devel python311-numpy-devel \ python311-pycairo python311-gobject-devel \ ### Windows MSYS2 Use the following commands when building in [MSYS2](http://msys2.org). For 32-bit targets, use "i686" in place of the "x86_64". pacman -S --noconfirm --needed git base-devel pacman -S --noconfirm --needed \ mingw-w64-x86_64-toolchain \ mingw-w64-x86_64-pkg-config \ mingw-w64-x86_64-python2-numpy \ mingw-w64-x86_64-gtk3 \ mingw-w64-x86_64-pygobject-devel \ mingw-w64-x86_64-lcms2 \ mingw-w64-x86_64-json-c \ mingw-w64-x86_64-librsvg \ mingw-w64-x86_64-hicolor-icon-theme \ mingw-w64-x86_64-python2-cairo \ mingw-w64-x86_64-python2-gobject \ mingw-w64-x86_64-mypaint-brushes2 ### OSX MacPorts To use Frameworks Python (currently 2.7.8) while satisfying the other dependencies from Macports, use: export PKG_CONFIG_PATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/pkgconfig/ export CFLAGS="-I/opt/local/include" sudo port install gtk3 sudo port install py27-numpy sudo port install py27-scipy sudo port install py27-pyobjc-cocoa # optional, for i18n support sudo port install py27-gobject3 sudo port install json-c sudo port install lcms2 sudo port install hicolor-icon-theme sudo port install librsvg These commands are poorly tested, and may be incomplete. Please send feedback if they're not working for you. ## Fetch the source Start by cloning the source from git. This will create a new directory named `mypaint`. Keep this folder around so you don't have to repeat this step. cd path/to/where/I/develop git clone https://github.com/mypaint/mypaint.git ## Migration from SCons We've moved the build system from SCons for portability reasons, and things may be a bit rough in comparison. If you have an old installation managed by SCons, please uninstall it before installing with `setup.py`. > The SCons files are no longer present in the source tree > as of revision `a332f03deebebaad84a4f3d5dedc987895dc5b70`. > To access them, you can check out an earlier revision. > > For example: `git checkout a332f03deebebaad84^` Real Pythonistas™ might expect `pip` to work. It doesn't, not yet: MyPaint has way too many support files that have to be in special folders, so it uses a custom installation scheme. ## Running the build script MyPaint is a Python project, and it uses a conventional `setup.py` script. However, this isn't a typical Python module, so `pip install` doesn't work with it yet. # Learn how to run setup.py cd mypaint python setup.py --help-commands # list all commands python setup.py --help build # get options for "build" # Some basic commands python setup.py build python setup.py clean --all We've added a few custom commands too, for people used to the old SCons way of working. # Test without a full installation python setup.py demo # Don't use raw "install" unless you know what you're doing python setup.py managed_install python setup.py managed_uninstall See above if you want to install MyPaint or use `pip`. This isn't a conventional installation scheme. ### Demo mode You can test MyPaint without installing it. The settings aren't saved between runs when you do this. python setup.py demo ### Unit tests Please run the doctests before committing new code. sudo apt-get install python-nose python setup.py nosetests We have some heavier conformance tests for the C++ parts too. These take longer to run. python setup.py test You should write doctests for important new Python code. Please consider writing tests in the `tests` folder too, if you make any changes to the C++ extension or `libmypaint`. To cleanup between unit tests you may want to run: python setup.py clean --all rm -vf lib/*_wrap.c* ### Managed install and uninstall MyPaint has an additional custom install command, for people used to our old SCons recipes. It isn't compatible with SCons installs, but it allows you to do an uninstall later. # For most Linux types sudo python setup.py managed_install sudo python setup.py managed_install --prefix=/usr The default install location is `/usr/local`. If you want to install without sudo, refer to [this section](#building-and-installing-locally) # You may need to make data files world-readable if you use "sudo" sudo find /usr/local -ipath '*mypaint*' -exec chmod -c a+rX {} \; # You can uninstall at any later time sudo python setup.py managed_uninstall sudo python setup.py managed_uninstall --prefix=/usr Note that uninstallation doesn't get rid of all the folders that the managed install created. ### Building and installing locally If you don't want to install MyPaint system-wide, or don't want to use sudo, follow these instructions to create a local install. If you also need to install and configure any [third-party dependencies](#install-third-party-dependencies) without using sudo, refer to their respective documentation for how to do so (for most dependencies, this is **_not recommended_**). In this section, the shell variable `BASE_DIR` is used to refer to the path of a directory which will be the base of your install. You can set it like this (modify if you want to install somewhere else): ``` BASE_DIR=$HOME/.local/ ``` If you have compatible versions of **libmypaint** and **mypaint-brushes** installed and configured, all you have to do is run: ``` python setup.py managed_install --prefix=$BASE_DIR ``` and jump to the [run instructions](#running-the-local-installation). If not, refer to the rest of this section. #### Installing libmypaint & mypaint-brushes locally You don't need to install libmypaint or mypaint-brushes **_locally_** in order to install MyPaint locally, but if you want to, use the `--prefix=` option to `configure` before running `make install` for each of them. E.g: ``` ./configure --prefix=$BASE_DIR && make install ``` Refer to [libmypaint's build instructions][LIB] for more details on building libmypaint. #### Configuring, building and installing If you want to use locally installed versions of **libmypaint** and **mypaint-brushes** you will need to make sure that pkg-config knows where to find them. To do this, set ```PKG_CONFIG_PATH``` before building. Assuming both **libmypaint** and **mypaint-brushes** were installed configured with ```--prefix=$BASE_DIR``` you can do this by running: ``` export PKG_CONFIG_PATH=$BASE_DIR/lib/pkgconfig/:$BASE_DIR/share/pkgconfig/ ``` > The two colon-separated paths refer to the locations of package configuration > files for libmypaint and mypaint-brushes respectively. Replace the respective > occurrence of $BASE_DIR if you installed either somewhere else. In addition to knowing where libmypaint is installed _when building_, MyPaint also needs to know its location _when running_. This _can_ be done by setting the `LD_LIBRARY_PATH` environment variable to to the location of libmypaint every time MyPaint is run, but this is _not_ recommended. The recommended way is to explicitly run the `build_ext` command with the `--set-rpath` flag, prior to installation. In short, you can build and install by running: ``` export PKG_CONFIG_PATH=$BASE_DIR/lib/pkgconfig/:$BASE_DIR/share/pkgconfig/ python setup.py build_ext --set-rpath managed_install --prefix=$BASE_DIR ``` > **Note**: remember to use the same prefix if uninstalling via `managed_uninstall` If you have already run the build script without `--set-rpath`, you can run the following to force a rebuild: ``` python setup.py build_ext --set-rpath --force ``` > **alternative to `--set-rpath`** > > If you want to build an older version of MyPaint that did not have this > option, you can instead use the built-in `--rpath=` option to `build_ext`, > setting the dependency path(s) manually. > > E.g: `python setup.py build_ext --rpath=$BASE_DIR/lib/` #### Running the local installation The start script `mypaint` will be placed in `$BASE_DIR/bin/`, so either add that path to your PATH environment variable: ``` export PATH=$BASE_DIR/bin/:$PATH mypaint ``` or create links to the script: ``` ln -s $BASE_DIR/bin/mypaint my-local-mypaint ./my-local-mypaint ``` ## Updating to the latest source Updating to the latest source at a later date is trivial, but doing this can mean that you have to rebuild the compiled parts of the app: cd path/to/mypaint python setup.py clean --all git pull ## Custom installation directory layout When running **`python setup.py install`** files will be installed in certain directories on your system. By default, these directories are set in the file **`setup.cfg`** in the **`[install]`** section. In those paths, **`$base`** is a placeholder that is replaced by the value set with **`--prefix`** in the install command (**`/usr`** by default). The installation directories can be overridden for each type by providing a flag to the **`install`** command equivalent to the name of one of the `install-xyz` variables in **`setup.cfg`**. For example: ``` python setup.py install --prefix=/usr/local --install-purelib='$base/lib64/mypaint' ```