How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories? How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories? c c

How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?


First, your $(OBJECTS) rule is problematic, because:

  1. it's kind of indiscriminate, making all sources prerequisites of every object,
  2. it often uses the wrong source (as you discovered with file1.o and file2.o)
  3. it tries to build executables instead of stopping at objects, and
  4. the name of the target (foo.o) is not what the rule will actually produce (obj/foo.o).

I suggest the following:

OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c    $(CC) $(CFLAGS) -c $< -o $@    @echo "Compiled "$<" successfully!"

The $(TARGET) rule has the same problem that the target name does not actually describe what the rule builds. For that reason, if you type make several times, Make will rebuild the target each time, even though there is no reason to. A small change fixes that:

$(BINDIR)/$(TARGET): $(OBJECTS)    $(LINKER) $@ $(LFLAGS) $(OBJECTS)    @echo "Linking complete!"

Once that's all in order, you might consider more sophisticated dependency handling; if you modify one of the header files, this makefile will not know which objects/executables must be rebuilt. But that can wait for another day.

EDIT:
Sorry, I omitted part of the $(OBJECTS) rule above; I've corrected it. (I wish I could use "strike" inside a code sample.)


You can add the -I flag to the compiler flags (CFLAGS) to indicate where the compiler should look for source files , and the -o flag to indicate where the binary should be left:

CFLAGS   = -Wall -I./srcTARGETPATH = ./bin$(TARGET): obj    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)    @echo "Linking complete!"

In order to drop the object files into the obj directory, use the -o option when compiling. Also, look at the $@ and $< automatic variables.

For example, consider this simple Makefile

CFLAGS= -g -Wall -O3                                                            OBJDIR= ./objSRCS=$(wildcard *.c)OBJS=$(SRCS:.c=.o )all:$(OBJS)%.o: %.c    $(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$@

Update>

By looking at your makefile, I realize you are using the -o flag. Good. Continue using it, but add a target directory variable to indicate where the output file should be written.


I have stopped writing makefiles these days, if your intention is to learn go ahead, else you have good makefile generator that comes with eclipse CDT. If you want some maintainability / multiple project support with in your build tree, have a look at the following -

https://github.com/dmoulding/boilermake I found this pretty good..!