diff options
author | Minijackson <minijackson@riseup.net> | 2020-10-13 14:46:56 +0200 |
---|---|---|
committer | Minijackson <minijackson@riseup.net> | 2020-10-13 14:46:56 +0200 |
commit | 65149417e1deb23f83726edfd41f3215ae0591e0 (patch) | |
tree | 90c6bcb4ad6dd9c597d04b51845e02d63c450237 /2020-10-13.md | |
parent | c9e775a44cb316d578827f333531f5101aa29658 (diff) | |
download | wtf-is-linux-slides-master.tar.gz wtf-is-linux-slides-master.zip |
Diffstat (limited to '2020-10-13.md')
-rw-r--r-- | 2020-10-13.md | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/2020-10-13.md b/2020-10-13.md new file mode 100644 index 0000000..f8a67f4 --- /dev/null +++ b/2020-10-13.md | |||
@@ -0,0 +1,432 @@ | |||
1 | --- | ||
2 | title: WTF is Linux | ||
3 | author: Rémi Nicole <remi.nicole@smile.fr> | ||
4 | date: 2020-10-13 | ||
5 | slide-level: 2 | ||
6 | aspectratio: 169 | ||
7 | |||
8 | theme: metropolis | ||
9 | colortheme: owl | ||
10 | beameroption: "show notes on second screen=right" | ||
11 | |||
12 | toc: true | ||
13 | highlightstyle: breezedark | ||
14 | lang: en-US | ||
15 | |||
16 | bibliography: ../bibliography.bib | ||
17 | --- | ||
18 | |||
19 | # Makefile primer | ||
20 | |||
21 | ## Goal | ||
22 | |||
23 | Make is a tool to create files | ||
24 | |||
25 | |||
26 | ::: notes | ||
27 | |||
28 | A Makefile is a file that will direct Make on how to create these files | ||
29 | |||
30 | ::: | ||
31 | |||
32 | ## Concepts---Rules[^rule-intro] | ||
33 | |||
34 | Target | ||
35 | : Usually the name of a file/directory that this rule creates | ||
36 | |||
37 | Prerequisites | ||
38 | : The files/directories that are needed to produce the target | ||
39 | |||
40 | Recipe | ||
41 | : The commands to execute in order to create the target | ||
42 | |||
43 | ```make | ||
44 | my_executable: source_1.c source_2.c | ||
45 | gcc source_1.c source_2.c -o my_executable | ||
46 | ``` | ||
47 | |||
48 | [^rule-intro]: <https://www.gnu.org/software/make/manual/make.html#Rules> | ||
49 | |||
50 | ::: notes | ||
51 | |||
52 | - The target can also be an action, but it is rarer | ||
53 | - If one of the prerequisite changes, Make figures out that the target needs to | ||
54 | be created again | ||
55 | |||
56 | ::: | ||
57 | |||
58 | ## Concepts---Variables[^variables] | ||
59 | |||
60 | Very similar to shell variables, but use `$(VAR)` to expand it. | ||
61 | |||
62 | ```make | ||
63 | MY_SOURCES = source_1.c source_2.c | ||
64 | |||
65 | my_executable: $(MY_SOURCES) | ||
66 | gcc $(MY_SOURCES) -o my_executable | ||
67 | ``` | ||
68 | |||
69 | [^variables]: <https://www.gnu.org/software/make/manual/make.html#Using-Variables> | ||
70 | |||
71 | ## Concepts---Implicit Variables[^implicit-variables] | ||
72 | |||
73 | Some variables are set implicitly by Make, for example: | ||
74 | |||
75 | `$(CC)`{.no_minted} | ||
76 | : The C compiler | ||
77 | |||
78 | `$(CXX)`{.no_minted} / `$(CPP)`{.no_minted} | ||
79 | : The C++ compiler | ||
80 | |||
81 | `$(RM)`{.no_minted} | ||
82 | : The `rm -f` command | ||
83 | |||
84 | `$(MAKE)`{.no_minted} | ||
85 | : The `make` command | ||
86 | |||
87 | [^implicit-variables]: <https://www.gnu.org/software/make/manual/make.html#Implicit-Variables> | ||
88 | |||
89 | ::: notes | ||
90 | |||
91 | Yes, you can call "make" inside of a Makefile | ||
92 | |||
93 | ::: | ||
94 | |||
95 | ## Concepts--Automatic Variables[^automatic-variables] | ||
96 | |||
97 | Some variables are set automatically per-rule, for example: | ||
98 | |||
99 | `$@`{.no_minted} | ||
100 | : The target of the current rule | ||
101 | |||
102 | `$<`{.no_minted} | ||
103 | : The first prerequisite of the current rule | ||
104 | |||
105 | `$^`{.no_minted} | ||
106 | : All prerequisites of the current rule | ||
107 | |||
108 | ... | ||
109 | |||
110 | [^automatic-variables]: <https://www.gnu.org/software/make/manual/make.html#Automatic-Variables> | ||
111 | |||
112 | ## Our example redone | ||
113 | |||
114 | ```make | ||
115 | MY_SOURCES = source_1.c source_2.c | ||
116 | |||
117 | my_executable: $(MY_SOURCES) | ||
118 | $(CC) $^ -o $@ | ||
119 | ``` | ||
120 | |||
121 | ## Relation with Buildroot | ||
122 | |||
123 | Buildroot uses Makefiles to: | ||
124 | |||
125 | - Figure out which packages to (re-)compile | ||
126 | - How to compile them | ||
127 | - Create the outputs (images, root filesystem, etc.) in general. | ||
128 | |||
129 | But it is heavily abstracted | ||
130 | |||
131 | # Setting up Buildroot for our modifications | ||
132 | |||
133 | ## For additional packages | ||
134 | |||
135 | - We create the directory `package/<company>` | ||
136 | - We put our additional packages in it | ||
137 | - We create the `my_company.mk` and `Config.in` files[^adding-project-specific-packages] | ||
138 | - And include the new `Config.in` in `package/Config.in` | ||
139 | |||
140 | [^adding-project-specific-packages]: | ||
141 | <https://buildroot.org/downloads/manual/manual.html#customize-packages> | ||
142 | |||
143 | ## Packages Makefile | ||
144 | |||
145 | ```makefile | ||
146 | include $(sort $(wildcard package/my_company/*/*.mk)) | ||
147 | ``` | ||
148 | |||
149 | ## Packages configuration file | ||
150 | |||
151 | In `package/my_company/Config.in`: | ||
152 | |||
153 | ```kconfig | ||
154 | source "package/my_company/my_package1/Config.in" | ||
155 | source "package/my_company/my_package2/Config.in" | ||
156 | source "package/my_company/.../Config.in" | ||
157 | # ... | ||
158 | ``` | ||
159 | |||
160 | ## Packages configuration file inclusion | ||
161 | |||
162 | In `package/Config.in`: | ||
163 | |||
164 | ```kconfig | ||
165 | # ---8<--- Rest of the configuration | ||
166 | |||
167 | # We add our own packages in our own submenu | ||
168 | menu "My Company packages" | ||
169 | # We just created this file | ||
170 | source "package/my_company/Config.in" | ||
171 | endmenu | ||
172 | |||
173 | endmenu # <-- Was here before, it's the "Target packages" submenu | ||
174 | ``` | ||
175 | |||
176 | ## For everything else | ||
177 | |||
178 | - We create the directory `board/<company>/<board>` | ||
179 | - We put our additional files, patches, configurations, scripts, etc. in it | ||
180 | |||
181 | ::: notes | ||
182 | |||
183 | In our case, the board would be `raspberrypi2`. | ||
184 | |||
185 | ::: | ||
186 | |||
187 | # Adding single files | ||
188 | |||
189 | ## Overlays | ||
190 | |||
191 | A file hierarchy from the root directory that is going to get copied on top of | ||
192 | the built system | ||
193 | |||
194 | Can be used for: | ||
195 | |||
196 | - Startup scripts | ||
197 | - Program configuration files | ||
198 | - Files containing data (like sound) | ||
199 | |||
200 | ::: notes | ||
201 | |||
202 | However, if a startup script, configuration file, or data file is tied to | ||
203 | a given package, it is usually better to install it with the package, instead | ||
204 | of using an overlay. | ||
205 | |||
206 | Overlays are more meant for files that are not tied to any specific package. | ||
207 | |||
208 | ::: | ||
209 | |||
210 | ## How to add an overlay | ||
211 | |||
212 | - Create the directory `board/<company>/<board>/rootfs_overlay` | ||
213 | - Add your file in that directory, as if it were the root directory | ||
214 | - Configure Buildroot (`make menuconfig`) and set | ||
215 | `BR2_ROOTFS_OVERLAY`[^overlay-config] to | ||
216 | `board/<company>/<board>/rootfs-overlay`. | ||
217 | |||
218 | [^overlay-config]: | ||
219 | Under "System configuration", "Root filesystem overlay directories" | ||
220 | |||
221 | # Adding packages | ||
222 | |||
223 | ## Packages---Structure | ||
224 | |||
225 | - Create the directory `package/<company>/<my-package>/` | ||
226 | - Create the file `package/<company>/<my-package>/Config.in`[^config-files] | ||
227 | - Create the file `package/<company>/<my-package>/<my-package>.mk`[^mk-files] | ||
228 | |||
229 | [^config-files]: <https://buildroot.org/downloads/manual/manual.html#_config_files> | ||
230 | |||
231 | [^mk-files]: <https://buildroot.org/downloads/manual/manual.html#_the_literal_mk_literal_file> | ||
232 | |||
233 | <!-- _____ --> | ||
234 | |||
235 | ::: notes | ||
236 | |||
237 | - The `Config.in` will allow Buildroot to add an option to install your | ||
238 | package. This will also specify your dependencies (what is needed to build or | ||
239 | run your package). | ||
240 | - The `<my-package>.mk` is a Makefile which instructs how to compile and | ||
241 | install your package. | ||
242 | |||
243 | ::: | ||
244 | |||
245 | ## Packages---Configuration | ||
246 | |||
247 | Example configuration: | ||
248 | |||
249 | ```kconfig | ||
250 | config BR2_PACKAGE_DUMMY_PACKAGE | ||
251 | bool "dummy package" | ||
252 | default n | ||
253 | depends on BR2_PACKAGE_BUSYBOX || BR2_PACKAGE_BASH | ||
254 | help | ||
255 | A dummy package for demonstration purposes | ||
256 | ``` | ||
257 | |||
258 | ## Packages---Makefile | ||
259 | |||
260 | Example Makefile configuration: | ||
261 | |||
262 | ```makefile | ||
263 | define DUMMY_PACKAGE_INSTALL_TARGET_CMDS | ||
264 | $(INSTALL) -m 0755 -D \ | ||
265 | $(DUMMY_PACKAGE_PKGDIR)/dummy_script.sh \ | ||
266 | $(TARGET_DIR)/usr/bin | ||
267 | endef | ||
268 | |||
269 | $(eval $(generic-package)) | ||
270 | ``` | ||
271 | |||
272 | ::: notes | ||
273 | |||
274 | - This "package" just installs a script that is in the same directory of the | ||
275 | `.mk` file | ||
276 | - It is important that all variables | ||
277 | |||
278 | ::: | ||
279 | |||
280 | ## Packages---More generic Makefile{.allowframebreaks} | ||
281 | |||
282 | ```makefile | ||
283 | LIBFOO_VERSION = 1.0 | ||
284 | LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz | ||
285 | LIBFOO_SITE = http://www.foosoftware.org/download | ||
286 | LIBFOO_LICENSE = GPL-3.0+ | ||
287 | LIBFOO_CONFIG_SCRIPTS = libfoo-config | ||
288 | LIBFOO_DEPENDENCIES = host-libaaa libbbb | ||
289 | |||
290 | # ---8<--- | ||
291 | ``` | ||
292 | |||
293 | \framebreak | ||
294 | |||
295 | If your package uses Makefiles to be built: | ||
296 | |||
297 | ```makefile | ||
298 | # ---8<--- | ||
299 | |||
300 | define LIBFOO_BUILD_CMDS | ||
301 | $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) all | ||
302 | endef | ||
303 | |||
304 | # ---8<--- | ||
305 | ``` | ||
306 | |||
307 | `$(@D)`{.makefile} is the directory containing the downloaded sources. | ||
308 | |||
309 | \framebreak | ||
310 | |||
311 | ```makefile | ||
312 | define LIBFOO_INSTALL_TARGET_CMDS | ||
313 | $(MAKE) \ | ||
314 | $(TARGET_CONFIGURE_OPTS) PREFIX=$(TARGET_DIR)/usr \ | ||
315 | -C $(@D) \ | ||
316 | install | ||
317 | # Or... | ||
318 | $(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(TARGET_DIR)/usr/lib | ||
319 | $(INSTALL) -d -m 0755 $(TARGET_DIR)/etc/foo.d | ||
320 | endef | ||
321 | |||
322 | $(eval $(generic-packages)) | ||
323 | ``` | ||
324 | |||
325 | ::: notes | ||
326 | |||
327 | - In this instances, our package is called "libfoo" | ||
328 | - `TARGET_CONFIGURE_OPTS` sets options like the compiler to use, the | ||
329 | compilation flags and other things | ||
330 | |||
331 | ::: | ||
332 | |||
333 | ## Packages---Notes | ||
334 | |||
335 | - This was for a "generic package" | ||
336 | - For package using common build frameworks (e.g. python, autotools, cmake, | ||
337 | etc.), some things are already done for you[^mk-files] | ||
338 | - Don't forget to include the package's `Config.in` in | ||
339 | `package/my_company/Config.in` | ||
340 | |||
341 | # Adding a service | ||
342 | |||
343 | ## Buildroot's Busybox init | ||
344 | |||
345 | Every script or executable that is named like `/etc/init.d/S<something>` is | ||
346 | going to be started on boot | ||
347 | |||
348 | Two solutions then: | ||
349 | |||
350 | - Add a script to the overlay (if not tied to one of your own package) | ||
351 | - Install it with your package in the `<PACKAGE>_INSTALL_TARGET_CMDS` | ||
352 | |||
353 | # Adding users | ||
354 | |||
355 | ## Using the board directory | ||
356 | |||
357 | - Create the file `board/<company>/<board>/users.txt`[^adding-users] | ||
358 | - Fill it with lines using the "makeusers" syntax[^makeusers-syntax] | ||
359 | - Set `BR2_ROOTFS_USERS_TABLES`[^users-conf] to `board/<company>/<board>/users.tx` | ||
360 | |||
361 | [^adding-users]: <https://buildroot.org/downloads/manual/manual.html#customize-users> | ||
362 | |||
363 | [^makeusers-syntax]: <https://buildroot.org/downloads/manual/manual.html#makeuser-syntax> | ||
364 | |||
365 | [^users-conf]: Under "System Configuration", "Path to the users tables" | ||
366 | |||
367 | ## Using the board directory---Example | ||
368 | |||
369 | ```kconfig | ||
370 | # ,---------------------- name | ||
371 | # | ,------------- group | ||
372 | # | | ,------ password | ||
373 | # | | | | ||
374 | # vvv vvvvvv v | ||
375 | foo -1 libfoo -1 * - - - LibFoo daemon | ||
376 | # ^^ ^^ ^^^^^^^^^^^^^ | ||
377 | # | | | | ||
378 | # | | '--- comment | ||
379 | # | '------------------- GID | ||
380 | # '----------------------------- UID | ||
381 | ``` | ||
382 | |||
383 | ::: notes | ||
384 | |||
385 | - If UID or GID is "-1", buildroot will select an unused number | ||
386 | - If password is "\*", then there is no password you cannot login as this user | ||
387 | (but you can still execute programs as this user) | ||
388 | |||
389 | ::: | ||
390 | |||
391 | ## In a package | ||
392 | |||
393 | Inside the `.mk` file. | ||
394 | |||
395 | ```makefile | ||
396 | define LIBFOO_USERS | ||
397 | foo -1 libfoo -1 * - - - LibFoo daemon | ||
398 | endef | ||
399 | ``` | ||
400 | |||
401 | # Saving the configuration | ||
402 | |||
403 | ## Why it is important | ||
404 | |||
405 | - Right now, every modification to the configuration (added packages, overlay, | ||
406 | etc.) is only in the build directory | ||
407 | - We want to save it so that people cloning our modified Buildroot can have the | ||
408 | same configuration | ||
409 | - Please often verify that your modifications are saved by deleting your | ||
410 | `output` directory, or downloading and compiling or project again. | ||
411 | |||
412 | ::: notes | ||
413 | |||
414 | - This is necessary for me (the reviewer) since I want to build exactly what you | ||
415 | have. | ||
416 | |||
417 | ::: | ||
418 | |||
419 | ## How to save the Buildroot configuration | ||
420 | |||
421 | Once you have done your configuration of Buildroot (`make menuconfig`), execute | ||
422 | these commands: | ||
423 | |||
424 | - Make sure the `BR2_DEFCONFIG` option[^defconfig-option] is set to | ||
425 | `configs/<my_company_board>_defconfig` | ||
426 | - Execute `make savedefconfig` to save it | ||
427 | |||
428 | And commit your changes | ||
429 | |||
430 | [^defconfig-option]: Under "Build options", "Location to save buildroot config" | ||
431 | |||
432 | # References | ||