]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/boot/efi/meson.build
dynamically load compression libraries
[thirdparty/systemd.git] / src / boot / efi / meson.build
CommitLineData
db9ecf05 1# SPDX-License-Identifier: LGPL-2.1-or-later
3a726fcd 2
776fabbc 3efi_config_h_dir = meson.current_build_dir()
320266b9 4efi_addon = ''
776fabbc 5
2d7c857d
JJ
6libefitest = static_library(
7 'efitest',
8 files(
9 'bcd.c',
10 'efi-string.c',
11 ),
12 build_by_default : false,
13 include_directories : [
14 basic_includes,
15 include_directories('.'),
16 ],
17 dependencies : userspace)
2c7c68e4 18
2d7c857d
JJ
19efitest_base = {
20 'link_with' : [
21 libefitest,
22 libshared,
23 ],
24}
25efi_test_template = test_template + efitest_base
26efi_fuzz_template = fuzz_template + efitest_base
2c7c68e4 27
2d7c857d
JJ
28executables += [
29 efi_test_template + {
30 'sources' : files('test-bcd.c'),
3fc72d54 31 'dependencies' : libzstd_cflags,
2d7c857d
JJ
32 'conditions' : ['ENABLE_BOOTLOADER', 'HAVE_ZSTD'],
33 },
34 efi_test_template + {
35 'sources' : files('test-efi-string.c'),
36 'conditions' : ['ENABLE_BOOTLOADER'],
37 },
38 efi_fuzz_template + {
39 'sources' : files('fuzz-bcd.c'),
40 },
41 efi_fuzz_template + {
42 'sources' : files('fuzz-efi-string.c'),
43 },
e9e40862
JJ
44 efi_fuzz_template + {
45 'sources' : files('fuzz-efi-osrel.c'),
46 },
2d7c857d
JJ
47 efi_fuzz_template + {
48 'sources' : files('fuzz-efi-printf.c'),
49 },
50]
2c7c68e4 51
dfca5587 52if conf.get('ENABLE_BOOTLOADER') != 1
9cf75222
JJ
53 subdir_done()
54endif
55
9cf75222 56efi_conf = configuration_data()
9cf75222
JJ
57efi_conf.set10('ENABLE_TPM', get_option('tpm'))
58
59foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
60 c = get_option('efi-' + ctype).split(',')
61 efi_conf.set(ctype.underscorify().to_upper(), 'EFI_TEXT_ATTR(@0@, @1@)'.format(
62 'EFI_' + c[0].strip().underscorify().to_upper(),
63 'EFI_' + c[1].strip().underscorify().to_upper()))
64endforeach
65
252b6b1b
JJ
66if meson.is_cross_build() and get_option('sbat-distro') == 'auto'
67 warning('Auto detection of SBAT information not supported when cross-building, disabling SBAT.')
68elif get_option('sbat-distro') != ''
9cf75222 69 efi_conf.set_quoted('SBAT_PROJECT', meson.project_name())
ea2a57be 70 efi_conf.set_quoted('PROJECT_VERSION', meson.project_version().split('~')[0])
3f6ce3d4 71 efi_conf.set_quoted('VERSION_TAG', version_tag)
9cf75222
JJ
72 efi_conf.set('PROJECT_URL', conf.get('PROJECT_URL'))
73 if get_option('sbat-distro-generation') < 1
74 error('SBAT Distro Generation must be a positive integer')
df7cacae 75 endif
9cf75222
JJ
76 efi_conf.set('SBAT_DISTRO_GENERATION', get_option('sbat-distro-generation'))
77 foreach sbatvar : [['sbat-distro', 'ID'],
78 ['sbat-distro-summary', 'NAME'],
79 ['sbat-distro-url', 'BUG_REPORT_URL']]
80 value = get_option(sbatvar[0])
252b6b1b 81 if (value == '' or value == 'auto') and not meson.is_cross_build()
9cf75222 82 cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1])
68a06b3c 83 value = run_command(sh, '-c', cmd, check: true).stdout().strip()
4b4ee0f7 84 endif
9cf75222
JJ
85 if value == ''
86 error('Required @0@ option not set and autodetection failed'.format(sbatvar[0]))
53f69d67 87 endif
9cf75222 88 efi_conf.set_quoted(sbatvar[0].underscorify().to_upper(), value)
e313e934
JJ
89 endforeach
90
9cf75222
JJ
91 pkgname = get_option('sbat-distro-pkgname')
92 if pkgname == ''
93 pkgname = meson.project_name()
9137c03c 94 endif
9cf75222 95 efi_conf.set_quoted('SBAT_DISTRO_PKGNAME', pkgname)
9137c03c 96
9cf75222
JJ
97 pkgver = get_option('sbat-distro-version')
98 if pkgver == ''
c78b611e
JJ
99 # This is determined during build, not configuration, so we can't display it yet.
100 efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION')
101 else
102 efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver)
37efbbd8 103 endif
ce4121c6 104endif
37efbbd8 105
2afeaf16 106summary({'UEFI architectures' : efi_arch + (efi_arch_alt == '' ? '' : ', ' + efi_arch_alt)},
dfca5587 107 section : 'UEFI')
3f871f12 108
e4e44a01
ZJS
109if efi_conf.get('SBAT_DISTRO', '') != ''
110 summary({
111 'SBAT distro': efi_conf.get('SBAT_DISTRO'),
112 'SBAT distro generation': efi_conf.get('SBAT_DISTRO_GENERATION'),
4122d686 113 'SBAT distro version': efi_conf.get('SBAT_DISTRO_VERSION'),
e4e44a01
ZJS
114 'SBAT distro summary': efi_conf.get('SBAT_DISTRO_SUMMARY'),
115 'SBAT distro URL': efi_conf.get('SBAT_DISTRO_URL')},
dfca5587 116 section : 'UEFI')
e4e44a01
ZJS
117endif
118
dfca5587
JJ
119configure_file(
120 output : 'efi_config.h',
121 configuration : efi_conf)
65dcf9f9 122
dfca5587 123############################################################
65dcf9f9 124
3c1eee5b
ZJS
125efi_includes = [
126 build_dir_include,
127 fundamental_include,
128 include_directories('.'),
129]
2afeaf16
JJ
130
131efi_c_args = [
132 '-DSD_BOOT=1',
133 '-ffreestanding',
134 '-fno-strict-aliasing',
135 '-fshort-wchar',
136 '-include', 'efi_config.h',
137]
138
139efi_c_args += cc.get_supported_arguments(
140 '-fwide-exec-charset=UCS2',
141 # gcc docs says this is required for ms_abi to work correctly.
142 '-maccumulate-outgoing-args',
48e1b2c2 143 '-mstack-protector-guard=global',
2afeaf16
JJ
144)
145
c4ad9b23
JJ
146# Debug information has little value in release builds as no normal human being knows
147# how to attach a debugger to EFI binaries running on real hardware. Anyone who does
148# certainly has the means to do their own dev build.
149if get_option('mode') == 'developer' and get_option('debug')
150 efi_c_args += '-DEFI_DEBUG'
151endif
152
2afeaf16 153efi_c_ld_args = [
2afeaf16
JJ
154 '-lgcc',
155 '-nostdlib',
156 '-static-pie',
157 '-Wl,--entry=efi_main',
158 '-Wl,--fatal-warnings',
159
a8b53f4f
JJ
160 # These flags should be passed by -static-pie, but for whatever reason the flag translation
161 # is not enabled on all architectures. Not passing `-static` would just allow the linker to
162 # use dynamic libraries, (which we can't/don't use anyway). But if `-pie` is missing and the
163 # gcc build does not default to `-pie` we get a regular (no-pie) binary that will be
164 # rightfully rejected by elf2efi. Note that meson also passes `-pie` to the linker driver,
165 # but it is overridden by our `-static-pie`. We also need to pass these directly to the
166 # linker as `-static`+`-pie` seem to get translated differently.
167 '-Wl,-static,-pie,--no-dynamic-linker,-z,text',
2afeaf16
JJ
168
169 # EFI has 4KiB pages.
170 '-z', 'common-page-size=4096',
171 '-z', 'max-page-size=4096',
172
173 '-z', 'noexecstack',
823bf39a 174 '-z', 'relro',
142f0c61 175 '-z', 'separate-code',
2afeaf16
JJ
176]
177
0b042d3d
JJ
178efi_c_ld_args += cc.get_supported_link_arguments(
179 # binutils >= 2.38
180 '-Wl,-z,nopack-relative-relocs',
181)
eff91e2f 182
2afeaf16
JJ
183# efi_c_args is explicitly passed to targets so that they can override distro-provided flags
184# that should not be used for EFI binaries.
185efi_disabled_c_args = cc.get_supported_arguments(
186 '-fcf-protection=none',
187 '-fno-asynchronous-unwind-tables',
188 '-fno-exceptions',
2afeaf16
JJ
189 '-fno-unwind-tables',
190)
2afeaf16
JJ
191efi_override_options = [
192 'b_coverage=false',
193 'b_pgo=off',
2afeaf16
JJ
194]
195
1e7ff4ba
JJ
196if get_option('b_sanitize') == 'undefined'
197 efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize-link-runtime')
198else
199 efi_disabled_c_args += cc.get_supported_arguments('-fno-sanitize=all')
200 efi_override_options += 'b_sanitize=none'
201endif
202
203efi_c_args += efi_disabled_c_args
204efi_c_ld_args += efi_disabled_c_args
205
2afeaf16
JJ
206if cc.get_id() == 'clang'
207 # clang is too picky sometimes.
208 efi_c_args += '-Wno-unused-command-line-argument'
209 efi_c_ld_args += '-Wno-unused-command-line-argument'
210endif
211
b87d6da4 212efi_arch_c_args = {
2afeaf16
JJ
213 'aarch64' : ['-mgeneral-regs-only'],
214 'arm' : ['-mgeneral-regs-only'],
7ea44f17
JJ
215 # Pass -m64/32 explicitly to make building on x32 work.
216 'x86_64' : ['-m64', '-march=x86-64', '-mno-red-zone', '-mgeneral-regs-only'],
217 'x86' : ['-m32', '-march=i686', '-mgeneral-regs-only', '-malign-double'],
218}
219efi_arch_c_ld_args = {
220 # libgcc is not compiled with -fshort-wchar, but it does not use it anyways,
221 # so it's fine to link against it.
0b042d3d 222 'arm' : cc.get_supported_link_arguments('-Wl,--no-wchar-size-warning'),
7ea44f17
JJ
223 'x86_64' : ['-m64'],
224 'x86' : ['-m32'],
b87d6da4 225}
2afeaf16 226
0b042d3d
JJ
227linker_sanity_code = 'void a(void) {}; void _start(void) { a(); }'
228linker_sanity_args = ['-nostdlib', '-Wl,--fatal-warnings']
229if not cc.links(linker_sanity_code,
230 name : 'linker supports -static-pie',
231 args : [linker_sanity_args, '-static-pie'])
232 error('Linker does not support -static-pie.')
233endif
234
235# https://github.com/llvm/llvm-project/issues/67152
236if not cc.links(linker_sanity_code,
237 name : 'linker supports LTO with -nostdlib',
238 args : [linker_sanity_args, '-flto'])
239 efi_c_args += '-fno-lto'
240 efi_c_ld_args += '-fno-lto'
241endif
242
243# https://github.com/llvm/llvm-project/issues/61101
244if efi_cpu_family_alt == 'x86' and not cc.links(linker_sanity_code,
245 name : 'linker supports LTO with -nostdlib (x86)',
246 args : [linker_sanity_args, '-flto', '-m32'])
247 efi_arch_c_args += { 'x86' : efi_arch_c_args['x86'] + '-fno-lto' }
248 efi_arch_c_ld_args += { 'x86' : efi_arch_c_ld_args['x86'] + '-fno-lto' }
249endif
250
2afeaf16
JJ
251############################################################
252
dfca5587 253libefi_sources = files(
e6b0cfad 254 'console.c',
e6d7dc9a 255 'device-path-util.c',
65dcf9f9 256 'devicetree.c',
ba279392 257 'drivers.c',
9080ffd4 258 'efi-string.c',
65dcf9f9 259 'graphics.c',
46ce6cf7 260 'initrd.c',
c2c62035 261 'log.c',
65dcf9f9 262 'measure.c',
0a1d8ac7 263 'part-discovery.c',
65dcf9f9 264 'pe.c',
0a1d8ac7 265 'random-seed.c',
65dcf9f9 266 'secure-boot.c',
05c9f9c2 267 'shim.c',
1e66a233 268 'ticks.c',
b3c5a707 269 'util.c',
ba279392 270 'vmm.c',
b3c5a707 271)
65dcf9f9 272
b3c5a707 273systemd_boot_sources = files(
65dcf9f9 274 'boot.c',
b3c5a707 275)
65dcf9f9 276
b3c5a707 277stub_sources = files(
65dcf9f9 278 'cpio.c',
ba2a105c 279 'linux.c',
65dcf9f9 280 'splash.c',
b3c5a707
JJ
281 'stub.c',
282)
65dcf9f9 283
f644ea3e
LB
284addon_sources = files(
285 'addon.c',
286)
287
1e7ff4ba
JJ
288if get_option('b_sanitize') == 'undefined'
289 libefi_sources += files('ubsan.c')
290endif
291
dfca5587 292if host_machine.cpu_family() in ['x86', 'x86_64']
b3c5a707 293 stub_sources += files('linux_x86.c')
65dcf9f9
ZJS
294endif
295
77fcf28c 296# BCD parser only makes sense on arches that Windows supports.
dfca5587 297if host_machine.cpu_family() in ['aarch64', 'arm', 'x86_64', 'x86']
b3c5a707 298 systemd_boot_sources += files('bcd.c')
77fcf28c 299endif
2afeaf16
JJ
300
301boot_targets = []
302efi_elf_binaries = []
303efi_archspecs = [
304 {
305 'arch' : efi_arch,
7ea44f17
JJ
306 'c_args' : [
307 efi_c_args,
308 '-DEFI_MACHINE_TYPE_NAME="' + efi_arch + '"',
309 efi_arch_c_args.get(host_machine.cpu_family(), []),
310 ],
311 'link_args' : [
312 efi_c_ld_args,
313 efi_arch_c_ld_args.get(host_machine.cpu_family(), []),
314 ],
2afeaf16
JJ
315 },
316]
317if efi_arch_alt != ''
318 efi_archspecs += {
319 'arch' : efi_arch_alt,
7ea44f17
JJ
320 'c_args' : [
321 efi_c_args,
322 '-DEFI_MACHINE_TYPE_NAME="' + efi_arch_alt + '"',
323 efi_arch_c_args.get(efi_cpu_family_alt, []),
324 ],
325 'link_args' : [
326 efi_c_ld_args,
327 efi_arch_c_ld_args.get(efi_cpu_family_alt, []),
328 ],
2afeaf16
JJ
329 }
330endif
331
332foreach archspec : efi_archspecs
333 libefi = static_library(
334 'efi' + archspec['arch'],
335 fundamental_sources,
336 libefi_sources,
56a0b906 337 version_h,
2afeaf16
JJ
338 include_directories : efi_includes,
339 c_args : archspec['c_args'],
2afeaf16
JJ
340 gnu_symbol_visibility : 'hidden',
341 override_options : efi_override_options,
342 pic : true)
343
0c491d0f
YW
344 kwargs = {
345 'include_directories' : efi_includes,
346 'c_args' : archspec['c_args'],
347 'link_args' : archspec['link_args'],
0c491d0f
YW
348 'gnu_symbol_visibility' : 'hidden',
349 'override_options' : efi_override_options,
350 'pie' : true,
351 }
352
2afeaf16
JJ
353 efi_elf_binaries += executable(
354 'systemd-boot' + archspec['arch'],
56a0b906 355 sources : [systemd_boot_sources, version_h],
0b042d3d 356 link_with : libefi,
2afeaf16 357 name_suffix : 'elf',
0c491d0f 358 kwargs : kwargs)
2afeaf16
JJ
359
360 efi_elf_binaries += executable(
361 'linux' + archspec['arch'],
56a0b906 362 sources : [stub_sources, version_h],
0b042d3d 363 link_with : libefi,
2afeaf16 364 name_suffix : 'elf.stub',
0c491d0f 365 kwargs : kwargs)
f644ea3e
LB
366
367 efi_elf_binaries += executable(
368 'addon' + archspec['arch'],
56a0b906 369 sources : [addon_sources, version_h],
f644ea3e 370 name_suffix : 'elf.stub',
0c491d0f 371 kwargs : kwargs)
2afeaf16
JJ
372endforeach
373
374foreach efi_elf_binary : efi_elf_binaries
816df466 375 name = efi_elf_binary.name()
f644ea3e
LB
376 name += name.startswith('systemd-boot') ? '.efi' : '.efi.stub'
377 # For the addon, given it's empty, we need to explicitly reserve space in the header to account for
378 # the sections that ukify will add.
d0bbe324 379 minimum_sections = name.endswith('.stub') ? '15' : '0'
3f80c139 380 exe = custom_target(
2afeaf16
JJ
381 name,
382 output : name,
383 input : efi_elf_binary,
384 install : true,
385 install_dir : bootlibdir,
386 install_tag : 'systemd-boot',
387 command : [
388 elf2efi_py,
ea2a57be 389 '--version-major=' + meson.project_version().split('~')[0],
2afeaf16
JJ
390 '--version-minor=0',
391 '--efi-major=1',
392 '--efi-minor=1',
393 '--subsystem=10',
f644ea3e 394 '--minimum-sections=' + minimum_sections,
898e9edc 395 '--copy-sections=.sbat,.sdmagic,.osrel',
2afeaf16
JJ
396 '@INPUT@',
397 '@OUTPUT@',
398 ])
3f80c139
ZJS
399 boot_targets += exe
400 if name.startswith('linux')
401 boot_stubs += exe
402 endif
320266b9
ZJS
403
404 # This is supposed to match exactly one time
405 if name == 'addon@0@.efi.stub'.format(efi_arch)
406 efi_addon = exe.full_path()
407 endif
2afeaf16
JJ
408endforeach
409
410alias_target('systemd-boot', boot_targets)