Reputation: 750
Having some trouble with GNUMAKE $(subst)
I cannot explain
My goal is to transform a "SRC_DIR" directory into an "OBJ_DIR"
In one case it works, the other it does not - I do not understand why.
I thought, that the two "HERE{1|2}" constructs below would be identical, it seems they are not. I do not believe it is a "delayed execution" problem because I am using the := (evaluate now, immediately in all cases)
PROJ_ROOT :=$(HOME)/a
BUILD_DIR :=$(PROJ_ROOT)/build/debug
HERE1:=$(shell pwd)
HERE2:=`pwd`
OK1 := $(subst $(PROJ_ROOT),$(BUILD_DIR),$(HERE1))
BAD := $(subst $(PROJ_ROOT),$(BUILD_DIR),$(HERE2))
TEST=$(subst ee,EE,feet on the street)
all:
@echo PR=$(PROJ_ROOT)
@echo BR=$(BUILD_DIR)
@echo H1=$(HERE1)
@echo H2=$(HERE2)
@echo OK1 is $(OK1)
@echo BAD IS $(BAD)
@echo TEST=$(TEST)
The output is below, the OK1 is correct, but BAD is wrong It should be the same ask OK1
PR=/home/foobar/a
BR=/home/foobar/a/build/debug
H1=/home/foobar/a/src/one/two/three
H2=/home/foobar/a/src/one/two/three
OK1 is /home/foobar/a/build/debug/src/one/two/three
BAD IS /home/foobar/a/src/one/two/three
TEST=fEEt on the strEEt
background: I have a large project (400+ source files) spread over about 10 directories, each directory has a src folder, ie: $(PROJECT_ROOT)/libfoo/src/foo.c, and $(PROJECT_ROOT)/libbar/src/bar.c - Unlike the "autoconfigure" method where SRCDIR != BUILD_DIR (you configure in the build dir, and create makefiles in the build dir, I am doing the opposite - I have a prebuilt makefile that should create/populate a build directory structure with object files.
To do that, I need to create various subdirectories under $(PROJECT_ROOT)/build" that MIRROR the source folders. For example the makefiles should create: $(PROJECT_ROOT)/build/debug/libfoo/src/foo.o, and $(PROJECT_ROOT)/build/debug/libbar/src/bar.o
thus I need to 'slice the 'lib{foo|bar}/src and paste this into/onto the root of the build directory using makefile tricks.
Upvotes: 0
Views: 51
Reputation: 100966
As mentioned in the comments:
HERE1:=$(shell pwd)
HERE2:=`pwd`
The first line runs the make shell
function and sets the value of HERE1
to the result of running the pwd
command, which is what you expected. The second line sets the value of HERE2
to the literal string `pwd`
.
When you use subst
on the string `pwd`
obviously nothing happens.
Once again, people are led astray by premature addition of @
. Never, ever, ever add @
to your recipes until after your makefile works completely.
If you removed the @
from the lines that used HERE2
then it would be immediately obvious why things worked differently. Make would print out the command it was going to run and you could see that HERE2
is not replaced by make but that it's the shell that is running the pwd
command:
echo H2=`pwd`
H2=/home/foobar/a/src/one/two/three
and:
echo BAD IS `pwd`
BAD IS /home/foobar/a/src/one/two/three
Upvotes: 0