Makefile: embedded statements - makefile

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=))

Related

snakemake program not running all functions?

configfile: "config.yaml"
DATA = config['DATA_DIR']
BIN = config['BIN']
JASPAR = config['DATA_DIR']
RESULTS = config['RESULTS']
# JASPAR = "{0}/JASPAR2020".format(DATA)
JASPARS, ASSEMBLIES, BATCHES, TFS, BEDS = glob_wildcards(os.path.join(DATA, "{jaspar}", "{assembly}", "TFs", "{batch}", "{tf}", "{bed}.bed"))
rule all:
input:
expand (os.path.join(RESULTS, "{jaspar}", "{assembly}", "LOLA_dbs", "JASPAR2020_LOLA_{batch}.RDS"), jaspar = JASPARS, assembly = ASSEMBLIES, batch = BATCHES)
rule createdb:
input:
files = expand(os.path.join(RESULTS, "{jaspar}", "{assembly}", "data", "{batch}", "{tf}", "regions", "{bed}.bed"), zip, jaspar = JASPARS, assembly = ASSEMBLIES, batch = BATCHES, tf = TFS, bed = BEDS)
output:
os.path.join(RESULTS, "{jaspar}", "{assembly}", "LOLA_dbs", "JASPAR2020_LOLA_{batch}.RDS")
shell:
"""
R --vanilla --slave --silent -f {BIN}/create_lola_db.R \
--args {RESULTS}/{wildcards.jaspar}/{wildcards.assembly}/data/{wildcards.batch} \
{output};
"""
Why my snakemake program is not considering "createdb" rule. It is only considering "all". Can someone please help me with this?
"snakemake only runs the first rule in a Snakefile, by default." - SOURCE
If that first rule's input isn't clearly linked to createdb, it's not going to know to run createdb. Because the only rule it wants to run would have to depend on createdb.
I suspect your problem is the input to your rule createdb shouldn't have expand() used for all the wildcards already handled by rule all, just bed?. See here.
Also other avenues to consider for debugging is investigating what you unpacked glob_wildcards() to and what files is.

Conditional variable assignement in makefile target

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

tinydtls configuration in Contiki

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'.

run a target always along with default target

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:
...
...

GNU Make: How to perform second expansion with suffix-changing substitution

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 $<

Resources