Discussion:
"Packing" binary data into object files using autotools
Thomas Nyberg
2017-08-14 10:19:06 UTC
Permalink
Hello,

I have a Makefile which I'm trying to convert to an autotools setup.
It's complicated by the fact that some code is not compiled until
runtime. I'll try to be as detailed as possible. In my hand-written
Makefile I have the following setup. I have a rule which tars up some
files and puts it in `code.tar`. Next I inject that code into an object
file using some basic gnu assembler instructions. That object file is
linked elsewhere into the final library. To be more specific, I have the
following situation:

# Rule injecting a tar archive into object code.
-------------------------------------------------------------------
code_archive_tar:
tar c --exclude='*.o' code/ > code.tar
as -o code_archive.o code_archive.S
rm -f code.tar
-------------------------------------------------------------------

# This is the actual code_archive.S file referenced above:
-------------------------------------------------------------------
.section .rodata
.global code_archive_tar
.type code_archive_tar, @object
.align 4
code_archive_tar:
.incbin "code.tar"
code_archive_tar_end:
.global code_archive_tar_size
.type code_archive_tar_size, @object
.align 4
code_archive_tar_size:
.int code_archive_tar_end - code_archive_tar
-------------------------------------------------------------------

# The actual data is accessed in another (C++) source file as
# follows:
-------------------------------------------------------------------
extern char code_archive_tar[];
extern unsigned code_archive_tar_size;
-------------------------------------------------------------------

The important parts of my current Makefile.am specified its required
sources as follows:

# Makefile.am
-------------------------------------------------------------------
[...]

library_la_SOURCES = \
... [A bunch of files...]

libmerriamengine_la_LDFLAGS = \
... [A bunch of libraries...]

CXXFLAGS = \
... [A bunch of compiler flags]

[...]
-------------------------------------------------------------------

It's hard for me to fit my own setup into this since autotools is
finding all the different files and linking them pretty automagically.
Basically what I need is (1) to signal some way for the tar procedure to
occur before the rest of the linking takes place and (2) to actually
signal to the linking phase that the object file that has been created
needs also to be added to the link itself.

Hopefully this isn't too confusing. I was reading about BUILT_SOURCES,
but I'm not totally sure that that is what I require. I also have added
in explicit Makefile rules into Makefile.am (e.g. the rule to tar up the
folder structure), but I'm having trouble getting (1) and (2) to work in
the last paragraph.

Any help is appreciated! Definitely yell at me if you need more info or
something I'm saying doesn't make sense! Thanks a lot!

Cheers,
Thomas
Thomas Nyberg
2017-08-14 13:31:28 UTC
Permalink
Hello,

I just wanted to simplify my previous question. Say I'm starting with
this file:

# Makefile.am
-------------------------------------------------------------------
[...]

library_la_SOURCES = \
... [A bunch of files...]
src/resources/code_archive.S
-------------------------------------------------------------------

Where that `src/resources/code_archive.S` file is the assembly file from
my previous email. This works correctly, _if_ the file `code.tar` is
found in the current directory. In other words, what I would like is for
the the following rule to be executed prior to the compilation of
`src/resources/code_archive.S`:

-------------------------------------------------------------------
code_tar:
tar c --exclude='*.o' code/ > code.tar
-------------------------------------------------------------------

How do I add that as a pre-compilation "hook" for the
`src/resources/code_archive.S` file? (Also though not as important is it
possible to have the post-compilation hook removing it as well?)

Thanks again for any help.

Cheers,
Thomas
Thomas Nyberg
2017-08-14 15:41:38 UTC
Permalink
Hello,

I figured out the issue and wanted to resolve it on the list. It was
quite trivial to do this using BUILT_SOURCES (not so sure why I had so
much trouble...). Basically something like the following suffices:

# Makefile.am
-------------------------------------------------------------------
[...]

BUILT_SOURCES = code.tar

code.tar:
tar c code/ > code.tar

CLEANFILES = code.tar

library_la_SOURCES = \
... [A bunch of files...]
src/resources/code_archive.S
-------------------------------------------------------------------

This produces the necessary tar file in the current directory before
doing the rest of the compilation. The CLEANFILES target cleans it again
afterwards.

Cheers,
Thomas
Gavin Smith
2017-08-14 20:19:12 UTC
Permalink
Post by Thomas Nyberg
Hello,
I just wanted to simplify my previous question. Say I'm starting with
# Makefile.am
-------------------------------------------------------------------
[...]
library_la_SOURCES = \
... [A bunch of files...]
src/resources/code_archive.S
-------------------------------------------------------------------
Where that `src/resources/code_archive.S` file is the assembly file from
my previous email.
I don't know if it is any better than the solution you found, but
another possibility may be to use the library_la_LIBADD variable, which
I read is supposed to be used to list objects to be added into the library.
The idea is to list a file generated from 'src/resources/code_archive.S'
in this variable. However, according to the documentation I read, this
would have to be a *.lo file (Libtool object), so you would have to
write Makefile rules to create such a thing (i.e. code_archive.lo
instead of code_archive.o).

There are various suggestions on how to deal with built sources in the
Automake manual:

https://www.gnu.org/software/automake/manual/html_node/Built-Sources-Example.html
Loading...