I'm trying to adapt the Example from the Official Documentation of GNU make to my Use Case: GNU make - Example of a Conditional
libs_for_gcc = -lgnu
normal_libs =
ifeq ($(CC),gcc)
libs=$(libs_for_gcc)
else
libs=$(normal_libs)
endif
foo: $(objects)
$(CC) -o foo $(objects) $(libs)
So, I created this Prototype:
libs_for_gcc="gcc libs"
normal_libs="normal libs"
libs=
all: do_nothing
@echo "all: done."
do_nothing:
@echo "do_nothing: done."
example:
@echo "example: go ..."
@echo "example - cc: '$(CC)'"
@echo "libs_for_gcc: $(libs_for_gcc)"
@echo "normal_libs: $(normal_libs)"
@echo "libs: $(libs)"
ifeq ($(CC),gcc)
libs=$(libs_for_gcc) && echo "libs: '$$libs'"
@echo "example - libs: '$(libs)'"
else
libs=$(normal_libs) && echo "libs: '$$libs'"
@echo example - libs: $(libs)
endif
@echo "example - libs: '$(libs)'"
@echo "example: done."
test: libs += " -Ddebug"
test: example foo
bar:
@echo "bar: go ..."
ifeq (${libs}, "")
@echo "bar - libs: empty"
@echo "assigning libs"
libs=$(libs_for_gcc)
else
@echo "bar - libs: not empty"
@echo "bar - libs: '${libs}'"
endif
@echo "bar - libs: '${libs}'"
@echo "bar: done."
foo:
@echo "foo: go ..."
ifneq ("$(libs)", "")
@echo "foo - libs: not empty"
@echo "foo - libs: '$(libs)'"
else
@echo "foo - libs: empty"
endif
@echo "foo: done."
Now when I run the Default Target with $ make
it just produces:
$ make
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs:
libs="normal libs"
example - libs:
example - libs: ''
example: done.
I see that the value of libs was not changed as intended.
When I run the make bar Target it produces:
$ make bar
bar: go ...
bar - libs: not empty
bar - libs: ''
bar - libs: ''
bar: done.
Here libs is not empty but it has nothing inside.
And when I run the make foo target it produces:
$ make foo
foo: go ...
foo - libs: empty
foo: done.
Here libs is understood as empty
As I see that libs is not changed correctly I tried to change the syntax to:
example:
# [...]
ifeq ($(CC),gcc)
libs := $(libs_for_gcc)
@echo "example - libs: '$(libs)'"
else
libs := $(normal_libs)
@echo example - libs: $(libs)
endif
But then I get the GNU make Error:
$ make
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs:
libs := "normal libs"
/bin/sh: 1: libs: not found
Makefile:7: recipe for target 'example' failed
make: *** [example] Error 127
I couldn't find any documentation about this behaviour so I appreciate any advise.
Edit:
- Added
allandtestTargets.
Background:
The GNU make Command is an important part of the toolchain for packaging and deploying software and thus important in the daily work of System Administrators and DevOps Engineers.
- The Debian and RPM Packaging uses GNU make to package software.
Makefile Driven Packaging
It runs the
./configure && make && make installcommand sequence. - The Travis CI Workflow uses GNU make for running testsuites.
C Language Automated Testing
It runs the
./configure && make && make testsequence.
All the completely different Use Case are managed by the same Makefile. Now for my concrete Use Case I'm working on setting up the Travis CI Workflow Sequence to enable Automated Testing for my static linked Source Code Library. So, contrary to the Packaging Sequence the Automated Testing Sequence requires Debug Features and advanced Output Evaluation to produce a meaningful Test. I want the Test to check the Error Report and also the Memory Usage Report to alert me of any hidden errors.
Using the Advice about setting the Variable at the Target Declaration Line I was able to change libs for test, example and foo targets.
I also saw the important hint about the Bash Variable libs which is only valid on the same line:
$ make
do_nothing: done.
all: done.
$ make test
example: go ...
example - cc: 'cc'
libs_for_gcc: gcc libs
normal_libs: normal libs
libs: -Ddebug
libs="normal libs" && echo "libs: '$libs'" ;
libs: 'normal libs'
example - libs: -Ddebug
example - libs: ' -Ddebug'
example: done.
foo: go ...
foo - libs: empty
foo - libs: ' -Ddebug'
foo: done.
The Recipe libs=$(libs_for_gcc) && echo "libs: '$$libs'" shows that a new Bash Variable libs was created and it did not affect the GNU make Variable.
Still the Conditional ifneq ($(libs),) cannot detect that libs was already set for the test target.