Porting to Mac

From ASCEND
Jump to: navigation, search

ASCEND now runs successfully on Mac without problems. The remaining work is to package ASCEND as an installer or as an 'app', and to fix it so that it connects with Apple Events for opening files from the Finder, etc -- see below for details.

This article is about planned development or proposed functionality. Comments welcome.

Installing the necessary tools

You should install the following tools in order to be able to build ASCEND on Mac:

Building

When the above tools are installed and you have obtained the source code either from a file release or from our code repository, now you should be able to build ASCEND. Try just running

scons

There should be some output to tell you if you're missing any important components. Otherwise, you should then be able to run

./test.py TestSolver.testlog10

and you should see a message saying 'OK'. At this stage you have a complete working copy of ASCEND, possibly minus some of the userful solvers like IPOPT, IDA, CONOPT. The other important thing that you're missing is the GTK+ GUI library that allows ASCEND to present its user interface.

Building Native GTK+

The Easy Way

The good people who develop PyGTK have produced a pre-compiled package: PyGTK.pkg.

As of July 2011 this is in testing, it worked perfectly for me though. RichardTowers 21:56, 7 July 2011 (UTC)

The Hard Way

ASCEND uses GTK+ for its GUI. This is a cross-platform GUI library that works primarily on Linux but is also supported on Windows and Mac OS X. For Mac, it is currently necessary to build it from source, following the instructions from the GTK-OSX project.

Steps are something like this:

  • Make sure you have Xcode, subversion and git installed, as outlined at http://sourceforge.net/apps/trac/gtk-osx/wiki/Build
  • Download the script [1] and run it using 'sh gtk-osx-build-setup.sh' (no quotes).
  • Edit the resulting ~/.jhbuildrc-custom file, adding 'build_policy = "updated-deps"' as a line at the end of the file (no single quotes).
  • Set up an alias that will run jhbuild in a stripped down environment that does not contain any reference to the Fink (/sw/...) or MacPorts (?) directories (if you have them): A good option is to set
alias jhbuild="PATH=/opt/subversion/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin:~/gtk/inst ~/.local/bin/jhbuild"
  • According to the description on Sourceforge, build PyGTK as follows:
    • jhbuild bootstrap
    • jhbuild build meta-gtk-osx-bootstrap
    • jhbuild build meta-gtk-osx-core
    • jhbuild pygtk (or should it be: meta-gtk-osx-python ?)

You can now test that PyGTK is working by running python and checking that import gtk doesn't cause errors.

If that's working, you should be able to use your working copy of ASCEND (as above) to run pygtk/ascdev. This should open ASCEND, but you may have to command-tab to the correct window, as it won't pop to the front automatically.

Here's a screenshot of ASCEND on Native GTK-Quartz on OS X!

Error creating thumbnail: File missing
Screenshot of the PyGTK GUI running on Mac OSX with GTK-OSX (Quartz/Native GTK)

Note: currently, the ASCEND GUI on Mac still behaves much the same as it would on Windows or Linux; we haven't yet 'mackified' the keyboard shortcuts and menu layout. This will be using the 'ige-mac-integration' library that's also provided by the GTK-OSX project.

Note that allegedly it is also possible to build native GTK using macports, but we haven't yet tried that.

Building the Tcl/Tk GUI

No work yet to determine what will be required to the Tcl/Tk GUI running on Mac.

It may be fairly straightforward to get this GUI running, possibly using these binaries for Tcl/Tk:

Preparing for distribution

The following part is still under development.

Once GTK is build using jhbuild above, we need to re-package ASCEND in the form of a 'normal' Mac OS X application. To do this,

cd ~/ascend
python scons/installgtk.py
scons install INSTALL_PREFIX=~/ascinst

Those steps will first copy GTK and associated files into dist/PyGTK.bundle. Next, they will copy all the ASCEND files as well as PyGTK.bundle into ~/ascinst/ASCEND.app. Other files will be added to the ~/ascint folder, in preparation for making a .dmg disk image that will be suitable for distribution.

Currently, we are still working out some final bugs with the creation of the PyGTK.bundle, so this final step doesn't entirely work.

Development notes

Packaging and distribution

It's recommended for most Mac applications that everything be distributed as an Application Bundle that just be dragged by the user into their Applications folder. This is certainly possible with ASCEND, but a problem is that the ASCEND Model Library is something that we would like users to see and interact with. We would like users to be able to see these folders and their contents easily using the Finder. Nesting the files within an Application bundle makes this rather difficult.

One option would be for the ASCEND application to unpack its model library to ~/Library/Application Support/ASCEND when the program is first run. This would require Python scripting, and would not be compatible with a shared installation of the Tcl/Tk GUI on the same system.

Another option would be to install the model library in /Library/Application Support/ASCEND/Models. This seems to be the right way forward, but it means that ASCEND can no longer just be dragged to the Applications folder to be installed. Instead, it would need an Installer to place the necessary files on the user's system. That's quite desirable, though, because such an installer could also check that the user has the correct versions of Python, GTK and PyGTK already installed on the system, and could even possibly download and install them first if required.

It's worth noting that Mac editors like TextEdit can't peer into Application Bundles, but non-Mac editors like gedit can do so... they don't impose the same restriction on entering inside such bundles.

As a first attempt for getting everything running, it seems wise to take the simple application bundle approach.

We're not currently proposing to provide the Tcl/Tk GUI for Mac. This is a whole separate packaging problem.

We're not currently proposing to package libascend as a Framework for Mac, although that is an option, and would be appropriate if attempting to provide both Tcl/Tk and PyGTK GUIs on the same machine, and to make it easier for users to develop their own solvers, etc, on that platform.

The general opinion on GTK is that we should include it within out Application Bundle. From the linux point of view, this is terribly inefficient, but such things are standard practise on Mac, and we should respect that in the first instance.

The alternative of providing ASCEND to the Mac community as a Fink package was considered, however, according to Fink developers, the current 'stable' repository for Fink is very stagnant, so we are unlikely to be able to use that as a means for distribution.

If we want to distribute ASCEND as a multi-component thing (libascend framework, Tcl/Tk GUI, PyGTK, model library all separate) then we would need to use the Apple tool, PackageMaker, which allows developers to produce their own .pkg installers, apparently[1]. It is preferable to distribute a simple Application Bundle within a .dmg Disk Image.

Creating ASCEND.app

To create the ASCEND application bundle

  • scons -j2 install INSTALL_PREFIX=~/ascinst
  • The bundle will appear as ~/ascinst/ASCEND.app
  • TODO: add necessary GTK files to the .app!
  • follow instructions below to turn it into a redistributable disk image

The file mac/Info.plist contains all the key-value stuff describing the application. We had to make changes to pygtk/ascend.in to accommodate the particularities of the Mac platform, too.

Creating a Disk Image (ASCEND-0.9.X.dmg)

Some instructions are here: http://www.wikihow.com/Make-a-DMG-File-on-a-Mac

In summary:

  • use the Applications/Utilities/Disk Utility application
  • create a new image large enough for your needs
  • mount and open the image
  • from the Terminal, run scons -j2 install INSTALL_PREFIX=(location of your disk image folder)
  • set the folder background image to ~/ascend/mac/folder-background.png
  • arrange the files so that they look OK, the folder-background arrow should point from the ASCEND.app to the Applications folder alias.
  • return to the disk image program
  • click 'convert' and convert to a compressed image (OK to overwrite)
  • all done, you can double-click the image file now, and it should mount and appear as you wanted it.

Finding all the GTK files

To create a safely porting ASCEND.app, we need to embed all of GTK into the application bundle. The above application won't be complete until we achieve that.

Looks like some Python packages called modulefinder (built-in to Python) or modulegraph (external) may be able to help with locating all the necessary files for satisfying Python 'import' dependencies.

Then, otool ('otool -L') can be used to find shared library dependencies.

There are also some other files such as bitmaps, 'locale' files, and maybe others that will be required for correct running of GTK; these also need to be bundled.

The tool ige-mac-bundler seems to provide some degree of automation for this process, although it seems to be more oriented for C application than Python. We have some notes on how it works.

The shell-script gimpguts.sh, available from GIMPskel.zip on this page also contains some code for pulling in the necessary bits of GTK for packaging.

Our solution is a Python script that makes calls to 'otool' and 'modulefinder'. We hope to be able to incorporate this script into our SCons build scripts as a 'tool', but at the moment, scons/installgtk.py is standalone. This is still under development.

Most Mac libraries by default are hard-wired with absolute dependency paths as described by Joe Di Pol. The solution seems to be to post-process the shared libraries after they have been copied, using 'install_name_tool'.

Problems with non-english Systems

You need to set your System to english - it's not about your system user interface language and not about your keyboard, it about the Formats.

Go to System Preferences -> Interantional -> Formats

select english US and reboot your system.

If you do not take this step, ascend will ignore all decimal places. PI will be 3.0000 instead of 3.1415, numbers like 0.12345 will be 0.00000 possibly causing "Division by Zero" Errors.

Problems With Matplotlib

Matplotlib is used for all plotting by the PyGTK GUI, and Matplotlib in turn depends on NumPy. NumPy doesn't work correctly with Apple's System Python, so you have to install MacPython to use the standard binary releases of Matplotlib and NumPy. Alternatively, it's possible to go back and download older versions of NumPy that do run on Apple's Python, but you'll presumably be losing some functionaly as a result.

The conclusion from all this is that it might be advisable for ASCEND on the Mac to be linked against MacPython, and for a runtime check to be made to ensure that the correct version is in place.

Connecting to Apple Events

Currently, GTK on Mac has no support for receiving or sending Apple Events. This is a problem, because Mac OS X attempts to communicate using Apple Events when a file is to be opened. If the app is not listening for events, then nothing will happen.

However, there seems to be a workaround for the case of Python scripts: appscript, which contains a module called py-aem. It may be possible to incorporate this into ASCEND as a way for processing such events. There may be other similar modules, possible. Also, PyObjC may provide another way of creating event listeners. These modules are included by default with MacPython.

According to GTK-OSX, there has not yet been any attempt to incorporate this stuff into ige-mac-integration, although it was agreed that it would be desirable to integrate it there (to benefit also C-based GTK applications ported to Mac).

An alternative approach might be to write a very small Carbon/Cocoa application that could do the event listening, and pass the events on to the main application.

Alternative approach: Homebrew?

A new method[2] of obtaining GTK, SWIG, SCons and other tools is via Homebrew.

An initial check of Homebrew shows that although it provides GTK+, at this stage it only provides the X11 version of GTK+, which does not help with the task of creating native GTK+ ASCEND as desired here. Also, the 'gtk-demo' compiled by Homebrew seems to segfault, not sure what the reason for that was.

References

  1. http://s.sudre.free.fr/Stuff/PackageMaker_Howto.html
  2. http://blog.abhiomkar.in/2010/01/02/macports-to-homebrew-new-packaging-system-for-mac-os-x/