21

I want to copy a file to a server using scp. But I want to use my current folder name in my makefile as variable.

I know I get my current path using $(CURDIR) but my local path isn't the same on my remote server.

E.g. my path is /Users/obstschale/Documents/Lab2/ and I want to copy Lab2.tar to user@server.au:/home/path/Lab2/.

copy2server:
    echo $(CURDIR)
    scp Lab2.tar user@server.au:/home/path/{folder}

I probably have to pipe $(CURDIR) into something and find my last folder.

Update: $(CURDIR) is the right variable. $(CURID) is the wrong one at least it didn't work for me.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Hans-Helge
  • 1,764
  • 3
  • 14
  • 21

5 Answers5

34

I didn't have luck with the backtick syntax in makefiles (GNU Make 3.81) as Sylvain describes it. If it doesn't work for you either, use

$(shell basename $(CURDIR))

instead of

`basename $(CURDIR)`
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
firefrorefiddle
  • 3,795
  • 20
  • 31
12

I tried this rule:

test:
    @echo $(CURDIR)           # e.g. /tmp/foobar/blafoor/baz
    @echo $(notdir $(CURDIR))  # gives "baz" here.

which worked fine for me.

maybe this is not intended to work, because notdir should

Extract the non-directory part of each file name.

reox
  • 5,036
  • 11
  • 53
  • 98
7

If you're looking to strip the last folder name in the path out, there are a number of built in makefile functions. See http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_8.html#SEC74 for a quick overview of file operations.

copytoserver:
    scp Lab2.tar user@server.au:/home/path/$(notdir $(CURDIR))

The key item of this is of course $(notdir $(CURDIR)). As you discovered, the $(CURDIR) contains the path to the directory in which the makefile was run, without the final '/'. The notdir function strips off everything up to and including the last '/' in a filename. This ends up stripping off everything but the final directory.

If $(CURDIR) still has the trailing '/', you can strip that off so the notdir function will do what you want like so:

$(notdir $(patsubst %/,%,$(CURDIR)))

Note that spacing in this case is critically important, placing a space before or after any of the commas will insert a space when it does the greedy pattern substitution.

mtalexan
  • 677
  • 1
  • 7
  • 17
  • If you have the directory with trailing '/' in a variable like here, you could also shorten it to `$(notdir $(CURDIR:/=))` using [substitution references](https://www.gnu.org/software/make/manual/make.html#Substitution-Refs) – SWdV Feb 09 '22 at 12:38
5

You can use basename shell command to extract the last component part of $(CURDIR).

copyserver:
   folder=`basename "$(CURDIR)"`; scp Lab2.tar user@server.au:/home/path/${folder}
Sylvain Defresne
  • 42,429
  • 12
  • 75
  • 85
-1

As of GNU Make 4.3, you can use the native notdir Make function, like so:

some_file := /some/path/file.ext

notdir_result := $(notdir $(some_file))
basename_result := $(shell basename $(some_file))

$(info 'notdir' on $(some_file) produces: $(notdir_result))
$(info 'basename' command on $(some_file) produces: $(basename_result))

The above Makefile produces when run:

'notdir' on /some/path/file.ext produces: file.ext
'basename' command on /some/path/file.ext produces: file.ext

For more information about available functions, see the GNU Make info manual: info "(make) File Name Functions".

Apteryx
  • 5,822
  • 3
  • 16
  • 18
  • `$(basename ...)` in GNU Make 4.3 does not produce the same result as `/usr/bin/basename`. The Make `basename` removes suffixes. See https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#index-basename-1 – Dan Halbert Jun 05 '23 at 23:00
  • Good point. I guess my answer still has some value in other contexts where only directory names without extensions are involved. – Apteryx Jun 06 '23 at 13:22
  • From the GNU Make doc: > For example, `$(basename src/foo.c src-1.0/bar hacks)` produces the result `‘src/foo src-1.0/bar hacks’`. So it really does something quite different: it removes a suffix (like `/usr/bin/basename -s` _and_ it does not strip the directory part. – Dan Halbert Jun 06 '23 at 17:45
  • Ah! it's `notdir` I should have used. Will update the answer. – Apteryx Jun 07 '23 at 02:30