67

I want to experiment with GCC whole program optimizations. To do so I have to pass all C-files at once to the compiler frontend. However, I use makefiles to automate my build process, and I'm not an expert when it comes to makefile magic.

How should I modify the makefile if I want to compile (maybe even link) using just one call to GCC?

For reference - my makefile looks like this:

LIBS  = -lkernel32 -luser32 -lgdi32 -lopengl32
CFLAGS = -Wall

OBJ = 64bitmath.o    \
      monotone.o     \
      node_sort.o    \
      planesweep.o   \
      triangulate.o  \
      prim_combine.o \
      welding.o      \
      test.o         \
      main.o

%.o : %.c
    gcc -c $(CFLAGS) $< -o $@

test: $(OBJ)
    gcc -o $@ $^ $(CFLAGS) $(LIBS)
Nils Pipenbrinck
  • 83,631
  • 31
  • 151
  • 221

3 Answers3

70
LIBS  = -lkernel32 -luser32 -lgdi32 -lopengl32
CFLAGS = -Wall

# Should be equivalent to your list of C files, if you don't build selectively
SRC=$(wildcard *.c)

test: $(SRC)
    gcc -o $@ $^ $(CFLAGS) $(LIBS)
Alex B
  • 82,554
  • 44
  • 203
  • 280
  • Why should it be the actual list of C files instead of wildcarding? – nornagon Jun 28 '11 at 02:00
  • 12
    @nornagon, s/should be/should be equivalent to/ – Alex B Jun 28 '11 at 02:02
  • 16
    @AlexB Speak English. What does that even mean? – Overv Jul 13 '12 at 22:39
  • 22
    @Overv it's `sed` syntax, meaning replace "should be" with "should be equivalent to" – kirb Jul 19 '12 at 08:00
  • @kranzky The question clearly states "pass all C-files at once to the compiler frontend", how is this not correct? – Alex B May 16 '13 at 00:37
  • sorry @AlexB, I was editing based on the answer I was looking for when googling for a solution and clicking on this SO question when it appeared as the #1 result :( – kranzky May 16 '13 at 03:14
  • 4
    This makefile is explained at http://stackoverflow.com/questions/3932895/makefile-aliases/3933012#3933012 – naught101 Apr 07 '14 at 12:33
  • FYI if you get an error like `makefile:8: *** missing separator. Stop.` it's because make doesn't like spaces and you need to prefix "gcc" with a tab instead of 4 spaces. – willbradley Apr 23 '21 at 00:35
62
SRCS=$(wildcard *.c)

OBJS=$(SRCS:.c=.o)

all: $(OBJS)
Danica
  • 28,423
  • 6
  • 90
  • 122
Manas
  • 629
  • 5
  • 2
  • This strikes me as not actually an answer to the original question, as it's likely to do many calls to `${CC}`. That said, it was essentially what I wanted for what I was trying to do. (I had a conversion I wanted to do on a bunch of text files, so I added my own `.SUFFIXES` line and such, but the `$(wildcard)` and the `$(VARIABLE:.ext1=.ext2)` conversion were exactly what I was looking for.) Explicitly not voting either up or down, though I'd say it's arguable that this deserves a down-vote *for this question*. – lindes Apr 30 '15 at 21:26
3

You need to take out your suffix rule (%.o: %.c) in favour of a big-bang rule. Something like this:

LIBS  = -lkernel32 -luser32 -lgdi32 -lopengl32
CFLAGS = -Wall

OBJ = 64bitmath.o    \
      monotone.o     \
      node_sort.o    \
      planesweep.o   \
      triangulate.o  \
      prim_combine.o \
      welding.o      \
      test.o         \
      main.o

SRCS = $(OBJ:%.o=%.c)

test: $(SRCS)
    gcc -o $@  $(CFLAGS) $(LIBS) $(SRCS)

If you're going to experiment with GCC's whole-program optimization, make sure that you add the appropriate flag to CFLAGS, above.

On reading through the docs for those flags, I see notes about link-time optimization as well; you should investigate those too.

James McPherson
  • 2,476
  • 1
  • 12
  • 16