Chris Aaaaa
Chris Aaaaa

Reputation: 167

Can I have local variables in included makefiles?

I am looking after a system with many hundreds of c files in many folders, there are multiple targets so not all the c files are required in each build.

Because not all files are required I cannot use a pure recursive build. And I don't want to do that, because I would rather not have a slow serial build with mystic dependencies anyway.

What I have come up with broadly is a top level makefile where I pull in a list of folders and include a makefile from each of these folders.

SUB_MAKEFILES := $(foreach subdir,$(SUBDIRS), $(subdir)/subdir.mk)
-include $(SUB_MAKEFILES)

Some folders have specific files to compile so the included file is pretty simple;

srcs += path/a.c path/b.c
deps += path/a.d path/b.d
objs += op/path/a.o op/path/b.o

op/path/%.o: path/%.c path/subdir.mk
   compile ...

I do not want to do this dozens of times so I have a generic pattern I use for folders where everything is to be compiled;

PATH155 := src/f1/f2/f3/f4

srcs += $(shell $(FFshell) $(PATH155) -maxdepth 1 -name '*.c')
deps += $(addprefix ${OUT_DIR}, $(patsubst %.c,%.d,$(shell $(FFshell) $(PATH155) -maxdepth 1 -name '*.c')))
objs   += $(addprefix ${OUT_DIR}, $(patsubst %.c,%.o,$(shell $(FFshell) $(PATH155) -maxdepth 1 -name '*.c')))

$(OUT_O_DIR)$(PATH155)/%.o: $(PATH155)/%.c $(PATH155)/subdir.mk
    gcc -c $(CFLGS) -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o"$@" "$<"

This works, however I would like to avoid having to make up a random unique name for the path where the subdir.mk file resides.

Is there anyway to replace "PATH155673423 := hand/entered/path" with something like "local SUBDIRPWD = $(some function...)".

Then I could just drop in a generic makefile and include it, no error prone typing of paths nor worries that I will get a unique name clash.

It would be nice to have a few less directory scans too, same issue really, need a local variable.

Even some sort of macro for the repeated variable names etc would be better

Maybe there is a way to include the makefiles in a loop instead and set a path variable just before each is included?

Ta

Chris

Upvotes: 7

Views: 5059

Answers (1)

MadScientist
MadScientist

Reputation: 100816

There is no such thing as variables scoped to a particular makefile, such as you're suggesting. However, you have a lot of options for making this work, from constructed variables to give scope, to using eval to generate functions. For example, something like this:

SUBDIRS := foo bar biz baz

define INCLUDE_FILE
path = $S
include $S
endef

$(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))

You can find out more about these by looking through this set of blog posts and the associated sections of the GNU make manual.

Upvotes: 10

Related Questions