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