]>
Commit | Line | Data |
---|---|---|
65a109ab LE |
1 | # Shell script that defines functions for determining some environmental |
2 | # characteristics for the edk2 "build" utility. | |
3 | # | |
4 | # This script is meant to be sourced, in a bash environment. | |
5 | # | |
6 | # Copyright (C) 2019 Red Hat, Inc. | |
7 | # | |
8 | # This program and the accompanying materials are licensed and made available | |
9 | # under the terms and conditions of the BSD License that accompanies this | |
10 | # distribution. The full text of the license may be found at | |
11 | # <http://opensource.org/licenses/bsd-license.php>. | |
12 | # | |
13 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT | |
14 | # WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
15 | ||
16 | ||
17 | # Verify whether the QEMU system emulation target is supported by the UEFI spec | |
18 | # and edk2. Print a message to the standard error, and return with nonzero | |
19 | # status, if verification fails. | |
20 | # | |
21 | # Parameters: | |
22 | # $1: QEMU system emulation target | |
23 | qemu_edk2_verify_arch() | |
24 | { | |
25 | local emulation_target="$1" | |
26 | local program_name=$(basename -- "$0") | |
27 | ||
28 | case "$emulation_target" in | |
29 | (arm|aarch64|i386|x86_64) | |
30 | ;; | |
31 | (*) | |
32 | printf '%s: unknown/unsupported QEMU system emulation target "%s"\n' \ | |
33 | "$program_name" "$emulation_target" >&2 | |
34 | return 1 | |
35 | ;; | |
36 | esac | |
37 | } | |
38 | ||
39 | ||
40 | # Translate the QEMU system emulation target to the edk2 architecture | |
41 | # identifier. Print the result to the standard output. | |
42 | # | |
43 | # Parameters: | |
44 | # $1: QEMU system emulation target | |
45 | qemu_edk2_get_arch() | |
46 | { | |
47 | local emulation_target="$1" | |
48 | ||
49 | if ! qemu_edk2_verify_arch "$emulation_target"; then | |
50 | return 1 | |
51 | fi | |
52 | ||
53 | case "$emulation_target" in | |
54 | (arm) | |
55 | printf 'ARM\n' | |
56 | ;; | |
57 | (aarch64) | |
58 | printf 'AARCH64\n' | |
59 | ;; | |
60 | (i386) | |
61 | printf 'IA32\n' | |
62 | ;; | |
63 | (x86_64) | |
64 | printf 'X64\n' | |
65 | ;; | |
66 | esac | |
67 | } | |
68 | ||
69 | ||
70 | # Translate the QEMU system emulation target to the gcc cross-compilation | |
71 | # architecture identifier. Print the result to the standard output. | |
72 | # | |
73 | # Parameters: | |
74 | # $1: QEMU system emulation target | |
75 | qemu_edk2_get_gcc_arch() | |
76 | { | |
77 | local emulation_target="$1" | |
78 | ||
79 | if ! qemu_edk2_verify_arch "$emulation_target"; then | |
80 | return 1 | |
81 | fi | |
82 | ||
83 | case "$emulation_target" in | |
84 | (arm|aarch64|x86_64) | |
85 | printf '%s\n' "$emulation_target" | |
86 | ;; | |
87 | (i386) | |
88 | printf 'i686\n' | |
89 | ;; | |
90 | esac | |
91 | } | |
92 | ||
93 | ||
94 | # Determine the gcc cross-compiler prefix (if any) for use with the edk2 | |
95 | # toolchain. Print the result to the standard output. | |
96 | # | |
97 | # Parameters: | |
98 | # $1: QEMU system emulation target | |
99 | qemu_edk2_get_cross_prefix() | |
100 | { | |
101 | local emulation_target="$1" | |
102 | local gcc_arch | |
103 | local host_arch | |
104 | ||
105 | if ! gcc_arch=$(qemu_edk2_get_gcc_arch "$emulation_target"); then | |
106 | return 1 | |
107 | fi | |
108 | ||
109 | host_arch=$(uname -m) | |
110 | ||
111 | if [ "$gcc_arch" == "$host_arch" ] || | |
112 | ( [ "$gcc_arch" == i686 ] && [ "$host_arch" == x86_64 ] ); then | |
113 | # no cross-compiler needed | |
114 | : | |
47fee64b PMD |
115 | elif ( [ -e /etc/debian_version ] && [ "$gcc_arch" == arm ] ); then |
116 | # force soft-float cross-compiler on Debian | |
117 | printf 'arm-linux-gnueabi-' | |
65a109ab LE |
118 | else |
119 | printf '%s-linux-gnu-\n' "$gcc_arch" | |
120 | fi | |
121 | } | |
122 | ||
123 | ||
124 | # Determine the edk2 toolchain tag for the QEMU system emulation target. Print | |
125 | # the result to the standard output. Print a message to the standard error, and | |
126 | # return with nonzero status, if the (conditional) gcc version check fails. | |
127 | # | |
128 | # Parameters: | |
129 | # $1: QEMU system emulation target | |
130 | qemu_edk2_get_toolchain() | |
131 | { | |
132 | local emulation_target="$1" | |
133 | local program_name=$(basename -- "$0") | |
134 | local cross_prefix | |
135 | local gcc_version | |
136 | ||
137 | if ! qemu_edk2_verify_arch "$emulation_target"; then | |
138 | return 1 | |
139 | fi | |
140 | ||
141 | case "$emulation_target" in | |
142 | (arm|aarch64) | |
143 | printf 'GCC5\n' | |
144 | ;; | |
145 | ||
146 | (i386|x86_64) | |
147 | if ! cross_prefix=$(qemu_edk2_get_cross_prefix "$emulation_target"); then | |
148 | return 1 | |
149 | fi | |
150 | ||
151 | gcc_version=$("${cross_prefix}gcc" -v 2>&1 | tail -1 | awk '{print $3}') | |
152 | # Run "git-blame" on "OvmfPkg/build.sh" in edk2 for more information on | |
153 | # the mapping below. | |
154 | case "$gcc_version" in | |
461de3c5 | 155 | ([1-3].*|4.[0-7].*) |
65a109ab LE |
156 | printf '%s: unsupported gcc version "%s"\n' \ |
157 | "$program_name" "$gcc_version" >&2 | |
158 | return 1 | |
159 | ;; | |
65a109ab LE |
160 | (4.8.*) |
161 | printf 'GCC48\n' | |
162 | ;; | |
163 | (4.9.*|6.[0-2].*) | |
164 | printf 'GCC49\n' | |
165 | ;; | |
166 | (*) | |
167 | printf 'GCC5\n' | |
168 | ;; | |
169 | esac | |
170 | ;; | |
171 | esac | |
172 | } | |
173 | ||
174 | ||
175 | # Determine the name of the environment variable that exposes the | |
176 | # cross-compiler prefix to the edk2 "build" utility. Print the result to the | |
177 | # standard output. | |
178 | # | |
179 | # Parameters: | |
180 | # $1: QEMU system emulation target | |
181 | qemu_edk2_get_cross_prefix_var() | |
182 | { | |
183 | local emulation_target="$1" | |
184 | local edk2_toolchain | |
185 | local edk2_arch | |
186 | ||
187 | if ! edk2_toolchain=$(qemu_edk2_get_toolchain "$emulation_target"); then | |
188 | return 1 | |
189 | fi | |
190 | ||
191 | case "$emulation_target" in | |
192 | (arm|aarch64) | |
193 | if ! edk2_arch=$(qemu_edk2_get_arch "$emulation_target"); then | |
194 | return 1 | |
195 | fi | |
196 | printf '%s_%s_PREFIX\n' "$edk2_toolchain" "$edk2_arch" | |
197 | ;; | |
198 | (i386|x86_64) | |
199 | printf '%s_BIN\n' "$edk2_toolchain" | |
200 | ;; | |
201 | esac | |
202 | } | |
203 | ||
204 | ||
205 | # Set and export the environment variable(s) necessary for cross-compilation, | |
206 | # whenever needed by the edk2 "build" utility. | |
207 | # | |
208 | # Parameters: | |
209 | # $1: QEMU system emulation target | |
210 | qemu_edk2_set_cross_env() | |
211 | { | |
212 | local emulation_target="$1" | |
213 | local cross_prefix | |
214 | local cross_prefix_var | |
215 | ||
216 | if ! cross_prefix=$(qemu_edk2_get_cross_prefix "$emulation_target"); then | |
217 | return 1 | |
218 | fi | |
219 | ||
220 | if [ -z "$cross_prefix" ]; then | |
221 | # Nothing to do. | |
222 | return 0 | |
223 | fi | |
224 | ||
225 | if ! cross_prefix_var=$(qemu_edk2_get_cross_prefix_var \ | |
226 | "$emulation_target"); then | |
227 | return 1 | |
228 | fi | |
229 | ||
230 | eval "export $cross_prefix_var=\$cross_prefix" | |
231 | } | |
fd75d2c2 LE |
232 | |
233 | ||
234 | # Determine the "-n" option argument (that is, the number of modules to build | |
235 | # in parallel) for the edk2 "build" utility. Print the result to the standard | |
236 | # output. | |
237 | # | |
238 | # Parameters: | |
239 | # $1: the value of the MAKEFLAGS variable | |
240 | qemu_edk2_get_thread_count() | |
241 | { | |
242 | local makeflags="$1" | |
243 | ||
244 | if [[ "$makeflags" == *--jobserver-auth=* ]] || | |
245 | [[ "$makeflags" == *--jobserver-fds=* ]]; then | |
246 | # If there is a job server, allow the edk2 "build" utility to parallelize | |
247 | # as many module builds as there are logical CPUs in the system. The "make" | |
248 | # instances forked by "build" are supposed to limit themselves through the | |
249 | # job server. The zero value below causes the edk2 "build" utility to fetch | |
250 | # the logical CPU count with Python's multiprocessing.cpu_count() method. | |
251 | printf '0\n' | |
252 | else | |
253 | # Build a single module at a time. | |
254 | printf '1\n' | |
255 | fi | |
256 | } | |
037973bb LE |
257 | |
258 | ||
259 | # Work around <https://bugzilla.tianocore.org/show_bug.cgi?id=1607> by | |
260 | # filtering jobserver-related flags out of MAKEFLAGS. Print the result to the | |
261 | # standard output. | |
262 | # | |
263 | # Parameters: | |
264 | # $1: the value of the MAKEFLAGS variable | |
265 | qemu_edk2_quirk_tianocore_1607() | |
266 | { | |
267 | local makeflags="$1" | |
268 | ||
269 | printf %s "$makeflags" \ | |
270 | | LC_ALL=C sed --regexp-extended \ | |
271 | --expression='s/--jobserver-(auth|fds)=[0-9]+,[0-9]+//' \ | |
272 | --expression='s/-j([0-9]+)?//' | |
273 | } |