title: How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?
body: <p>A few months ago, I came up with the following generic <code>Makefile</code> for school assignments:</p>
  
  <pre><code># ------------------------------------------------
  # Generic Makefile
  #
  # Author: yanick.rochon@gmail.com
  # Date  : 2010-11-05
  #
  # Changelog :
  #   0.01 - first version
  # ------------------------------------------------
  
  # project name (generate executable with this name)
  TARGET   = projectname
  
  CC       = gcc -std=c99 -c
  # compiling flags here
  CFLAGS   = -Wall -I.
  
  LINKER   = gcc -o
  # linking flags here
  LFLAGS   = -Wall
  
  SOURCES  := $(wildcard *.c)
  INCLUDES := $(wildcard *.h)
  OBJECTS  := $(SOURCES:.c=*.o)
  rm       = rm -f
  
  $(TARGET): obj
      @$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
      @echo "Linking complete!"
  
  obj: $(SOURCES) $(INCLUDES)
      @$(CC) $(CFLAGS) $(SOURCES)
      @echo "Compilation complete!"
  
  clean:
      @$(rm) $(TARGET) $(OBJECTS)
      @echo "Cleanup complete!"
  </code></pre>
  
  <p>This will basically compile every <code>.c</code> and <code>.h</code> file to generate <code>.o</code> files and the executable <code>projectname</code> all in the same folder.</p>
  
  <p>Now, I'd like to push this a little. <strong>How can I write a Makefile to compile a C project with the following directory structure?</strong></p>
  
  <pre><code> ./
   ./Makefile
   ./src/*.c;*.h
   ./obj/*.o
   ./bin/&lt;executable&gt;
  </code></pre>
  
  <p>In other words, I'd like to have a Makefile that compiles C sources from <code>./src/</code> into <code>./obj/</code> and then link everything to create the executable in <code>./bin/</code>.</p>
  
  <p>I've tried to read different Makefiles, but I simply can't make them work for the project structure above; instead, the project fails to compile with all sorts of errors. Sure, I could use full blown IDE (Monodevelop, Anjuta, etc.), but I honestly prefer to stick with gEdit and the good ol' terminal.</p>
  
  <p>Is there a guru who can give me a working solution, or clear information about how this can be done? Thank you!</p>
  
  <p>** <strong>UPDATE (v4)</strong> **</p>
  
  <p>The final solution :</p>
  
  <pre><code># ------------------------------------------------
  # Generic Makefile
  #
  # Author: yanick.rochon@gmail.com
  # Date  : 2011-08-10
  #
  # Changelog :
  #   2010-11-05 - first version
  #   2011-08-10 - added structure : sources, objects, binaries
  #                thanks to http://stackoverflow.com/users/128940/beta
  #   2017-04-24 - changed order of linker params
  # ------------------------------------------------
  
  # project name (generate executable with this name)
  TARGET   = projectname
  
  CC       = gcc
  # compiling flags here
  CFLAGS   = -std=c99 -Wall -I.
  
  LINKER   = gcc
  # linking flags here
  LFLAGS   = -Wall -I. -lm
  
  # change these to proper directories where each file should be
  SRCDIR   = src
  OBJDIR   = obj
  BINDIR   = bin
  
  SOURCES  := $(wildcard $(SRCDIR)/*.c)
  INCLUDES := $(wildcard $(SRCDIR)/*.h)
  OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
  rm       = rm -f
  
  
  $(BINDIR)/$(TARGET): $(OBJECTS)
      @$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
      @echo "Linking complete!"
  
  $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
      @$(CC) $(CFLAGS) -c $&lt; -o $@
      @echo "Compiled "$&lt;" successfully!"
  
  .PHONY: clean
  clean:
      @$(rm) $(OBJECTS)
      @echo "Cleanup complete!"
  
  .PHONY: remove
  remove: clean
      @$(rm) $(BINDIR)/$(TARGET)
      @echo "Executable removed!"
  </code></pre>