Posts Tagged ‘metis’

taucs on Mac OS X

Tuesday, July 13th, 2010

Yesterday I spent way too long trying to get taucs compiled and linking on a Mac machine running OS X 10.6.

Because my Qt is compiling for 32 bits I needed a 32-bit/i386 libtaucs.a, this was not so easy. I began hoping to compile a universal library, but couldn’t manage to do it. I’ve previously posted about how to compile a 64-bit version of taucs on a mac 10.6 machine (this was not so bad).

Update: Thanks to the useful comment below, I’ve modify these steps so that the result is a unviersal (32-bit and 64-bit) libtaucs.a

Part one: Compiling libtaucs.a (universal)

In the taucs directory (here on out [taucs] issue the following:


cp config/darwin.mk config/darwin10.0.mk

Then open up config/darwin10.0.mk and edit the following lines to look like this:


CFLAGS    = -arch i386 -arch x86_64 -O3 -faltivec

LIBBLAS   = -framework Accelerate
LIBLAPACK = -framework Accelerate
LIBMETIS  = -lmetis

LIBF77 = -lf2c

Now, this part is really messy but hopefully I’ll remember everything I did. Before compiling libtaucs.a we need to compile libf2c.a and libmetis.a, and we need to do it so that both are at least i386. I think I managed to get mine to both be universal (i386 and x86_64).

So, I’ve stripped these commands out of the buildf2c.sh script. Issue them in a terminal:


curl http://netlib.sandia.gov/cgi-bin/netlib/netlibfiles.tar?filename=netlib/f2c -o "f2c.tar"
tar -xvf f2c.tar
gunzip -rf f2c/*
cd f2c
unzip libf2c.zip -d libf2c
cd ..
sed 's/CC = cc/CC = \/usr\/bin\/cc/' f2c/libf2c/makefile.u > f2c/libf2c/makefile
sed 's/CC = cc/CC = \/usr\/bin\/cc/' f2c/src/makefile.u > f2c/src/makefile

At this point we need to edit the makefiles to make sure that they build universal libraries:

In libf2c/makefile edit the following lines to look like this:


CFLAGS = -arch x86_64 -arch i386 -O
LDFLAGS += -arch x86_64 -arch i386

# compile, then strip unnecessary symbols
.c.o:
        $(CC) -c -DSkip_f2c_Undefs $(CFLAGS) $*.c
#        ld $(LDFLAGS) -r -x -o $*.xxx $*.o
#        mv $*.xxx $*.o

AND AGAIN in src/makefile edit the following lines to look like this:


CFLAGS = -arch x86_64 -arch i386 -O
LDFLAGS += -arch x86_64 -arch i386

# compile, then strip unnecessary symbols
.c.o:
        $(CC) -c -DSkip_f2c_Undefs $(CFLAGS) $*.c
#        ld $(LDFLAGS) -r -x -o $*.xxx $*.o
#        mv $*.xxx $*.o

Note: Be sure to comment out the ld ... and mv ... lines above.

Now back to compiling:


cd f2c/libf2c
make f2c.h
if test ! -d /usr/local/include; then
    sudo mkdir -p /usr/local/include
fi
sudo cp f2c.h /usr/local/include/
make
if test ! -d /usr/local/lib; then
    sudo mkdir -p /usr/local/lib
fi
sudo cp libf2c.a /usr/local/lib/
sudo ranlib /usr/local/lib/libf2c.a
cd ../src
make
if test ! -d /usr/local/bin; then
    sudo mkdir -p /usr/local/bin
fi
sudo cp f2c /usr/local/bin/
cd ..
chmod +x fc
sudo cp fc /usr/local/bin
sudo ln  -s /usr/local/bin/fc /usr/local/bin/f77
sudo chmod +x /usr/local/bin/f77

Following the rest of the buildf2c.sh on your own to build the executables.

Next, we need to compile libmetis.a.

Download and unzip the source then in the metis folder edit Makefile.in:


# What options to be used by the compiler
COPTIONS = -arch i386 -arch x86_64

# What options to be used by the loader
LDOPTIONS = -arch i386 -arch x86_64

Then issue:


make

and then


sudo cp libmetis.a /usr/local/lib/

Now, finally, go back to [taucs]. Here you can issue:


./configure
make

This should produce a universal libtaucs.a library.

Part two: Using libtaucs.a

You should have no problem compiling any of the examples, like those in [taucs]/progs, as long as you include the right headers and the library. For example I can issue the following (be sure to replace the [taucs]s):


cc -arch i386 -o direct [taucs]/progs/direct.c \
-I[taucs]/src/ -I[taucs]/build/darwin10.0/ \
-L[taucs]/lib/darwin10.0/ -ltaucs -framework \
Accelerate -lmetis -lf2c

or


cc -arch x86_64 -o direct [taucs]/progs/direct.c \
-I[taucs]/src/ -I[taucs]/build/darwin10.0/ \
-L[taucs]/lib/darwin10.0/ -ltaucs -framework \
Accelerate -lmetis -lf2c

Though I do get the warning:


In file included from taucs_with_LU/src/taucs.h:7,
                 from taucs_with_LU/progs/direct.c:17:
taucs_with_LU/build/darwin10.0/taucs_config_build.h:5:24: warning: missing whitespace after the macro name

This is because of a #define that uses darwin10.0 and periods are not allowed.

Update:

If you are using a mac then taucs will try to define a macro called OSTYPE and set it to an invalid c value: darwin10.0 (invalid because of the period). As a result whenever you include taucs.h you’ll get hundreds of warnings. I fix this by opening [taucs]/build/taucs_config_build.h and commenting out the following lines before I make:


/* This is an automatically generated file */
/* Configuration name: anonymous */
//#define TAUCS_OSTYPE darwin10.0
...
//#define OSTYPE_darwin10.0
...

You should also be able to compile this simple c program, saved in taucs_super_simple.c:


#include <taucs.h>
int main(int argc, char* argv[])
{
  double x = taucs_get_nan();
  return 1;
}

I can compile and run this with:


cc -arch i386 -o taucs_super_simple taucs_super_simple.c \
-I[taucs]/src/ -I[taucs]/build/darwin10.0/ \
-L[taucs]/lib/darwin10.0/ -ltaucs -framework Accelerate
./taucs_super_simple

Now if you try the same simple program, naively translated to cpp like this, saved in taucs_super_simple.cpp:


extern "C"{
#include <taucs.h>
}
int main(int argc, char* argv[])
{
  double x = taucs_get_nan();
  return 1;
}

and you try to compile with something like this:


c++ -arch i386 -o taucs_super_simple taucs_super_simple.cpp \
-I[taucs]/src/ -I[taucs]/build/darwin10.0/ \
-L[taucs]/lib/darwin10.0/ -ltaucs -framework Accelerate

You’ll get a bagillion of these errors:


/usr/include/c++/4.2.1/complex:1104: error: template with C linkage

That’s because taucs.h uses some complex library that is weird. Not sure why exactly you have to do this, but just add:


#include <complex>

above

extern "C"{
#include <taucs.h>
}

Do this anytime you include taucs. This should now compile with the above command.

Compiling libtaucs.a for Mac OS X 10.6

Monday, July 12th, 2010

This was my second attempt at compiling taucs for a mac. After some frustrating compiling and recompiling, I think I’ve figured out how to do it.

In the taucs directory:


cp config/darwin.mk config/darwin10.0.mk

Then edit the following lines in config/darwin10.0.mk to look like this:


LIBBLAS   = -framework Accelerate
LIBLAPACK = -framework Accelerate

Remove the libf2c.a file if it came with your taucs distribution:


rm external/lib/libf2c.a

Follow these instructions for downloading and using the buildf2c.sh script. This will install the libf2c.a file in /usr/local/lib/

Download the metis source and build it. For me this just meant issuing make.

Then copy the libmetis.a file from the metis directory to the taucs directory (change paths accordingly):


cp metis-4.0/libmetis.a taucs/external/lib/libmetis.a

Finally in the taucs directory you can configure and make:


./configure
make

Update: The above solution produces a 64-bit, x86_64 library on a 10.6 mac machine. Unfortunately I need a 32-bit, i386 library (or universal) because Qt still defaults to 32-bits.