12
votes

Looking for some help passing variables from one level to the next in a makefile. I have a source tree that needs to be built to run on various target architectures. To keep the higher level makefile clean I created separate makefiles that contain architecture specific information and include only the one that is required using the include directive :)

Later in the makefile I transfer to another directory to build the source files. The build fails and I see that the failure is caused by the architecture-specific variables not being passed.

ifeq ($(ARCH), my_arch)        |
include build/my_archdefs.mk   |  section 1 
endif                          |

<more commands>
debug:
      $(MAKE) -C src debug

The makefile to build the code tree is in the src directory. As a stop gap measure I included section 1 referenced above in the lower level makefile and in this case I noticed that the variable ARCH was not being passed down.

Here are a couple of links I found that seemed related but I'm not able to figure out what I need to do make this work. http://www.gnu.org/software/make/manual/html_node/Options_002fRecursion.html#Options_002fRecursion http://www.gnu.org/software/make/manual/html_node/Include.html

It seems to me that the info I need is lurking in the links I referenced above but I'm just not seeing it. Any pointers will be much appreciated.

Thanks.

2

2 Answers

14
votes

This link should help: http://www.gnu.org/software/make/manual/html_node/Variables_002fRecursion.html#Variables_002fRecursion

In your top level Makefile just add the line export and all of your variables will be exported to your submakes.

Example:

File Makefile:

ID=asdf
export
all:
    @echo ${ID}
    @make -f Makefile2

File Makefile2:

all:
    @echo ${ID}

Output:

$ make
asdf
make[1]: Entering directory `/home/user/Desktop/a'
asdf
make[1]: Leaving directory `/home/user/Desktop/a'
4
votes

Example for your reference:

Below is the "Makefile" which is at the top level.

Makefile

export ROOT_DIR=${PWD}

all:        
       $(MAKE) -C test

Then, there is another "Makefile" inside the "test" folder (with respect to the current location), as below:

Makefile

all:    
        echo $(ROOT_DIR)

When you say "make all" at the top-level folder, then it will subsequently build as per the current location-Makefile, and then subsequently as per the said rule at the "test" folder location (taking Makefile at "test" location for build rules). Therefore, when the parent-Makefile, exports some variable, then for that build-environment, the exported variable will be visible to all the sub-directory Makefiles.

However, if you try to explicitly go inside "test" folder and attempt to "make all", then you will have to explicitly set the environment variable, prior to it (which in previous case, is set in the top-level Makefile).

More Info.