[c] Makefile to compile multiple C programs?

This is an incredibly simple question, but I'm new to makefiles. I am trying to make a makefile that will compile two independent programs:

program1:
    gcc -o prog1 program1.c

program2:
    gcc -o prog2 program2.c

All the examples online go into way more details than I need and are confusing! All I really want it to do is to run the two gcc lines. What am I doing wrong?

This question is related to c makefile

The answer is


all: program1 program2

program1:
    gcc -Wall -o prog1 program1.c

program2:
    gcc -Wall -o prog2 program2.c

all: program1 program2

program1:
    gcc -Wall -ansi -pedantic -o prog1 program1.c

program2:
    gcc -Wall -ansi -pedantic -o prog2 program2.c

I rather the ansi and pedantic, a better control for your program. It wont let you compile while you still have warnings !!


This will compile all *.c files upon make to executables without the .c extension as in gcc program.c -o program.

make will automatically add any flags you add to CFLAGS like CFLAGS = -g Wall.

If you don't need any flags CFLAGS can be left blank (as below) or omitted completely.

SOURCES = $(wildcard *.c)
EXECS = $(SOURCES:%.c=%)
CFLAGS = 

all: $(EXECS)

Pattern rules let you compile multiple c files which require the same compilation commands using make as follows:

objects = program1 program2
all: $(objects)

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

############################################################################
# 'A Generic Makefile for Building Multiple main() Targets in $PWD'
# Author:  Robert A. Nader (2012)
# Email: naderra at some g
# Web: xiberix
############################################################################
#  The purpose of this makefile is to compile to executable all C source
#  files in CWD, where each .c file has a main() function, and each object
#  links with a common LDFLAG.
#
#  This makefile should suffice for simple projects that require building
#  similar executable targets.  For example, if your CWD build requires
#  exclusively this pattern:
#
#  cc -c $(CFLAGS) main_01.c
#  cc main_01.o $(LDFLAGS) -o main_01
#
#  cc -c $(CFLAGS) main_2..c
#  cc main_02.o $(LDFLAGS) -o main_02
#
#  etc, ... a common case when compiling the programs of some chapter,
#  then you may be interested in using this makefile.
#
#  What YOU do:
#
#  Set PRG_SUFFIX_FLAG below to either 0 or 1 to enable or disable
#  the generation of a .exe suffix on executables
#
#  Set CFLAGS and LDFLAGS according to your needs.
#
#  What this makefile does automagically:
#
#  Sets SRC to a list of *.c files in PWD using wildcard.
#  Sets PRGS BINS and OBJS using pattern substitution.
#  Compiles each individual .c to .o object file.
#  Links each individual .o to its corresponding executable.
#
###########################################################################
#
PRG_SUFFIX_FLAG := 0
#
LDFLAGS := 
CFLAGS_INC := 
CFLAGS := -g -Wall $(CFLAGS_INC)
#
## ==================- NOTHING TO CHANGE BELOW THIS LINE ===================
##
SRCS := $(wildcard *.c)
PRGS := $(patsubst %.c,%,$(SRCS))
PRG_SUFFIX=.exe
BINS := $(patsubst %,%$(PRG_SUFFIX),$(PRGS))
## OBJS are automagically compiled by make.
OBJS := $(patsubst %,%.o,$(PRGS))
##
all : $(BINS)
##
## For clarity sake we make use of:
.SECONDEXPANSION:
OBJ = $(patsubst %$(PRG_SUFFIX),%.o,$@)
ifeq ($(PRG_SUFFIX_FLAG),0)
        BIN = $(patsubst %$(PRG_SUFFIX),%,$@)
else
        BIN = $@
endif
## Compile the executables
%$(PRG_SUFFIX) : $(OBJS)
    $(CC) $(OBJ)  $(LDFLAGS) -o $(BIN)
##
## $(OBJS) should be automagically removed right after linking.
##
veryclean:
ifeq ($(PRG_SUFFIX_FLAG),0)
    $(RM) $(PRGS)
else
    $(RM) $(BINS)
endif
##
rebuild: veryclean all
##
## eof Generic_Multi_Main_PWD.makefile

A simple program's compilation workflow is simple, I can draw it as a small graph: source -> [compilation] -> object [linking] -> executable. There are files (source, object, executable) in this graph, and rules (make's terminology). That graph is definied in the Makefile.

When you launch make, it reads Makefile, and checks for changed files. If there's any, it triggers the rule, which depends on it. The rule may produce/update further files, which may trigger other rules and so on. If you create a good makefile, only the necessary rules (compiler/link commands) will run, which stands "to next" from the modified file in the dependency path.

Pick an example Makefile, read the manual for syntax (anyway, it's clear for first sight, w/o manual), and draw the graph. You have to understand compiler options in order to find out the names of the result files.

The make graph should be as complex just as you want. You can even do infinite loops (don't do)! You can tell make, which rule is your target, so only the left-standing files will be used as triggers.

Again: draw the graph!.


Do it like so

all: program1 program2

program1: program1.c
    gcc -o program1 program1.c

program2: program2.c
    gcc -o program2 program2.c

You said you don't want advanced stuff, but you could also shorten it like this based on some default rules.

all: program1 program2

program1: program1.c
program2: program2.c

SRC = a.cpp b.cpp
BIN = $(patsubst %.cpp,%,$(SRC))

all: $(BIN)

clean:
    rm -f $(BIN)

.PHONY: all clean

make all will do:

c++     a.cpp   -o a
c++     b.cpp   -o b

If you set CXX and CXXFLAGS variables make will use them.