Reputation: 1314
I am optimizing a some makefile of a very big project, and I found that GNU make's vpath
command can only do very limited work. For example:
vpath %.o $(OBJPATH)
means search all object files in the path value by OBJPATH. That means /dir1/../dir2/obj1.o
and /dir3/../dir2/obj1.o
are the same file, but, if I have already made /dir1/../dir2/obj1.o
, when the tools thinking rules for /dir3/../dir2/obj1.o
, it still can not find it, and has to remake /dir3/../dir2/obj1.o
, even though it stands for the same file as /dir1/../dir2/obj1.o
.
I checked the GNU make source code; it uses a hash table to compare the file path strings, so if the strings are different, although they stand for the same file, they still cannot be matched using vpath
.
Why not realize vpath
with more powerful capabilities?
Upvotes: 0
Views: 2623
Reputation: 58598
Re:
[GNU Make] uses a hash table to compare the file path strings, so if the strings are different, although they stand for the same file, they still cannot be matched using vpath.
Make is doing approximately the right thing. Detecting whether two objects are the same requires relying on unique ID's in the filesystem (such as inode numbers) which are OS and filesystem specific.
Why do you use two different paths to refer to the same target or prerequisite? Arguably, what you're doing in your Makefile is worse than Make relying on string equality for path comparisons.
Also, you may be misunderstanding something. The vpath
directive and VPATH
variable are related to the search for prerequisite files.
You rarely, if ever, want to be searching for object files as prerequisites (even though of course they are prerequisites to building an executable or library).
This is because object files cannot be assumed to exist, and you don't search for something that may not exist. When you do a clean build, the object files are not there. Your Makefile has to know what their exact names are. It is the prerequisites which can vary. For instance you know that you want to build foo.o
(which may already exist from a previous build or may not). What you don't necessarily know is the source file from which foo.o
is built. Is it libfoo/foo.c
or utils/foo.c
? This is the problem that vpath
solves: it will search those places and find foo.c
, similarly to how PATH
helps your shell to find a program foo
in /bin
or /usr/bin
, etc.
VPATH/vpath
are somewhat of a hack for writing quick and dirty makefiles for small projects, which will not scale to a large configuration. There is no point in trying to improve them.
Upvotes: 6