|
1 | 1 | #!/usr/bin/env python3 |
2 | | -"""Generate installation rules for public SDK headers and their local includes.""" |
| 2 | +"""Generate install rules for actual local includes of public SDK headers.""" |
3 | 3 | from pathlib import Path |
4 | 4 | import re |
5 | 5 | import sys |
6 | | -root=Path(sys.argv[1]).resolve() |
7 | | -native=root/'experiments/WebScene.NativeEngine.Probe/native' |
8 | | -authoring=root/'src/WebScene.NativeWeb/include' |
9 | | -roots=[authoring,native,native/'graphics'] |
10 | | -pending=list(authoring.rglob('*.hpp'))+[native/'webscene/compiled_document.hpp',native/'graphics/native_webgpu_surface.h'] |
11 | | -seen=set() |
12 | | -while pending: |
13 | | - item=pending.pop().resolve() |
14 | | - if item in seen:continue |
15 | | - seen.add(item) |
16 | | - for included in re.findall(r'^\s*#\s*include\s*[<"]([^">]+)[">]',item.read_text(),re.M): |
17 | | - candidates=[item.parent/included]+[base/included for base in roots] |
18 | | - match=next((candidate for candidate in candidates if candidate.is_file()),None) |
19 | | - if match:pending.append(match) |
20 | | - elif included.startswith(('webscene_','webscene/')): |
21 | | - raise RuntimeError(f'Unresolved SDK header dependency {included} in {item}') |
22 | | -for item in sorted(seen): |
23 | | - relative=item.relative_to(authoring if item.is_relative_to(authoring) else native) |
24 | | - print(f'install(FILES "{item}" DESTINATION "include/{relative.parent.as_posix()}")') |
25 | | - print(f'set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "{item}")') |
| 6 | + |
| 7 | +TOKENS = re.compile( |
| 8 | + r'(?P<include>^[ \t]*\#[ \t]*include[ \t]*[<"](?P<path>[^">\r\n]+)[">])' |
| 9 | + r'|(?:u8|u|U|L)?R"(?P<delimiter>[^ ()\\\t\r\n]{0,16})\(.*?\)(?P=delimiter)"' |
| 10 | + r'|/\*.*?\*/|//[^\r\n]*' |
| 11 | + r'|"(?:\\.|[^"\\\r\n])*"' |
| 12 | + r'|(?<![\w])\x27(?:\\.|[^\x27\\\r\n])*\x27', |
| 13 | + re.MULTILINE | re.DOTALL, |
| 14 | +) |
| 15 | + |
| 16 | +def includes(text): |
| 17 | + return [m.group('path') for m in TOKENS.finditer(text) if m.group('include')] |
| 18 | + |
| 19 | +def generate(root): |
| 20 | + root=Path(root).resolve() |
| 21 | + native=root/'experiments/WebScene.NativeEngine.Probe/native' |
| 22 | + authoring=root/'src/WebScene.NativeWeb/include' |
| 23 | + roots=[authoring,native,native/'graphics'] |
| 24 | + pending=[(path,[]) for path in sorted(authoring.rglob('*.hpp'))+[native/'webscene/compiled_document.hpp',native/'graphics/native_webgpu_surface.h']] |
| 25 | + seen=set() |
| 26 | + while pending: |
| 27 | + item,chain=pending.pop();item=item.resolve() |
| 28 | + if item in seen:continue |
| 29 | + if not any(item.is_relative_to(base) for base in (authoring,native)): |
| 30 | + raise RuntimeError('Public header includes a producer-only source: '+' -> '.join(str(path.relative_to(root)) for path in chain+[item])) |
| 31 | + seen.add(item) |
| 32 | + for included in includes(item.read_text()): |
| 33 | + candidates=[item.parent/included]+[base/included for base in roots] |
| 34 | + match=next((candidate for candidate in candidates if candidate.is_file()),None) |
| 35 | + if match:pending.append((match,chain+[item])) |
| 36 | + elif included.startswith(('webscene_','webscene/')): |
| 37 | + raise RuntimeError(f'Unresolved SDK header dependency {included} in {item}') |
| 38 | + for item in sorted(seen): |
| 39 | + relative=item.relative_to(authoring if item.is_relative_to(authoring) else native) |
| 40 | + print(f'install(FILES "{item}" DESTINATION "include/{relative.parent.as_posix()}")') |
| 41 | + print(f'set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "{item}")') |
| 42 | + json_root=root/'samples/NativeKestrel/third_party/nlohmann' |
| 43 | + print('if(CMAKE_SYSTEM_NAME STREQUAL "Linux")') |
| 44 | + print(f'install(FILES "{json_root}/json.hpp" DESTINATION include/third_party/nlohmann)') |
| 45 | + print(f'install(FILES "{json_root}/LICENSE.MIT" DESTINATION share/licenses/WebScene RENAME nlohmann-LICENSE)') |
| 46 | + print('endif()') |
| 47 | + print(f'WebScene SDK header closure: {len(seen)} files',file=sys.stderr) |
| 48 | + |
| 49 | +if __name__=='__main__': |
| 50 | + generate(sys.argv[1]) |
0 commit comments