]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/boot/efi/meson.build
tree-wide: drop license boilerplate
[thirdparty/systemd.git] / src / boot / efi / meson.build
1 # SPDX-License-Identifier: LGPL-2.1+
2 #
3 # Copyright 2017 Zbigniew Jędrzejewski-Szmek
4
5 efi_headers = files('''
6 console.h
7 disk.h
8 graphics.h
9 linux.h
10 measure.h
11 pe.h
12 splash.h
13 util.h
14 shim.h
15 '''.split())
16
17 common_sources = '''
18 disk.c
19 graphics.c
20 measure.c
21 pe.c
22 util.c
23 '''.split()
24
25 systemd_boot_sources = '''
26 boot.c
27 console.c
28 shim.c
29 '''.split()
30
31 stub_sources = '''
32 linux.c
33 splash.c
34 stub.c
35 '''.split()
36
37 if conf.get('ENABLE_EFI') == 1 and get_option('gnu-efi') != 'false'
38 efi_cc = get_option('efi-cc')
39 efi_ld = get_option('efi-ld')
40
41 efi_incdir = get_option('efi-includedir')
42 have_header = (gnu_efi_arch != '' and
43 cc.has_header('@0@/@1@/efibind.h'.format(efi_incdir, gnu_efi_arch)))
44
45 if have_header and EFI_MACHINE_TYPE_NAME == ''
46 error('gnu-efi is available, but EFI_MACHINE_TYPE_NAME is unknown')
47 endif
48
49 efi_libdir = get_option('efi-libdir')
50 if efi_libdir == ''
51 cmd = 'cd /usr/lib/$(@0@ -print-multi-os-directory) && pwd'.format(efi_cc)
52 ret = run_command('sh', '-c', cmd)
53 if ret.returncode() == 0
54 efi_libdir = ret.stdout().strip()
55 endif
56 endif
57
58 have_gnu_efi = have_header and efi_libdir != ''
59 else
60 have_gnu_efi = false
61 endif
62
63 if get_option('gnu-efi') == 'true' and not have_gnu_efi
64 error('gnu-efi support requested, but headers were not found')
65 endif
66
67 if have_gnu_efi
68 efi_conf = configuration_data()
69 efi_conf.set_quoted('PACKAGE_VERSION', meson.project_version())
70 efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
71 efi_conf.set10('ENABLE_TPM', get_option('tpm'))
72 efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
73
74 efi_config_h = configure_file(
75 output : 'efi_config.h',
76 configuration : efi_conf)
77
78 objcopy = find_program('objcopy')
79
80 efi_ldsdir = get_option('efi-ldsdir')
81 arch_lds = 'elf_@0@_efi.lds'.format(gnu_efi_arch)
82 if efi_ldsdir == ''
83 efi_ldsdir = join_paths(efi_libdir, 'gnuefi')
84 cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
85 if cmd.returncode() != 0
86 efi_ldsdir = efi_libdir
87 cmd = run_command('test', '-f', join_paths(efi_ldsdir, arch_lds))
88 if cmd.returncode() != 0
89 error('Cannot find @0@'.format(arch_lds))
90 endif
91 endif
92 endif
93
94 message('efi-libdir: "@0@"'.format(efi_libdir))
95 message('efi-ldsdir: "@0@"'.format(efi_ldsdir))
96 message('efi-includedir: "@0@"'.format(efi_incdir))
97
98 compile_args = ['-Wall',
99 '-Wextra',
100 '-std=gnu90',
101 '-nostdinc',
102 '-ggdb', '-O0',
103 '-fpic',
104 '-fshort-wchar',
105 '-ffreestanding',
106 '-fno-strict-aliasing',
107 '-fno-stack-protector',
108 '-Wsign-compare',
109 '-Wno-missing-field-initializers',
110 '-isystem', efi_incdir,
111 '-isystem', join_paths(efi_incdir, gnu_efi_arch),
112 '-include', efi_config_h]
113 if efi_arch == 'x86_64'
114 compile_args += ['-mno-red-zone',
115 '-mno-sse',
116 '-mno-mmx',
117 '-DEFI_FUNCTION_WRAPPER',
118 '-DGNU_EFI_USE_MS_ABI']
119 elif efi_arch == 'ia32'
120 compile_args += ['-mno-sse',
121 '-mno-mmx']
122 endif
123
124 efi_ldflags = ['-T',
125 join_paths(efi_ldsdir, arch_lds),
126 '-shared',
127 '-Bsymbolic',
128 '-nostdlib',
129 '-znocombreloc',
130 '-L', efi_libdir,
131 join_paths(efi_ldsdir, 'crt0-efi-@0@.o'.format(gnu_efi_arch))]
132 if efi_arch == 'aarch64' or efi_arch == 'arm'
133 # Aarch64 and ARM32 don't have an EFI capable objcopy. Use 'binary'
134 # instead, and add required symbols manually.
135 efi_ldflags += ['--defsym=EFI_SUBSYSTEM=0xa']
136 efi_format = ['-O', 'binary']
137 else
138 efi_format = ['--target=efi-app-@0@'.format(gnu_efi_arch)]
139 endif
140
141 systemd_boot_objects = []
142 stub_objects = []
143 foreach file : common_sources + systemd_boot_sources + stub_sources
144 o_file = custom_target(file + '.o',
145 input : file,
146 output : file + '.o',
147 command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@']
148 + compile_args,
149 depend_files : efi_headers)
150 if (common_sources + systemd_boot_sources).contains(file)
151 systemd_boot_objects += [o_file]
152 endif
153 if (common_sources + stub_sources).contains(file)
154 stub_objects += [o_file]
155 endif
156 endforeach
157
158 libgcc_file_name = run_command(efi_cc, '-print-libgcc-file-name').stdout().strip()
159 systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
160 stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
161 no_undefined_symbols = find_program('no-undefined-symbols.sh')
162
163 foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects],
164 ['stub.so', stub_efi_name, stub_objects]]
165 so = custom_target(
166 tuple[0],
167 input : tuple[2],
168 output : tuple[0],
169 command : [efi_ld, '-o', '@OUTPUT@'] +
170 efi_ldflags + tuple[2] +
171 ['-lefi', '-lgnuefi', libgcc_file_name])
172
173 test('no-undefined-symbols-' + tuple[0],
174 no_undefined_symbols,
175 args : [so])
176
177 stub = custom_target(
178 tuple[1],
179 input : so,
180 output : tuple[1],
181 command : [objcopy,
182 '-j', '.text',
183 '-j', '.sdata',
184 '-j', '.data',
185 '-j', '.dynamic',
186 '-j', '.dynsym',
187 '-j', '.rel',
188 '-j', '.rela',
189 '-j', '.reloc']
190 + efi_format +
191 ['@INPUT@', '@OUTPUT@'],
192 install : true,
193 install_dir : bootlibdir)
194
195 set_variable(tuple[0].underscorify(), so)
196 set_variable(tuple[0].underscorify() + '_stub', stub)
197 endforeach
198 endif
199
200 ############################################################
201
202 if have_gnu_efi
203 test_efi_disk_img = custom_target(
204 'test-efi-disk.img',
205 input : [systemd_boot_so, stub_so_stub],
206 output : 'test-efi-disk.img',
207 command : [test_efi_create_disk_sh, '@OUTPUT@',
208 '@INPUT0@', '@INPUT1@', splash_bmp])
209 endif