help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question Regarding Emile van Bergen's Non-Recursive Make


From: Mike Shal
Subject: Re: Question Regarding Emile van Bergen's Non-Recursive Make
Date: Sun, 30 Nov 2008 16:47:29 -0500

On 11/30/08, Davidson, Josh <address@hidden> wrote:
> For each of his subdirectory makefiles, he has a group of object file
> targets called OBJS_$(d) that are ultimately compiled using the implicit
> rule above ($(d) is the subdirectory for that makefile).  The way he enables
> custom compilation flags for his object targets is by adding a prerequisite
> as follows:
>
>   $(OBJS_$(d)):  CF_TGT := -I$(d)
>
> Is there a potential race condition with this approach if –j is used?  It
> seems to me that CF_TGT could be overridden by another $(OBJS_$(d)) in a
> different subdirectory.  If there isn't a race condition, is GNU make
> creating a target specific copy of CF_TGT or somehow locking it until the
> target has finished updating?

You can think of make operating in two phases: 1) Read in the
Makefile(s) to build the DAG, and 2) process the DAG and execute the
commands as necessary. The first part is done serially, regardless of
whether or not you pass in -j. So in that article, ant/Rules.mk and
bee/Rules.mk are parsed one after the other, not in parallel. I doubt
you would gain much efficiency by parallelizing that anyway since the
first phase is largely IO bound reading in Makefiles and such (and it
certainly wouldn't be worth the headaches involved in implementing
it).

In the second phase, make walks through the DAG and starts running
commands. It can pull off multiple independent nodes from the DAG and
run them at the same time based on your use of the -j flag. Your
parallelization here speeds things up because you can run the compiler
on separate cores, or read in one file (IO) while another is compiled
(CPU).

Since make has already read in all the Makefiles (which includes
Rules.mk files in your example), it needs to do what you suggest,
which is keep a private copy of the CF_TGT for each target. You should
be able to see that if you run 'make -p' and look for CF_TGT. For
example:

$ cat Makefile
all: foo.o bar.o
        @echo "done"
CF_TGT := -flags1
OBJS := foo.o
$(OBJS): CF_TGT := -flags2

%.o:
        @echo "Flags for $@: $(CF_TGT)"

$ make
Flags for foo.o: -flags2
Flags for bar.o: -flags1
done

Long story short is if you follow that article you shouldn't have to
worry about race conditions while reading in the Makefiles.

Things change, of course, if you're using a recursive make setup and
parallelization. In that case each instance of make reads in and
parses its own DAG, and there can be multiple of those running at the
same time. It can easily get confusing, and I highly disrecommend it.

-Mike




reply via email to

[Prev in Thread] Current Thread [Next in Thread]