aboutsummaryrefslogtreecommitdiff
path: root/docs/recommended_practices_for_makefiles.md
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2025-01-05 21:40:39 -0300
committerHisham Muhammad <hisham@gobolinux.org>2025-01-05 21:40:39 -0300
commitf5c5db5a7378d97a6f261ffaa10c84e2005bfc4e (patch)
treec2f0cb86890fb90a85a7f091746543c7ff14ac5e /docs/recommended_practices_for_makefiles.md
parent7fe5532c695711d23fd9d7e13a9e6235478171b6 (diff)
downloadluarocks-f5c5db5a7378d97a6f261ffaa10c84e2005bfc4e.tar.gz
luarocks-f5c5db5a7378d97a6f261ffaa10c84e2005bfc4e.tar.bz2
luarocks-f5c5db5a7378d97a6f261ffaa10c84e2005bfc4e.zip
docs: import Wiki docs into the main repo
Diffstat (limited to 'docs/recommended_practices_for_makefiles.md')
-rw-r--r--docs/recommended_practices_for_makefiles.md176
1 files changed, 176 insertions, 0 deletions
diff --git a/docs/recommended_practices_for_makefiles.md b/docs/recommended_practices_for_makefiles.md
new file mode 100644
index 00000000..1391ec3b
--- /dev/null
+++ b/docs/recommended_practices_for_makefiles.md
@@ -0,0 +1,176 @@
1# Recommended practices for Makefiles
2
3When authoring a Lua module, especially those containing C code, developers
4are always faced with some build and deployment issues: where to find
5libraries, where to install modules, which flags to pass when building, and so
6on. Looking at the existing modules available in the web, it is clear to see
7that there are no _de facto_ standards in Makefiles for Lua modules, and that
8many of them are incomplete copies of one another, and many of them share the
9same deficiencies. Here is a list of some of those issues we found during the
10development of LuaRocks, and how to avoid them. Following the recommendations
11below will improve the portability of your Makefiles and make things easier
12for writing rocks, other packagers such as Linux distributions, and your
13users.
14
15# Do not ask users to edit files "by hand"
16
17Asking users to hand-edit things is error-prone. Even though systems like
18LuaRocks support applying patches -- which is the automated equivalent of
19hand-tweaking files -- this adds maintenance burden, as patches have to be
20updated on each release if any change happens in the file. Always use
21variables, so that they can be overridden by automated processes. Hand-tweaks
22in the code can be avoided by propagating C defines from Makefiles as well.
23
24Don't:
25```
26// Edit this to suit your installation
27const char* bla_dir = "/usr/local/share/bla";
28```
29
30Do:
31
32```
33BLA_DIR=/usr/local/share/bla
34# ...
35bla.o:
36 $(CC) -c bla.c -DBLA_DIR=\"$(BLA_DIR)\"
37```
38
39## Do not hardcode any paths
40
41This is a corollary to the above recommendation, really. Whenever you are
42passing any paths, don't write them directly in Makefile rules. Always factor
43them out into variables.
44
45# Provide a nice "install" rule
46
47A large number of Makefiles for Lua modules ship without an "install" rule,
48probably due to the long-standing lack of standard install locations for
49modules that plagued the Lua world in the past. Nowadays, however, the
50convention of using .../lib/lua/5.1/ for C modules and .../share/lua/5.1/ for
51Lua modules (relative to the prefix where Lua is installed) is well
52established, and there is no reason not to use it. To make things even easier
53for your users, you can also factor out the common Lua prefix. /usr/local is a
54good default, since it is also the default for the vanilla Lua tarball.
55
56Don't:
57
58```
59# no make install rule!
60```
61
62Do:
63
64```
65LUA_DIR=/usr/local
66LUA_LIBDIR=$(LUA_DIR)/lib/lua/5.1
67LUA_SHAREDIR=$(LUA_DIR)/share/lua/5.1
68
69# ...
70
71install:
72 mkdir -p $(LUA_LIBDIR)/bla
73 cp bla/core.so $(LUA_LIBDIR)/bla
74 mkdir -p $(LUA_SHAREDIR)/bla
75 cp bla.lua $(LUA_SHAREDIR)
76 cp bla/extras.lua $(LUA_SHAREDIR)/bla
77```
78
79Some packagers recommend prepending an empty `$(DESTDIR)` variable to all target
80paths in your install rule, but that's not strictly necessary if your paths
81are all set into variables, which can be redefined for the "make install" run,
82like in the example above.
83
84# Do not assume libraries are in the system path
85
86If your program uses LibPNG, adding "-lpng" to your Makefile is not enough.
87Your users may have the LibPNG library somewhere else, so let them specify the
88locations of both the libraries and headers. The default values you pick are
89not really important, as long as they're overridable by the user, but
90/usr/local is always a good choice on Unix systems as this is the first
91typical "non-system path" that users may want to use.
92
93Of course, use one library per value; don't assume all third-party libraries
94can be found in the same place.
95
96Don't:
97
98```
99gcc -o bla bla.c -lpng
100```
101
102Do:
103
104```
105LIBPNG_DIR=/usr/local
106LIBPNG_INCDIR=$(LIBPNG_DIR)/include
107LIBPNG_LIBDIR=$(LIBPNG_DIR)/lib
108
109# ...
110 $(CC) -o bla bla.c -lpng -L$(LIBPNG_LIBDIR) -I$(LIBPNG_INCDIR)
111```
112
113# Avoid compiler assumptions
114
115Even if your code only compiles in GCC and is Unix-only, there are still build portability issues to look out for. The main ones are:
116
117* **Not all GCCs link libraries with the same flags** - for instance, linking
118 shared libraries is done with "-shared" on Linux and "-bundle -undefined
119 dynamic_lookup -all_load" on Mac OSX. Factoring the flags in a variable is
120 a nice gesture for users of other operating systems. (LuaRocks can take
121 care of the detection part and set the flag appropriately, but packages of
122 other systems will benefit as well.)
123
124* **The compiler is not always called "gcc"** - this one is for the people in
125 the embedded world; in their toolchains, their cross-compilers often have
126 names like "arm-nofpu-gcc". $(CC) is a standard variable in make. Just use
127 that instead of "gcc" and you're good to go.
128
129Don't:
130
131```
132bla.so:
133 gcc -o bla.so -shared bla.o
134```
135
136Do:
137
138```
139LIBFLAG=-shared
140# ...
141bla.so:
142 $(CC) -o bla.so $(LIBFLAG) bla.o
143```
144
145# Do not "overload" variables
146
147As mentioned in the topic about third-party libraries above, don't reuse variables just because two conceptually different locations happen to point to the same place. For example, do not assume that the directory you're using to _find_ libraries and the directory you're _installing_ libraries to is the same. That little economy will only cause confusion and trouble to your users.
148
149Don't:
150
151```
152LIBDIR=/usr/local/lib
153INCDIR=/usr/local/include
154# ...
155bla.so:
156 $(CC) $(LIBFLAG) -o bla.so -lpng -L$(LIBDIR) -I$(INCDIR)
157install:
158 mkdir -p $(LIBDIR)
159 cp bla.so $(LIBDIR)/lua/5.1
160```
161
162Do:
163
164```
165LIBPNG_DIR=/usr/local
166LIBPNG_LIBDIR=$(LIBPNG_DIR)/lib
167LIBPNG_INCDIR=$(LIBPNG_DIR)/include
168LUA_DIR=/usr/local
169LUA_LIBDIR=$(LUA_DIR)/lib/lua/5.1
170# ...
171bla.so:
172 $(CC) $(LIBFLAG) -o bla.so -lpng -L$(LIBPNG_LIBDIR) -I$(LIBPNG_INCDIR)
173install:
174 mkdir -p $(LUA_LIBDIR)
175 cp bla.so $(LUA_LIBDIR)
176```