0

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
kaushil
  • 1
  • 1
  • 3
  • Have you tried writing your Makefile without variables first? – melpomene Jul 08 '19 at 07:13
  • No i dont but when i add multiple .o files path then it gives error like you can not use -c and -o together for multiple files – kaushil Jul 08 '19 at 07:19
  • 1
    Possible duplicate of [Getting make to create object files in a specific directory](https://stackoverflow.com/questions/14639794/getting-make-to-create-object-files-in-a-specific-directory) – John Bollinger Jul 08 '19 at 14:38

1 Answers1

2

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....

code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • As i make chganges what if i have source files in different directory do i need to write that " $(OBJDIR)/main.o $(OBJDIR)/fred.o" for every single .c file – kaushil Jul 09 '19 at 05:14
  • Well then you start to get into a more complex makefile - I would suggest this is a variation of this question, this is like a thread that you will pull answering many questions along the way. You will want to expand your simple make file with each iteration improving as you go until you end up with quite a complicated makefile but that is very easy to maintain etc... I will add another example - but a simple one - to show how you can have multiple source files, but you will want to keep improving on this... – code_fodder Jul 09 '19 at 06:23