Trouble creating a check program in automake - automake

I'm trying to learn automake (Autotools by John Calcotte) and am stumped on creating a check program to test my C++ library. A partial listing of the program is given below. The example in the text shows creation of a test program using a shell script testing the output of the test program. I have a program, linked to the library, which when executed tests the library functionality. Do I have to create the test program using noinst and then execute using a shell script? Any scripting examples or references to examples would help.
Thanks
The errors are:
src/Makefile.am:27: warning: variable 'check_SOURCES' is defined but no program or
src/Makefile.am:27: library has 'check' as canonical name (possible typo)
# Create a library
lib_LIBRARIES = libslip.a
libslip_a_SOURCES = $(sources) $(privateHeaders)
# Header files for testing SLIP
testHead=TestGlobal.h TestHeader.hp TestIO.h TestMisc.h TestOperators.h TestReader.h TestReplace.h TestSequencer.h TestUtilities.h
# Source files for testing SLIP
testCPP=Test.cpp TestGlobal.cpp TestHeader.cpp TestIO.cpp TestMisc.cpp TestOperators.cpp TestReader.cpp TestReplace.cpp TestSequencer.cpp TestUtilities.cpp
# Test Program
check_PROGRAMS = Test
check_SOURCES = $(testHead) $(testCPP)
TESTS = $(check_PROGRAMS)

It's just a slight misunderstanding: check_PROGRAMS = Test is fine, but just as with the libslip sources, Test is used as a prefix:
Test_SOURCES = TestGlobal.h TestHeader.hp TestIO.h TestMisc.h TestOperators.h \
TestReader.h TestReplace.h TestSequencer.h TestUtilities.h Test.cpp \
TestGlobal.cpp TestHeader.cpp TestIO.cpp TestMisc.cpp TestOperators.cpp \
TestReader.cpp TestReplace.cpp TestSequencer.cpp TestUtilities.cpp
In this case, it's fine to include headers in SOURCES. Each new line after the line break should start with a TAB character. Of course, you can continue using $(testHead) and $(testCPP) variables if you prefer. To link with libslip:
Test_LDADD = libslip.a
or simply:
LDADD = libslip.a
if linking libslip with all programs in this Makefile. check_PROGRAMS targets are implicitly noinst.
You might also find the Autotools Mythbuster a useful resource.

Related

Automake: Include extra files in default sources

I'm writing some simple tests for my library, and I'm trying to keep my Makefile.am file as tidy as I can, so I'm trying to rely on the default _SOURCES functionality. This is my current Makefile.am:
AM_CPPFLAGS = $(MYLIB_CFLAGS) -I..
AM_DEFAULT_SOURCE_EXT = .vala
AM_LDFLAGS = $(MYLIB_LIBS)
VALAFLAGS = -D GLIB_2_32 --vapidir=../ --pkg mylib_internal --pkg libsoup-2.4 --pkg json-glib-1.0 --pkg gee-1.0
TESTS = autocomplete
check_PROGRAMS = autocomplete
autocomplete_LDADD = ../mylib.la
autocomplete_SOURCES = autocomplete.vala common.vala
CLEANFILES = *.c
If I leave out the autocomplete_SOURCES variable, autocomplete.vala is automatically used, and that's great (as per the default _SOURCES functionality), but I need to include common.vala as well. In fact, every test program I am going to write will want to have this common.vala in their source file list. Is there a way for me to not having to specify the *_SOURCES for every single test program I write?
Bonus: They will all want to have mylib.la in their *_LDADD as well, so again, is there a way for me to accomplish this globally, instead of having to have it specified for every test program?
EDIT: I figured out that you can just use LDADD without the prefix to get it to apply to every compiled program. That helps a bit... now to figure out the *_SOURCES...
There isn't a way to do this.
You can introduce a variable that you use everywhere, if you want:
general_stuff = whatever.vala
x_SOURCES = $(general_stuff) ...
y_SOURCES = $(general_stuff) ...

Defining additional make targets using gnu autotools

I am beginning to learn autotools in order to first understand and later extend an existing project's build system. Currently the project builds a program as it's output. The build system is quite complex consisting of several subdirectories and Makefile.am's with files generated in a maintainer-mode and so on. I would like to optionally be able to create a library using much of the same source code, reusing much of the the existing build system.
What I am imagining is a new make target so that after running configure, I can then run either make to make the program, or, say, make library to build the library. What is the correct way to do this or something with a similar effect?
I do not want to build both the library and program when I run plain make (just the program as before), and I do not want to build the program when I run make library (I only want the library).
If someone could provide a simple example, e.g. a program made up of main.c, foo.c and bar.c and a library made up of foo.c and bar.c that would be really helpful too.
EDIT
To clarify, I originally thought that the program and lib could be built entirely separately. The library contains only a subset of the code of the main program, and I believed the two were separate entities. However, things are more complicated. The program itself is built and used to output some code which is then compiled into the program in a second step (I think). I have effectively got what I want by doing the following steps.
First add a conditional to configure.ac
dnl Adds LIBRARY conditional for --enable-foolib mode to
dnl build foo as a library
AC_ARG_ENABLE(foolib,
AS_HELP_STRING([--enable-foolib],
[enable qucslib build, default: no]),
[case "${enableval}" in
yes) foolib=true ;;
no) foolib=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-foolib]) ;;
esac],
[foolib=false])
AM_CONDITIONAL(FOOLIB, test x"$foolib" = x"true")
Then in the appropriate Makefile.am I did something similar to the following:
if FOOLIB
noinst_LIBRARIES = libbar.a libfoo.a
else
noinst_LIBRARIES = libbar.a
endif
bin_PROGRAMS = barprog
barprog_SOURCES = main.cpp src1.cpp src2.cpp etc.cpp
barprog_LDADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
... other stuff
if FOOLIB
libfoo_a_LIBADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
libfoo_a_SOURCES = src1.cpp src2.cpp etc.cpp
endif
Then when I want to make the library I do
configure --enable-foolib
make
This works for now, but seems kludgy. I wasn't sure though how to implement the provided answer in the build system.
If the program depends on the library, then it will not be possible to build the program without building the library. You already have the ability to build individual libraries: configure && make libfoo.a should work just fine (or make libfoo.la). If you wish a target named library, you can simply add the following to any Makefile.am:
library:
libfoo.a
(Or you may need libfoo.la. Basically, if the library is specified in Makefile.am under the LIBRARIES primary, then you would use libfoo.a, but if specified under an LTLIBRARIES primary, you would use libfoo.la.) This will only create a library target in each directory that contains a Makefile.am. If you have a complex recursive build (you should really simplify it, but that's another question), you can put something like the following in your top-level Makefile.am to build the libraries throughout the tree:
library:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) library
This assumes you have added a library target to subdir/Makefile.am as described above.
To be pedantic, you might want to use $(am__cd) instead of cd, but it's not strictly necessary.

understanding data assigned to macros in a makefile

I have searched through this forum but am not able to find an answer to this question, still if I have missed it please excuse me and direct me to the same.
I am trying to understand makefiles and came across the makefile for the tcpreplay utility on Linux. There are lot of macros that have been defined with the value starting an ending in a #. What are these values, how are they used? A snippet:
ACLOCAL = #ACLOCAL#
AMTAR = #AMTAR#
AR = #AR#
AUTOCONF = #AUTOCONF#
AUTOGEN = #AUTOGEN#
AUTOHEADER = #AUTOHEADER#
This is a makefile template, likely for software built with a GNU configure script. When configure is run, the #NAME# placeholders are replaced with proper values as determined at runtime. E.g. #AR# will be the name (or path) of the archiver, /usr/bin/ar. You then have a proper Makefile that you can run with a make invokation. If an actual Makefile still contains #NAME# placeholders, there was an error in running configure.
You are very likely not looking at a file named Makefile but one named Makefile.in. The .in suffix indicating that this is input to configure.
You can find all the gory details in the GNU autoconf manual.

Evaluate automake variable only once

We are using automake & autoconf to build our multi-package software. I was wondering how to fill a variable with the output of e.g. shell-scripts once and reuse this, e.g. for needed include dirs
INCLUDES := -I`some-ext-config --incdir`
Using := instead of = here makes this variable filled once so some-ext-config will only be called once (AFAIK this comes from plain make). Of course INCLUDES is the depreciated cousin of AM_CPPFLAGS, but would I have used that one instead, the shell script would have been called for each compile.
Using INCLUDES instead of AM_CPPFLAGS is an acceptable solution for me (though I imagine there might be portability issues), but I have no solution for e.g. LDFLAGS for a libtool library
libmylib_la_LDFLAGS := `some-ext-config --ldflags` # will always be evaluated
What is the general solution inside automake if I want to make sure these external tools are not called multiple times? I would like to stay away from using an obvious AC_SUBST in configure.ac since we have to make sure our packages can be build both from subdirectories (some configure.ac in there) and with an recursive make from the top-level and a configure.ac there which shouldn't need to know too much about the different subprojects.
:= is GNU-make specific, so you are advised to use just = in automake. If you do not want to run the shell script everytime INCLUDES (or AM_CPPFLAGS, does not matter, it would occur with either), then run the script in configure.ac and use variable substitution via AC_SUBST. That is essentially what pkg-config would do — and come to speak of it, you could just use that instead of some-ext-config if there is a .pc file.
# configure.ac
libfoo_CPPFLAGS=$(some-ext-config --incdir);
libfoo_LIBS=$(some-ext-config --libs);
AC_SUBST([libfoo_CPPFLAGS])
AC_SUBST([libfoo_LIBS])
# Makefile.am
AM_CPPFLAGS = -Iwhatever ${libfoo_CPPFLAGS}
bin_PROGRAMS = foo
foo_LDADD = ${libfoo_LIBS}
This is a more lengthy explanation of what I suggested in a comment to jørgensen's answer.
I understand your top-level configure.ac must generate the makefiles of multiple sub-projects, and performs the required tests so that you don't have to run the configure in any subproject (a sub-configure serves only when you want to work on this particular sub-project).
In that case, you want to avoid duplicating as much stuff as possible from various configure.ac. I suggest you factor all the code of the sub-configure that must also be performed by the top-level configure in an m4 macro. This includes tests, AC_SUBSTS, and Makefile declarations.
For instance using only one-subproject. Here is a top-level ./configure.ac:
AC_INIT([toplevel], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
SUB1_COMMON([sub1/]) dnl Stuff from the subproject
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
With ./Makefile.am:
ACLOCAL_AMFLAGS = -I sub1/m4
SUBDIRS = sub1
Now here is sub1/configure.ac for the sub-project:
AC_INIT([sub1], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
AC_CONFIG_MACRO_DIR([m4])
SUB1_COMMON
AC_OUTPUT
With SUB1_COMMON defined in m4/common.m4:
AC_DEFUN([SUB1_COMMON],
[AC_SUBST([PYTHON3LIB], [`pkg-config --libs python3`])
AC_CONFIG_FILES([$1Makefile])])
And finally sub1/Makefile.am is just:
ACLOCAL_AMFLAGS = -I m4
# Build something.
...
The SUB1_COMMON contains all the code you want to share between the two configure.ac files, and use argument $1 to relocate the config files appropriately. In this example, the variable PYTHON3LIB will be defined regardless of which configure were run.

OCaml makefile dependency problem

I am using OCaml Makefile for a project I am working on and I have the folowing modules
DynamicTree.ml
Huffman_Dynamic.ml which uses DynamicTree
Huffman_Static.ml
main.ml which uses both Huffman_Static and Huffman_Dynamic.
This is my make file :
# put here the names of your source files (in the right order)
SOURCES = huffman_static.ml dynamictree.ml huffman_dynamic.ml main.ml
# the name of the resulting executable
RESULT = huffman
# generate type information (.annot files)
ANNOTATE = yes
# make target (see manual) : byte-code, debug-code, native-code
all: native-code
include OCamlMakefile
When I try to make the project, I get an Unbound value DynamicTree.create_anchor_leaf that results from ocamlopt -c -dtypes huffman_dynamic.ml generated by Makefile.
The Ocaml Makefile wepage states that it generates automatically dependencies, am I missing something here?
Thank you.
Is the capitalization of your name correct ? In your post you use both DynamicTree.ml and dynamictree.ml.
Are you sure the issue comes from the Makefile ? Is there really a create_anchor_leaf function exported by DynamicTree.ml ? No .mli hiding it ?

Resources