Makefile ifndef variable in target - makefile

Please believe me: I searched and tested a lot... but I don't get whats wrong here:
VERSION := 123
all:
ifndef VERSION
$(error VERSION not set)
else
$(info Start deploy $(VERSION))
endif
outputs VERSION not set
what I really wanted was to call make like VERSION=1.2.3 make but not even setting the variable in the Makefile worked
What am I missing?

For me it outputs Start deploy 123.
Note that ifndef and $(error) and $(info) are part of makefile syntax, not the recipe syntax belonging to all target. So, your code is equivalent to:
VERSION := 123
ifndef VERSION
$(error VERSION not set)
else
$(info Start deploy $(VERSION))
endif

Related

Cause makefile to error if an environment variable is not set?

I'd like my makefile to crash if an environment variable is not set. This is what I have so far:
ifneq ($(shell echo $${VIRTUAL_ENV:+True}),True)
$(error Looks like no virtualenv is active)
endif
and it works!
I'm wondering if there's a more elegant way to do this, perhaps with make directly instead of calling $(shell ...).
Thanks for your help!
You can make use of the origin function...
ifeq ($(origin VIRTUAL_ENV),undefined)
$(error Looks like no virtualenv is active)
endif
This could be simplest option, but isn't as fine tuned as using origin.
ifndef VIRTUAL_ENV
$(error Looks like no virtualenv is active)
endif
One caveat here is that you can't distinguish if VIRTUAL_ENV defined in the Makefile or in the environment.
As #KurtisRader pointed out in a comment, this is possible because environment vars are implicitly "imported" into make's namespace https://www.gnu.org/software/make/manual/html_node/Environment.html.

How to check if a file exists in Makefile

I am using makefile to build my program in multiple system. Some system have installed colorgcc script. In my Makefile i want to check, if script exists
and depending on it i setting up CC variable. But my Makefile don't work correctly - in system, that haven't colorgcc, make always set $(CC) as colorgcc. Here's part of Makefile:
ifneq ("$(wildchar /usr/bin/colorgcc)","")
CC=colorgcc
else
CC=gcc
endif
I also tried to use this variant:
ifeq ( $(shell test -e /usr/bin/colorgcc), )
CC=colorgcc
else
CC=gcc
endif
In both case $(CC) doesn't depend of existence file /usr/bin/colorgcc
How can i solve my problem?
In the first case, you mistyped the function $(wildcard ...) so you get nothing, always.
In the second case, the output of test is always the empty string. It will set its exit code depending on whether the condition is true or not, but you are not examining its exit code, just the output it prints, which will always be nothing at all.

How to use ifeq inside of a define in GNU Make?

I'm trying to do an ifeq inside of a define within a Makefile, but I seem to be running into some errors, and I'm wondering if I'm missing something. I have the following Makefile:
$(info ---- start ----)
ifeq ("X","Y")
$(info DOES not appear_1)
endif
define TESTDEF
ifeq ("X","Y")
$(info SHOULD not appear)
# $(error DEFINITELY SHOULD not error...)
endif
endef
$(eval $(call TESTDEF, 1,2,3))
I'm getting the following error:
---- start ----
SHOULD not appear
Makefile:14: *** DEFINITELY SHOULD not error.... Stop.
Is there some trick that I'm missing? Is it possible to do ifeq's inside define? (note: this happens on both my native GNU 3.81 make, and on my mips uclibc cross-compiler)
When you call this function, Make evaluates the definition, using whatever parameters you provide (irrelevant in this case). So if the definition includes something like $(info ...) or $(error ...), even in a comment, Make will evaluate it and you'll see the result (see documentation; I've tested it in GNUMake 3.81).
To get the behavior you want, add a couple of dollar signs:
define TESTDEF
ifeq ("X","Y")
$$(info SHALL not appear)
# $$(info DEFINITELY SHALL not error...)
endif
endef
$(eval $(call TESTDEF))

How can I print message in Makefile?

I want to print some message while doing build process with a makefile. The following one can print the message, but it will not execute the script after it. How can I fix this issues?
ifeq (yes, ${TEST})
CXXFLAGS := ${CXXFLAGS} -DDESKTOP_TEST
test:
#echo '************ TEST VERSION ************'
else
release:
#echo "************ RELEASE VERSIOIN **********"
endif
It's not clear what you want, or whether you want this trick to work with different targets, or whether you've defined these targets elsewhere, or what version of Make you're using, but what the heck, I'll go out on a limb:
ifeq (yes, ${TEST})
CXXFLAGS := ${CXXFLAGS} -DDESKTOP_TEST
test:
$(info ************ TEST VERSION ************)
else
release:
$(info ************ RELEASE VERSIOIN **********)
endif
$(info your_text) : Information. This doesn't stop the execution.
$(warning your_text) : Warning. This shows the text as a warning.
$(error your_text) : Fatal Error. This will stop the execution.
src: https://www.gnu.org/software/make/manual/make.html#Make-Control-Functions

Using ifeq and ifndef in GNU Make

I've written a fairly simple test Makefile where I define two targets, all & clean. I've got two different conditional statements. One checks for the existence of the $(MAKECMDGOALS) special variable and the other detects whether any of the command line targets matched those listed in a variable (NODEPS). The problem I'm having is that none of the branches within my conditionals get executed. Ultimately I want to use a conditional to decide whether the target I'm supplying should include some autogenerated dependency files but at the moment I'm struggling to get either expression to even evaluate. I'm running GNU make version 3.81 and I've tried it under Ubuntu and Mac OS X to no avail.
NODEPS := clean
INCLUDE = $(filter $(NODEPS),$(MAKECMDGOALS))
.PHONY : all clean
ifndef $(MAKECMDGOALS)
#echo "$$(MAKECMDGOALS) is not defined"
else
#echo "$(MAKECMDGOALS) is defined"
endif
ifneq (0, $(words $(INCLUDE)))
#echo "INCLUDE = $(INCLUDE) != 0"
else
#echo "INCLUDE = $(INCLUDE) == 0"
endif
all :
#echo "all : $(MAKECMDGOALS)"
clean :
#echo "clean : $(MAKECMDGOALS)"
I eventually managed to work out what was wrong. #eriktous was right, pointing out that I should be using $(info) rather than #echo. More subtly though, part of the problem was that I'd indented the #echos with a tab. It seems that tabs are mandatory for rules but not allowed in conditionals. The other mistake was I'd expanded the $(MAKECMDGOALS) variable in the test condition when it should have been written as just ifndef MAKECMDGOALS.
https://www.gnu.org/software/make/manual/html_node/Make-Control-Functions.html
A makefile is not a shell script. You can not "randomly" place executable statements anywhere you like and expect them to be executed.
There are various ways of communicating with the outside world from within a makefile: $(info ...), $(warning ...), $(error ...) and $(shell #echo ...) (some or all of these may be GNU make extensions).
Ps: you misspelled PHONY.

Resources