I am developing a CGI program in C on Linux using gcc, GNU make and the SQLite library. How does my makefile look?
# Automatic Variables
# $@ file name of target
# $< name of the first prerequisite
# $? name of all prerequisites newer than target
# $^ names of all prerequisites
# Pattern rule example - complile object files from prerequisites
# %.o: %.c
# $(CC) -c $(CFLAGS) $< -o $@
#
# Predefined Variables
# CC compiler, default gcc
# CFLAGS compiler flags
# LDFLAGS linker flags such as -L (extra directories searched for -l)
# LDLIBS libaries such as -lfoo
CC=gcc
CFLAGS=-ansi -pedantic -Wall -Wextra -O2
LDLIBS=-ldl -lpthread
# directory of SQLite library
SQLITEDIR=sqlite
sqlfun.cgi: sqlfuncgi.o sqlite3.o
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
sqlite3.o: $(SQLITEDIR)/sqlite3.c
$(CC) -o $@ $^ -c -Os
sqlfuncgi.o: sqlfuncgi.c
$(CC) -o $@ $^ -c $(CFLAGS)
.PHONY: clean test
clean:
rm -f sqlfun.cgi *.o
test:
clear
cppcheck --enable=all --inconclusive --std=c89 sqlfuncgi.c
valgrind --leak-check=yes ./sqlfun.cgi test
-
\$\begingroup\$ Please see What to do when someone answers . I have rolled back Rev 3 → 2. \$\endgroup\$200_success– 200_success2018年01月25日 21:50:28 +00:00Commented Jan 25, 2018 at 21:50
1 Answer 1
First impressions
This is clear and easy to read, and follows conventions well.
Use more built-ins
You can use more of Make's built-in rules. For example, this rule can be omitted entirely:
sqlfuncgi.o: sqlfuncgi.c
$(CC) -o $@ $^ -c $(CFLAGS)
If you add $(SQLITEDIR) to the VPATH, the sqlite3.o rule becomes simply
sqlite3.o: CFLAGS += -Os
And the link rule can use the built-in LINK.c variable:
sqlfun.cgi: sqlfuncgi.o sqlite3.o
$(LINK.c) -o $@ $^ $(LDLIBS)
Special targets
Good use of .PHONY. We probably also want .DELETE_ON_ERROR to ensure that if any command fails, its partially-written outputs don't hang around and appear to be made
Portability improvement
We can use Make's predefined $(RM) in place of rm -f.
-
\$\begingroup\$ Thanks Toby. As you said, I could have omitted the sqlitefuncgi.o rule since it would be implicitly built - but I find it clearer to have it explicitly documented. I didn't know about VPATH, so I have added it. I also added a system include path since I don't want to see compiler warnings from sqlite/sqlite3.h. I also added your suggestions $(RM) and .DELETE_ON_ERROR. I can't find any documentation about LINK.c - what does it do? Is $(CFLAGS) superfluous in the sqlfun.cgi recipe? I assume this rule only does linking not compiling \$\endgroup\$user2309803– user23098032018年01月25日 20:52:54 +00:00Commented Jan 25, 2018 at 20:52
-
\$\begingroup\$
$(LINK.c)is one of Make's built-in variables (that can be examined usingmake --print-data-base- which on my system shows it defined as$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)), and it's used in the default rule for building from C sources. You'd use$(LINK.cc)instead for C++ code, to link the C++ standard library as well. \$\endgroup\$Toby Speight– Toby Speight2018年01月26日 08:35:47 +00:00Commented Jan 26, 2018 at 8:35