cross compiling octave

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

cross compiling octave

John W. Eaton-6
After much confusion and many false starts, I've finally managed to
construct a set of cross-compiler tools for compiling Cygwin programs
on a Linux system, and I've also made some changes to Octave's
configure script and Makefiles so that cross compiling will work.

Details can be found in the script below, which I've used to build the
cross tools.  At the end, it prints out a message explaining what else
needs to be done by hand to complete the cross build of Octave.

I'm posting the script here in case anyone else wants to give this a
try.  I downloaded the CVS version of Cygwin after failing to get the
results I wanted with several other combinations of compilers and
Cygwin sources.

Once I had the working cross compiler, I tried to use it to build
ncurses and readline libraries, but gave up after I failed to build
ncurses.  Simply copying these libraries from a working Cygwin sytem
seemed to be a much easier solution.

With these tools on my 1.4GHz Athlon system it takes about 25 minutes
to do a complete build vs. about 45 minutes to do the same build using
Windows+Cygwin running under vmware on the same hardware.  With gcc
2.95 on the Linux system doing a native build, it only takes about 12
minutes.  For comparison, I just tried a native Linux build with
gcc-3.2, and it takes about 20 minutes, so it seems that gcc-3.2 is
considerably slower than gcc-2.95, and even slower when it is doing a
cross compile.  Hmm.

jwe



#! /bin/sh

set -e

## Get a copy of the following sources before starting:

binutils_src="binutils-2.13"
gcc_src="gcc-3.2"
winsup_src="winsup-cvs"

## Set top directory.  This directory should contain the source trees.

topdir=`pwd`

## Install directory and target

prefix=/usr/local/cross
target=i386-pc-cygwin

## Prepare build directories

builddir=$topdir/build

mkdir $builddir $builddir/binutils $builddir/gcc $builddir/winsup

## Build and install a cross version of binutils:

cd $builddir/binutils
$topdir/$binutils_src/configure --target=$target --prefix=$prefix
make all install

## Fix PATH:

PATH=$prefix/bin:$PATH

## Copy include files from newlib and winsup to cross dir:

inctop=$prefix/$target
for d in newlib/libc winsup/cygwin ; do
  echo $d
  cd $topdir/$winsup_src/$d
  for f in `find include -name '*.h'` ; do
    dest="$inctop/`dirname $f`"
    if [ ! -d $dest ]; then mkdir $dest ; fi
    if [ -f $inctop/$f ]; then echo $f ; else cp $f $dest ; fi
  done
done

## Patch $prefix/$target/include/sys/errno.h.  The modified version of
## the errno file will be overwritten after building.

cd $inctop/include/sys

patch << EOF
--- errno.h~ 2002-10-07 14:24:11.000000000 -0500
+++ errno.h 2002-10-07 14:32:47.000000000 -0500
@@ -15,6 +15,7 @@
 extern int *__errno _PARAMS ((void));
 #endif
 
+#if 0
 /* Please don't use these variables directly.
    Use strerror instead. */
 extern __IMPORT _CONST char * _CONST _sys_errlist[];
@@ -23,6 +24,7 @@
 extern __IMPORT const char * const sys_errlist[];
 extern __IMPORT int sys_nerr;
 #endif
+#endif
 
 #define __errno_r(ptr) ((ptr)->_errno)
EOF

## Build and install a cross version of gcc (no libs):

cd $builddir/gcc
$topdir/$gcc_src/configure \
  --enable-languages="c,c++,f77" \
  --with-included-gettext \
  --target=$target \
  --enable-shared \
  --prefix=$prefix \
  --with-newlib
make all-gcc install-gcc

## Finish building all of gcc:

make all install

## Build and install cygwin:

cd $builddir/winsup
$topdir/$winsup_src/configure --target=$target --prefix=$prefix
make all install

## Rearrange some include files and libraries:

cd $prefix/$target/include
mv w32api/* .
rmdir w32api

cd $prefix/$target/lib
mv w32api/* .
rmdir w32api

## Prompt the installer to do some stuff by hand:

cat << EOF

Now you should copy some things from your existing Cygwin installation:

  /usr/include/readline   -> $prefix/$target/include
  /usr/include/ncurses    -> $prefix/$target/include
  /usr/lib/libreadline.a  -> $prefix/$target/lib
  /usr/lib/libncurses.a   -> $prefix/$target/lib
  /usr/lib/libncurses++.a -> $prefix/$target/lib

Then you can build octave with something like:

  configure --host=$target
  make

This should detect $target-gcc, $target-g++, etc. as cross-compiler
tools if you still have $prefix/bin in your path.

Octave's build process also compiles and runs a few C/C++ programs on
the build system that are used for constructing documentation files.
Since these programs must run on the build system, they can't be
compiled by the cross compiler.  The rules to compile them use
$(BUILD_CC) and $(BUILD_CXX) instead of $(CC) and $(CXX).  By default,
configure will set BUILD_CC=gcc and BUILD_CXX=g++, so it should work
without having to set those variables by hand if gcc and g++ are
available on the build system to compile programs that are needed
during the build process (but not to run on the host system).

EOF