darwin.apple_sdk: drop gen-frameworks.py (replaced by new SDK pattern)

-147
-147
pkgs/os-specific/darwin/gen-frameworks.py
··· 1 - #!/usr/bin/env nix-shell 2 - #!nix-shell -i python -p python3 swiftPackages.swift-unwrapped 3 - 4 - """ 5 - Generate a frameworks.nix for a macOS SDK. 6 - 7 - You may point this tool at an Xcode bundled SDK, but more ideal is using the 8 - SDK from Nixpkgs. For example: 9 - 10 - SDK_PATH="$(nix-build --no-link -A darwin.apple_sdk_11_0.MacOSX-SDK)" 11 - ./gen-frameworks.py "$SDK_PATH" > ./new-frameworks.nix 12 - """ 13 - 14 - import json 15 - import os 16 - import subprocess 17 - import sys 18 - 19 - ALLOWED_LIBS = ["simd"] 20 - 21 - HEADER = """\ 22 - # This file is generated by gen-frameworks.nix. 23 - # Do not edit, put overrides in apple_sdk.nix instead. 24 - { libs, frameworks }: with libs; with frameworks; 25 - { 26 - """ 27 - 28 - FOOTER = """\ 29 - } 30 - """ 31 - 32 - 33 - def eprint(*args): 34 - print(*args, file=sys.stderr) 35 - 36 - 37 - def name_from_ident(ident): 38 - return ident.get("swift", ident.get("clang")) 39 - 40 - 41 - def scan_sdk(sdk): 42 - # Find frameworks by scanning the SDK frameworks directory. 43 - frameworks = [ 44 - framework.removesuffix(".framework") 45 - for framework in os.listdir(f"{sdk}/System/Library/Frameworks") 46 - if not framework.startswith("_") 47 - ] 48 - frameworks.sort() 49 - 50 - # Determine the longest name for padding output. 51 - width = len(max(frameworks, key=len)) 52 - 53 - output = HEADER 54 - 55 - for framework in frameworks: 56 - deps = [] 57 - 58 - # Use Swift to scan dependencies, because a module may have both Clang 59 - # and Swift parts. Using Clang only imports the Clang module, whereas 60 - # using Swift will usually import both Clang + Swift overlay. 61 - # 62 - # TODO: The above is an assumption. Not sure if it's possible a Swift 63 - # module completely shadows a Clang module. (Seems unlikely) 64 - # 65 - # TODO: Handle "module 'Foobar' is incompatible with feature 'swift'" 66 - # 67 - # If there were a similar Clang invocation for scanning, we could fix 68 - # the above todos, but that doesn't appear to exist. 69 - eprint(f"# scanning {framework}") 70 - result = subprocess.run( 71 - [ 72 - "swiftc", 73 - "-scan-dependencies", 74 - # We provide a source snippet via stdin. 75 - "-", 76 - # Use the provided SDK. 77 - "-sdk", 78 - sdk, 79 - # This search path is normally added automatically by the 80 - # compiler based on the SDK, but we have a patch in place that 81 - # removes that for SDKs in /nix/store, because our xcbuild stub 82 - # SDK doesn't have the directory. 83 - # (swift-prevent-sdk-dirs-warning.patch) 84 - "-I", 85 - f"{sdk}/usr/lib/swift", 86 - # For some reason, 'lib/swift/shims' from both the SDK and 87 - # Swift compiler are picked up, causing redefinition errors. 88 - # This eliminates the latter. 89 - "-resource-dir", 90 - f"{sdk}/usr/lib/swift", 91 - ], 92 - input=f"import {framework}".encode(), 93 - stdout=subprocess.PIPE, 94 - ) 95 - if result.returncode != 0: 96 - eprint(f"# Scanning {framework} failed (exit code {result.returncode})") 97 - result.stdout = b"" 98 - 99 - # Parse JSON output. 100 - if len(result.stdout) != 0: 101 - data = json.loads(result.stdout) 102 - 103 - # Entries in the modules list come in pairs. The first is an 104 - # identifier (`{ swift: "foobar" }` or `{ clang: "foobar" }`), and 105 - # the second metadata for that module. Here we look for the pair 106 - # that matches the framework we're scanning (and ignore the rest). 107 - modules = data["modules"] 108 - for i in range(0, len(modules), 2): 109 - ident, meta = modules[i : i + 2] 110 - 111 - # NOTE: We may match twice, for a Swift module _and_ for a 112 - # Clang module. So matching here doesn't break from the loop, 113 - # and deps is appended to. 114 - if name_from_ident(ident) == framework: 115 - dep_idents = meta["directDependencies"] 116 - deps += [name_from_ident(ident) for ident in dep_idents] 117 - # List unfiltered deps in progress output. 118 - eprint(ident, "->", dep_idents) 119 - 120 - # Filter out modules that are not separate derivations. 121 - # Also filter out duplicates (when a Swift overlay imports the Clang module) 122 - allowed = frameworks + ALLOWED_LIBS 123 - deps = set([dep for dep in deps if dep in allowed]) 124 - 125 - # Filter out self-references. (Swift overlay importing Clang module.) 126 - if framework in deps: 127 - deps.remove(framework) 128 - 129 - # Generate a Nix attribute line. 130 - if len(deps) != 0: 131 - deps = list(deps) 132 - deps.sort() 133 - deps = " ".join(deps) 134 - output += f" {framework.ljust(width)} = {{ inherit {deps}; }};\n" 135 - else: 136 - output += f" {framework.ljust(width)} = {{}};\n" 137 - 138 - output += FOOTER 139 - sys.stdout.write(output) 140 - 141 - 142 - if __name__ == "__main__": 143 - if len(sys.argv) != 2: 144 - eprint(f"Usage: {sys.argv[0]} <path to MacOSX.sdk>") 145 - sys.exit(64) 146 - 147 - scan_sdk(sys.argv[1])
···