Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A quick note:

> INCS=-I./

This is generally a bad idea, unless you're explicitly trying to override #include <stdio.h> with a local file (and there are better ways to do that). <> are for system files, "" are for local files.

So off the bat, your makefile example is better than most makefiles out there. I still see things that look like some dumb IDE wrote them with explicit .d and x.c: x.o rules littered about.

Though I do note you aren't taking advantage of the built-in makefile rules (which are defined in POSIX), and you aren't taking advantage of gcc's -MMD flag, which does the dependencies during compilation instead of a separate step. That eliminates much of the file:

  LDLIBS=-lglfw -lGLEW
  CFLAGS+=-std=gnu99 -g -ggdb -W -Wall -Wextra -pedantic
  CFLAGS+=-MMD
  CFLAGS+=$(INCS)
  CFLAGS+=-march=native -mno-80387 -mfpmath=sse -O3
  SRCS=$(wildcard *.c)
  OBJS=$(SRCS:.c=.o)
  EXECUTABLE=main

  .PHONY: all clean
  all: $(EXECUTABLE)

  $(EXECUTABLE): $(OBJS)
  	$(CC) $(CFLAGS) $(LDLIBS) -o $@ $^

  -include *.d

  clean:
  	rm -f $(EXECUTABLE)
  	rm -f $(OBJS) *.d
Furthermore, I like to name my objects explicitly instead of using * .c, which lets you order them on the command line, if you find that makes a difference. In particular, if your executable is named the same as one of your C source files then you don't even need the link line, as long as the C source file is the first dependency:

  LDLIBS=-lglfw -lGLEW
  CFLAGS+=-std=gnu99 -g -ggdb -W -Wall -Wextra -pedantic
  CFLAGS+=-MMD
  CFLAGS+=$(INCS)
  CFLAGS+=-march=native -mno-80387 -mfpmath=sse -O3
  OBJS=main.o obj1.o obj2.o

  .PHONY: all clean
  all: main

  main: $(OBJS)

  -include *.d

  clean:
  	rm -f $(EXECUTABLE)
  	rm -f $(OBJS) *.d
I tend to like to prefix variables with the thing you are making so that different executables in the same Makefile can have (drastically) different compilation parameters:

  .PHONY: all clean
  all: main

  main: LDLIBS=-lglfw -lGLEW
  main: CFLAGS+=-std=gnu99 -g -ggdb -W -Wall -Wextra -pedantic
  main: CFLAGS+=-MMD
  main: CFLAGS+=$(INCS)
  main: CFLAGS+=-march=native -mno-80387 -mfpmath=sse -O3
  main: OBJS=main.o obj1.o obj2.o

  main: $(OBJS)

  -include *.d

  clean:
  	rm -f $(EXECUTABLE)
  	rm -f $(OBJS) *.d
If you have an embedded project that needs both compiling and cross-compiling that trick can work wonders.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: