help-make
[Top][All Lists]
Advanced

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

RE: EXTERNAL: Re: help with prerequisites


From: Polder, Matthew J
Subject: RE: EXTERNAL: Re: help with prerequisites
Date: Wed, 08 Sep 2010 12:02:47 -0400

While not able to sleep last night I realized my problem was, as Luke deftly 
points out, not using .SECONDEXPANSION. However, his last recommendation avoids 
this and is elegant in my view. Thanks for the awesome dissection and 
resolution Luke!

-----Original Message-----
From: Luke Shumaker [mailto:address@hidden 
Sent: Tuesday, September 07, 2010 4:56 PM
To: Polder, Matthew J
Cc: address@hidden
Subject: EXTERNAL: Re: help with prerequisites

On Tue, 2010-09-07 at 15:40 -0400, Polder, Matthew J wrote:
> ...
> $(OBJS): $(patsubst %.o,%.cpp,$(notdir $@))
>      $(CC) -c $^ -o $@
>      $(CC) -c $(SRC_DIR)/$(*F).cpp -o $@

There are a few problems here:

First
$@ is not yet set when the dependencies are being evaluated. To use $@
in the dependency list, you must use ``.SECONDEXPANSION:'', like so:

.SECONDEXPANSION:
$(OBJS): $$(patsubst %.o,%.cpp,$$(notdir $$@))
        $(CC) ...

Note that .SECONDEXPANSION will apply to all rules after it.  In many
cases this doesn't matter, but it's generally better to place second
expansion rules at the end of the Makefile

Second
Both commands in the recipe output to the same file, the second line
entirely overwrites the first line.

Third
Your use of `$*' is weird here, to quote the 3.82 manual (regarding this
use of $*):
> GNU make does this bizarre thing only for compatibility with other
> implementations of make. You should generally avoid using ‘$*’ except
> in implicit rules or static pattern rules.
Which is interesting because this is the only behavior documented in
FreeBSD make, and GNU Make's normal behavior is undocumented in
FreeBSD's make.

Fourth:
I would avoid using SECONDEXPANSION/patsubst in the rule, try this:

#!/usr/bin/make -f

TARGET = test
SRC = apple.cpp
VPATH = src
SRC_DIR = src

CC = g++
OBJ_RELEASE_DIR = release
OBJ_DIR = ../$(TARGET)/objs
BIN_DIR = bin

# for readability
objdir=$(OBJ_DIR)/$(OBJ_RELEASE_DIR)

OBJS = $(patsubst %.cpp,$(objdir)/%.o,$(SRC))

all: $(BIN_DIR)/$(TARGET)

$(OBJS): $(objdir)/%.o: $(SRC_DIR)/%.cpp
     $(CC) -c '$<' -o '$@'

$(BIN_DIR)/$(TARGET): $(OBJS)
     $(CC) $^ -o '$@'

--END FILE--

I hope this helps.

~ LukeShu



reply via email to

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