2
votes

I currently have 10 tests in my autotoolset project. Any time I make a change to one of my src/ files and recompile, each test is rebuilt and linked. This is starting to have a considerable impact on my development time.

What is the best way to conditionally build binary programs, tests or otherwise, with GNU autotoolset? For instance, if I'm working in test/check_curl_requestheaders.cc, and I make a change, I am only going to want to recompile the library and then that one test and none of the other binaries.

I saw some mention of using automake conditionals (like WANTS_XXX) but I am not 100% certain that is what I'm looking for nor am I sure how that would be configured by autoconf.

I am sort of hoping for something that will end up looking like this:

./configure
make test/check_curl_requestheaders

or

./configure --only-build=test/check_curl_requestheaders
make

Pointers?

EDIT I'm not doing a configure before every make. If I make changes to check_curl_requestheaders, only check_curl_requestheaders is rebuilt as one would expect. The problem is that if I'm working on the RequestHeaders part of the library, and make a change to say, src/curl/requestheaders.cc, all of the the tests and other binaries are rebuilt, not just the check_curl_requestheaders. That is taking far too long, and that is what I am trying to avoid. If I have a dozen binaries, is there a way to rebuild only one of them?

3

3 Answers

2
votes

I'm confused. In any project I've ever worked on, running 'make' from either ${top_builddir} or from ${top_builddir}/tests/ will not rebuild or run any tests. Tests are only built and executed for 'make check'. Are you using check_PROGRAMS in your Makefile.am?

In general, conditional compilation is handled with automake conditionals and Makefile.am snippets like:

if WANT_FOO
bin_PROGRAMS += foo
endif

but I'm certain this is not what you are looking for. It sounds like you have specified bogus dependencies in a Makefile.am, and you should post a minimal version of it/them.

PS: in your shell script, you can just do

export OUT
...
(cd src && make >> $OUT) || exit 3
0
votes

When you change some source file, you should not have to reconfigure at all. Just run make again, and it should only rebuild those binaries that are actually affected by the change. So when you change test/check_curl_requestheaders, then do a plain make, then only test/check_curl_requestheaders should be rebuilt, anyway. If anything else gets rebuilt also, you have a bug in your makefile.

Of course, if you do configure first (which you should not), it is not surprising that more stuff gets rebuilt.

Edit: If you change the library, and then only want to rebuild a single test, then

make test/check_curl_requestheaders

should be sufficient. This would require you to have a target named test/check_curl_requestheaders in your toplevel makefile. That target may look like

test/%:    library
    make -C test $*

assuming you have a separate makefile in the test directory, and assuming that this makefile assumes that the library has already been built.

0
votes

I'm not sure this is the best way to do this, but it turns out that the programs in my test folder did have their own unique make targets. However, there were some issues.

  1. If I issue make at the top level, all of src/ and test/ are built
  2. If I issue make at test/ level, changes to src/ won't be picked up

To solve this, I wrote a shell script that does the following:

  1. Enter src, and build it. (if changes to src/ have happened, src/ is rebuilt)
  2. Enter test, and build a specific binary. (this will rebuild the specific binary if it has changed and will relink of the code in src/ has been updated by the previous step)

The code is listed below:

#!/bin/sh

TYPE="$1"
WHICH="$2"
OUT="`readlink -f ./buildandrun.out`"

rm -rf $OUT

if test ! -n "$WHICH"
then
    echo "Please specify which type to build"
    exit 1
fi

if test ! -n "$WHICH"
then
    echo "Please specify which $TYPE to build"
    exit 2
fi

RV=0

echo "" >> $OUT
echo "Building src" >> $OUT
echo "" >> $OUT

cd src
make >> $OUT || RV=3
cd ..

if test $RV != 0; then exit $RV; fi

echo "" >> $OUT
echo "Building $TYPE/$WHICH" >> $OUT
echo "" >> $OUT

cd $TYPE
make "$WHICH" >>  $OUT || RV=4
cd ..

if test $RV != 0; then exit $RV; fi

echo "" >> $OUT
echo "Running $TYPE/$WHICH" >> $OUT
echo "" >> $OUT

$TYPE/$WHICH || RV=5

exit $RV

This lets me do the following:

./buildandrun.sh test check_curl_requestheaders

Hopefully there will eventually be someone who can show me a more elegant solution to this problem, preferably using autoconf and automake. I have a feeling that this is probably something that these tools do out of the box and I just haven't discovered it yet.