4
votes

I am looking for a way to substitute the folder on a list of source files variable within makefile.

Is there something that works here?

I start off by finding my source files

program_C_SRCS := $(wildcard  $(SRCDIR)/*.c)
program_CXX_SRCS := $(wildcard $(SRCDIR)/*.cpp)

the results (if I understand GNU makefiles correctly) look typically like

src/main.cpp
src/sensor.cpp

then I build by object files

program_C_OBJS := ${program_C_SRCS:.c=.o}
program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.opp}

this replaces the extensions of my source files as per expected.

Finally, I want to replace "src/" with "obj/"

program_C_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_C_OBJS)}
program_CXX_OBJPATH := ${subst $(SRCDIR) , $(OBJDIR) , $(program_CXX_OBJS)}

However, this does not work.

I have gone through the GNU makefile website to no avail. This solution Makefile to put object files from source files different directories into a single, separate directory? comes close but the objects directory must be explicitly included everywhere and the sources directory does not include source path information.

In my makefile the list of source files include the path and I would prefer that the list of object files include the corresponding object directory, too.

The rest of the makefile tries also to use variables

linking stage

$(program_NAME): $(program_OBJS)
    $(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $(program_OBJS) -o "$(program_NAME)"

compile stage

%.opp : %.cpp | mkdirobjdir
    $(CXX) $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c -o "$@" "$<"

and finally the rules

main_enose.opp : main_enose.cpp core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.opp : core_enose.cpp core_enose.h
$(OBJDIR)/core_enose.h :
1

1 Answers

6
votes

Your problem here is the spaces around the commas in the $(subst) calls. make isn't ignoring them the way you expect it might. It is seeing them as literal values in the string to find, the string to replace and the to do the replacement in.

Remove them.

program_C_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_C_OBJS)}
program_CXX_OBJPATH := ${subst $(SRCDIR),$(OBJDIR),$(program_CXX_OBJS)}

That said you probably either want to use $(patsubst) to limit where the replacement happens:

program_C_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_C_OBJS))
program_CXX_OBJPATH := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(program_CXX_OBJS))

or you want to use $(notdir) and $(addprefix) to handle stripping all the directory information and adding it back:

program_C_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_C_OBJS)))
program_CXX_OBJPATH := $(addprefix $(OBJDIR)/,$(notdir $(program_CXX_OBJS)))