On Fri, 29 Oct 2010 09:46:03 +1300
Charles Manning <
manningc2@actrix.gen.nz> wrote:
> I then rebuilt with:
> arm-linux-gnueabi-gcc --static xx.c -o xx_arm
> which gave a 555kbytes binary which ran.
>
> What's the magic to get shared library building working?
Most preferable first:
0: use a build system or
1: write a custom Makefile or
2: specify all the commands on the command-line
The magic is the -I (capital i) to include headers not assumed by gcc
and -l (lower case L) to link against the shared libraries. The
specific paths and library names usually need to come from metadata like
pkgconfig or a build system Makefile. Your test program compiles in so
far as it does not yet need any include directives - that comes as soon
as you use more than the barest C functions. I haven't time right now
to test the sample code, but it is a -l (lower case L) option you're
likely to need.
Which shared libraries you need to specify doesn't usually vary from
native to cross building, it's the paths which change.
The process of identifying the dependencies is manual - each function
you use can bring in different shared libraries. Inspecting the
statically linked binary can help identify most of the libraries
necessary. Packaging tools can only help you *after* the code has been
compiled successfully.
None of this is balloon specific - most of the stuff isn't even
cross-compiling specific. Identification of shared library command line
options is common to all builds.
What differs with cross is that the cross version of the library needs
to be installed - but you've done that already for the static linking
to work.
It is probably as simple as:
arm-linux-gnueabi-gcc xx.c -lm -o xx_arm
In this case, /usr/lib/libm.so is the shared library to link against (I
haven't compiled the test code, I'm guessing it is libm, it may be
another, it could be a couple) and the cross version, naturally,
in /usr/arm-linux-gnueabi/lib/libm.so which is part of your
cross-compiling toolchain. By callign arm-linux-gnueabi-gcc, the path
change is already picked up.
The other option, (capital i) is to include stuff which the compiler
has not already found and generally whatever you add as specific
include directives must also appear as an explicit linkage.
It's much, much easier to do this with a build system - even writing a
custom Makefile only saves you from typos, you have to do all the
determination yourself. A modern build system will at least add these
"internal" linkages for you and will ensure that other linkages (like
libglib2.0-0 or libxml or whatever) are used consistently.
Compare the build logs of any particular package - the simpler the code
the better - to see the linkage and include directives being used.
https://buildd.debian.org/fetch.cgi?pkg=popt;ver=1.16-1;arch=armel;stamp=1273726993
Get to the build logs via these pages:
http://packages.qa.debian.org/p/popt.html
Enter the package name in the box top right to see a different package.
Click on the buildd logs: link on the centre right.
Click on the "Installed" link for the architecture you want, presumably
armel.
Skip through all the preamble and look for stuff like:
/bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I.
-I.. -I. -I.. -O2 -Wall -W -g -D_GNU_SOURCE -D_REENTRANT -MT popt.lo
-MD -MP -MF .deps/popt.Tpo -c -o popt.lo ../popt.c libtool: compile:
gcc -DHAVE_CONFIG_H -I. -I.. -I. -I.. -O2 -Wall -W -g -D_GNU_SOURCE
-D_REENTRANT -MT popt.lo -MD -MP -MF .deps/popt.Tpo -c ../popt.c -fPIC
-DPIC -o .libs/popt.o libtool: compile: gcc -DHAVE_CONFIG_H -I. -I..
-I. -I.. -O2 -Wall -W -g -D_GNU_SOURCE -D_REENTRANT -MT popt.lo -MD -MP
-MF .deps/popt.Tpo -c ../popt.c -o popt.o >/dev/null 2>&1 mv
-f .deps/popt.Tpo .deps/popt.Plo
and
/bin/bash ./libtool --tag=CC --mode=link gcc -O2 -Wall -W -g
-D_GNU_SOURCE -D_REENTRANT -no-undefined
-Wl,--version-script=../libpopt.vers -o libpopt.la -rpath /usr/lib
popt.lo poptparse.lo poptconfig.lo popthelp.lo poptint.lo
libtool: link: gcc
-shared .libs/popt.o .libs/poptparse.o .libs/poptconfig.o .libs/popthelp.o .libs/poptint.o
-Wl,--version-script=../libpopt.vers -Wl,-soname -Wl,libpopt.so.0
-o .libs/libpopt.so.0.0.0
There is nearly always duplication in the options list created by any
build system but duplication is not a problem for the compiler, only
for the human reader.
In most cases, the include directives are separate from the linkages
because most modern build systems create a set of temporary object files
and then link those together.
For cross-compiling, all that differs is that the include path, if you
need it, needs to be the cross path. The path to the cross library at
the link stage only needs to be left to the linker (which, as it's
part of arm-linux-gnueabi-gcc knows where to look). Some awkward builds
overwrite this value which is a PITA.
Naturally, if you link against shared libraries in the build, those
libraries must also exist on the balloon. -cross packages on the build
machine, ordinary packages on the loon. This is where a packaging
system is strongly recommended, as well as a build system because
tools exist to calculate these things and ensure the linked objects
exist.
--
Neil Williams
=============
http://www.data-freedom.org/
http://www.linux.codehelp.co.uk/
http://e-mail.is-not-s.ms/