Re: 回复: 回复: Implicit rule for linking multiple object files

2022-08-11 Thread Paul Smith
On Fri, 2022-08-12 at 02:37 +0800, ljh wrote:
> Aren't the order of compiling object files of first two rules
> certain?

The POSIX standard for make mandates that prerequisites are tried by
make in the order they are listed in the prerequisite list, with the
exception that implicit rules will prepend the prerequisites (this is
what you want, else the $< variable will contain some random target).

GNU make will, of course, obey the standard.

The problem is that when you enable parallel builds (make -j), even
though make will still try things in the order in which they are
listed, you can get files built in other orders depending on how long
prerequisites take to be built.

The correct way to write makefiles is to declare all the dependency
relationships between targets explicitly in the makefile, and NOT rely
on implicit ordering of prerequisites.

When you write a rule in make like this:

   target: prereq1 prereq1

this tells make that "target" depends on "prereq1" and "prereq2", and
so make will never start building "target" until after BOTH "prereq1"
and "prereq2" are done.

However, that rule says NOTHING about any relationship between
"prereq1" and "prereq2", to each other.  As far as make is concerned
these targets are 100% independent and make will definitely not ensure
that, for example, "prereq1" is complete before it starts building
"prereq2" (for example when you use -j).

If you want to define a relationship between "prereq1" and "prereq2",
you have to put that in a separate rule.  See below.

> # ok: in order of writing, with recipe
> x: y.o z.o x.o
>     $(CC) $^ -o $@

Since you've declared your own rule here the pattern rule is not used
and, as long as you don't use -j, you are guaranteed that the
prerequisites are built in that order.

> # ok: compiles x.o last, no mentioning x.o
> x: y.o z.o

Here the pattern rule is used, but the pattern rule chosen is "% :
%.cpp" which means it will not build x.o at all.  Instead it builds the
y.o and z.o object files, then it does the compile of x.cpp and link
together in one command.  If you examine the link line make prints very
carefully you'll see that it contains x.cpp not x.o, and there will be
no x.o file in your directory when you're done:

   g++ -o x x.cpp y.o z.o
^

So, this works for your specific purposes.

Note that when your module requirements get more complex, it's very
likely this will no longer work.  It's a magical accident of the fact
that your file that uses modules has the same name as the program
you're trying to create.

> The rest of the below three rules are not suitable if compiling order
> matters.
> 
> # compiles x.o first, mentioning x.o
> x: y.o z.o x.o
> 
> # compiles x.o first
> x: $(patsubst %.y,%.o,$(wildcard *.y))
> 
> # in order of file names, with recipe
> x: $(patsubst %.y,%.o,$(wildcard *.y))
>     $(CC) $^ -o $@ 

None of the 5 rules above are really suitable, if compiling order
matters.

If compiling order matters, then you should tell make what the
necessary order is, by declaring prerequisites.

If it's the case that x.o can't be created until y.o and z.o are
completed, then you have to write that into your makefile, like this:

  x.o : y.o z.o

(note you don't need a recipe here: you can use the default rule to
build the x.o file.  You're just telling make about some extra
prerequisites it has to complete before it can build x.o)



Re: 回复: 回复: Implicit rule for linking multiple object files

2022-08-11 Thread Martin Dorey
> Aren't the order of compiling object files of first two rules certain?

No, it's unspecified.  Earlier in this thread, you wrote:

>> The manual states that the x.c compiles first.

The example you're looking at just teaches that compiling x.c first is allowed. 
 It doesn't teach that x.c will always be compiled first.

> Will GNU Make keep their ordering behavior or are they just some random 
> ordering caused by some random bugs

You care about the order but haven't told make that, so the bug is in your 
makefile, not GNU Make.


From: ljh 
Sent: Thursday, August 11, 2022 11:37
To: Martin Dorey ; Philip Guenther 

Cc: psmith ; bug-make 
Subject: 回复: 回复: Implicit rule for linking multiple object files

* EXTERNAL EMAIL *
Thanks Martin,

Your Makefile is too advanced for me to understand by now.

I tested out the below five rules.
Aren't the order of compiling object files of first two rules certain?
Will GNU Make keep their ordering behavior or are they just some random ordering
caused by some random bugs (sorry, no offensive, I love GNU Make)

# ok: in order of writing, with recipe
x: y.o z.o x.o
$(CC) $^ -o $@

# ok: compiles x.o last, no mentioning x.o
x: y.o z.o


The rest of the below three rules are not suitable if compiling order matters.

# compiles x.o first, mentioning x.o
x: y.o z.o x.o

# compiles x.o first
x: $(patsubst %.y,%.o,$(wildcard *.y))

# in order of file names, with recipe
x: $(patsubst %.y,%.o,$(wildcard *.y))
$(CC) $^ -o $@