Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding `CC` and `CXX` variables in makefiles

I have a master makefile, which contains generic settings, and a child makefile that has project specific settings.

From my other question about overriding variables in a makefile, I learned that I can use the following code in my master makefile:

CC ?= avr-gcc
CXX ?= avr-g++

In the child makefile, I use colorgcc and override these variables:

CC ?= color-avr-gcc
CXX ?= color-avr-g++

Everything works.

But, if I remove the above lines from my child makefile, make starts using gcc and g++ instead of avr-gcc and avr-g++.

I guess both CC and CXX are treated differently and they are provided with default values by make and I am not able to assign default values to them using the following statements:

CC ?= avr-gcc
CXX ?= avr-g++

My questions:

  • Is my assumption correct?
  • If yes, is there any other way to provide default values to CC and CXX in the master makefile and let make use it, if I don't override them in the child makefile?

Edit:

As per Chrono Kitsune's suggestion I did the following

master makefile

CC = avr-gcc
CXX = avr-g++
# Add other master macros here.
# Add other master targets here.

child makefile

CC ?= color-avr-gcc
CXX ?= color-avr-g++
# There are no child macros or targets

include master.mk

Unfortunately, even this didn't work. When I run make child.mk it is picking up the CC and CXX defined in master.

PS: BTW, my master makefile is a makefile for Arduino and the full source code is available in github.

like image 301
Sudar Avatar asked Sep 03 '25 09:09

Sudar


1 Answers

Split your master makefile into two files: master.macros and master.targets. The .macros file will contain any macros such as CC and CXX, and the .targets file will contain the actual targets to make.

Child makefile:

CC ?= color-avr-gcc
CXX ?= color-avr-g++
# Add other child macros here.

include master.macros

# Add child targets here.

include master.targets

master.macros:

CC = avr-gcc
CXX = avr-g++
# Add other master macros here.

master.targets:

# Add master targets here.

If you set CC on the command line, the entire project will use that. Otherwise if CC is set in the child makefile, the entire project will use that CC. If neither is used, the entire project will use the CC macro in master.macros.

If you need anything more complicated, such as a different CC being used in building master targets only, you will want to use a different CC variable such as MASTER_CC that defaults to $(CC), though you can override it as needed by using a command line like make MASTER_CC=avr-gcc if you don't want to use whatever CC is in the child makefile. You'd use the ?= assignment, and all rules would need to be explicit and you would substitute any $(CC) in a rule for $(MASTER_CC) of course:

master.macros:

MASTER_CC ?= $(CC)
MASTER_CXX ?= $(CXX)

It will use color-avr-gcc for example if that is the value of CC. Otherwise, you'd need to use make MASTER_CC=avr-gcc to use avr-gcc instead. I haven't tested this last bit, meaning there are probably bugs, but I'd imagine the first solution is what you need: split the master makefile into two files, and use CC ?= ... in the part containing only master macros and the child makefile.