The open source OpenXR runtime
1#!/usr/bin/env python3
2# Copyright 2019-2023, Collabora, Ltd.
3# SPDX-License-Identifier: BSL-1.0
4"""Simple script to update vk_helpers.{c,h}."""
5
6from pathlib import Path
7from typing import Callable, Iterable, List, Optional
8
9
10def get_device_cmds():
11 # NOTE: Be sure to use the Vulkan 1.0 name of functions in here!
12 # (so, the decorated extension version)
13 # If you want to alias it in the generated file, use the member_name
14 # keyword argument.
15 return [
16 Cmd("vkDestroyDevice"),
17 Cmd("vkDeviceWaitIdle"),
18 Cmd("vkAllocateMemory"),
19 Cmd("vkFreeMemory"),
20 Cmd("vkMapMemory"),
21 Cmd("vkUnmapMemory"),
22 None,
23 Cmd("vkCreateBuffer"),
24 Cmd("vkDestroyBuffer"),
25 Cmd("vkBindBufferMemory"),
26 None,
27 Cmd("vkCreateImage"),
28 Cmd("vkDestroyImage"),
29 Cmd("vkBindImageMemory"),
30 None,
31 Cmd("vkGetBufferMemoryRequirements"),
32 Cmd("vkFlushMappedMemoryRanges"),
33 Cmd("vkGetImageMemoryRequirements"),
34 Cmd(
35 "vkGetImageMemoryRequirements2KHR",
36 member_name="vkGetImageMemoryRequirements2",
37 ),
38 Cmd("vkGetImageSubresourceLayout"),
39 None,
40 Cmd("vkCreateImageView"),
41 Cmd("vkDestroyImageView"),
42 None,
43 Cmd("vkCreateSampler"),
44 Cmd("vkDestroySampler"),
45 None,
46 Cmd("vkCreateShaderModule"),
47 Cmd("vkDestroyShaderModule"),
48 None,
49 Cmd("vkCreateQueryPool"),
50 Cmd("vkDestroyQueryPool"),
51 Cmd("vkGetQueryPoolResults"),
52 None,
53 Cmd("vkCreateCommandPool"),
54 Cmd("vkDestroyCommandPool"),
55 Cmd("vkResetCommandPool"),
56 None,
57 Cmd("vkAllocateCommandBuffers"),
58 Cmd("vkBeginCommandBuffer"),
59 Cmd("vkCmdBeginQuery"),
60 Cmd("vkCmdCopyQueryPoolResults"),
61 Cmd("vkCmdEndQuery"),
62 Cmd("vkCmdResetQueryPool"),
63 Cmd("vkCmdWriteTimestamp"),
64 Cmd("vkCmdPipelineBarrier"),
65 Cmd("vkCmdBeginRenderPass"),
66 Cmd("vkCmdSetScissor"),
67 Cmd("vkCmdSetViewport"),
68 Cmd("vkCmdClearColorImage"),
69 Cmd("vkCmdEndRenderPass"),
70 Cmd("vkCmdBindDescriptorSets"),
71 Cmd("vkCmdBindPipeline"),
72 Cmd("vkCmdBindVertexBuffers"),
73 Cmd("vkCmdBindIndexBuffer"),
74 Cmd("vkCmdDraw"),
75 Cmd("vkCmdDrawIndexed"),
76 Cmd("vkCmdDispatch"),
77 Cmd("vkCmdCopyBuffer"),
78 Cmd("vkCmdCopyBufferToImage"),
79 Cmd("vkCmdCopyImage"),
80 Cmd("vkCmdCopyImageToBuffer"),
81 Cmd("vkCmdBlitImage"),
82 Cmd("vkCmdPushConstants"),
83 Cmd("vkEndCommandBuffer"),
84 Cmd("vkFreeCommandBuffers"),
85 None,
86 Cmd("vkCreateRenderPass"),
87 Cmd("vkDestroyRenderPass"),
88 None,
89 Cmd("vkCreateFramebuffer"),
90 Cmd("vkDestroyFramebuffer"),
91 None,
92 Cmd("vkCreatePipelineCache"),
93 Cmd("vkDestroyPipelineCache"),
94 None,
95 Cmd("vkResetDescriptorPool"),
96 Cmd("vkCreateDescriptorPool"),
97 Cmd("vkDestroyDescriptorPool"),
98 None,
99 Cmd("vkAllocateDescriptorSets"),
100 Cmd("vkFreeDescriptorSets"),
101 None,
102 Cmd("vkCreateComputePipelines"),
103 Cmd("vkCreateGraphicsPipelines"),
104 Cmd("vkDestroyPipeline"),
105 None,
106 Cmd("vkCreatePipelineLayout"),
107 Cmd("vkDestroyPipelineLayout"),
108 None,
109 Cmd("vkCreateDescriptorSetLayout"),
110 Cmd("vkUpdateDescriptorSets"),
111 Cmd("vkDestroyDescriptorSetLayout"),
112 None,
113 Cmd("vkGetDeviceQueue"),
114 Cmd("vkQueueSubmit"),
115 Cmd("vkQueueWaitIdle"),
116 None,
117 Cmd("vkCreateSemaphore"),
118 Cmd(
119 "vkSignalSemaphoreKHR",
120 member_name="vkSignalSemaphore",
121 requires=("VK_KHR_timeline_semaphore",),
122 ),
123 Cmd(
124 "vkWaitSemaphoresKHR",
125 member_name="vkWaitSemaphores",
126 requires=("VK_KHR_timeline_semaphore",),
127 ),
128 Cmd(
129 "vkGetSemaphoreCounterValueKHR",
130 member_name="vkGetSemaphoreCounterValue",
131 requires=("VK_KHR_timeline_semaphore",),
132 ),
133 Cmd("vkDestroySemaphore"),
134 None,
135 Cmd("vkCreateFence"),
136 Cmd("vkWaitForFences"),
137 Cmd("vkGetFenceStatus"),
138 Cmd("vkDestroyFence"),
139 Cmd("vkResetFences"),
140 None,
141 Cmd("vkCreateSwapchainKHR"),
142 Cmd("vkDestroySwapchainKHR"),
143 Cmd("vkGetSwapchainImagesKHR"),
144 Cmd("vkAcquireNextImageKHR"),
145 Cmd("vkQueuePresentKHR"),
146 None,
147 Cmd("vkGetMemoryWin32HandleKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
148 Cmd("vkGetFenceWin32HandleKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
149 Cmd("vkGetSemaphoreWin32HandleKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
150 Cmd("vkImportFenceWin32HandleKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
151 Cmd("vkImportSemaphoreWin32HandleKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
152 None,
153 Cmd("vkGetMemoryFdKHR", requires=("!defined(VK_USE_PLATFORM_WIN32_KHR)",)),
154 Cmd("vkGetFenceFdKHR", requires=("!defined(VK_USE_PLATFORM_WIN32_KHR)",)),
155 Cmd("vkGetSemaphoreFdKHR", requires=("!defined(VK_USE_PLATFORM_WIN32_KHR)",)),
156 Cmd("vkImportFenceFdKHR", requires=("!defined(VK_USE_PLATFORM_WIN32_KHR)",)),
157 Cmd("vkImportSemaphoreFdKHR", requires=("!defined(VK_USE_PLATFORM_WIN32_KHR)",)),
158 None,
159 Cmd(
160 "vkGetMemoryAndroidHardwareBufferANDROID",
161 requires=("VK_USE_PLATFORM_ANDROID_KHR",),
162 ),
163 Cmd(
164 "vkGetAndroidHardwareBufferPropertiesANDROID",
165 requires=("VK_USE_PLATFORM_ANDROID_KHR",),
166 ),
167 None,
168 Cmd('vkGetMemoryHostPointerPropertiesEXT', requires=("VK_EXT_external_memory_host",)),
169 None,
170 Cmd("vkGetCalibratedTimestampsEXT", requires=("VK_EXT_calibrated_timestamps",)),
171 None,
172 Cmd("vkGetPastPresentationTimingGOOGLE"),
173 None,
174 Cmd("vkGetSwapchainCounterEXT", requires=("VK_EXT_display_control",)),
175 Cmd("vkRegisterDeviceEventEXT", requires=("VK_EXT_display_control",)),
176 Cmd("vkRegisterDisplayEventEXT", requires=("VK_EXT_display_control",)),
177 None,
178 Cmd("vkGetImageDrmFormatModifierPropertiesEXT", requires=("VK_EXT_image_drm_format_modifier",)),
179 None,
180 Cmd("vkCmdBeginDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
181 Cmd("vkCmdEndDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
182 Cmd("vkCmdInsertDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
183 Cmd("vkQueueBeginDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
184 Cmd("vkQueueEndDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
185 Cmd("vkQueueInsertDebugUtilsLabelEXT", requires=("VK_EXT_debug_utils",)),
186 Cmd("vkSetDebugUtilsObjectNameEXT", requires=("VK_EXT_debug_utils",)),
187 Cmd("vkSetDebugUtilsObjectTagEXT", requires=("VK_EXT_debug_utils",)),
188 None,
189 Cmd("vkWaitForPresentKHR", requires=("VK_KHR_present_wait",)),
190 ]
191
192
193def get_instance_cmds():
194 return [
195 Cmd("vkDestroyInstance"),
196 Cmd("vkGetDeviceProcAddr"),
197 Cmd("vkCreateDevice"),
198 Cmd("vkDestroySurfaceKHR"),
199 None,
200 Cmd("vkCreateDebugReportCallbackEXT"),
201 Cmd("vkDestroyDebugReportCallbackEXT"),
202 None,
203 Cmd("vkEnumeratePhysicalDevices"),
204 Cmd("vkGetPhysicalDeviceProperties"),
205 Cmd(
206 "vkGetPhysicalDeviceProperties2KHR",
207 member_name="vkGetPhysicalDeviceProperties2",
208 ),
209 Cmd(
210 "vkGetPhysicalDeviceFeatures2KHR",
211 member_name="vkGetPhysicalDeviceFeatures2",
212 ),
213 Cmd("vkGetPhysicalDeviceMemoryProperties"),
214 Cmd("vkGetPhysicalDeviceQueueFamilyProperties"),
215 Cmd("vkGetPhysicalDeviceSurfaceCapabilitiesKHR"),
216 Cmd("vkGetPhysicalDeviceSurfaceFormatsKHR"),
217 Cmd("vkGetPhysicalDeviceSurfacePresentModesKHR"),
218 Cmd("vkGetPhysicalDeviceSurfaceSupportKHR"),
219 Cmd("vkGetPhysicalDeviceFormatProperties"),
220 Cmd(
221 "vkGetPhysicalDeviceFormatProperties2KHR",
222 member_name="vkGetPhysicalDeviceFormatProperties2",
223 ),
224 Cmd(
225 "vkGetPhysicalDeviceImageFormatProperties2KHR",
226 member_name="vkGetPhysicalDeviceImageFormatProperties2",
227 ),
228 Cmd("vkGetPhysicalDeviceExternalBufferPropertiesKHR"),
229 Cmd("vkGetPhysicalDeviceExternalFencePropertiesKHR"),
230 Cmd("vkGetPhysicalDeviceExternalSemaphorePropertiesKHR"),
231 Cmd("vkEnumerateDeviceExtensionProperties"),
232 Cmd("vkEnumerateDeviceLayerProperties"),
233 None,
234 Cmd(
235 "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT",
236 requires=("VK_EXT_calibrated_timestamps",),
237 ),
238 None,
239 Cmd(
240 "vkCreateDisplayPlaneSurfaceKHR", requires=("VK_USE_PLATFORM_DISPLAY_KHR",)
241 ),
242 Cmd(
243 "vkGetDisplayPlaneCapabilitiesKHR",
244 requires=("VK_USE_PLATFORM_DISPLAY_KHR",),
245 ),
246 Cmd(
247 "vkGetPhysicalDeviceDisplayPropertiesKHR",
248 requires=("VK_USE_PLATFORM_DISPLAY_KHR",),
249 ),
250 Cmd(
251 "vkGetPhysicalDeviceDisplayPlanePropertiesKHR",
252 requires=("VK_USE_PLATFORM_DISPLAY_KHR",),
253 ),
254 Cmd("vkGetDisplayModePropertiesKHR", requires=("VK_USE_PLATFORM_DISPLAY_KHR",)),
255 Cmd("vkReleaseDisplayEXT", requires=("VK_USE_PLATFORM_DISPLAY_KHR",)),
256 None,
257 Cmd("vkCreateXcbSurfaceKHR", requires=("VK_USE_PLATFORM_XCB_KHR",)),
258 None,
259 Cmd("vkCreateWaylandSurfaceKHR", requires=("VK_USE_PLATFORM_WAYLAND_KHR",)),
260 None,
261 Cmd(
262 "vkAcquireDrmDisplayEXT",
263 requires=("VK_USE_PLATFORM_WAYLAND_KHR", "VK_EXT_acquire_drm_display"),
264 ),
265 Cmd(
266 "vkGetDrmDisplayEXT",
267 requires=("VK_USE_PLATFORM_WAYLAND_KHR", "VK_EXT_acquire_drm_display"),
268 ),
269 None,
270 Cmd(
271 "vkGetRandROutputDisplayEXT", requires=("VK_USE_PLATFORM_XLIB_XRANDR_EXT",)
272 ),
273 Cmd("vkAcquireXlibDisplayEXT", requires=("VK_USE_PLATFORM_XLIB_XRANDR_EXT",)),
274 None,
275 Cmd("vkCreateAndroidSurfaceKHR", requires=("VK_USE_PLATFORM_ANDROID_KHR",)),
276 None,
277 Cmd("vkCreateWin32SurfaceKHR", requires=("VK_USE_PLATFORM_WIN32_KHR",)),
278 None,
279 Cmd("vkGetPhysicalDeviceSurfaceCapabilities2EXT", requires=("VK_EXT_display_surface_counter",)),
280 None,
281 Cmd("vkCreateDebugUtilsMessengerEXT", requires=("VK_EXT_debug_utils",)),
282 Cmd("vkSubmitDebugUtilsMessageEXT", requires=("VK_EXT_debug_utils",)),
283 Cmd("vkDestroyDebugUtilsMessengerEXT", requires=("VK_EXT_debug_utils",)),
284 ]
285
286
287# Sorted KHR, EXT, Vendor, interally alphabetically
288INSTANCE_EXTENSIONS_TO_CHECK = [
289 "VK_KHR_external_memory_capabilities",
290 "VK_EXT_display_surface_counter",
291 "VK_EXT_swapchain_colorspace",
292 "VK_EXT_debug_utils",
293]
294# Sorted KHR, EXT, Vendor, interally alphabetically
295DEVICE_EXTENSIONS_TO_CHECK = [
296 "VK_KHR_8bit_storage",
297 "VK_KHR_external_fence_fd",
298 "VK_KHR_external_memory",
299 "VK_KHR_external_semaphore_fd",
300 "VK_KHR_format_feature_flags2",
301 "VK_KHR_global_priority",
302 "VK_KHR_image_format_list",
303 "VK_KHR_maintenance1",
304 "VK_KHR_maintenance2",
305 "VK_KHR_maintenance3",
306 "VK_KHR_maintenance4",
307 "VK_KHR_present_wait",
308 "VK_KHR_synchronization2",
309 "VK_KHR_timeline_semaphore",
310 "VK_KHR_video_maintenance1",
311 "VK_EXT_calibrated_timestamps",
312 "VK_EXT_display_control",
313 "VK_EXT_external_memory_dma_buf",
314 "VK_EXT_external_memory_host",
315 "VK_EXT_global_priority",
316 "VK_EXT_image_drm_format_modifier",
317 "VK_EXT_robustness2",
318 "VK_ANDROID_external_format_resolve",
319 "VK_GOOGLE_display_timing",
320]
321
322ROOT = Path(__file__).resolve().parent.parent
323DIR = ROOT / "src" / "xrt" / "auxiliary" / "vk"
324HELPERS_H_FN = DIR / "vk_helpers.h"
325BUNDLE_INIT_C_FN = DIR / "vk_bundle_init.c"
326FUNCTION_LOADERS_C_FN = DIR / "vk_function_loaders.c"
327
328BEGIN_TEMPLATE = "\t// beginning of GENERATED %s code - do not modify - used by scripts"
329END_TEMPLATE = "\t// end of GENERATED %s code - do not modify - used by scripts"
330
331
332class Cmd:
333 def __init__(
334 self,
335 name: str,
336 member_name: Optional[str] = None,
337 *,
338 requires: Optional[Iterable[str]] = None,
339 ):
340 self.name = name
341 if not member_name:
342 member_name = name
343 self.member_name = member_name
344 if not requires:
345 # normalize empty lists to None
346 requires = None
347 self.requires = requires
348
349 def __repr__(self) -> str:
350 args = [repr(self.name)]
351 if self.member_name != self.name:
352 args.append(repr(self.member_name))
353 if self.requires:
354 args.append(f"requires={repr(self.requires)}")
355 return "Function({})".format(", ".join(args))
356
357
358def wrap_condition(condition):
359 if "defined" in condition:
360 return condition
361 return "defined({})".format(condition)
362
363
364def compute_condition(pp_conditions):
365 if not pp_conditions:
366 return None
367 return " && ".join(wrap_condition(x) for x in pp_conditions)
368
369
370class ConditionalGenerator:
371 """Keep track of conditions to avoid unneeded repetition of ifdefs."""
372
373 def __init__(self):
374 self.current_condition = None
375
376 def process_condition(self, new_condition: Optional[str], finish: bool = False) -> Optional[str]:
377 """Return a line (or lines) to yield if required based on the new condition state."""
378 lines = []
379 if self.current_condition and new_condition != self.current_condition:
380 # Close current condition if required.
381 lines.append("#endif // {}".format(self.current_condition))
382 if not finish:
383 # empty line
384 lines.append("")
385 self.current_condition = None
386
387 if not finish and new_condition != self.current_condition:
388 # Open new condition if required
389 lines.append("#if {}".format(new_condition))
390 self.current_condition = new_condition
391
392 if lines:
393 return "\n".join(lines)
394
395 def finish(self) -> Optional[str]:
396 """Return a line (or lines) to yield if required at the end of the loop."""
397 return self.process_condition(None, finish=True)
398
399
400def generate_per_command(
401 commands: List[Cmd], per_command_handler: Callable[[Cmd], str]
402):
403 conditional = ConditionalGenerator()
404 for cmd in commands:
405 if not cmd:
406 # empty line
407 yield ""
408 continue
409 condition = compute_condition(cmd.requires)
410 condition_line = conditional.process_condition(condition)
411 if condition_line:
412 yield condition_line
413
414 yield per_command_handler(cmd)
415
416 # close any trailing conditions
417 condition_line = conditional.finish()
418 if condition_line:
419 yield condition_line
420
421
422def generate_structure_members(commands: List[Cmd]):
423 def per_command(cmd: Cmd):
424 return "\tPFN_{} {};".format(cmd.name, cmd.member_name)
425
426 yield from generate_per_command(commands, per_command)
427 yield ''
428
429
430def generate_proc_macro(macro: str, commands: List[Cmd]):
431 name_width = max([len(cmd.member_name) for cmd in commands if cmd])
432
433 def per_command(cmd: Cmd) -> str:
434 return "\tvk->{} = {}(vk, {});".format(
435 cmd.member_name.ljust(name_width), macro, cmd.name
436 )
437
438 return generate_per_command(
439 commands,
440 per_command,
441 )
442
443
444def make_ext_member_name(ext: str):
445 return "has_{}".format(ext[3:])
446
447
448def make_ext_name_define(ext: str):
449 str = ext.upper()
450 str = str.replace("1", "_1")
451 str = str.replace("2", "_2")
452 str = str.replace("3", "_3")
453 str = str.replace("4", "_4")
454
455 return "{}_EXTENSION_NAME".format(str)
456
457
458def generate_ext_members(exts):
459 for ext in exts:
460 yield "\tbool {};".format(make_ext_member_name(ext))
461
462
463def generate_ext_check(exts):
464 yield "\t// Reset before filling out."
465
466 for ext in exts:
467 yield "\tvk->{} = false;".format(make_ext_member_name(ext))
468
469 yield ""
470 yield "\tconst char *const *exts = u_string_list_get_data(ext_list);"
471 yield "\tuint32_t ext_count = u_string_list_get_size(ext_list);"
472 yield ""
473 yield "\tfor (uint32_t i = 0; i < ext_count; i++) {"
474 yield "\t\tconst char *ext = exts[i];"
475 yield ""
476
477 conditional = ConditionalGenerator()
478 for ext in exts:
479 condition_line = conditional.process_condition(compute_condition((ext,)))
480 if condition_line:
481 yield condition_line
482 yield "\t\tif (strcmp(ext, {}) == 0) {{".format(make_ext_name_define(ext))
483 yield "\t\t\tvk->{} = true;".format(make_ext_member_name(ext))
484 yield "\t\t\tcontinue;"
485 yield "\t\t}"
486 # close any trailing conditions
487 condition_line = conditional.finish()
488 if condition_line:
489 yield condition_line
490 yield "\t}"
491
492
493def replace_middle(
494 lines: List[str], start_sentinel: str, end_sentinel: str, new_middle: List[str]
495) -> List[str]:
496 middle_start = lines.index(start_sentinel) + 1
497 middle_end = lines.index(end_sentinel)
498 return lines[:middle_start] + new_middle + lines[middle_end:]
499
500
501DEVICE_TEMPLATES = {
502 "BEGIN": BEGIN_TEMPLATE % "device loader",
503 "END": END_TEMPLATE % "device loader",
504}
505INSTANCE_TEMPLATES = {
506 "BEGIN": BEGIN_TEMPLATE % "instance loader",
507 "END": END_TEMPLATE % "instance loader",
508}
509INSTANCE_EXT_TEMPLATES = {
510 "BEGIN": BEGIN_TEMPLATE % "instance extension",
511 "END": END_TEMPLATE % "instance extension",
512}
513EXT_TEMPLATES = {
514 "BEGIN": BEGIN_TEMPLATE % "device extension",
515 "END": END_TEMPLATE % "device extension",
516}
517
518
519def process_helpers_h():
520 with open(str(HELPERS_H_FN), "r", encoding="utf-8") as fp:
521 lines = [line.rstrip() for line in fp.readlines()]
522
523 lines = replace_middle(
524 lines,
525 INSTANCE_TEMPLATES["BEGIN"],
526 INSTANCE_TEMPLATES["END"],
527 list(generate_structure_members(get_instance_cmds())),
528 )
529
530 lines = replace_middle(
531 lines,
532 DEVICE_TEMPLATES["BEGIN"],
533 DEVICE_TEMPLATES["END"],
534 list(generate_structure_members(get_device_cmds())),
535 )
536
537 lines = replace_middle(
538 lines,
539 INSTANCE_EXT_TEMPLATES["BEGIN"],
540 INSTANCE_EXT_TEMPLATES["END"],
541 list(generate_ext_members(INSTANCE_EXTENSIONS_TO_CHECK)),
542 )
543
544 lines = replace_middle(
545 lines,
546 EXT_TEMPLATES["BEGIN"],
547 EXT_TEMPLATES["END"],
548 list(generate_ext_members(DEVICE_EXTENSIONS_TO_CHECK)),
549 )
550
551 with open(str(HELPERS_H_FN), "w", encoding="utf-8") as fp:
552 fp.write("\n".join(lines))
553 fp.write("\n")
554
555
556def process_function_loaders_c():
557 with open(str(FUNCTION_LOADERS_C_FN), "r", encoding="utf-8") as fp:
558 lines = [line.rstrip() for line in fp.readlines()]
559
560 lines = replace_middle(
561 lines,
562 INSTANCE_TEMPLATES["BEGIN"],
563 INSTANCE_TEMPLATES["END"],
564 list(generate_proc_macro("GET_INS_PROC", get_instance_cmds())),
565 )
566
567 lines = replace_middle(
568 lines,
569 DEVICE_TEMPLATES["BEGIN"],
570 DEVICE_TEMPLATES["END"],
571 list(generate_proc_macro("GET_DEV_PROC", get_device_cmds())),
572 )
573
574 with open(str(FUNCTION_LOADERS_C_FN), "w", encoding="utf-8") as fp:
575 fp.write("\n".join(lines))
576 fp.write("\n")
577
578def process_bundle_init_c():
579 with open(str(BUNDLE_INIT_C_FN), "r", encoding="utf-8") as fp:
580 lines = [line.rstrip() for line in fp.readlines()]
581
582
583 lines = replace_middle(
584 lines,
585 INSTANCE_EXT_TEMPLATES["BEGIN"],
586 INSTANCE_EXT_TEMPLATES["END"],
587 list(generate_ext_check(INSTANCE_EXTENSIONS_TO_CHECK)),
588 )
589
590 lines = replace_middle(
591 lines,
592 EXT_TEMPLATES["BEGIN"],
593 EXT_TEMPLATES["END"],
594 list(generate_ext_check(DEVICE_EXTENSIONS_TO_CHECK)),
595 )
596
597 with open(str(BUNDLE_INIT_C_FN), "w", encoding="utf-8") as fp:
598 fp.write("\n".join(lines))
599 fp.write("\n")
600
601
602if __name__ == "__main__":
603 process_helpers_h()
604 process_bundle_init_c()
605 process_function_loaders_c()