How to remove continous extensions in Makefile? - makefile

For example, I want $(remove_all_extensions foo.bar.buz.x.y.z) to return foo.
basename doesn't work because it only remove the last extension so $(basename foo.bar.buz.x.y.z) returns foo.bar.buz.x.y.
Is there any built-in function I can use in Makefile to achieve the requirement?

You can use glob-match in gmtt which can cut strings with glob syntax. For your problem the pattern *.* is fitting. If a match with the input string results, glob-match returns the string portion corresponding to the glob character, which in this case is * for the leading portion, then the first . and then the rest with all commas for the remaining *.
include gmtt/gmtt.mk
FILES := foo.bar.buz.x.y.z frob.ni.ca.te biz.bof zulu.oat.s
$(foreach f,$(FILES),$(info $(call glob-match,$(f),*.*)))
Output:
foo . bar.buz.x.y.z
frob . ni.ca.te
biz . bof
zulu . oat.s
so you have to $(firstword ) on the result of that call.

Related

make/gmake: given a variable starting with multiple ../, create a variable with one less ../

Given a variable, how can I create another variable with the leading repetitions of ../ that the first variable starts with, albeit with one less repetition?
For instance, given ../../../foo/bar, how do I end up with ../../?
I've tried a perl regexp like perl -e '$a = "../../../foo/bar"; $a =~ /^\.\.\/((\.\.\/)+)/; print "$1\n"' but can't figure out the magic incantation of quotes, backslashes, dollar signs, and so on needed to run it within $(shell).
Further I suspect there's a simpler way to do it.
This will remove one ../ at the front: $(patsubst ../%,%,$(ORIGINAL_PATH))
To isolate the first streak of ../ one could go as follows:
space := $(strip) $(strip)#
FIRST_STREAK := $(firstword $(subst $(space)../,../,$(subst ../,../$(space),$(ORIGINAL_PATH))))
Let's write this as a function:
space := $(strip) $(strip)#
UP_PATH = $(patsubst ../%,%,$(firstword $(subst $(space)../,../,$(subst ../,../$(space),$1))))
Test it:
ORIGINAL_PATH := ../../../foo/bar/../baz
$(info $(call UP_PATH,$(ORIGINAL_PATH)))
Output:
../../

subst "/dev/ttyPS1" to \""/dev/ttyPS1\"" in makefile

I'm trying to perform this substitution without any success with the following,
a="/dev/ttyPS1"
b=$(patsubst \"%\",\\\"\"%\\"\",$(a))
c=$(subst \",\\\"\",$(a))
$(info $(a) $(b) $(c))
Output :
$ make
"/dev/ttyPS1" "/dev/ttyPS1" "/dev/ttyPS1"
Desired Output :
$ make
"/dev/ttyPS1" \""/dev/ttyPS1\"" \""/dev/ttyPS1\""
I must be doing something dumb with the escape sequences since it doesn't appear to change at all... I don't have any preference on how I get there (patsubst, subst, or other). Any ideas? Thanks.
You don't need to escape quotes with backslashes in make syntax: quotes are not special to make. Thus your subst of \" never matches because there's no two-character string \" in the string "/dev/ttyPS1".
Try:
a = "/dev/ttyPS1"
b = $(patsubst "%",\""%"\",$(a))
c = $(subst ",\"",$(a))
$(info $(a) $(b) $(c))

How to trim a string in makefile?

I have this string cccccc:dddddd
I want to get cccccc only
I looked at makefile docs but still confused how to do this with make functions
This doesn't work but I want to do something like match from : to end of line and trim all of that
MY_VAR:=cccccc:dddddd
....
derp:
echo $(subst :.*,"",$(MY_VAR))
:dddddd is not static so I cant just hardcode that in like $(subst :dddddd,"",$(MY_VAR))
You can try something like:
MY_VAR := $(firstword $(subst :, ,$(MY_VAR))
Note this requires that "cccccc" does not contain whitespace.

Makefile: do operation on files with specific extension from a variable

I'm working on a Makefile which needs to be able to do the following:
From a user given variable, SRVS, containing file names, e.g.,
SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c
produce a list of all files with a certain extension to be used by a foreach loop.
This list should not contain the extension anymore.
Currently, I can parse and get all the files into a usable list, but am unable to do so for an extension.
What I have:
$(foreach SRV, $(shell echo $(SRVS) | tr ',' ' '), \
CLASSPATH=$(SELF)/default_runtime javac $(UJ_DIR)/services/java/$(SRV).java && \
find $(UJ_DIR)/services/java/ -iname "$(SRV).class" -type f >> $(SELF)/files && \
) true
Which will take a list of SRVS and produce list usable by foreach and the code therein. For instance, the above example would result in "test1 test2 test3 test4 test5" to be used by the foreach loop
I'd like now to specify the extension, for instance .c, so that the above example would result in "test2 test3 test5".
Can you help me out?
First, you do not need to call shell (this is uselessly slow) because there are make built-in functions that do what you want. If, in the definition of variable SRVS you really cannot separate your file names with spaces (the standard make word separator) instead of commas, subst can do it for you. But there is a little trick because the comma is itself the arguments separator of make functions:
comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))
Next, filter is the make function that allows to select files by extension:
SRVS2 := $(filter %.c,$(SRVS1))
And finally, basename removes the suffix:
SRVS3 := $(basename $(SRVS2))
Demo:
$ cat Makefile
SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c
comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))
SRVS2 := $(filter %.c,$(SRVS1))
SRVS3 := $(basename $(SRVS2))
all:
$(info SRVS1 = $(SRVS1))
$(info SRVS2 = $(SRVS2))
$(info SRVS3 = $(SRVS3))
$ make -q
SRVS1 = Test1.java test2.c test3.c test4.java test5.c
SRVS2 = test2.c test3.c test5.c
SRVS3 = test2 test3 test5
Or, all at once:
$ cat Makefile
TAGS := $(basename $(filter %.c,$(subst $(comma), ,$(SRVS))))
all:
$(info TAGS = $(TAGS))
$ make -q
TAGS = test2 test3 test5

rule that matches file containing a pattern

How do I create a rule that matches any file that contains foo, like a/foo.h or foo.c? Double % sign doesn't work.
FOOS := $(shell find . -name "*foo*")
$(FOOS):
#echo do something with $#

Resources