Introduction
Introduction Statistics Contact Development Disclaimer Help
makefile-guideline.txt - bitreich-style - Style guide for programmers.
git clone git://bitreich.org/bitreich-style
Log
Files
Refs
Tags
README
LICENSE
---
makefile-guideline.txt (8924B)
---
1 Title: Guidelines for writing simple portable Makefiles
2
3
4 This page describes some guidelines and good practices for writing simpl…
5 portable POSIX Makefiles. It assumes a basic level of understanding in
6 writing Makefiles and focuses on projects that use the C programming
7 language.
8
9 make is used because it has been around for a long time, is available
10 on many systems, is a POSIX standard and has been proven to work well
11 for most projects.
12
13
14 Targets
15 -------
16
17 The following targets should be defined in the Makefile:
18
19 * all or the "default": build the project.
20 * clean: clean files used by compilation, such as: object files, compiled
21 binaries.
22 * install: install the built project.
23 * uninstall (optional): uninstall the project.
24 * dist (optional): create a source tarball of the project intended as
25 redistribution for source packages.
26 * tests (optional): run unit tests.
27
28
29 Portability
30 -----------
31
32 Do not use GNUisms in Makefiles. Testing with different make
33 implementations, such as BSD make, which mostly respects POSIX, is very
34 useful. Use POSIX Makefile rules:
35 https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
36
37 Try to place yourself in the shoes of a package maintainer / porter. This
38 helps make sure that the package is easy to maintain:
39
40 * https://www.openbsd.org/faq/ports/
41 * https://www.netbsd.org/docs/pkgsrc/
42 * https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/boo…
43 * https://wiki.voidlinux.org/A_General_Introduction_To_Package_Creation
44
45
46 Variables
47 ---------
48
49 It is recommended to respect the following commonly-used variables.
50
51 * $DESTDIR: make use of the $DESTDIR variable for the install targets. T…
52 makes it simpler to install the package to another location and make b…
53 packages. It is the prefix destination directory to install to (before…
54 It should be unset by default.
55
56 * $PREFIX: this variable specifies the prefix location to install to, it…
57 "/usr/local" by default since this is most commonly used for ports.
58
59 * $MANPREFIX or $MANDIR:
60 * Distributions can use different locations for man pages for ports or…
61 * Some distributions package documentation in a separate package (proj…
62
63 Specifying compiler and linker flags:
64
65 * $CC, $CFLAGS, $LDFLAGS, $CPPFLAGS: make sure to respect the default se…
66 as specified in POSIX:
67 https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html u…
68 section "Default rules". This make it easier for the ports build syste…
69 the set variables and not having to patch the Makefile in some way.
70
71 * $CFLAGS: do not hard-code optimization flags like (-O2) or diagnostic …
72 such as -Wall, -Wextra, -pedantic. Even more importantly, do not
73 specify unportable compiler flags.
74
75 * $LDFLAGS: do not hard-code linker flags like -s (symbol stripping) or …
76 -static or such flags.
77
78 * Libraries: using separate variables for compile and link per library (…
79 example libpng, libjpeg) can be useful for building in ports.
80 For example a variable LIBPNG_CFLAGS, LIBPNG_LDFLAGS for the header fi…
81 library location.
82
83
84 Considerations
85 --------------
86
87 * It is not recommended to suppress compilation output with the @ prefix…
88 example to make output look nicer aligned). The verbose output is very…
89 for debugging and suppressing it only adds debugging abstractions.
90
91 * Try to use a single-file Makefile, at least for small projects. If ne…
92 configuration could be included from the Makefile: config.mk. Keep in…
93 that reducing abstractions will increase readability and debugability.…
94 maintainers/porters do not want to have to relearn a new system for ea…
95 software package.
96
97 * As specified above, different systems can use different locations for …
98 things like man pages, X11 header files and libraries and ports instal…
99
100 Examples:
101 * X11: commonly uses /usr/X11R6 on BSD-like platforms.
102 * Man page directories: on OpenBSD: /usr/local/man.
103
104 Testing on many different systems is useful! For example: Linux, OpenBSD…
105
106
107 Examples
108 --------
109
110 Below is an example of a Makefile from the json2tsv project. It is
111 line-numbered and annotated with remarks on why things are done the way
112 they are.
113
114 1 .POSIX:
115
116 Specify POSIX compatibility: "To receive exactly the behavior described …
117 section, the user shall ensure that a portable makefile shall: Include t…
118 special target .POSIX"
119
120 2
121 3 NAME = json2tsv
122 4 VERSION = 0.5
123 5
124
125 Define a name and version variable of the project which can be reused, f…
126 example for the dist tarball.
127
128 6 # paths
129 7 PREFIX = /usr/local
130 8 MANPREFIX = ${PREFIX}/man
131 9 DOCPREFIX = ${PREFIX}/share/doc/${NAME}
132 10
133
134 Specify default sane paths.
135
136 11 RANLIB = ranlib
137 12
138
139 This variable is not specified by default in POSIX. It is commonly "ranl…
140 but can be overwritten.
141
142 13 BIN = ${NAME}
143
144 In this case it's simple: the binary is the program name.
145
146 14 SRC = ${BIN:=.c}
147
148 C source files, so just json2tsv.c here.
149
150 15 HDR = json.h
151
152 Header files.
153
154 16 MAN1 = ${BIN:=.1}
155
156 Man section 1 pages.
157
158 17 DOC = \
159 18 LICENSE\
160 19 README
161 20
162
163 Other documentation and license files.
164
165 21 LIBJSON = libjson.a
166 22 LIBJSONSRC = json.c
167 23 LIBJSONOBJ = ${LIBJSONSRC:.c=.o}
168 24
169 25 LIB = ${LIBJSON}
170 26
171
172 Build the json.c file as a local reusable linkable library (libjson.a).
173
174 27 all: ${BIN}
175 28
176
177 The default build rule: build the binary.
178
179 29 ${BIN}: ${LIB} ${BIN:=.o}
180 30
181
182 The binary depends on the libjson library and its own object file.
183
184 31 OBJ = ${SRC:.c=.o} ${LIBJSONOBJ}
185 32
186
187 The object files are all C source-code substituted to from .c to .o and …
188 local libjson library files, so: json2tsv.o json.o
189
190 33 ${OBJ}: ${HDR}
191 34
192
193 Ensure the object files are recompiled if the header file contents chang…
194
195 35 .o:
196 36 ${CC} ${LDFLAGS} -o $@ $< ${LIB}
197
198 Linking, use the system specified LDFLAGS.
199
200 37
201 38 .c.o:
202 39 ${CC} ${CFLAGS} ${CPPFLAGS} -c $<
203
204 Compiling, use the system specified CFLAGS and CPPFLAGS.
205
206 40
207 41 ${LIBJSON}: ${LIBJSONOBJ}
208 42 ${AR} -rc $@ $?
209 43 ${RANLIB} $@
210 44
211
212 Create an archive of the libjson object files. Note that ar -s is an ext…
213 so ranlib is called as a separate command. It is also useful to be speci…
214 separately for cross-compiling.
215
216 45 dist:
217 46 rm -rf "${NAME}-${VERSION}"
218 47 mkdir -p "${NAME}-${VERSION}"
219 48 cp -f ${MAN1} ${DOC} ${HDR} \
220 49 ${SRC} ${LIBJSONSRC} Makefile "${NAME}-${V…
221
222 Use the -f (force) options for rm ensures make does not return an error
223 on failure. For cp it ensures to overwrite the file even if it is busy. …
224 mkdir the -p flag is used to create all intermediary directories and to …
225 return an error if the directory already exists.
226
227 50 # make tarball
228 51 tar cf - "${NAME}-${VERSION}" | gzip -c > "${NAME}…
229
230 Make a tarball. gzip from stdin is used for portability (tar z is non-PO…
231 https://pubs.opengroup.org/onlinepubs/007908799/xcu/tar.html
232
233 52 rm -rf "${NAME}-${VERSION}"
234 53
235
236 54 clean:
237 55 rm -f ${BIN} ${OBJ} ${LIB}
238
239 Remove the binary, object files and the local archive library (.a) file.
240
241 56
242 57 install: all
243 58 # installing executable files.
244 59 mkdir -p "${DESTDIR}${PREFIX}/bin"
245 60 cp -f ${BIN} "${DESTDIR}${PREFIX}/bin"
246
247 cp's -f flag ensures overwriting the file even if it is busy.
248
249 61 for f in ${BIN}; do chmod 755 "${DESTDIR}${PREFIX}…
250 62 # installing example files.
251 63 mkdir -p "${DESTDIR}${DOCPREFIX}"
252 64 cp -f ${DOC} "${DESTDIR}${DOCPREFIX}"
253 65 for d in ${DOC}; do chmod 644 "${DESTDIR}${DOCPREF…
254 66 # installing manual pages for general commands: se…
255 67 mkdir -p "${DESTDIR}${MANPREFIX}/man1"
256 68 cp -f ${MAN1} "${DESTDIR}${MANPREFIX}/man1"
257 69 for m in ${MAN1}; do chmod 644 "${DESTDIR}${MANPRE…
258 70
259
260 Explicitly set permissions for executable files and for documentation.
261
262 71 uninstall:
263 72 # removing executable files.
264 73 for f in ${BIN}; do rm -f "${DESTDIR}${PREFIX}/bin…
265 74 # removing example files.
266 75 for d in ${DOC}; do rm -f "${DESTDIR}${DOCPREFIX}/…
267
268 76 -rmdir "${DESTDIR}${DOCPREFIX}"
269
270 Try to remove the doc directory, but if it is shared by other packages a…
271 rmdir returns an error code then that is ok and make still proceeds.
272
273 77 # removing manual pages.
274 78 for m in ${MAN1}; do rm -f "${DESTDIR}${MANPREFIX}…
275 79
276 80 .PHONY: all clean dist install uninstall
277
278
279 References
280 ----------
281
282 - https://www.gnu.org/prep/standards/standards.html#DESTDIR
283 - https://nullprogram.com/blog/2017/08/20/
284 - https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
285 - https://pubs.opengroup.org/onlinepubs/9699919799/
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.