We are facing a slightly weird problem in GNU Make.
In one of the part Makefile, we try to modify a string in order to get right filename.
So "dummy_1_.pl" is to converted to "dummy_1.pl".
We tried to use following way :-
MY_STRING := dummy_1_.pl
UNDPL := _.pl
DPL := .pl
$(subst $(UNDPL), $(DPL), $(MY_STRING) )
Surprisingly it doesn't work. We can replace ".", "pl", ".pl" etc all this way. However just "" or "." or "_.pl" etc replacement strings starting with an underscore doesn't seem to work.
Is underscore a special character in Make. Are we missing something basic here... We are at GNU Make 3.81
Any help/thought is highly appreciated. Thanks in advance!.
EDIT :-
The problem was posted in short for focused discussion. It seems, the details are necessary. This applies to a pattern rule as below. There's a OUT_V_FILES target that contains *blah_cpu.v *foo_gpu.v etc various target files. (The special string "cpu", "gpu" etc are part of a list.) We want to derive blah.pl, foo.pl respectively as input file for the rule.
DEVICES := cpu gpu memc dram
MY_STRING := $$(foreach dev,$(DEVICES),$$(subst $$(dev),$(NOTHING),$$(notdir %.pl)))
NOTHING :=
UDOT := _.
DOT := .
$(OUT_V_FILES) : %.v : $(subst $(UDOT),$(DOT),S(MY_STRING)) Makefile
#Body of rule+++++++++
There are two problems here. 1) you never assign the result of the $(subst ... invocation and 2) you have to be aware that whitespace is significant within the context of string manipulation functions. With that in mind your makefile code should be something like...
MY_STRING := $(subst $(UNDPL),$(DPL),$(MY_STRING))
In your updated example, it looks like you have some issues when setting MY_STRING. If you correct it to have the proper filename(s), you get:
MY_STRING := $$(foreach dev,$(DEVICES),$$(subst $$(dev),$(NOTHING),$$(notdir %.pl)))
$(info 1. MY_STRING=$(MY_STRING))
MY_STRING := dummy_1_.pl
$(info 2. MY_STRING=$(MY_STRING))
NOTHING :=
UDOT := _.
DOT := .
MY_NEW_STRING=$(subst $(UDOT),$(DOT),$(MY_STRING))
$(info MY_NEW_STRING=$(MY_NEW_STRING))
gives
1. MY_STRING=$(foreach dev,cpu gpu memc,$(subst $(dev),,$(notdir %.pl)))
2. MY_STRING=dummy_1_.pl
MY_NEW_STRING=dummy_1.pl
Related
In a GNU makefile, I need to rename
/infiles/signal_*.wav
to
/outfiles/out_signal_*.wav
This works (using subst):
SIGNALIN += $(wildcard /infiles/signal_*.wav)
TEMP += $(subst infiles,outfiles, $(SIGNALIN) )
SIGNALOUT += $(subst signal,out_signal, $(TEMP) )
Is there a better, one-line way that would not include the TEMP line?
You can wrap function calls:
SIGNALOUT += $(subst signal,out_signal,$(subst infiles,outfiles,$(SIGNALIN)))
In your case there are not really replacements at two places. What you want is replace /infiles/ at the beginning of each word by /outfiles/out_. And that's one place. Try:
SIGNALOUT := $(patsubst /infiles/%,/outfiles/out_%,$(SIGNALIN))
I want to filter out a pattern as "-Wl, Bdynamic -lmylib" from a long LDFLAGS list. But filter-out function can only handle space-separated list, is there other method to do this in Makefile?
The only way to do it is by replacing spaces with some other character that you know doesn't appear in the variable value. For example suppose you know that the ^ character never appears in your variable value, then you can do something like this:
# Create a variable containing a space
E :=
S := $E $E
LDFLAGS := $(subst ^,$S,$(subst -Wl^Bdynamic^-lmylib,,$(subst $S,^,$(LDFLAGS))))
Am trying to match specific string after doing subst on a variable ; substitution is ok but while trying to match make returns error 127.
Does anyone know what's going on here ? why make should return error ?
$> make -f strsearch.mk
CODE : BBROY_OF_GREAT_BRITAIN_HAD_A_GREAT_WIFE
MORSE = BBROY OF GREAT BRITAIN HAD A GREAT WIFE
**make: MORSE: Command not found
make: * [search_new] Error 127
Here is the snippet of makefile:
VAR1 := BBROY_OF_GREAT_BRITAIN_HAD_A_GREAT_WIFE
search_new:
#echo CODE : $(VAR1)
MORSE = $(subst _, , $(VAR1))
#echo word count : ($words $(MORSE))
#echo After substitution Britain matches: $(filter %BRITAIN%, $(MORSE))
Your variable declaration is in the wrong place or form:
The form you use is for global assignment and cannot be inside a target block.
Either make it a global variable outside a target block
Or use the shell and eval to set the variable value. See the accepted answer for how to approach this issue: Define make variable at rule execution time
A 3rd option is to define the variable as a sort-of prerequisite which is then assigned at the time the dependencies are evaluated.
In a Makefile, I can get the full path string by $(CURDIR). The result is like /home/jones/prj/platform/Application_UBUNTU/build_os. How do I extract the UBUNTU from the string?
I use subst to replace '/' as space.
DIR = $(subst /, " ", $(CURDIR))
I get result as home jones prj platform Application_UBUNTU build_os.
Then I try to use filter command but I cannot use % or wildcard to match Application_UBUNTU out. Thanks for help in advance.
Use the penultimateword macro from my answer here.
penultimateword = $(wordlist $(words $1),$(words $1), x $1)
BUILD_OS=$(call penultimateword,$(subst /, ,$(CURDIR)))
BUILD_OS=$(subst _, ,$(BUILD_OS))
BUILD_OS=$(word 2,$(BUILD_OS))
This is obviously sensitive to extra underscores in the path/etc.
I have a list of file path like that:
FILE_PATH := a1.so a2.so bla/a3.so bla/a3.so bla/blo/a4.so....
I need to add a prefix to the basename in order to get:
FILE_PATH_PREFIXED := liba1.so liba2.so bla/liba3.so bla/liba3.so bla/blo/liba4.so....
any idea?
Look at Make's addsuffix function.
Here is an example we use with `addsuffix` to place obj files one directory below
the source.
SOURCE += MainThread.cpp
SOURCE += Blah.cpp
OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o)))
From the make manual:
$(addprefix prefix,names...)
The argument names is regarded as a series of names, separated by
whitespace; prefix is used as a unit. The value of prefix is
prepended to the front of each individual name and the resulting
larger names are concatenated with single spaces between them. For
example,
$(addprefix src/,foo bar)
produces the result src/foo src/bar.