Matplotlib 1.1.0 for Solaris on SPARC and x86, Part 1: Compiling

on

This is part 1 of a three-part series on building and packaging matplotlib as a multi-architecture, Solaris IPS package. At the end of this series, you should be able to install matplotlib as easily as any other Solaris 11 package, on both SPARC and x86 machines.

  1. Compiling matplotlib 1.1.0 for Solaris on SPARC and x86
  2. Setting up Solaris IPS servers to host packages for SPARC and x86
  3. Packaging matplotlib 1.1.0 for Solaris on SPARC and x86
pkg install library/python-2/python-matplotlib-26
Example of a plot made with
matplotlib

Overview

Matplotlib is a library for creating plots from Python.

Matplotlib has become a frequently used tool in my toolbox. I love how simple it is to go from a couple numpy arrays to many different types of plots.

Setup build environment

For this build we will be using Solaris Studio. Add Solaris Studio to your path. My Solaris Studio was installed at /opt/SUNWspro, so I ran:

export PATH="/opt/SUNWspro/bin:${PATH}"

Solaris 11 comes with Python 2.6 and numpy libraries built-in. Using these worked just fine for me.

If not done before, install system headers, for compilation. If these are not present, you will get an error like: "/usr/include/python2.6/Python.h", line 22: Error: #error "Something's broken. UCHAR_MAX should be defined in limits.h.".

sudo pkg install system/header

We need to trick Python distutils into using C++ instead of C. The easiest way I found to do this was to set the C compiler environment variable to the Solaris Studio C++ compiler.

export CC=CC

Apply changes to matplotlib 1.1.0

I used the source distribution of matplotlib 1.1.0 for these instructions. Different changes may be needed for other versions.

There are only a few changes needed to get matplotlib to compile with Solaris Studio. Basically, I needed to set the standard libraries to ['Crun', 'Cstd']. I then had to change every library listed in the build file to link with the standard libraries (add the std_libs extension to all build_* functions in compile).

diff -r matplotlib-1.1.0/setupext.py matplotlib-1.1.0-modified/setupext.py
43a44,47
> SOLARIS
>
>   > python setup.py build --compiler=?
>
260a265,267
> elif sys.platform == 'sunos5':
>     std_libs = ['Crun', 'Cstd']
>     print "sunos5 libraries set"
343a351
>     module.include_dirs.append('/usr/include')
1044a1053,1054
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1057a1068,1069
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1071a1084,1085
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1094a1109,1110
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1113a1130,1131
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1153d1170
<
1154a1172,1174
>
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1187d1206
<
1188a1208,1210
>
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1221d1242
<
1222a1244,1246
>
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1249d1272
<
1250a1274,1276
>
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1270a1297,1299
>
> 	# put this last for library link order
>     delaunay.libraries.extend(std_libs)
1286d1314
<
1287a1316,1318
>
> 	# put this last for library link order
>     module.libraries.extend(std_libs)
1302d1332
<
1304a1335,1336
>     # put this last for library link order
>     module.libraries.extend(std_libs)
1305a1338
>
1323d1355
<
1325a1358,1359
>     # put this last for library link order
>     module.libraries.extend(std_libs)
1326a1361,1362
>
>
1340a1377,1380
>
>     # put this last for library link order
>     module.libraries.extend(std_libs)
>
setupext.py.diff

Compile!

If this is the only machine on which you need matplotlib, you can go ahead an run the standard Python build commands:

python setup.py build
python setup.py install

To build a multiple architecture matplotlib IPS package, the easiest thing to do is to build on a SPARC machine and an x86 machine. This means following these instructions twice, once on each machine.

In order to create a package of matplotlib for use on other machines, one should install to a "prototype" installation folder. Since Python is installed in /usr on S11, we create a faux "usr" directory in our prototype installation folder. Replace [sparc|i386] with whichever architecture you are currently building.

mkdir ../install_[sparc|i386]
mkdir ../install_[sparc|i386]/usr

Next, use the distutils --prefix option to install into your prototype installation folder.

  python setup.py install --prefix ../install_[sparc|x86]/usr

That's it! Now all we need to do is package it. :-)

Thanks to Yong Sun for his very helpful instructions on building version 0.98.3.

The next step after compiling is finding a way to distribute it. In part 2, I walk you through setting up the IPS servers you'll need to publish matplotlib for SPARC and x86.