Configure automake to install extra programs - makefile

My project is a library and automake is configured to build it and test it. There is also additional target which builds demo application for my library. It's defined in Makefile.am as EXTRA_PROGRAMS. I'd like to be able to install with make install or similar. Is there a way to do it but still keep optionality of this target (i.e. simply defining this target in bin_PROGRAMS will make this target required)?

The usual way to do this sort of thing is to have configure substitute the value into bin_PROGRAMS conditionally. In your Makefile.am this would look like:
bin_PROGRAMS = main-program $(test_program)
EXTRA_PROGRAMS = test-program
Then in configure.in you'd do something like:
if mumble; then
test_program=test-program
fi
AC_SUBST(test_program)

Related

Configure compilation options and compiler autoconf

I'm working on a personal project with Rust and tcl but i still want to use the classic makefile structure.
I know that to compile multifile I just need to declare mod second on main.rs and rustc automatically connect the modules. So I use
$ rustc main.rs -o output -C debuginfo=2
Now I tried to integrate autoconf and automake because I want to make a configure script to check for tcl, rustup etc... But I don't know how to edit to compile with rustc and its options insead of cc and c options (like trying a .o that doesn't compile because they don't have a main function).
for the configure.ac i used:
AC_CONFIG_SRCDIR([source/main.rs])
AC_CONFIG_AUX_DIR(config)
# I manually checked for rustup and tclsh
AM_INIT_AUTOMAKE
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
for the Makefile.am:
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = output
SUBDIRS = sources
output_SOURCES = sources/main.rs
I have the main directory with configure.ac and Makefile.am and the sources directory with all the stuff (and also the config directory for autoconf)
Now I tried to integrate autoconf and automake because I want to make a configure script to check for tcl, rustup etc...
The configure script is the responsibility of Autoconf. It is not obligatory to use Automake together with Autoconf, and you should consider whether it would be sensible for you to use Autoconf alone. That would give you complete control over the generated Makefile, as you would write a Makefile.in directly instead of relying on Automake to do that for you. Presumably, you would write a much simpler Makefile.in than Automake generates, and that's fine.
Automake is not necessarily out of the question, but its manual has this to say about language support:
Automake currently only includes full support for C, C++ (see C++
Support), Objective C (see Objective C Support), Objective C++ (see
Objective C++ Support), Fortran 77 (see Fortran 77 Support), Fortran
9x (see Fortran 9x Support), and Java (see Java Support with gcj).
There is only rudimentary support for other languages, support for
which will be improved based on user demand.
Some limited support for adding your own languages is available via
the suffix rule handling (see Suffixes).
The referenced section about suffix rules shows how you might use such a rule to teach Automake how to build Rust programs. It might look something like this:
.rs:
$(RUSTC) $< -o $# $(AM_RUSTFLAGS) $(RUSTFLAGS)
SUFFIXES = .rs
That assumes that configure will identify the Rust compiler and export its name as RUSTC. AM_RUSTFLAGS is for defining compilation flags internally in your project (typically in your Makefile.am), and RUSTFLAGS is for the builder to add or override compilation flags at build time.
But since the compiler does not produce intermediate object files (or so I gather), I would expect that defining sources in output_SOURCES would not yield a working Makefile, and that you would probably need the name of the top-level Rust source to match the name of the wanted binary (i.e. output.rs instead of main.rs). The single-suffix rule should, then, get your binary built without any sources being explicitly specified. You would also want to name all contributing Rust sources in the EXTRA_SOURCES variable, else they would be omitted from distribution packages built via make dist.
Note, too, that the above does not define all the build dependencies that actually exist if you're building multifile programs. I would suggest doing that by adding an appropriate prerequisite-only rule, such as
output: $(output_extra_sources)
(with no recipe) in multifile cases. This will ensure that make will recognize when output needs to be rebuilt as a result of a modification to one of its sources other than output.rs.

automake: distcheck with CPPFLAGS

I am looking for something like DISTCHECK_CONFIGURE_FLAGS but more flexible.
I am using an external package in my program. Let's say foo and on my laptop it's installed to ${HOME}/soft/foo.
configuring with the autotools is simple:
./configure CPPFLAGS=-I${HOME}/soft/foo/include LDFLAGS=-L${HOME}/soft/foo/lib
but distcheck is giving me headaches. When distcheck unpacks and configures, how do I tell it to use my CPPFLAGS and LDFLAGS?
DISTCHECK_CONFIGURE_FLAGS is close, but incorrect: other maintainers might have the foo library installed under /opt/ or /software/random/whatever or /usr/local/foo-master and I don't want to impose my environment on other maintainers.
The answer is to not hard-code anything in the Makefile.am. Automake will inherit several environment variables from autoconf.
All one needs to do is pass the CPPFLAGS and LDFLAGS used to configure the package:
DISTCHECK_CONFIGURE_FLAGS = CPPFLAGS=${CPPFLAGS} CFLAGS=${CFLAGS}\
${CXXFLAGS}=${CXXFLAGS} LDFLAGS=${LDFLAGS}
and now 'make distcheck' will use the requested flags and find the headers and libraries for the desired package.

Include Makerules from sub.mk with Makefile.am

is it possible to not generate the Makerules from Makefile.am, but include the Makerules from a predefined sub.mk?
Well, I have a big Makefile-Project i want to build a custom App for.
Building an App for this project is done with a Makefile in the following structure:
PROJDIR ?= ../..
TARGET = myApp
SRC_C = main.c
include $(PROJDIR)/prog.mk
The actual makerules are hidden somewhere in prog.mk which requires the variables TARGET, SRC_C etc.
Now, i want to use an independent Automake project to generate the Makefile of my App.
Is it even possible to let Makefile.am generate a Makefile like the one above?
Can someone provide an example for this?
No, automake by design is not going to generate anything close to that, since it's a full stack to define your targets and it'll take care of building them.
You can use autoconf alone, by writing a template Makefile.in and have it substitute the variables you figure out at ./configure time, but that means you're essentially on your own to write the structure.

Adding a dependency for a target in automake

I've run into a problem with automake that I can't seem to find a clean solution for, which seem like it should be possible (even simple), but nothing simple works.
Basically the problem I have is with a source file that includes an autogenerated header file. I can add the dependencies to generate the header file just file, and once the header exists, everything works, as automake's auto dependency generation takes care of everything. The problem is the first time you run make in a clean tree, the dependency files don't exist, so automake doesn't know to generate the header file, which makes the compile of the file including the header fail without generating any dependencies. Its a chicken-and-egg problem -- you need to manually tell (auto)make to build the header file.
The obvious solution is just to add a dependency to the Makefile.am file for the header, but that doesn't work, since having a dependency for a target override automake's automatic rule generation, as the docs say:
Note that Automake does not make any distinction between rules with commands and rules that only specify dependencies. So it is not possible to append new dependencies to an automake-defined target without redefining the entire rule.
For now I've hacked around the problem by 'hiding' the dependency from automake, but this only works for GNU-make:
Makefile.am:
bin_PROGRAMS = foo
foo_SOURCES = main.c foobar.c baz.c
gen.h: system.spec
...command to regen gen.h
# foobar.c #includes gen.h, so it needs to exist prior to compiling foobar.c
$(eval foo-foobar.o: gen.h)
This does the trick, but seems ugly. Is there a better automake-safe way of doing this?
Automake supplies BUILT_SOURCES to solve this problem. Files added to this are built before ordinary compilations are done -- it is specifically intended for generated headers and sources.
In your case this should suffice:
BUILT_SOURCES = gen.h
sample Makefile.am should be like
bin_PROGRAMS = foo
foo_SOURCES = main.c foobar.c baz.c
nodist_foo_SOURCES = gen.h
BUILT_SOURCES = gen.h
CLEANFILES = gen.h
gen.h: Makefile system.spec
command to regen gen.h
#above line should begin with a <TAB>

Compile subdir-objects multiple times

Automake 1.14 is causing us a few issues. At first, automake errored with the complaint:
warning: source file 'X' is in a subdirectory but option 'subdir-objects' is disabled
So I enabled subdir-objects, but now it isn't recompiling some files. For example, lets say
src/a/foo.c is compiled in SUBDIR a but in src/b, I would like to compile it again with different preprocessor flags, however since ../a/foo.o already exists, make doesn't rebuild it. This is because subdir-objects changes am_b_OBJECTS to look for ../a/foo.o instead of foo.o. Is there a way I can get around the original complaint and instruct make to build the file a second time with the appropriate preprocessor flags? This all worked on previous versions of automake.
I would settle for executing rm ../a/foo.o before compiling src/b but I don't know how to edit the Makefile.am to make that happen.
This happens if you're using subdir-objects under the same tree from different Makefile.am files. As automake can't see you're using the same source file with different parameters it'll assume it was rebuilt correctly.
The proper solution to this is to not use separate Makefile.am files and instead rephrase the build system as non-recursive automake and so in that case it would then build foo.c as foo-a.o and foo-b.o.

Resources