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
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))
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
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.
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.
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 $# $<