Discussion:
Hierarchical autoconf project with cross-compiled subproject
panic
2016-01-26 20:45:26 UTC
Permalink
Hi all,

(no need to CC me, I just subscribed to the list)

TL;DR
I'm seeking advice for a project that involves software on a "normal"
(x86/x86_64/arm) and a cross-compiled (here: AVR microcontroller, but it
could be any other) platform.
How to correctly handle a cross-compiled subproject in autoconf/-tools?


My project roughly looks like the following:
.
├── configure.ac
├── Makefile.am
├── cross-su
│ ├── configure.ac
│ ├── configure.gnu
│ ├── Makefile.am
│ └── firmware.c
├── src
│ ├── Makefile.am
│ └── hello.c
└── ...

There is software to be run on the build system in src/ and there is
software in cross-sub/ that needs to be cross-compiled. Both parts work
together/depend on each other so it makes sense to have them in the same
project. This has the advantage to just have to run
./configure && make && make install
or
make dist
and one gets everything needed.

As far as I understand the autotools, one project is meant to be built
for one platform. Therefore, the cross-compiled part in this example is
an independent autotools project with separate `configure.ac' and
`Makefile.am'.
Using AC_CONFIG_SUBDIRS([cross-sub]) [0] in the upper `configure.ac'
allows us to call the subproject's configure script.

This is correctly done by the various tools like autoreconf, configure,
make...

However, when using AC_CONFIG_SUBDIRS it is not possible to change the
`configure' parameters (like --host=avr) for the subproject, thus, I use
a hack already mentioned in [1] by having a `configure.gnu' wrapper.
The `configure.gnu' file is called by the upper `configure' script
instead of the normal subproject's `configure'.
In the `configure.gnu' I then call `./configure' with `--host=avr' and
some other parameters, like a different --prefix or --bindir.
(Likely, I could also write an m4 macro that takes the arguments for the
subproject, but I didn't want to touch m4.)

I can now generate the configure and Makefile.am scripts recursively by
just running
autoreconf -vi
and then
mkdir build && cd build/ && ../configure && make
and everything is checked and compiled correctly, for instance the use
of 'gcc' and 'avr-gcc' dependent on the project.

If someone runs `make install' that, too, works fine.

/After this long introduction, finally to the yet unsolved problem/:
When `make install-strip' is run, `make' runs recursively through the
directories and calls
/bin/mkdir -p '/the/install/dir'
STRIPPROG='strip' /bin/bash /to/project/build-aux/install-sh -c -s \
thebinary '/the/install/dir'

This fails for the subproject, because to strip a cross-compiled ELF
file, `$host-strip' (here: avr-strip) would be needed instead of normal
`strip'.

The subproject's Makefile -- correctly -- has a variable
STRIP = avr-strip
in it, and runs all fine when it is built alone.
But when it is called recursively from the upper Makefile this is
overridden via STRIPPROG='strip', which then fails and aborts `make'.

The problem might occur also with other targets, but install-strip was
the one where I noticed it.

Is there a fix to this, how can this behaviour be avoided?
Is there a more generic/universal way to handle subprojects that need to
be cross-compiled?
How can I make sure that no environment variables and parameters
"pollute"/override those in the subproject?

I temporarily put online a minimum working example [2] where you can
test this for yourself. In case you don't have the avr-gcc and avr-libc
cross-tools installed and want to try with other cross-tools, simply
replace `--host=avr' in configure.gnu with what you need.

Thanks for reading so much text &
Cheers,
-- panic

[0]
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Subdirectories.html#Subdirectories
[1] https://lists.gnu.org/archive/html/autoconf/2010-01/msg00087.html
[2] https://home.in.tum.de/~benes/mwe/autotools-mwe.tar.xz
Wookey
2016-01-26 21:25:45 UTC
Permalink
Post by panic
How to correctly handle a cross-compiled subproject in autoconf/-tools?
Well, the short version is that you are working against the design and
making your life difficult. Having a project which is then either all
compiled or all cross-compiled is what everything expects, so even with
the co-dependencies I'd still think that it was easier to package the
parts independently of the target architecture in the normal way, then
build the pieces for the arches required.

However it is possible to cross-builds parts of a project (e.g gcc
bootstrap) so I expect what you want to do can be arranged. I have
never actually tried to do what you are aiming for.
Post by panic
When `make install-strip' is run, `make' runs recursively through the
directories and calls
/bin/mkdir -p '/the/install/dir'
STRIPPROG='strip' /bin/bash /to/project/build-aux/install-sh -c -s \
thebinary '/the/install/dir'
This fails for the subproject, because to strip a cross-compiled ELF
file, `$host-strip' (here: avr-strip) would be needed instead of normal
`strip'.
One way is to make sure that $host-strip works both natively and
cross. (i.e you have a link for amd64-strip or arm64-strip or whatever
the non-avr arch is.). Then just calling $host-strip (e.g. by setting
STRIPPROG) works in both cases.

I don't know if there is a more autotoolsy way of dealing with this.

Wookey
--
Principal hats: Linaro, Debian, Wookware, ARM
http://wookware.org/
panic
2016-01-27 10:33:27 UTC
Permalink
Post by Wookey
Post by panic
How to correctly handle a cross-compiled subproject in autoconf/-tools?
Well, the short version is that you are working against the design and
making your life difficult. Having a project which is then either all
compiled or all cross-compiled is what everything expects, so even with
It's a pity but also reasonable.
Post by Wookey
the co-dependencies I'd still think that it was easier to package the
parts independently of the target architecture in the normal way, then
build the pieces for the arches required.
I agree, that'll be the way to go.

Thanks,
-- panic

Loading...