I use this blog as a soap box to preach (ahem... to talk :-) about subjects that interest me.

Tuesday, January 4, 2011

Fortran and Eclipse on the Mac

In this post, I describe how I installed a Fortran compiler within Eclipse on my 64-bit Macintosh running the Snow Leopard system (OS X 10.6.5).


The first step was to get the “Eclipse IDE for C/C++ Developers” Helios package from
http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr. I downloaded the file eclipse-cpp-helios-macosx-cocoa-x86_64.tar.gz (86.9 MB) by clicking on the “Mac OS X(Cocoa 64)” link. The Helios release (Eclipse 3.6 of 2010-06-23) includes the Photran package.

I placed the downloaded file in a directory I will identify with /basedir/ for simplicity. I completed the installation of the package by expanding it. The Eclipse application was in /basedir/eclipse/Eclipse.app

Photran is part of Eclipse's Parallel Tool Platform (PTP). Therefore, the next step was to install PTP. To do so, I performed the following steps from within Eclipse:
  • Opened “Help > Install New Software...”
  • Chose “Helios - http://download.eclipse.org/releases/helios” in “Work with:” drop down menu.
  • Expanded the “General Purpose Tools” category by clicking on the little triangle on its left.
  • Scrolled down until I reached the PTP-related items and selected four of them as shown in the following snapshot:

  • In the “Programming Languages” category, I selected Fortran as shown in the following snapshot:
  • Clicked on “Next” and then on “Finish”, restarting Eclipse when prompted.
    The default Fortran compiler for Eclipse is gfortran. But as Eclipse Helios is a 32-bit application, I had to download the gfortran for MacOS X Tiger and Leopard, not for the latest Snow Leopard, which is a 64-bit OS. To get the 32-bit version of gfortran, I went to http://hpc.sourceforge.net/ and clicked on
    gfortran-leopard-intel-bin.tar.gz (Intel Mac gfortran only), updated June 2009 (Leopard only)
    (14.6 MB)

    After expanding it into /basedir/, I got a folder named usr with inside a folder named local. Clearly, I was supposed to expand it from the root directory.
    So, I typed in a terminal window (as root) the following command:

    $ mv -v /Basedir/usr/local/* /usr/local/
    /Basedir/usr/local/bin -> /usr/local/bin
    /Basedir/usr/local/include -> /usr/local/include
    /Basedir/usr/local/lib -> /usr/local/lib
    /Basedir/usr/local/libexec -> /usr/local/libexec
    /Basedir/usr/local/share -> /usr/local/share

    Note that there must not be spaces in the directory names, because gfortran/gcc cannot cope with it. Be aware that gfortran is also available from http://gcc.gnu.org/wiki/GFortranBinaries, but if you download from there the file gfortran-macosx-x86.dmg allegedly for Tiger and Leopard, you actually get the 64-bit gfortran for Snow Leopard! Perhaps they have fixed it by now...

    When I tried to compile a simple Fortran program, “make” reported the following error on the Eclipse console:

    **** Build of configuration Release for project ftest ****
    make all
    Building file: ../ftest.for
    Invoking: GNU Fortran Compiler
    gfortran -funderscoring -O3 -Wall -c -fmessage-length=0 -o"ftest.o" "../ftest.for"
    /bin/sh: gfortran: command not found
    make: *** [ftest.o] Error 127

    The problem occurred because Eclipse doesn’t get the paths from /etc/paths, but from the XML file ~/.MacOSX/environment.plist
    as explained in:
    and

    Indeed, if you look at /etc/paths you find:

    /usr/bin
    /bin
    /usr/sbin
    /sbin
    /usr/local/bin

    Here is what I did to create the necessary file:

    $ cd
    $ mkdir ~/.MacOSX
    $ cd ~/.MacOSX
    $ cat > environment.plist
    <xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
      <key>PATH</key>
      <string>/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
    </dict>
    </plist>
    cntl-D

    environment.plist sets the environment for all processes launched by a specific user.
    I logged out and back in on the Mac, to force a loading of environment.plist.

    At this point, I could launch my test program by double-clicking on its icon, but not from within Eclipse. Eclipse’s “Binaries” folder was not there. This was bad also because without binaries I couldn’t use the debugger. The problem was that Snow Leopard by default compiles objects for 64-bit processors, while Eclipse Helios only understands 32-bits. I found the explanation in:

    Fortunately, beside gcc 4.2, which is the default C compiler, Snow Leopard also has gcc 4.0, which compiles to 32 bits. What I needed to do was to force the system to use it. Obviously, it is a bit sad to have to generate 32-bit applications when your system can handle 64-bits, but I felt that the convenience of using Eclipse was too good to give up. Once debugged with Eclipse, I could always recompile the program to run on 64 bits. And probably the next version of Eclipse will be 64-bit savvy.

    Anyhow, To use 4.0 as a default, I had to go to /usr/bin and type the following as root:

    $ cd /usr/bin
    $ rm cc gcc c++ g++
    $ ln -s gcc-4.0 cc
    $ ln -s gcc-4.0 gcc
    $ ln -s c++-4.0 c++
    $ ln -s g++-4.0 g++

    But there was still a problem: When I tried to debug, Eclipse reported dozens of errors like the following two (for libgfortran and libgcc):

    warning: Could not find object file "/Users/gkhanna/gcc-4.4-20090623/i386-apple-darwin9.7.0/libgfortran/.libs/matmul_r8.o" - no debug information available for "../.././libgfortran/generated/matmul_r8.c".

    warning: Could not find object file "/Users/gkhanna/gcc-4.4-20090623/i386-apple-darwin9.7.0/libgcc/_muldi3_s.o" - no debug information available for "../.././libgcc/../gcc/libgcc2.c".

    But the debugger worked! I could set breakpoints in Fortran! And there was no user named gkhanna on my Mac. G.Khanna was the guy who built the libraries I downloaded from http://hpc.sourceforge.net/ . He clearly built them with objects that had the debugging information in them. He should have stripped the debugging symbols from the objects before building the libraries. I got this information from a couple of places, including: http://www.macresearch.org/gfortran-leopard

    I typed
    $ nm -a libgfortran.3.dylib | grep matmul_r8
    and got the following:

    00000000 - 00 0000 SO ../.././libgfortran/generated/matmul_r8.c
    4a443ad3 - 00 0001 OSO /Users/gkhanna/gcc-4.4-20090623/i386-apple-darwin9.7.0/libgfortran/.libs/matmul_r8.o
    00063a80 T __gfortran_matmul_r8
    00063a80 - 01 0000 FUN __gfortran_matmul_r8

    This meant that Eclipse was using the dynamic libraries. I needed to strip the debugging symbols from them. To be on the safe side, I made two copies of the dynamic libraries and worked on one of the copies, so that I could always revert to the original libraries if something went wrong.

    $ cd work_copy
    $ ls –l
    total 2736
    -rw-r--r--@ 1 giulio staff 261384 26 Jun 2009 libgcc_s.1.dylib
    -rw-r--r--@ 1 giulio staff 17372 26 Jun 2009 libgcc_s.10.4.dylib
    -rw-r--r--@ 1 giulio staff 17500 26 Jun 2009 libgcc_s.10.5.dylib
    -rwxr-xr-x@ 1 giulio staff 996600 26 Jun 2009 libgfortran.3.dylib
    -rwxr-xr-x@ 1 giulio staff 76948 26 Jun 2009 libgomp.1.dylib
    -rwxr-xr-x@ 1 giulio staff 17040 26 Jun 2009 libssp.0.dylib
    $ strip -x libgcc_s.1.dylib
    $ strip -x libgcc_s.10.4.dylib
    strip: dynamic stub library can't be changed once created: /usr/local/lib/work_copy/libgcc_s.10.4.dylib (for architecture i386)
    $ strip -x libgcc_s.10.5.dylib
    strip: dynamic stub library can't be changed once created: /usr/local/lib/work_copy/libgcc_s.10.5.dylib (for architecture i386)
    $ strip -x libgfortran.3.dylib
    $ strip -x libssp.0.dylib
    $ ls -l
    total 2264
    -rw-r--r-- 1 giulio staff 202368 6 Sep 18:46 libgcc_s.1.dylib
    -rw-r--r--@ 1 giulio staff 17372 26 Jun 2009 libgcc_s.10.4.dylib
    -rw-r--r--@ 1 giulio staff 17500 26 Jun 2009 libgcc_s.10.5.dylib
    -rwxr-xr-x 1 giulio staff 818288 6 Sep 18:47 libgfortran.3.dylib
    -rwxr-xr-x@ 1 giulio staff 76948 26 Jun 2009 libgomp.1.dylib
    -rwxr-xr-x 1 giulio staff 13548 6 Sep 18:47 libssp.0.dylib

    When I copied the stripped libraries back to /usr/local/lib/ and tried again my test program in Eclipse, I was happy to see that all nasty warning messages had disappeared!

    4 comments:

    1. Hi Giulio,

      thank you very much for posting these great instructions on getting eclipse to run with fortran!
      I followed closely, and now have it working.
      Unfortunately, only after that I found out that there is a follow up post, suggesting to install SR1 of eclipse. The screenshots suggest you did that. Did you have to change any settings of the fortran 32 bit setup described in this post?
      This brings me to another question: How did you "install" the new eclipse SR1? Just downloaded, then do you get a folder with an eclipse.app in it? Did you put that folder into /Applications ? Did you remove the old eclipse folder first?

      Thanks again for your great posts!

      Cheers,
      Claus

      ReplyDelete
    2. Hi Claus,

      I'm happy you found my information useful.

      To update Eclipse, including PTP, click on the "Install New Software" of the "Help" menu. Type http://download.eclipse.org/tools/ptp/updates/helios in the "Work with" field and then click on the button "Add" to its right.

      Then, select "--All Available Sites--". In the field below, select the packages you want to upgrade and follow the instructions.

      If you are not sure what versions you have, click on the link "already installed" and take a snapshot as a reference.

      Everything kept working as before. I didn't need to do anything. Somehow, I expected it, because the new versions are not very different from the previous ones.

      Good luck!

      Giulio.
      P.S. And find me some new flags ;-)

      ReplyDelete
    3. I got eclipse PTP as a single package then installed gfortran, finally I edited the eclipse fortran project (makefile) to point to the full path of gfortran and that is it. It is just working.

      ReplyDelete
    4. Thanks for your comment. This post is almost three and a half years old. I would expect that things have change since I wrote it.
      I'm happy that there are people "out there" who use fortran. Perhaps it is because it makes me feel less "obsolete"! It was the first computer language I learnt, using punched cards on a Univac mainframe, when personal computers were still something for Science Fiction stories.

      Ciao, Giulio.

      ReplyDelete