Dot in front of variables in make files - makefile

I am not able to figure out what does a dot . in front of a variable in makefile does. For e.g.:
SOURCEDIRS = . $(PROJECTDIRS) $(TARGET_DIRS_CONCAT)
vpath %.c $(SOURCEDIRS)
It would be great if someone could tell me.
Thanks!

Generally it just refers to your current directory.
I.e. If you were on a linux machine, and you cd /home/user/Darth and run ls ., you should see the contents of the the folder Darth. So in this case, it looks like it's just including the current directory that you're in into the SOURCEDIRS.

Related

Include a third makefile with a path relative to second, when second isn't in directory of first

I have a Makefile with only project-level definitions: which source files to use, what binary or library to make, etc..
It includes ../../Make.Arch for architecture-specific definitions (such as compiler command).
In turn, Make.Arch is meant to include ../etc/Makefile.Standard for all the boilerplate of actually allowing the make system to work .
But include requires a path relative to where the makefile is actually being run (or maybe where the first Makefile is), not relative to the second... What to do?
Make interprets relative paths from the working directory, the directory in which Make is being run. You haven't specified how you're running Make, so I'll assume your running it in the directory with Makefile.
If you are allowed to modify the makefiles, you can change the paths.
You could change Make.Arch from this:
include ../etc/Makefile.Standard
to this:
include ../../../etc/Makefile.Standard
but that would require that any makefile that uses Make.Arch be two directories down from it. That's clearly not a good idea. But we can use a variable:
include $(ARCH_DIR)/../etc/Makefile.Standard
which is provided by Makefile (or any other makefile that uses Make.Arch):
ARCH_DIR := ../..
include $(ARCH_DIR)/Make.Arch
If you are not allowed to modify the makefiles, then you must cheat. One way is to create a symbolic link to Makefile.Standard.
mkdir ../etc
ln -s ../../../etc/Makefile.Standard ../etc
Now Makefile will work. (It ought to be possible to make a link to etc/, but for some reason I can't get that to work right now.)

Getting the fulll path of an included file in the Makefile

A Makefile contains
include ../../common/common.mk
at the end of the file. I want to see the full path during the invocation. How can I do that?
$(info full path to common.mk: $(abspath ../../common/common.mk))
include ../../common/common.mk
Usually, make does not change working directory during execution. Most likely, you can check for ../../common/common.mk from command line just before running **make*. But if you use make -C some/directory then the working directory will be whatever you specify after -C (relative to your current directory).

Makefile rule that detects any changed file in a directory (and subdirs)

I want to create a Makefile rule that runs whenever anything is changed inside a directory (which contains multiple source files in different languages, and at different subdirectory levels).
As an example, take this Makefile:
newest: src
touch newest
with a tree like:
src/
src/a
scr/subdir/
scr/subdir/c
First time I run make, newest is created all right. But if I now touch src/subdir/b, make does nothing.
Is it possible at all to create such a rule?
I think you would need to use something like FILES := $(shell find src -type f) and a rule of newest: $(FILES) to get the sort of behavior you want.

How to get the basename of the current folder as variable in a makefile?

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.
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)`
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.
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.
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}
As of GNU Make 4.3, you can use the native basename Make function, like so:
CURRENT_DIRECTORY := $(basename $(CURDIR))
$(info current directory is: $(CURRENT_DIRECTORY))
For more information about available functions, see the GNU Make info manual: info "(make) File Name Functions".

Search current directory last when looking for dependencies using GNU make and VPATH

This is a GNU Make dependency resolution issue.
My problem is that I copy the source files from a remote file server to a scratch disk (which speeds up the build process by 50%). If the file copy fails, I want to use the source files from the file server, else I want to read them from the scratch disk.
I have tried to use the vpath mechanism, but the problem is that, as far as I understand, make will by default start looking for the source files in the current directory and only if it fails to find the files there, look in the directories listed with vpath.
Is it possible to have make first look in the vpath directories before looking in the current directory? Or perhaps only look in the vpath directories (and explicitly and dynamically add the current directory to vpath)?
Only way I can think of is to temporary change directory so that make always will fail to find the source files.
Look at the path to the source directory on the server. Suppose it's "/server/someplace/src/". And suppose you don't have a "src" directory in the current directory (if you do, we just have to tweak this method). Just make sure that the path to the source directory on the scratch disk ends in "/src/", such as "/scratch/wednesday/src/". Then you can do this:
SCRATCH_PATH = /scratch/wednesday/
SERVER_PATH = /server/someplace/
VPATH = $(SCRATCH_PATH) $(SERVER_PATH)
%.o: src/%.cc
$(CC) blah blah blah

Resources