Swift - Friday Pie
Swift - Friday Pie

Reputation: 14589

Re-evaluating GNU make makefile variable

I have inherited a large branched project? that requires a volatile set of .a archives $(LIB_FILES) to be included into link target, located in some directories $(LIB_DIRS). I can write an expression like this:

LIBDEP = $(foreach ldir, $(LIB_DIRS), \
    $(filter $(addprefix %/, $(LIB_FILES)), $(wildcard $(ldir)/* )))

The problem is that they might not exist at moment of make's invocation and would be built by invoking $(MAKE) inside of another target's rule, which is a prerequisite to the link step.

The problem is actual list of files that should be created varies on external factors determined at their build steps, that I can't hard-code it properly, without turning makefile into a spaghetti mess and said variable is not re-evaluated at the moment of link command invocation.

I have suspicion that $(eval ) function can be used somehow, but manual is not very forthcoming as well as I didn't found examples of its use in this way.

Toolchain: GCC and binutils, make 3.81

Upvotes: 1

Views: 1314

Answers (2)

Vroomfondel
Vroomfondel

Reputation: 2898

Another solution is to create an explicit dependency of your make script on the output of the step which currently creates the variable $(LIB_FILES). This is what the manual is dealing with in the chapter How makefiles are remade and it aims at the technique which make is best at, namely deriving dependencies from the existence and timestamp of files (instead of variables). The following hopefully depicts your situation with the process of deducing a new set of libraries simulated by the two variables $(LIBS_THIS_TIME) and $(LIB_CONFIG_SET).

LIBS_THIS_TIME = foo.a:baz.a:bar.a
LIB_CONFIG_SET = $(subst :,_,$(LIBS_THIS_TIME))

include libdeps.d

linkstep:
    @echo I am linking $^ now
    touch $@

libdeps.d: $(LIB_CONFIG_SET)
    -rm libdeps.d
    $(foreach lib,$(subst :, ,$(LIBS_THIS_TIME)),echo linkstep: $(lib) >> libdeps.d;)

$(LIB_CONFIG_SET):
    touch $@

If make finds that libdeps.d is not up to date to your current library configuration it is remade before make executes any other rule, although it is not the first target in the makefile. This way, if your build process creates a new or different set of libraries, libdeps.d would be remade first and only then make would carry on with the other targets in your top makefile, now with the correct dependecy information.

Upvotes: 2

Renaud Pacalet
Renaud Pacalet

Reputation: 28920

It sometimes happens that you need to invoke make several times in succession. One possibility to do this is to use conditionals:

ifeq ($(STEP),)
all:
    <do-first-step>
    $(MAKE) STEP=2 $@
else ifeq ($(STEP),2)
all:
    <do-second-step>
    $(MAKE) STEP=3 $@
else ifeq ($(STEP),3)
all:
    <do-third-step>
endif

In each step you can generate new files and have them existing for the next step.

Upvotes: 2

Related Questions