Smoother cross compilation of 1.3.12



I've managed to cross compile the related libraries for gtk 1.3.12 for a
variety of architectures. It's painful, but doable.

A couple comments on making this easier, but first some background on
what I'm doing and how. The linux environment I'm working in supports
cross compilation, from a host of x86/ppc/solaris to a target of
mips/arm/x86/ppc. It also supports native compilation on the
mips/arm/x86/ppc box.

The target machine usually NFS mounts its root directory from /opt/*. I
note (usually). So the cross compilation process has to be able to
dynamically place the libraries and binaries anywhere on the filesystem
- and yet support native compilation, and preferably do all of it from
the databases kept on the target systems /opt/*/usr/lib/pkgconfig and
/opt/*/usr/lib/*.la (dirs, and others)

Therein lies problems A & B. 

pkg-config has no real notion of cross compilation except for the
bootstrapping process {pc_top_builddir}. 

The .pc files for the related packages, although they have the ability
to overwrite the --prefix, --libdir, etc, tend not to use the prefixes
in actual use for the libdir arg. (see pango-0.23 for an example -
libdir and includedir do not depend on {prefix})

There's three ways to do it - one is keep a separate pkgconfig database
on the host machine, and hand tweak the .pc files if the target dir
moves. A second is to normalize the .pc files, run a script to extract
out the prefix info on a per file basis, and do other magic to insure
that the libdir is actually wherever it is at compile time.

and the third way is to patch pkgconfig to use a new environment
variable and ask (beg), pkg-config users to use it or something like it
in creating their .pc files. 

I chose the third way.

Patched pkgconfig to support an environment variable
"CROSS_COMPILE_DIR", and modified the 

Now I can have one database of pkgconfig code, modifiable at
compiletime... if only I can convince the world to stick a:

prefix=${CROSS_COMPILE_PREFIX} prefix@

in their pc files.

patches available on request. Also patched pkg-config to use the native
glib library rather than build it's own as compiling glib is a pain...
as per problem C)

Problem B) autoconf

All the new code and much of the higher end code (gnome, etc) depend on
libtool. My personal feelings about this obscure shell script aside,
it's got problems in a cross compilation environment - typically libtool
will fail on a link step because it decodes a .la file, then does magic
parsing of a -lsomething into a /usr/lib/something.so - which is
typically a native host library and not what I want.

It would be really great to just turn off -l parsing in libtool and let
the gcc compiler figure it out. I couldn't figure it out. 

so I wrote a script that postprocesses and demangles the libtool
generated .la file. 

It gets rid of /usr/lib/*.la references, the -L references, any
hardcoded paths to -l in the dependency_libs variable, and makes
libdir=$CROSS_COMPILE_PREFIX'/usr/lib', etc.

Is there a better solution?

Problem C) glib-1.3.12 requires a plethora of environment variables in
order to get through configure, and a couple patches to configure.in,
and 

(this is where the ability to do a native compile, at least once, is
really handy)

For the record, for hard hat linux, these were:

export ac_cv_func_getpgrp_void='yes'
export ac_cv_func_setvbuf_reversed='no'
export ac_cv_sys_restartable_syscalls='yes'
export ac_cv_func_getpwuid_r='yes'
export ac_cv_func_posix_getpwuid_r='yes'
export glib_cv_has__inline='yes'
export glib_cv_has__inline__='yes'
export glib_cv_hasinline='yes'
export glib_cv_sane_realloc='yes'
export glib_cv___va_copy='yes'
export glib_cv_va_copy='no'
export glib_cv_va_val_copy='yes'
export glib_cv_sizeof_gmutex=24
export glib_cv_rtldglobal_broken='no'
export glib_cv_uscore='no'
export glib_cv_stack_grows=no
export ac_cv_sizeof_pthread_mutex_t=24
export ac_cv_sizeof_fpos_t=12
export ac_cv_sizeof_float=4
export ac_cv_sizeof_char=1
export ac_cv_sizeof_void_p=4
export ac_cv_sizeof_int=4
export ac_cv_sizeof_long_long=8
export ac_cv_sizeof_off_t=4
export ac_cv_sizeof_pthread_t=4
export glib_sizeof_pthread_t=4
export ac_cv_sizeof_short=2
export ac_cv_sizeof_double=8
#export ac_cv_page_size=4096 ? 
export ac_cv_sizeof_wchar_t=4
export ac_cv_sizeof_uintptr_t=4
export ac_cv_sizeof_long=4
export glib_cv_sizeof_size_t=4
export glib_cv_sizeof_ptrdiff_t=4
export glib_cv_sizeof_intmax_t=4
export glib_cv_sizeof_system_thread=4
export ac_cv_sizeof___int64=8
export glib_cv_long_long_format=ll
export posix_priority_min='sched_get_priority_min(SCHED_OTHER)'
export posix_priority_max='sched_get_priority_max(SCHED_OTHER)'


export glib_genmarshal=%{_hhl_host_bin_dir}/glib-genmarshal

Note that glib_genmarshal thing - yes, you need to natively compile
glib2 before you can cross compile it. It would be nice to have
CROSS_COMPILE support in the makefiles for host and target, but, all
I did was patch the makefile to allow genmarshal to be a external
program so you do a make glib-genmarshal=local_glib_genmarshal


--- gobject/Makefile.am Sat Nov 17 16:38:47 2001
+++ gobject/Makefile.am.new     Thu Dec 27 00:35:34 2001
@@ -157,13 +157,13 @@
 $(srcdir)/stamp-gmarshal.h: @REBUILD@ gmarshal.list gmarshal.h
glib-genmarshal$(EXEEXT)
        echo "#ifndef __G_MARSHAL_H__" > xgen-gmh \
        && echo "#define __G_MARSHAL_H__" >> xgen-gmh \
-       && ./glib-genmarshal --nostdinc --prefix=g_cclosure_marshal
$(srcdir)/gmarshal.list --header >> xgen-gmh \
+       && $(glib_genmarshal) --nostdinc --prefix=g_cclosure_marshal
$(srcdir)/gmarshal.list --header >> xgen-gmh \
        && echo "#endif /* __G_MARSHAL_H__ */" >> xgen-gmh \
        && (cmp -s xgen-gmh $(srcdir)/gmarshal.h || cp xgen-gmh
$(srcdir)/gmarshal.h) \
        && rm -f xgen-gmh xgen-gmh~ \
        && echo timestamp > $@
 $(srcdir)/gmarshal.c: @REBUILD@ $(srcdir)/stamp-gmarshal.h
-       ./glib-genmarshal --nostdinc --prefix=g_cclosure_marshal
$(srcdir)/gmarshal.list --body >> xgen-gmc \
+       $(glib_genmarshal) --nostdinc --prefix=g_cclosure_marshal
$(srcdir)/gmarshal.list --body >> xgen-gmc \
        && cp xgen-gmc $(srcdir)/gmarshal.c \
        && rm -f xgen-gmc xgen-gmc~
 $(srcdir)/gmarshal.strings: @REBUILD@ $(srcdir)/gmarshal.list


And so on.

Another patch to configure.in

--- configure.in        Thu May  3 18:32:12 2001
+++ configure.in.new    Thu May  3 18:34:05 2001
@@ -1022,6 +1022,9 @@
                        G_THREAD_LIBS="-pthread"
                fi
                ;;
+            *linux*) # Linux has pthreads. Period. Why test?
+                       G_THREAD_LIBS="-lpthread"
+               ;;
              *)
                for thread_lib in "" pthread pthread32 pthreads c_r
thread dce; do
                        if test x"$thread_lib" = x; then



A more controversial patch to configure.in - I don't need ansi
prototypes - but I suppose we should propose environment variables that
would let you bypass this test. 

--- configure.in        Thu Nov 22 10:00:09 2001
+++ configure.in.new    Wed Dec 26 23:39:58 2001
@@ -312,26 +312,6 @@
   fi
 fi

-dnl DU4 native cc currently needs -std1 for ANSI mode (instead of K&R)
-AC_MSG_CHECKING([for extra flags to get ANSI library prototypes])
-glib_save_LIBS=$LIBS
-LIBS="$LIBS -lm"
-AC_TRY_RUN([#include <math.h>
-             int main (void) { return (log(1) != log(1.)); }],
-     AC_MSG_RESULT(none needed),
-     glib_save_CFLAGS=$CFLAGS
-     CFLAGS="$CFLAGS -std1"
-     AC_TRY_RUN([#include <math.h>
-                 int main (void) { return (log(1) != log(1.)); }],
-         AC_MSG_RESULT(-std1),
-         AC_MSG_RESULT()
-         CFLAGS=$glib_save_CFLAGS
-         AC_MSG_WARN(
-                [No ANSI prototypes found in library. (-std1 didn't
work.)])
-     )
-)
-LIBS=$glib_save_LIBS
-
 dnl NeXTStep cc seems to need this
 AC_MSG_CHECKING([for extra flags for POSIX compliance])
 AC_TRY_COMPILE([#include <dirent.h>], [DIR *dir;],
@@ -1424,7 +1404,10 @@
                        [AC_MSG_RESULT(yes)
                          AC_DEFINE(G_THREAD_USE_PID_SURROGATE, 1,
[whether to use the PID niceness surrogate for thread priorities])
                         ],
-                       [AC_MSG_RESULT(no)])
+                       [AC_MSG_RESULT(no)],
+                       [AC_MSG_RESULT(yes)
+                         AC_DEFINE(G_THREAD_USE_PID_SURROGATE, 1,
[whether to use the PID niceness surrogate for thread priorities])
+                        ])
        elif test x"$have_threads" = xwin32; then
                # It's a pointer to a private struct
                GLIB_SIZEOF(,struct _GThreadData *, system_thread)


And this patch is just me being lazy. I suspect some cpp hacking might
"just work".

--- acglib.m4   Fri Dec  8 14:48:45 2000
+++ acglib.m4.new       Thu May  3 16:59:57 2001
@@ -111,6 +111,7 @@
 else
   glib_nl='\n'
 fi
+if false; then
 AC_MSG_CHECKING(system definitions for $glib_sysdef_msg)
 cat >confrun.c <<_______EOF
 #include <stdio.h>
@@ -146,4 +147,10 @@
        done
        AC_MSG_RESULT(failed)])
 rm -f confrun.c
+else
+echo -e "#define GLIB_SYSDEF_POLLIN =1\n#define GLIB_SYSDEF_POLLOUT =4
+#define GLIB_SYSDEF_POLLPRI =2\n#define GLIB_SYSDEF_POLLERR =8
+#define GLIB_SYSDEF_POLLHUP =16\n #define GLIB_SYSDEF_POLLNVAL =32"
>>$glib_sysdefso
+AC_MSG_RESULT(done)
+fi
 ])

Problem D) pango

pango wants to run tools and tests even if cross compiling. Should just
default to generating them. Trivial patch...

Problem E) gtk+ 

At this point gtk+ cross compiles... with a few more trivial patches
along the same lines as the above.....





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]