Alex Reynolds
Alex Reynolds

Reputation: 96927

Conditional in makefile that redefines variable?

I have a variable in my makefile I would like to either unset or redefine, so that targets a, b and c use the correct value of MY_VARIABLE (or none at all) within their respective makefiles.

If I run make foo with the following:

export MY_VARIABLE := 'false'
foo: prep_foo dist
prep_foo:
    $(shell export MY_VARIABLE='true')
    echo ${MY_VARIABLE}
dist: a b c
a: 
    make -C a/src
b: 
    make -C b/src
c: 
    make -C c/src

I get this output:

export MY_VARIABLE='true'
echo 'false'
false
...

If, instead, I run make foo with the following makefile:

export MY_VARIABLE := 'false'
foo: prep_foo dist
prep_foo:
    $(shell unset MY_VARIABLE)
    echo ${MY_VARIABLE}
dist: a b c
a: 
    make -C a/src
b: 
    make -C b/src
c: 
    make -C c/src

I get the following output:

make: unset: No such file or directory
echo 'false'
false
...

How can I unset or redefine MY_VARIABLE when specifying a target (like foo, in this case)?

EDIT

Here is the situation I would like to avoid:

dist: a b c 
foo: a_foo b_foo c_foo
a:
    make -C a/src
...
a_foo
    make -C a_foo/src

I just want the a target to use a different value for my particular variable, so that compilation is handled differently in that target's makefile.

Also, it doesn't look like I can export or unset variables within a target. For example:

dist: a b c 
foo: a_foo b_foo c_foo
a:
    make -C a/src
...
a_foo:
    export MY_VARIABLE='true'; make -C a/src

If I try to do so, I get something similar to the following error on the export MY_VARIABLE='true' line (and similarly if I try to use unset):

Makefile:16: *** unterminated variable reference.  Stop.

Does this help clarify what I'm trying to do?

EDIT 2

I tried a target which touch-es a file and tries to run the child target's makefile (which checks for the file's existence):

foo: prep_foo
prep_foo:
    touch a/src/.foo
    make -C a/src

When I try to run this via make foo, I get the following error:

Makefile:14: *** commands commence before first target.  Stop.

If I remove the make statement from prep_foo, then I can touch the file without getting the error message, but I cannot trigger making the a target, so this doesn't seem to help.

The following yields the same commands commence before first target error message:

foo: prep_foo a
prep_foo:
    touch a/src/.foo

Is there an example of using touch to communicate state to child targets?

Upvotes: 4

Views: 2896

Answers (2)

choroba
choroba

Reputation: 241758

The common way to communicate between targets in a Makefile is through files. Just touch a file in one target and check it in the other. Can this help you solve your problem?

Upvotes: 1

sarnold
sarnold

Reputation: 104020

Don't forget that every single shell execution in make is done in a new process. Trying to fiddle with the environment variables of recipes like this does not really make much sense -- the environment you have modified in any given line is gone after that shell dies, before the next line is executed.

You may be able to do the job like this:

a:
    unset MY_VARIABLE; $MAKE -C a/src

or

a:
    $MAKE MY_VARIABLE=foo -C a/src

Upvotes: 0

Related Questions