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
\$\endgroup\$
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.

\$\endgroup\$
  • \$\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 Jan 25 '18 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\$ – Toby Speight Jan 26 '18 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.