You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since you are starting with ``make`` we highly recommend to always include
250
-
the first line, like with Fortrans ``implicit none`` we do not want to have
250
+
the first line, like with Fortran's ``implicit none`` we do not want to have
251
251
implicit rules messing up our ``Makefile`` in surprising and harmful ways.
252
252
253
253
Next, we have a configuration section where we define variables, in case you
@@ -264,15 +264,17 @@ Also, we slightly changed the build rule for the object files to account for
264
264
appending the ``.o`` suffix instead of substituting it.
265
265
Notice that we still need to explicitly define the interdependencies in the
266
266
``Makefile``. We also added a dependency for the object files on the ``Makefile``
267
-
itself, in case you change the compiler, this will allow you to savely rebuild.
267
+
itself, in case you change the compiler, this will allow you to safely rebuild.
268
268
269
269
Now you know enough about ``make`` to use it for building small projects.
270
+
If you plan to use ``make`` more extensively, we have compiled a few tips
271
+
for you as well.
270
272
271
273
{% capture note %}
272
274
273
275
In this guide, we avoided and disabled a lot of the commonly used ``make``
274
276
features that can be particularly troublesome if not used correctly, we highly
275
-
recommend staying away from the buildin rules and variables if you do not feel
277
+
recommend staying away from the builtin rules and variables if you do not feel
276
278
confident working with ``make``, but explicitly declare all variables and rules.
277
279
278
280
You will find that ``make`` is capable tool to automate short interdependent
@@ -284,6 +286,100 @@ completely or in parts.
284
286
{% include note.html title="Note" content=note %}
285
287
286
288
289
+
### Recursively expanded variables
290
+
291
+
Commonly seen in many projects are recursively expanded variables (declared with
292
+
``=`` instead of ``:=``). Recursive expansion of your variables allows out-of-order
293
+
declaration and other neat tricks with ``make``, since they are defined as rules,
294
+
which are expanded at runtime, rather than being defined while parsing.
295
+
296
+
For example, declaring and using your Fortran flags with this snippet will work
297
+
completelyfine:
298
+
299
+
```make
300
+
all:
301
+
echo$(FFLAGS)
302
+
303
+
FFLAGS = $(include_dirs) -O
304
+
include_dirs += -I./include
305
+
include_dirs += -I/opt/some_dep/include
306
+
```
307
+
308
+
You should find the expected (or maybe unexpected) printout after running ``make``
309
+
310
+
echo -I./include -I/opt/some_dep/include -O
311
+
-I./include -I/opt/some_dep/include -O
312
+
313
+
{% include note.html content="appending with ``+=`` to an undefined variable will produce a recursively expanded variable with this state being inherited for all further appending." %}
314
+
315
+
While, it seems like an interesting feature to use, it tends to lead to
316
+
surprising and expected outcomes. Usually, when defining variables like your
317
+
compiler, there is little reason to actually use the recursive expansion at all.
318
+
319
+
The same can easily be archived using the ``:=`` declaration:
320
+
321
+
```make
322
+
all:
323
+
echo$(FFLAGS)
324
+
325
+
include_dirs := -I./include
326
+
include_dirs += -I/opt/some_dep/include
327
+
FFLAGS := $(include_dirs) -O
328
+
```
329
+
330
+
{% include important.html content="always think of a ``Makefile`` as a whole set of rules, it must be parsed completely before any rule can be evaluated." %}
331
+
332
+
You can use whatever kind of variables you like most, mixing them should be done
333
+
carefully, of course. It is important to be aware of the differences between the
334
+
two kinds and the respective implications.
335
+
336
+
337
+
### Comments and whitespace
338
+
339
+
There are some caveats with whitespace and comments, which might pop up from
340
+
time to time when using ``make``. First, ``make`` does not know of any data
341
+
type except for strings and the default separator is just a space.
342
+
This means ``make`` will give a hard time trying to build a project which
343
+
has spaces in file names. If you encounter such case, renaming the file
344
+
is possibly the easiest solution at hand.
345
+
346
+
Another common problem is leading and trailing whitespace, once introduced,
347
+
``make`` will happily carry it along and it does in fact make a difference
348
+
when comparing strings in ``make``.
349
+
350
+
Those can be introduced by comments like
351
+
352
+
```make
353
+
prefix := /usr # path to install location
354
+
install:
355
+
echo "$(prefix)/lib"
356
+
```
357
+
358
+
While the comment will be correctly removed by ``make``, the trailing two spaces
359
+
are now part of the variable content. Run ``make`` and check that this is indeed
360
+
the case:
361
+
362
+
```
363
+
echo "/usr /lib"
364
+
/usr /lib
365
+
```
366
+
367
+
To solve this issue, you can either move the comment, or strip the whitespace with
368
+
the ``strip`` function instead. Alternatively, you could try to ``join`` the
369
+
strings.
370
+
371
+
```make
372
+
prefix := /usr # path to install location
373
+
install:
374
+
echo "$(strip $(prefix))/lib"
375
+
echo "$(join $(join $(prefix), /), lib)"
376
+
```
377
+
378
+
All in all, none of this solutions will make your ``Makefile`` more readable,
379
+
therefore, it is prudent to pay extra attention to whitespace and comments when
380
+
writing and using ``make``.
381
+
382
+
287
383
## The meson build system
288
384
289
385
After you have learned the basics of ``make``, which we call a low-level build
0 commit comments