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