Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting make to create object files in a specific directory

GNU Make 3.82 gcc 4.7.2 c89 

I have the following make file:

INC_PATH=-I/home/dev_tools/apr/include/apr-1 LIB_PATH=-L/home/dev_tools/apr/lib LIBS=-lapr-1 -laprutil-1 RUNTIME_PATH=-Wl,-rpath,/home/dev_tools/apr/lib CC=gcc CFLAGS=-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE $(INC_PATH) SOURCES=$(wildcard src/*.c) OBJECTS=$(patsubst %.c, %.o, $(SOURCES))  EXECUTABLE=bin/to  all:    build $(EXECUTABLE)  $(EXECUTABLE):  $(OBJECTS)     $(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)  $(OBJECTS): $(SOURCES)     $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS)  build:     @mkdir -p bin  clean:     rm -rf $(EXECUTABLE) $(OBJECTS) bin     find . -name "*~" -exec rm {} \;     find . -name "*.o" -exec rm {} \; 

My directory structure is like this project/src project/bin. My Makefile is in the project (root) folder, and all my *.h and *.c are in the src directory. Currently I have only one source file called timeout.c

I get this error:

gcc: error: src/timeout.o: No such file or directory 

I have used this to get all the source files:

SOURCES=$(wildcard src/*.c) 

And the object files:

OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) 

However, the make seems to create the object file in the project root folder where the Makefile is. Should it not put it in the src directory?

like image 208
ant2009 Avatar asked Feb 01 '13 04:02

ant2009


1 Answers

You have two problems in this rule (well, three):

$(OBJECTS): $(SOURCES)     $(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) 

You haven't noticed yet, but the rule makes each object dependent on all sources, and tries to build that way. Not a problem as long as you have only one source. Easy to fix with a static pattern rule and an automatic variable:

$(OBJECTS): src/%.o : src/%.c     $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) 

Also, the command ("$(CC)...") doesn't specify an output file name, so gcc will infer it from the source file name; if you give it src/timeout.c, it will produce timeout.o (in the working directory, project/). So you should specify the desired path to the output file. Easy to do with another automatic variable:

$(OBJECTS): src/%.o : src/%.c     $(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) -o $@ 
like image 125
Beta Avatar answered Sep 22 '22 17:09

Beta