Getting make to create object files in a specific directory
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 $@
Use gcc
's -o option to write the output file to a particular location. For instance, you could say:
$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) -o $(OBJECTS)
Unfortunately, there's a problem with this line: if there is more than one source file in $(SOURCES)
, it won't work, since $(OBJECTS)
will also contain multiple file names, and the -o option only binds to the first argument.
A way to compile each file in a list of source code files is to use implicit rules. In gmake
, you would write:
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
where $< is replaced with name of the input file and $@ is replaced with the name out the output file.
I solved this request and here is my Makefile and directory tree.
PROJECT := main.exe
DIR_SRC += .
DIR_SRC += ./src
DIR_INC += -lpthread
DIR_INC += -I./inc
DIR_INC += $(addprefix -I, $(DIR_SRC))
SRC_C += $(wildcard $(addsuffix /*.c, $(DIR_SRC)))
#OBJ := $(filter %.o, $(SRC_C:.c=.o))
OBJ := $(patsubst %.c, %.o, $(SRC_C))
EXE := $(PROJECT)
CC_PREFIX :=
CC := $(CC_PREFIX)gcc
CFLAG =
CLIB = -L .
.PHONY:all
all:$(OBJ) $(EXE)
%.o: %.c
$(CC) $(CFLAG) $(DIR_INC) -c $< -o $@
$(EXE): $(OBJ)
$(CC) $(CFLAG) $(CLIB) $(OBJ) -o $@
clean:
rm -r $(EXE) $(OBJ)
See my directory tree: