views:

441

answers:

3

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?

A: 

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.

Martin v. Löwis
I'm not doing a configure every time. :) The problem is that any changes to any of the src/* files require *all* of the tests and binaries to rebuild because they all rely on the src/* files.If I make changes to check_curl_requestheaders, only check_curl_requestheaders is rebuilt. That works as expected. I apologize for the confusion.
Beau Simensen
It's difficult to help when you don't show your Makefiles, and how it comes that it rebuilds more than you want. See my edit for another guess.
Martin v. Löwis
The problem is I'm using autoconf and automake so I'm not generating my Makefiles myself and I'm asking how to instruct autoconf and automake to only build some of the binaries instead of all of them. I can try and write more on this later, but this is what I have for now!
Beau Simensen
My recommendation wrt. automake: don't. It *is* possible to write makefiles yourself, so you should do that.
Martin v. Löwis
Thanks for your feedback, Martin. I'll keep it in mind in the future. For now I'm going to have to stick with automake and autoconf but in the future I may consider trying to find something else to work with.
Beau Simensen
There is nothing wrong with autoconf; it is automake which has limited usability. However, it is not too late - you can still have custom rules in your makefile, even with automake
Martin v. Löwis
A: 

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.

Beau Simensen
+2  A: 
William Pursell
Thanks for your feedback! I had not been using `check_PROGRAMS`, I had been using `TESTS`. Not sure why I would use one over another. I get lost in the various autotoolset docs and tutorials. :-/
Beau Simensen