Reputation: 1
I have multiple source files in different directory. Now i want to compile their objects into to different directory. How can i do it?
I tried this but it is giving me error
`SRCDIR = ${SRC}/unix/fs
SRCDIR = ${SRC}/share/ch
SRCDIR = ${SRC}/linux/fs
SRCDIR = ${SRC}/unix/ch
OBJDIR = ${HOME}/build/libverify`
OBJS = ${OBJDIR}/check_format.o
OBJS += ${OBJDIR}/check_code.o
$(CC) $(CFLAGS) -c -o $(OBJS) $(SRCDIR)
It successfully build one check_format.o file but gives error for another .o files
gcc: error: /home/build/libverify/check_code.o: No such file or directory
Upvotes: 0
Views: 8819
Reputation: 16331
Here is a really simple example with one file src/main.cpp
getting compiled into an object file in obj/main.o
:
OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@
Similar to your makefile you specify the obj and src dirs. Then you specify the object file(s) you want to create in the variable OBJS
.
But then you need a target to call make on. Make uses the first target it comes across is you don't pass in a parameter. So here I added build:
which depends on OBJS
. Therefore when I run make
it runs the target build
and then tries to build each of the items in OBJS
.
Finally we need a pattern-rule which says:
Things like look like obj/%.o
(% is wildcard), they depend on the source file src/%.cpp
(replace .cpp with .c or .cxx or whatever). The in the body of the rule we add our make line.
gcc -c $< -o $@
where $< is the dependency (source file) and $@ is the target (object file).
Note: I am not specifying a source list (SRCS) because they are implied by the pattern matching of the object. I.e. if I want to create a file obj/test.o
then it depends on the file src/test.cpp
existing - based on the the pattern-rule that I have entered here. So I can modify my makefile to add more source files by doing:
OBJDIR = obj
SRCDIR = src
OBJS = $(OBJDIR)/main.o
OBJS += $(OBJDIR)/fred.o
OBJS += $(OBJDIR)/bob.o
$(info objs: $(OBJS))
build: $(OBJS)
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
gcc -c $< -o $@
Output from running make
is:
$ make
objs: obj/main.o obj/fred.o obj/bob.o
gcc -c src/main.cpp -o obj/main.o
gcc -c src/fred.cpp -o obj/fred.o
gcc -c src/bob.cpp -o obj/bob.o
Note: I added the line $(info objs: $(OBJS))
to print out the value of OBJS
UPDATE
This is realy simply version how to have more then one source folder - but you will want to keep improving on this since its quite basic
OBJ_DIR = obj
SOURCES = src1/bob.cpp
SOURCES += src2/fred.cpp
SOURCES += src3/main.cpp
OUT_DIRS = $(sort $(dir $(SOURCES)))
# Calculate the objects files - should be:
# obj/src1/bob.o
# obj/src2/fred.o
# obj/src3/main.o
OBJS = $(addprefix $(OBJ_DIR)/,$(addsuffix .0,$(basename $(pathsubst %,%,$(SOURCES)))))
$(info objs: $(OBJS))
build: $(OBJS)
# Now this rule also requres the object sub-dirs to be created first
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(OUT_DIRS)
gcc -c $< -o $@
# Rule to create the object dir folders
$(OUT_DIRS):
mkdir -p $@
note: I did not test this one - but I have explained how the OBJS list should be formed - it "should" work. So here we are still using the same pattern rule but now we are including the source sub folders into the object paths so that the pattern will still match. You will get a directory structure inside obj/
as explained in the comment.
You can see by adding a bit if "intelligence" to the makefile it gets more complex more quickly - but now you can add source files into any number of sub-folders or sub-sub-folders etc....
Upvotes: 2