Passing parameters to regression tests in automake - makefile

I'm writing a regression test for our package that is currently using autotools (i.e., autoconf/automake). The following Makefile.am exemplifies the simplest check. When make check is invoked, it compiles tester.c to generate tester and then launches tester.sh that ends up invoking test (among other commands). That works fine.
However, for some tests I need to pass some information gathered at configure time to tester.sh. So is it possible to pass this information as a parameter? The value is available in a variable in the Makefile (i.e. it is AC_SUBSTed) but these variables are not forwarded to child processes spawned by the make command. If that's not possible, would it be feasible to have an extra rule that is executed before tester.sh that generates a file with the parameters that are captured later through tester.sh?
File Makefile.am
check_PROGRAMS = tester
TESTS = tester.sh
tester_SOURCES = tester.c

Since I'm interested on passing one of the Makefile variables into the test, I have decided to attack this problem by creating an auxiliar program (named pass_variable_PREFIX) that will show the prefix variable defined in the Makefile. This auxiliar program will be later used by the tester.sh to know the value of prefix. I understand that this may not be the best solution, but it works so far.
Here comes the related code:
Makefile.am
check_PROGRAMS = tester pass_variable_PREFIX
TESTS = tester.sh
tester_SOURCES = tester.c
pass_variable_PREFIX_SOURCES = pass_variable_PREFIX.c
pass_variable_PREFIX_CFLAGS = -DPREFIX="\"$(prefix)\""
pass_variable_PREFIX.c
#include <stdio.h>
int main (int argc, char *argv[])
{
printf (PREFIX"\n");
return 0;
}
tester.sh
#!/bin/bash
PREFIX=`./pass_variable_PREFIX`
echo $PREFIX
./tester

Related

Expand Variables in Target of an Included Makefile

I am trying to build a framework which is supposed to apply similar operations to different designs/projects. Therefore, I have a general Makefile which defines general targets used for most of the operations. The idea is then that each design has its own main Makefile. This main Makefile includes the general Makefile for the general functionality, defines some variables for some basic configuration of the general Makefile, but can also extend or override variables from the general Makefile or define new targets or override targets when they are not applicable.
So the simplified directory structure looks something like this:
<Root Dir>
| -- targets.mk
| -- design1
| -- Makefile
| -- design2
| -- Makefile
The simplified general Makefile targets.mk looks something like this
${FF_LIST}: ${SRC_FILES}
#echo "Extract FF List for ${DESIGN_NAME}"
.PHONY: get_ff_list
get_ff_list: ${FF_LIST}
#echo "Get FF list for ${DESIGN_NAME} from ${FF_LIST}"
And the simplified design specific Makefile looks something like this:
include ../targets.mk
DESIGN_NAME = design1
FF_LIST = ./misc/ff_list.csv
With this implementation, I have the problem now, when calling the target get_ff_list within the design1 directory, that the recipe for the get_ff_list target is executed but the prerequisites are not, although the echo prints the right file.
user:/tmp/make_test/design1$ make get_ff_list
Get FF list for design1 from ./misc/ff_list.csv
It seems like that the target ${FF_LIST} is not expanded correctly. I can understand that during the time I am including the targets.mk Makefile this variable does not exist. However, my understanding of Makefile's recursive variable declaration with = should expand the variable every time the variable is used (as it is done and seems to work within the recipe itself).
I could include the targets.mk Makefile at the end after the configuration/setting the variables, like:
DESIGN_NAME = design1
FF_LIST = ./misc/ff_list.csv
include ../targets.mk
This seems to work and solve this particular issue. However, when I also want to extend or override variables/targets from the general Makefile, then it becomes a bit less obvious where to include it. Especially, if I am not the only one using the framework and other users create there own new designs.
Maybe this is even not a good way to use Makefiles to begin with. I would also be happy to get suggestions of better ways to implement this.
However, my understanding of Makefile's recursive variable declaration with = should expand the variable every time the variable is used (as it is done and seems to work within the recipe itself).
No. Read the section of the manual on How make Reads a Makefile to understand when variables are expanded immediately, and when the expansion is deferred.
The simplest way to do what you want is for the include targets.mk to come at the end of the Makefile, not at the beginning. If that's not feasible then you'll have to split the main makefile into two parts, one that sets variables and is included first, and the other that defines rules and is included last.

Using Condition statements with Makefile targets

Hello i'm trying to use condition statements in my makefile to have it execute different make targets, but it skips over the condition and goes right to the else.
He's a general example of what i'm trying to do
ifdef ($(RUN_TEST))
all: install run uninstall
else
all: install uninstall
endif
You did not indicate on what system you are running the Makefile, as there are slightly differing make programs available. Make can be run on linux and windows and comes in different variants.
However, I have worked with most variants, and there is a common way you can resolve your problem. You have to realise that the makefile is not a program executed in the conventional sequential manner. It is a series of declarations or definitions of actions to be performed at some future time. You cannot read through it in a sequential manner like a program. In particular the definitions of dependencies are not executed and cannot be embedded within statements, even pre-processed statements.
The best way to achieve what you want it to put the dependencies in a variable and set that variable conditionally, like this:
if ($(RUN_TEST))
ALL=install run uninstall
else
ALL=install uninstall
endif
all : $(ALL)
This should work on most implementations.
The GNU make ifdef operation takes the name of a variable to test; you are providing it the expansion of a variable. You want to write it like this:
ifdef RUN_TEST
ALL = install run uninstall
else
ALL = install uninstall
endif
By using $(RUN_TEST) you're actually testing a variable named by the expansion of RUN_TEST. So for example if RUN_TEST is set to true, then ifdef $(RUN_TEST) actually tests to see if the variable true is defined or not.

Trouble creating a check program in 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.

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) ...

gcc recompile "make" result no changes

i'm using cs50 appliance.
i've tried to write a new file test.c , found as long as i include int i line, it doesn't generate a new file test, if i remove that line and make again, it can generate test file. then i made changes on the test file, it still output the original file result, no reflect the new changes.
#include <stdio.h>
#include <cs50.h>
int
main (void)
{
printf("Number: \n");
int i = GetInt();
}
it was running properly before though... anyone can help please?
Apparently your default rules for make run the compiler on test.c.
The compiler notices that you are assigning a value to variable i, but you never use that value in any way; it would normally report this as a warning.
Apparently either your compiler or make are configured in such a way that this warning becomes a fatal error to make.
The remedy is to use the variable. It looks as though you need to pick up a book on the C programming language, or follow a course, if that's not what you're doing already.

Resources