I have a default target "all" but I want to initialize a few variables ever time I run the makefile . whatever is the target for make flow.
cat Makefile
all: last_step
initialize:
ifeq (,$(filter $(ps),0 1))
#$(eval override ps=0)
endif
step1:
<>
step2: step1
<>
....
last_step: second_last_step
<>
I want to initialize the variable every time a make file is run .
initialize target should be run in both the following flow styles.
make .
make nth-step
Nothing easier:
ifeq (,$(filter $(ps),0 1))
override ps=0
endif
all: last_step
...
step1:
...
...
Related
I'm trying to get conditional assignment in a makefile target, only if it was not set by the requiring target:
REPO_PROD = prod
REPO_DEV = dev
.PHONY: ko-build-container
ko-build-container: KO_DOCKER_REPO ?= $(REPO_PROD)
ko-build-container:
#echo $(KO_DOCKER_REPO)
.PHONY: ko-build-container-dev
ko-build-container-dev: KO_DOCKER_REPO = $(REPO_DEV)
ko-build-container-dev: ko-build-container
Unfortunately make ko-build-container-dev prints prod.
What am I missing here ?
Another alternative is to use a third target, like:
ko-build-container-base:
echo $(KO_DOCKER_REPO)
ko-build-container: KO_DOCKER_REPO = $(REPO_PROD)
ko-build-container: ko-build-container-base
ko-build-container-dev: KO_DOCKER_REPO = $(REPO_DEV)
ko-build-container-dev: ko-build-container-base
Apparently, with GNU make, the outcome of the conditional assignment (assign or not assign) is decided in a phase where only global variables are available, but the selection of the final value comes from a later phase where inherited target-specific variables are also available. So, even more bizarre than what you observed, after skipping a conditional assignment because a global variable was set, the final value is not necessarily that of the global variable, it can be inherited from a parent target! Demo:
$ cat Makefile
.PHONY: sub all
all: VAR = all
all: sub
# no global VAR set => assign instead of using inherited VAR = all
sub: VAR ?= sub
sub:
#echo $(VAR)
$ make
sub
$ cat Makefile
.PHONY: all
VAR = global
# global VAR set => do not assign, use global VAR = global
all: VAR ?= all
all:
#echo $(VAR)
$ make
global
$ cat Makefile
.PHONY: sub all
VAR = global
all: VAR = all
all: sub
# global VAR set => do not assign... but use inherited VAR = all
sub: VAR ?= sub
sub:
#echo $(VAR)
$ make
all
This strange behavior is reported here: https://savannah.gnu.org/bugs/?18305 and there is also a discussion about whether it should/could be fixed.
Separating the outcome from the selection of the value in conditional assignments is clearly a bug, I think. Nobody would imagine such a weird behavior. Anyway, instead of a target-specific conditional assignment you could use the workaround suggested in the discussion:
$ cat Makefile
REPO_PROD = prod
REPO_DEV = dev
.PHONY: ko-build-container
ko-build-container:
#echo $(or $(KO_DOCKER_REPO),$(REPO_PROD))
.PHONY: ko-build-container-dev
ko-build-container-dev: KO_DOCKER_REPO = $(REPO_DEV)
ko-build-container-dev: ko-build-container
$ make ko-build-container-dev
dev
I am currently trying to configure tinydtls as described in the README in order to later include it into an application, or at least, make the examples run.
The first steps, including the resulting warnings:
home/name/contiki/apps/tinydtls$ autoreconf
aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in'
home/name/contiki/apps/tinydtls$ ./configure --with-contiki
home/name/contiki/apps/tinydtls$ make
with both TARGET=native and TARGET=zoul
The compilation always ends with (many) undefined reference errors:
obj_zoul/dtls.o: In function dtls_add_ecdsa_signature_elem':
dtls.c:(.text.dtls_add_ecdsa_signature_elem+0x10): undefined reference to `dtls_ec_key_from_uint32_asn1'
dtls_ec_key_from_uint32_asn1 is located in contiki/apps/tinydtls/crypto.c.
Adding #include crypto.h in dtls.c doesn't fix the problem, but #include crypto.c does (fix this first error). Accordingly I assume the problem must have to do something with the linking.
How should the Makefile, of which I pasted a (hopefully significant) part under this question, be adjusted?
SHELL = /bin/sh
MKDIR = mkdir
ETAGS = /bin/false
prefix = /usr/local
exec_prefix = ${prefix}
abs_builddir = /home/name/contiki/apps/tinydtls
top_builddir = .
libdir = ${exec_prefix}/lib
includedir = ${prefix}/include/tinydtls
package = tinydtls-0.8.2
install := cp
# files and flags
SOURCES:= dtls.c crypto.c ccm.c hmac.c netq.c peer.c dtls_time.c session.c
ifneq ("", "1")
SOURCES += debug.c
endif
SUB_OBJECTS:=aes/rijndael.o ecc/ecc.o sha2/sha2.o
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES)) $(SUB_OBJECTS)
HEADERS:=dtls.h hmac.h debug.h dtls_config.h uthash.h numeric.h crypto.h global.h ccm.h \
netq.h t_list.h alert.h utlist.h prng.h peer.h state.h dtls_time.h session.h \
tinydtls.h
CFLAGS:=-Wall -pedantic -std=c99
CPPFLAGS:= -DDTLSv12 -DWITH_SHA256 -DDTLS_CHECK_CONTENTTYPE
SUBDIRS:=tests doc platform-specific sha2 aes ecc
DISTSUBDIRS:=$(SUBDIRS) examples/contiki
DISTDIR=$(top_builddir)/$(package)
FILES:=Makefile.in configure configure.in dtls_config.h.in tinydtls.h.in \
Makefile.tinydtls $(SOURCES) $(HEADERS)
LIB:=libtinydtls.a
LDFLAGS:=
ARFLAGS:=cru
doc:=doc
Edit: Changed the directory for this post to /home/name/...
Edit2: Added warnings after 'autoreconf'.
Structure:
makefile
system/
-> makefile
-> kernel/
-> -> makefile
-> -> src/
-> FutureModules
-> -> makefile
-> -> src/
userland/
-> makefile
-> FutureModules
-> -> makefile
-> -> src/
Currently I'm building it with make system.
I'd like to split it up into Debug/Test/Release builds so that i can do something like make debug system or make -d system with multiple targets (e.g. make debug system userland or something like that).
I'd like to change the targets so i can directly build a target instead of building system and manually have to add the desired targets in system/makefile.
Now in order to achieve this:
Do constants get shared between makefiles? So when i do make system and i define CFLAGS += -g -Og in the root makefile, does the system/makefile get the constants from the root makefile?
Do constants stay the same in a make session? So when i do make debug system userland and have something like debug: CFLAGS += -g -Og, do system and userland get the -g -Og flags?
EDIT: I managed to achieve 2. by using $(shell find -maxdepth 1 -type d) and some other commands.
Solved it with:
#Build mode. m=d => Debug | m=t => Test | m=r => release | default => release
ifeq ($(m), d)
NASBUILD = $(NASDEBUG)
GASBUILD = $(GASDEBUG)
CPPBUILD = $(CPPDEBUG)
CBUILD = $(CDEBUG)
else ifeq ($(m), t)
NASBUILD = $(NASTEST)
GASBUILD = $(GASTEST)
CPPBUILD = $(CPPTEST)
CBUILD = $(CTEST)
else ifeq ($(m), r)
NASBUILD = $(NASRELEASE)
GASBUILD = $(GASRELEASE)
CPPBUILD = $(CPPRELEASE)
CBUILD = $(CRELEASE)
else
NASBUILD = $(NASRELEASE)
GASBUILD = $(GASRELEASE)
CPPBUILD = $(CPPRELEASE)
CBUILD = $(CRELEASE)
endif
export NASBUILD
export GASBUILD
export CPPBUILD
export CBUILD
Where xxxBUILD and so on gets added to the corresponding xxxFLAGS.
I have in the /bin folder a file program.cc.
The following Makefile statements
BINS = $(wildcard bin/*.cc)
EXECS = $(notdir $(BINS))
EXECSR = $(EXECS:.cc=)
mean that EXECSR is program
I try to avoid the intermediary variable EXECS in the above statements
BINS = $(wildcard bin/*.cc)
EXECSR = $($(notdir $(BINS)):.cc=)
but this approach fails - EXECSR is empty. How should I modify the Makefile to avoid the intermediary variable EXECS?
EXECSR = $(notdir $(BINS:.cc=))
What I'm going for (what's failing)
I have a list of dependencies for each file:
point_deps =
bounds_deps = point
triangle_deps = point bounds
Image_deps = types bounds triangle
main_deps = Image triangle bounds point types
I'd like to write a rule to include the relevant dependencies. Here's my best attempt:
out/%.o: src/%.cpp src/%.h $$($$*_deps:%=src/%.h)
g++ -o $# -c $<
I expect $* to evaluate to, for instance, "main". Then the suffix-changing substitution should change each entry in the dependency list to begin with "src/" and end with ".h".
When I try to run the code above, I get an error (on the out/%.o line):
makefile:26: *** multiple target patterns. Stop.
What's working (non-optimal)
For now I have to create a separate variable for each file's header dependencies:
point_deps_h = $(point_deps:%=src/%.h)
bounds_deps_h = $(bounds_deps:%=src/%.h)
triangle_deps_h = $(triangle_deps:%=src/%.h)
Image_deps_h = $(Image_deps:%=src/%.h)
main_deps_h = $(main_deps:%=src/%.h)
Then I can use secondary-expansion to include the correct header files:
out/%.o: src/%.cpp src/%.h $$($$*_deps_h)
g++ -o $# -c $<