11
11
import sys
12
12
13
13
## Configurable settings
14
- # Target to build for.
15
- TARGET = 'x86_64-uefi'
16
- # Configuration to build.
17
- CONFIG = 'debug'
18
-
19
- # QEMU executable to use
20
- QEMU = 'qemu-system-x86_64'
21
-
22
14
# Path to workspace directory (which contains the top-level `Cargo.toml`)
23
15
WORKSPACE_DIR = Path (__file__ ).resolve ().parents [1 ]
24
16
25
- # Path to directory containing `OVMF_{CODE/VARS}.fd`.
26
- # TODO: use installed OVMF, if available.
27
- OVMF_DIR = WORKSPACE_DIR / 'uefi-test-runner'
28
-
29
- # Set to `True` or use the `--verbose` argument to print commands.
30
- VERBOSE = False
17
+ # Try changing these with command line flags, where possible
18
+ SETTINGS = {
19
+ # Print commands before running them.
20
+ 'verbose' : False ,
21
+ # Run QEMU without showing GUI
22
+ 'headless' : False ,
23
+ # Target to build for.
24
+ 'target' : 'x86_64-uefi' ,
25
+ # Configuration to build.
26
+ 'config' : 'debug' ,
27
+ # QEMU executable to use
28
+ 'qemu_binary' : 'qemu-system-x86_64' ,
29
+ # Path to directory containing `OVMF_{CODE/VARS}.fd`.
30
+ # TODO: use installed OVMF, if available.
31
+ 'ovmf_dir' : WORKSPACE_DIR / 'uefi-test-runner' ,
32
+ }
33
+
34
+ def build_dir ():
35
+ 'Returns the directory where Cargo places the build artifacts'
36
+ return WORKSPACE_DIR / 'target' / SETTINGS ['target' ] / SETTINGS ['config' ]
37
+
38
+ def esp_dir ():
39
+ 'Returns the directory where we will build the emulated UEFI system partition'
40
+ return build_dir () / 'esp'
41
+
42
+ def run_xtool (tool , * flags ):
43
+ 'Runs cargo-x<tool> with certain arguments.'
44
+
45
+ cmd = ['cargo' , tool , '--target' , SETTINGS ['target' ], * flags ]
46
+
47
+ if SETTINGS ['verbose' ]:
48
+ print (' ' .join (cmd ))
31
49
32
- BUILD_DIR = WORKSPACE_DIR / 'target' / TARGET / CONFIG
33
- ESP_DIR = BUILD_DIR / 'esp'
50
+ sp .run (cmd ).check_returncode ()
34
51
35
52
def run_xbuild (* flags ):
36
- 'Runs Cargo XBuild with certain arguments.'
37
-
38
- cmd = ['cargo' , 'xbuild' , '--target' , TARGET , * flags ]
39
-
40
- if VERBOSE :
41
- print (' ' .join (cmd ))
53
+ 'Runs cargo-xbuild with certain arguments.'
54
+ run_xtool ('xbuild' , * flags )
42
55
43
- sp .run (cmd ).check_returncode ()
56
+ def run_xclippy (* flags ):
57
+ 'Runs cargo-xclippy with certain arguments.'
58
+ run_xtool ('xclippy' , * flags )
44
59
45
60
def build (* test_flags ):
46
61
'Builds the tests and examples.'
47
62
48
- run_xbuild ('--package' , 'uefi-test-runner' , * test_flags )
49
- run_xbuild ('--package' , 'uefi' , '--examples' )
63
+ xbuild_args = [
64
+ '--package' , 'uefi-test-runner' ,
65
+ * test_flags ,
66
+ ]
67
+
68
+ if SETTINGS ['config' ] == 'release' :
69
+ xbuild_args .append ('--release' )
70
+
71
+ run_xbuild (* xbuild_args )
50
72
51
73
# Copy the built test runner file to the right directory for running tests.
52
- built_file = BUILD_DIR / 'uefi-test-runner.efi'
74
+ built_file = build_dir () / 'uefi-test-runner.efi'
53
75
54
- boot_dir = ESP_DIR / 'EFI' / 'Boot'
76
+ boot_dir = esp_dir () / 'EFI' / 'Boot'
55
77
boot_dir .mkdir (parents = True , exist_ok = True )
56
78
57
79
output_file = boot_dir / 'BootX64.efi'
58
80
59
81
shutil .copy2 (built_file , output_file )
60
82
83
+ def clippy ():
84
+ 'Runs Clippy on all projects'
85
+
86
+ run_xclippy ('--all' )
87
+
61
88
def doc ():
62
89
'Generates documentation for the library crates.'
63
90
sp .run ([
@@ -69,18 +96,19 @@ def doc():
69
96
'--package' , 'uefi-services' ,
70
97
])
71
98
72
- def run_qemu (headless ):
99
+ def run_qemu ():
73
100
'Runs the code in QEMU.'
74
101
75
102
# Rebuild all the changes.
76
103
build ('--features' , 'qemu-f4-exit' )
77
104
78
- ovmf_code , ovmf_vars = OVMF_DIR / 'OVMF_CODE.fd' , OVMF_DIR / 'OVMF_VARS.fd'
105
+ ovmf_dir = SETTINGS ['ovmf_dir' ]
106
+ ovmf_code , ovmf_vars = ovmf_dir / 'OVMF_CODE.fd' , ovmf_dir / 'OVMF_VARS.fd'
79
107
80
108
if not ovmf_code .is_file ():
81
- raise FileNotFoundError (f'OVMF_CODE.fd not found in the `{ OVMF_DIR } ` directory' )
109
+ raise FileNotFoundError (f'OVMF_CODE.fd not found in the `{ ovmf_dir } ` directory' )
82
110
83
- examples_dir = BUILD_DIR / 'examples'
111
+ examples_dir = build_dir () / 'examples'
84
112
85
113
qemu_flags = [
86
114
# Disable default devices.
@@ -98,7 +126,7 @@ def run_qemu(headless):
98
126
'-drive' , f'if=pflash,format=raw,file={ ovmf_vars } ,readonly=on' ,
99
127
100
128
# Mount a local directory as a FAT partition.
101
- '-drive' , f'format=raw,file=fat:rw:{ ESP_DIR } ' ,
129
+ '-drive' , f'format=raw,file=fat:rw:{ esp_dir () } ' ,
102
130
103
131
# Mount the built examples directory.
104
132
'-drive' , f'format=raw,file=fat:rw:{ examples_dir } ' ,
@@ -111,7 +139,7 @@ def run_qemu(headless):
111
139
# When running in headless mode we don't have video, but we can still have
112
140
# QEMU emulate a display and take screenshots from it.
113
141
qemu_flags .extend (['-vga' , 'std' ])
114
- if headless :
142
+ if SETTINGS [ ' headless' ] :
115
143
# Do not attach a window to QEMU's display
116
144
qemu_flags .extend (['-display' , 'none' ])
117
145
@@ -125,9 +153,9 @@ def run_qemu(headless):
125
153
#'-debugcon', 'file:debug.log', '-global', 'isa-debugcon.iobase=0x402',
126
154
])
127
155
128
- cmd = [QEMU ] + qemu_flags
156
+ cmd = [SETTINGS [ 'qemu_binary' ] ] + qemu_flags
129
157
130
- if VERBOSE :
158
+ if SETTINGS [ 'verbose' ] :
131
159
print (' ' .join (cmd ))
132
160
133
161
# This regex can be used to detect and strip ANSI escape codes when
@@ -167,32 +195,36 @@ def main():
167
195
168
196
parser = argparse .ArgumentParser (usage = usage , description = desc )
169
197
170
- common = argparse .ArgumentParser (add_help = False )
171
- common .add_argument ('--verbose' , '-v' , help = 'print commands before executing them' , action = 'store_true' )
172
- common .add_argument ('--headless' , help = 'run QEMU without a GUI' , action = 'store_true' )
198
+ parser .add_argument ('verb' , help = 'command to run' , type = str ,
199
+ choices = ['build' , 'run' , 'doc' , 'clippy' ])
173
200
174
- subparsers = parser .add_subparsers (dest = 'verb' )
201
+ parser .add_argument ('--verbose' , '-v' , help = 'print commands before executing them' ,
202
+ action = 'store_true' )
175
203
176
- build_parser = subparsers .add_parser ('build' , parents = [common ])
177
- run_parser = subparsers .add_parser ('run' , parents = [common ])
178
- doc_parser = subparsers .add_parser ('doc' , parents = [common ])
204
+ parser .add_argument ('--headless' , help = 'run QEMU without a GUI' ,
205
+ action = 'store_true' )
206
+
207
+ parser .add_argument ('--release' , help = 'build in release mode' ,
208
+ action = 'store_true' )
179
209
180
210
opts = parser .parse_args ()
181
211
182
212
# Check if we need to enable verbose mode
183
- global VERBOSE
184
- VERBOSE = VERBOSE or opts .verbose
185
- headless = opts .headless
213
+ SETTINGS ['verbose' ] = opts .verbose
214
+ SETTINGS ['headless' ] = opts .headless
215
+ SETTINGS ['config' ] = 'release' if opts .release else 'debug'
216
+
217
+ verb = opts .verb
186
218
187
- if opts . verb == 'build' :
219
+ if verb == 'build' :
188
220
build ()
189
- elif opts . verb == 'run ' :
190
- run_qemu ( headless )
191
- elif opts . verb == 'doc' :
221
+ elif verb == 'clippy ' :
222
+ clippy ( )
223
+ elif verb == 'doc' :
192
224
doc ()
193
- elif opts . verb is None or opts .verb == '' :
225
+ elif verb == 'run' or verb is None or opts .verb == '' :
194
226
# Run the program, by default.
195
- run_qemu (headless )
227
+ run_qemu ()
196
228
else :
197
229
raise ValueError (f'Unknown verb { opts .verb } ' )
198
230
0 commit comments