rampatowl
rampatowl

Reputation: 1772

Recursive search in VPATH?

My C++ project has source files organized in nested subdirectories of ./src. I have a pattern rule in my makefile which compiles all of the .cpp source files into objects:

$(OBJDIR)/%.o: %.cpp makefile
    $(CXX) -c $< -o $@

Since I am using this pattern rather than writing a compilation rule for each source file, I need to tell make to look recursively through ./src for these prerequisites. Right now I have:

VPATH := $./src/:./src/folder1:./src/folder2:./src/folder3

This works, but it feels pretty inelegant and also causes bugs when I inevitably forget to add in a new folder.

Hoping someone has a better solution!

Upvotes: 3

Views: 1264

Answers (2)

Reinier Torenbeek
Reinier Torenbeek

Reputation: 17383

You can automate the building of the VPATH variable like yours by searching for subdirectories and replacing spaces with colons:

space :=
space +=
VPATH := $(subst $(space),:,$(shell find src -type d))

This assumes that you have no spaces in your directories or filenames.

With this approach, it is not clear to me what you would do if two source files in two different subdirectories have the same name -- but that seems to be more related to your overall setup than to your question about the VPATH specifically.

For the $(space) variable trick, see the nifty Escaping comma and space in GNU Make blog post.

Upvotes: 4

Sam Varshavchik
Sam Varshavchik

Reputation: 118350

gmake itself does not have any functions for recursive directory traversal, so you have to resort to $(shell ...):

VPATH := $(shell find src -type d -print | tr '\012' ':' | sed 's/:$$//')

Tweak the shell script to get the right semantics. You want to use the := operator, in order to evaluate this one time.

Upvotes: 1

Related Questions