views:

287

answers:

4

I'm trying to glue two build systems together. Both are recursive (rules in the makefile use make to call other makefiles to build components of the project).

I'll call them 'A' and 'B' where 'A' builds the application and 'B' builds libraries used by 'A'.

The top level makefile in A calls 'make TARGET=whatever' which means that all the recursively-invoked bits of the build inherit the value of TARGET as a read-only variable, including the build system from B, which is called as part of the recursive build.

I don't want this to happen in the build system for 'B' (which come from a different project) as the makefiles there use TARGET for their own purposes and the build fails since TARGET has the wrong value and is read-only.

I can only see two solutions to this, neither of which is palettable;

1) Rename TARGET to something else in the makefile in A that sets it and in the makefiles in A that use it, to avoid the clash with the lower levels of the build system.

2) Use the 'override' directive everywhere in the makefiles in B where the TARGET variable is set, to override its read-only status.

Anyone got any better ideas? - ideally, I want nothing to be inherited by the B's build system from A's, except those options I explicitly pass to the B build system from A.

Incidentally, I'm using GNU Make v3.80.

A: 

Perhaps you can use the "unexport" directive to prevent TARGET from being propagated to B's makefile?

JesperE
Unfortunately, the unexport directive only prevents variables exported using export from being exported - it has no effect on variables passed on the command line to the current make process or inherited from the command line of a parent make.It looks as if setting a value via the make command line makes it indestructably read-only to all child makes.
John Skilleter
Then I'm out of ideas.
JesperE
+1  A: 

You could set MAKEOVERRIDES to nothing in the second-level makefile in A.

callb:
      cd subdir && $(MAKE) MAKEOVERRIDES=

This passes down the normal commandline parameters like -k and -s but not commandline variable definitions.

Or you use the historical MFLAGS which is the same as MAKEFLAGS except MFLAGS doesn't contain the commandline variable definitions.

callb:
     cd subdir && $(MAKE) $(MFLAGS)

Details about this two options can be read here: The GNU Make Manual

A: 

At the point where build system A invokes build system B, do not use '${MAKE}' directly; invoke a shell script that invokes build system B (possibly after sanitizing the environment).

To achieve the behaviour where the commands are executed by 'make -n', prefix the command line in the makefile with '+' (similar to prefixing the line with '@' or '-').

Jonathan Leffler
A: 

I just ran into the same problem... after some experimenting the following approach seems to work:

callb:
    cd subdir && $(MAKE) TARGET=

This appears to have the effect of undefining TARGET, which is what you (and I) want.

Cheers, Dan.

DG