Reputation: 105193
I have the following Makefile
rules:
DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
OBJS := $(SOURCES:.cpp=.o)
With this definition all my .o
files are located in the same directories (and sub-directories) as their .cpp
counterparts. Such allocation principle turns the project directory into a mess very soon (with 50+ files). I would like to make a new specific folder for .o
files and place them there. I need to write a make-rule that will convert every .o
file name like the following:
foo/bar/test.o —> objects/foo-bar-test.o
How can I create such a rule in Makefile
? Thanks in advance!
Upvotes: 4
Views: 12075
Reputation: 29021
I'm not sure if you can specify patterns with these modification directly, but you always can use macros (at least in GNU make). An example could be this:
define export_rule
objects/$(patsubst %.cpp,%.o,$(subst /,-,$(1))) : $(1)
<<your rules here>>
endef
SOURCES = $(shell find $(DIR) -name "*.cpp")
$(foreach s,$(SOURCES), $(eval $(call export_rule,$(s))))
This defines the exact rules you want, avoiding (as some solutions proposed above) the name clashes in case two files with the same name reside in different directories.
Upvotes: 3
Reputation: 46824
You can try to start with something like this:
DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
OBJS := $(SOURCES:%.cpp=obj/%.o)
obj/%.o: %.cpp
$(CC) -c -o $@ $^
If you don't want to mess with default build rules (taking Michael Aaron Safyan's advice), you could try to go along the lines of:
DIR = src
SOURCES = $(shell find $(DIR) -name "*.cpp")
ODIR=obj
OBJS:= $(SOURCES:%.cpp=obj/%.o)
CP=cp
MKDIR=mkdir -p
$(ODIR)/%.cpp : %.cpp
$(MKDIR) $(DIR $@)
$(CP) $< $@
Which will copy the cpp file to the obj directory before it is compiled there (note that this may cause some problems if you're relying on include files to reside in the same directory of the source file)
Upvotes: 3
Reputation:
I use a rule like this:
$(ODIR)/%.o: $(SDIR)/%.cpp
$(CC) -c $(INC) -o $@ $< $(CFLAGS)
where
ODIR = object file output directory
SDIR = .cpp source file directory
INC = list of -I flags
CFLAGS = the usual
Upvotes: 6
Reputation: 95629
It is generally not a good idea to override the default build rules, as using the defaults leads to greater portability, and changing them can be incredibly fragile (believe me, I've tried to do what you've asked before. It may work for one platform, but then try to cross-compile the library or build it on a different system and you're toast). I have two suggestions for you that you will hopefully find agreeable.
Upvotes: 3