Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get base name of folder in GNU make

It seems the basename function as interpreted by GNU make is not the same as bash's basename. The former strips the suffix, while the latter will also strip the path. How can I get the base name of a folder in my makefile?

Also, why in did they change it? (It took me 20 minutes to find the source of my error)

like image 864
ari Avatar asked Sep 14 '12 05:09

ari


People also ask

What is $@ in makefile?

The file name of the target of the rule. If the target is an archive member, then ' $@ ' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ' $@ ' is the name of whichever target caused the rule's recipe to be run.

How can I get PWD in makefile?

How can I get PWD in makefile? You can use shell function: current_dir = $(shell pwdpwdIn Unix-like and some other operating systems, the pwd command (print working directory) writes the full pathname of the current working directory to the standard output.

What is Notdir in makefile?

$(notdir names …) Extracts all but the directory-part of each file name in names . If the file name contains no slash, it is left unchanged. Otherwise, everything through the last slash is removed from it. A file name that ends with a slash becomes an empty string.

What does Addprefix do in makefile?

What is add prefix in makefile? $(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.


2 Answers

I guess the basename(1) command has two orthogonal functionalities -- stripping suffices, stripping leading directory portions -- and the GNU make authors wanted to be able to invoke each functionality separately. And of course only one concept could get the name basename.

Certainly in a makefile it's useful to be able to convert foo/bar/baz.c to foo/bar/baz so that you can tack a new suffix on the end to construct a related filename in the same directory as a source file.

The comments on @ire_and_curses answer note that $(notdir $(CURDIR)) doesn't suffice for your purposes, as (being a directory) CURDIR may have been specified as

CURDIR = /foo/bar/

and the notdir strips the whole thing due to the trailing slash. To allow for this way of writing a directory path, you need to strip a trailing slash explicitly with e.g. $(notdir $(CURDIR:%/=%)).

like image 195
John Marshall Avatar answered Nov 03 '22 19:11

John Marshall


Yeah, it's weird. You can get the behaviour you want by chaining notdir and basename:

$(notdir names...)
    Extracts all but the directory-part of each file name in names... For example,    
              $(notdir src/foo.c hacks)

    produces the result ‘foo.c hacks’. 

...

$(basename names...)
    Extracts all but the suffix of each file name in names. If the file name
    contains a period, the basename is everything starting up to (and not
    including) the last period... For example,

              $(basename src/foo.c src-1.0/bar hacks)

    produces the result ‘src/foo src-1.0/bar hacks’. 

So, for example, you could convert /home/ari/src/helloworld.c to helloworld.html by chaining functions like this:

SRC=/home/ari/src/helloworld.c
TARGET=$(addsuffix .html, $(notdir $(basename $(SRC))))
like image 27
ire_and_curses Avatar answered Nov 03 '22 17:11

ire_and_curses