1
\$\begingroup\$

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
200_success
146k22 gold badges191 silver badges481 bronze badges
asked Jan 25, 2018 at 5:16
\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

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.

answered Jan 25, 2018 at 9:30
\$\endgroup\$
2
  • \$\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\$ Commented Jan 25, 2018 at 20:52
  • \$\begingroup\$ $(LINK.c) is one of Make's built-in variables (that can be examined using make --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\$ Commented Jan 26, 2018 at 8:35

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.