I am trying to have my cpp source files and my object files in separate directories, so I'm trying to use Make's patsubst to replace the paths. After nothing was compiling, I made a phony target to simply print out the relevant variables and I discovered that patsubst was returning nothing. This doesn't make a lot of sense to me, as from what I can tell, targets that don't match the pattern should pass through unchanged, so even if my patterns are malformed I should still be seeing something get returned.
My variables are declared like this:
SRC_DIR := source/
SRC := $(wildcard $(SRC_DIR)*.cpp)
OBJ_DIR := obj/
OBJ := $(PATSUBST $(SRC_DIR)%.cpp, $(OBJ_DIR)%.o, $(SRC))
My phony target that just prints out the above variables looks like this:
.PHONY: print
print:
@echo $(SRC_DIR)
@echo $(SRC)
@echo $(OBJ_DIR)
@echo $(OBJ)
and the result of running make print
is this:
user@athena:~/proj$ make print
source/
source/main.cpp source/util.cpp
obj/
user@athena:~/proj$
Other things I've tried
I've tried SRC_DIR and OBJ_DIR having trailing slashes and not having them, I've tried $(SRC:$(SRC_DIR)%.cpp=$(OBJ_DIR)%.o)
which did work, and $(OBJ) would have both main.o and util.o, but then my static rule ($(OBJ): $(OBJ_DIR)%.o : $(SRC_DIR)%.cpp
) would only trigger for main.cpp, and wouldn't try to compile util.cpp, which I'm considering a completely separate issue?
I hope I'm just doing something dumb and there's a simple fix, but I've been racking my brain and I can't see what would be causing patsubst to just be blank. Any help would be greatly appreciated.
CodePudding user response:
Like (virtually) all programming languages, makefiles are case-sensitive. $(FOO)
is not the same as $(foo)
, and $(PATSUBST ...)
is not the same as $(patsubst ...)
.
In fact, $(PATSUBST ...)
is nothing and expands to the empty string.