kaushil
kaushil

Reputation: 1

How to compile .o files in another directory using makefile?

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

Answers (1)

code_fodder
code_fodder

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

Related Questions