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: Davidson, Josh
Subject: RE: Question Regarding Emile van Bergen's Non-Recursive Make
Date: Sun, 30 Nov 2008 17:28:57 -0700

Thanks for clearing that up.  I do have one more question regarding his
approach.  I am attempting to place my objects in a different location
than the source files, and I'm using the VPATH variable for the source
files only.

A snippet view of the individual target makefiles I am using is below:

sp              := $(sp).x
dirstack_$(sp)  := $(d)
d               := $(dir)

#LINES REMOVED

OBJDIR_$(d) := $(d)/obj.$(ARCH)

#LINES REMOVED

$(OBJDIR_$(d))/%.o: %.c
                $(COMP)

#LINES REMOVED

d               := $(dirstack_$(sp))
sp              := $(basename $(sp))


The issue I am running into is that the $(OBJDIR_$(d)) in the implicit
rule seems to be treated as recursively expanded.  In other words, if I
comment out the lines that reset $(d) at the bottom of the makefile, the
implicit rule is invoked when I run make with a specific object file as
an argument.  If they are left in, allowing $(d) to reset, Make tells me
"Nothing to do for MyDir/obj32.sun/MyFile.o

Josh

-----Original Message-----
From: Mike Shal [mailto:address@hidden 
Sent: Sunday, November 30, 2008 2:47 PM
To: Davidson, Josh
Cc: address@hidden
Subject: Re: Question Regarding Emile van Bergen's Non-Recursive Make

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]