a problem about Makefile

Programming, for all ages and all languages.
Post Reply
User avatar
jiakai
Posts: 5
Joined: Tue Dec 07, 2010 1:07 am
Location: China

a problem about Makefile

Post by jiakai »

I encountered a problem about Makefile during my kernel development.
Here is a simplified Makefile:

Code: Select all

x: obj/./t
	touch x

obj/t: a
	touch obj/t
when file a is changed, x is not updated; however, if I change "obj/./t" to "obj/t", everything works as expected.

Can anybody help? Thanks a lot!

And the output of make -v is:
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-pc-linux-gnu
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: a problem about Makefile

Post by Solar »

Actually, when trying your Makefile, I get:

Code: Select all

make: *** No rule to make target `obj/./t', needed by `x'.  Stop.
When I change the second rule to this

Code: Select all

obj/./t: a
everything works fine.

Conclusion: The make dependency resolver works on strings, not files, and thus cannot recognize un-normalized file paths (those with . or .. in them) as equal to normalized ones.

Not much of a problem if you know about it.

Which results in the next question: Where does the dot in obj/./t come from, and how to avoid it?
Every good solution is obvious once you've found it.
User avatar
jiakai
Posts: 5
Joined: Tue Dec 07, 2010 1:07 am
Location: China

Re: a problem about Makefile

Post by jiakai »

Solar wrote:Actually, when trying your Makefile, I get:

Code: Select all

make: *** No rule to make target `obj/./t', needed by `x'.  Stop.
When I change the second rule to this

Code: Select all

obj/./t: a
everything works fine.

Conclusion: The make dependency resolver works on strings, not files, and thus cannot recognize un-normalized file paths (those with . or .. in them) as equal to normalized ones.

Not much of a problem if you know about it.

Which results in the next question: Where does the dot in obj/./t come from, and how to avoid it?
Thanks for your reply!

in my Makefile, I use find to find all the sources:

Code: Select all

CXXSOURCES = $(shell find . -name "*.cpp")
and find outputs './' before every entry.

maybe I should use text functions provided by make to get rid of it?
User avatar
jiakai
Posts: 5
Joined: Tue Dec 07, 2010 1:07 am
Location: China

Re: a problem about Makefile

Post by jiakai »

now I use

Code: Select all

 $(patsubst ./%,%,$(shell find . -name "*.cpp"))
it works, but is there a way to tell make to resolve un-normalized paths?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: a problem about Makefile

Post by Solar »

I don't think you can make's string comparison take filepath normalization into account. (You know, make works on non-Unix machines like Windows, too, and you'd have to program each system's peculiarities into make if you'd want that kind of capabilities.)

There are two ways out of your dilemma:

1) feed filenames through readlink before using them in your makefile (which canonicalizes not only . and .., but symlinks too).

or, better IMHO,

2) make find start with a subdirectory ("find src -name \*.cpp") instead of the current directory, so the output will start with "src/" instead of "./".

Also note the difference between "=" and ":=" in make (evaluate always vs. evaluate once), and how "find . -name *.cpp" fails miserably when there is a .cpp file in the current directory (use "find . -name \*.cpp").

I see what you are trying to do - build in a different directory than the sources - and admit I haven't tweaked my own makefiles to do that, yet. I'll look into it and add it to the Makefile tutorial.
Every good solution is obvious once you've found it.
User avatar
jiakai
Posts: 5
Joined: Tue Dec 07, 2010 1:07 am
Location: China

Re: a problem about Makefile

Post by jiakai »

Thanks for Solar's rapid reply!
I agree with the solution that make find start with a subdirectory

and I have another question:
if the make dependency resolver works on strings, how can the following Makefile work?

Code: Select all

x: ./t
	touch x
t: a
	touch t
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: a problem about Makefile

Post by Solar »

I haven't had a look into the internals of make, so I could just guess here. (Leading dots receiving special handling?)

If you are really interested in internal workings, perhaps you'd like to take it to [email protected] (the official mailing list).

This is not a dismissal, I'd like to know too. I'm just not in a mind of digging through make's sources to find out. 8)
Every good solution is obvious once you've found it.
User avatar
jiakai
Posts: 5
Joined: Tue Dec 07, 2010 1:07 am
Location: China

Re: a problem about Makefile

Post by jiakai »

OK, I will try that mail list. I'll post a reply once having a result
Post Reply