How to get the tail of `$^` in Makefile - makefile

I have the following rule in a Makefile
%/collapsed_flow_profile.png: \
code/piv/plot_collapsed_flow_profiles.R \
%/experiment2/averaged_flow_profile.csv \
%/experiment3/averaged_flow_profile.csv \
%/experiment4/averaged_flow_profile.csv \
%/experiment6/averaged_flow_profile.csv \
%/experiment7/averaged_flow_profile.csv
code/piv/plot_collapsed_flow_profiles.R \
$*/collapsed_flow_profile.png \
$*/experiment2/averaged_flow_profile.csv \
$*/experiment3/averaged_flow_profile.csv \
$*/experiment4/averaged_flow_profile.csv \
$*/experiment6/averaged_flow_profile.csv \
$*/experiment7/averaged_flow_profile.csv
As you can see, I'm passing all the dependencies except the first one as an argument to the code used in the recipe. Since $^ automatic variable contains all the dependencies, it is possible to remove the first dependency from $^ and pass it to the code as an argument?

There are $(firstword a b c) -> a and $(filter-out ...) and $(wordlist s,e,text) functions for transforming text. Combining them might be able to do what you want. The excellent documentation has the details.
PS: What happened to experiment 5? Outlier? Does not fit expectations? :-)

Related

where is the rule to build a $(obj)/subdir target in linux kernel makefile?

In linux kernel Makefile.build:
`
# To build objects in subdirs, we need to descend into the directories
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;`
the $(obj)/subdir/built-in.a depends on $(obj)/subdir prereq, but where is the rule to build $(obj)/subdir?
I assume the following rule is only for $(obj)/ directory, and can't apply for the above subdir.
`
# Build
# ---------------------------------------------------------------------------
$(obj)/: $(if $(KBUILD_BUILTIN), $(targets-for-builtin)) \
$(if $(KBUILD_MODULES), $(targets-for-modules)) \
$(subdir-ym) $(always-y)
#:`
Thanks!
I have looked up the makefile, but have not found any clue.
I already got the answer from a Linux kernel maintainer, as below:
See around line 500.
$(subdir-ym):
$(Q)$(MAKE) $(build)=$# \
need-builtin=$(if $(filter $#/built-in.a, $(subdir-builtin)),1) \
need-modorder=$(if $(filter $#/modules.order, $(subdir-modorder)),1) \
$(filter $#/%, $(single-subdir-goals))

Erratic behaviour in a makefile resulting in re-building targets

I'm using makefiles to structure a data analysis pipeline consisting of various steps such as extracting data, sampling and modelling. However, when I create an additional "upper-level" makefile (such as modelling) that depends on others, and I try to run make again (either on the new makefile or any other upper-level makefiles), it tries to re-build everything again from the lowest-level makefile targets.
In the code below I show the "lowest level" makefile and another one (makefile.sample that includes the first one):
Makefile
all:
make $(DATA_TRN)
make $(Y_TRN)
# dates
SNAP_TRN := 2019-06-18
SNAP_TST := 2019-07-24
# Targets
TARGET_CLASS = m1_vol
TARGET_SURV = m1_qty
TARGET_INIT = act_qty
END_DUR = 1
# dirs
DIR_DATA := data
DIR_CONFIG := configs
# data files for training and predict
DATA_TRN := $(DIR_DATA)/processed/churnvol_train_$(SNAP_TRN).csv
DATA_TST := $(DIR_DATA)/processed/churnvol_test_$(SNAP_TST).csv
# labels
Y_TRN := $(DIR_DATA)/processed/label_train_$(SNAP_TRN).csv
Y_TST := $(DIR_DATA)/processed/label_test_$(SNAP_TST).csv
# Config files
CONFIG_PANEL := $(DIR_CONFIG)/config_panel.yaml
CONFIG_INPUT := $(DIR_CONFIG)/config_inpute.yaml
FEATS := $(DIR_CONFIG)/featimp_churnvol.csv
# Generates a clean dataset (inputed and one hot encoded)
$(DATA_TRN): $(CONFIG_INPUT) $(FEATS) | $(DATA_DIR)
python src/_buildDataset.py --train-file $(DATA_TRN) \
--test-file $(DATA_TST) \
--train-date $(SNAP_TRN) \
--test-date $(SNAP_TST) \
--config-panel $(CONFIG_PANEL) \
--config-input $< \
--feats $(lastword $^)
$(Y_TRN): $(DATA_TRN) | $(DATA_DIR)
python src/_extractColumns.py --data $< \
--columns $(TARGET_INIT),$(TARGET_CLASS),$(TARGET_SURV) \
--file $#
clean:
-rm -rf $(DATA_TST) $(DATA_TRN) $(Y_TRN) $(Y_TST)
.PHONY: all clean
Makefile.sample.u1
include Makefile
sample:
make -f Makefile.sample.$(SAMPLE_NAME) $(DATA_TRN_SAMPLE)
SAMPLE_NAME = u1
MIN_RATIO = 0.333333 # ratio of minority class for undersampling
DATA_TRN_SAMPLE := $(DIR_DATA)/processed/churnvol_train_$(SAMPLE_NAME)_$(SNAP_TRN).csv
$(DATA_TRN_SAMPLE): $(DATA_TRN) | $(DATA_DIR)
python ./src/_generate_sample_u1.py --data-train $< \
--data-file $# \
--min-ratio $(MIN_RATIO) \
--end-feat $(TARGET_SURV) \
--end-dur $(END_DUR)
.PHONY: sample
From these 2 makefiles, I'm assuming that make only needs to rebuild $(DATA_TRN) if either $(CONFIG_INPUT) or $(FEATS) changed after $(DATA_TRN) right? The problem is that both timestamps show a previous date from the target $(DATA_TRN) and when I run make all it still rebuilds the target. src/_buildDataset.py also shows a previous date. I've tried to debug and running make $(DATA_TRN) returns a $(DATA_TRN) is up to date. message. However, when I run make $(Y_TRN) it rebuild $(DATA_TRN), which I find odd. This also means that when I run make -f Makefile.sample.u1 sample, it also goes on to rebuild $(DATA_TRN). Can someone help me figure out if I did something wrong? Or other ways to debug, such as knowing exactly what file make marked as "changed". Thank you

how do I dispatch the functions that generated by halide (tutorial lesson 15)?

The tutorial generates 3 functions with different target and pack into a single static library along with halide runtime.
The question is, how do I call it ?
To my understanding, I should check the cpu feature before calling the functions.
What is the best way the dispatch these functions ?
./lesson_15_generate \
-g my_first_generator \
-f my_first_generator_basic \
-e object,c_header\
-o . \
target=host-x86-64-no_runtime
./lesson_15_generate \
-g my_first_generator \
-f my_first_generator_sse41 \
-e object,c_header\
-o . \
target=host-x86-64-sse41-no_runtime
./lesson_15_generate \
-g my_first_generator \
-f my_first_generator_avx \
-e object,c_header\
-o . \
target=host-x86-64-avx-no_runtime
You can get Halide to do the dispatch for you at runtime using a comma-separated list of targets:
./lesson_15_generate \
-g my_first_generator \
-f my_first_generator \
-e static_library,c_header\
-o . \
target=x86-64-avx-no_runtime,x86-64-sse41-no_runtime,x86-64-no_runtime
That makes it compile three different pieces of code for the three targets. Calling "my_first_generator" will then automatically dispatch to the first thing in the list that it thinks it can run, based on checking the CPU ID on the first call.

I'm trying to build Ressurection Remix. When I run brunch, I get:*** missing separator and *** recipe commences before first target, for the same line

When i run brunch, i get these errors for the same line:
1) With tab
*** recipe commences before first target
2) Without tab
*** missing separator
I have seen this question already, but it didn't seem helpful.
The lines around the problematic line are:
# Wifi
PRODUCT_PACKAGES += \
dhcpcd.conf \
hostapd \
libwpa_client \
wpa_supplicant \
wpa_supplicant.conf \
lib_driver_cmd_mt66xx
PRODUCT_PACKAGES += \
librs_jni \
com.android.future.usb.accessory \
charger \
charger_res_images \
libnl_2 \
libion \
Snap
The line in qustion is
librs_jni \
What am i doing wrong?
I have also attached my edited makefile here
(The problematic line is 41)
And the original makefile here (from the device tree on github)
\ needs to be the last character in the line to act as the line-pasting token. You can't have white space after it.

Makefile rule to build with same name, but different directory

I would like a rule something like:
build/%.ext: src/%.ext
action
I have one directory of files in a folder that I want to optimize and then output to a different folder. However, the files have the same name in the input and output folders. I have tried various iterations of the rule above, but make will either always or never rebuild depending how I tweak the above. Suggestions?
EDIT:
I ended up with the following solution, which works great!
JS = \
src/js/script2.js \
src/js/script1.js
JS_OPT = $(patsubst src/js/%.js,web/js/%.js, $(JS))
all: $(JS_OPT)
$(JS_OPT): web/js/%.js: src/js/%.js
cat $# | ./bin/jsmin > $<
Try somethink like this:
INPUT_FILES = \
src/a.txt \
src/b.txt \
OPTIMIZED_FILES=$(patsubst src/%.ext,build/%.ext,$(INPUT_FILES))
$(OPTIMIZED_FILES): build/%.ext: src/%.txt
optimize_command $# $<

Resources