| 
 | 1 | +push!(Base.LOAD_PATH, dirname(@__DIR__))  | 
 | 2 | + | 
 | 3 | +using TOML, Artifacts, Base.BinaryPlatforms  | 
 | 4 | +include("./platform_augmentation.jl")  | 
 | 5 | +artifacts_toml = joinpath(dirname(@__DIR__), "Artifacts.toml")  | 
 | 6 | + | 
 | 7 | +# Update Base.parse to support riscv64, needed for Julia <1.12  | 
 | 8 | +@static if !haskey(BinaryPlatforms.arch_mapping, "riscv64")  | 
 | 9 | + | 
 | 10 | +    BinaryPlatforms.arch_mapping["riscv64"] = "(rv64|riscv64)"  | 
 | 11 | + | 
 | 12 | +    function bbparse(::Type{Platform}, triplet::AbstractString; validate_strict::Bool = false)  | 
 | 13 | +        arch_mapping = BinaryPlatforms.arch_mapping  | 
 | 14 | +        os_mapping = BinaryPlatforms.os_mapping  | 
 | 15 | +        libc_mapping = BinaryPlatforms.libc_mapping  | 
 | 16 | +        call_abi_mapping = BinaryPlatforms.call_abi_mapping  | 
 | 17 | +        libgfortran_version_mapping = BinaryPlatforms.libgfortran_version_mapping  | 
 | 18 | +        cxxstring_abi_mapping = BinaryPlatforms.cxxstring_abi_mapping  | 
 | 19 | +        libstdcxx_version_mapping = BinaryPlatforms.libstdcxx_version_mapping  | 
 | 20 | +      | 
 | 21 | +        # Helper function to collapse dictionary of mappings down into a regex of  | 
 | 22 | +        # named capture groups joined by "|" operators  | 
 | 23 | +        c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")")  | 
 | 24 | +      | 
 | 25 | +        # We're going to build a mondo regex here to parse everything:  | 
 | 26 | +        triplet_regex = Regex(string(  | 
 | 27 | +            "^",  | 
 | 28 | +            # First, the core triplet; arch/os/libc/call_abi  | 
 | 29 | +            c(arch_mapping),  | 
 | 30 | +            c(os_mapping),  | 
 | 31 | +            c(libc_mapping),  | 
 | 32 | +            c(call_abi_mapping),  | 
 | 33 | +            # Next, optional things, like libgfortran/libstdcxx/cxxstring abi  | 
 | 34 | +            c(libgfortran_version_mapping),  | 
 | 35 | +            c(cxxstring_abi_mapping),  | 
 | 36 | +            c(libstdcxx_version_mapping),  | 
 | 37 | +            # Finally, the catch-all for extended tags  | 
 | 38 | +            "(?<tags>(?:-[^-]+\\+[^-]+)*)?",  | 
 | 39 | +            "\$",  | 
 | 40 | +        ))  | 
 | 41 | +      | 
 | 42 | +        m = match(triplet_regex, triplet)  | 
 | 43 | +        if m !== nothing  | 
 | 44 | +            # Helper function to find the single named field within the giant regex  | 
 | 45 | +            # that is not `nothing` for each mapping we give it.  | 
 | 46 | +            get_field(m, mapping) = begin  | 
 | 47 | +                for k in keys(mapping)  | 
 | 48 | +                    if m[k] !== nothing  | 
 | 49 | +                        # Convert our sentinel `nothing` values to actual `nothing`  | 
 | 50 | +                        if endswith(k, "_nothing")  | 
 | 51 | +                            return nothing  | 
 | 52 | +                        end  | 
 | 53 | +                        # Convert libgfortran/libstdcxx version numbers  | 
 | 54 | +                        if startswith(k, "libgfortran")  | 
 | 55 | +                            return VersionNumber(parse(Int,k[12:end]))  | 
 | 56 | +                        elseif startswith(k, "libstdcxx")  | 
 | 57 | +                            return VersionNumber(3, 4, parse(Int,m[k][11:end]))  | 
 | 58 | +                        else  | 
 | 59 | +                            return k  | 
 | 60 | +                        end  | 
 | 61 | +                    end  | 
 | 62 | +                end  | 
 | 63 | +            end  | 
 | 64 | +      | 
 | 65 | +            # Extract the information we're interested in:  | 
 | 66 | +            arch = get_field(m, arch_mapping)  | 
 | 67 | +            os = get_field(m, os_mapping)  | 
 | 68 | +            libc = get_field(m, libc_mapping)  | 
 | 69 | +            call_abi = get_field(m, call_abi_mapping)  | 
 | 70 | +            libgfortran_version = get_field(m, libgfortran_version_mapping)  | 
 | 71 | +            libstdcxx_version = get_field(m, libstdcxx_version_mapping)  | 
 | 72 | +            cxxstring_abi = get_field(m, cxxstring_abi_mapping)  | 
 | 73 | +            function split_tags(tagstr)  | 
 | 74 | +                tag_fields = filter(!isempty, split(tagstr, "-"))  | 
 | 75 | +                if isempty(tag_fields)  | 
 | 76 | +                    return Pair{String,String}[]  | 
 | 77 | +                end  | 
 | 78 | +                return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+"))  | 
 | 79 | +            end  | 
 | 80 | +            tags = split_tags(m["tags"])  | 
 | 81 | +      | 
 | 82 | +            # Special parsing of os version number, if any exists  | 
 | 83 | +            function extract_os_version(os_name, pattern)  | 
 | 84 | +                m_osvn = match(pattern, m[os_name])  | 
 | 85 | +                if m_osvn !== nothing  | 
 | 86 | +                    return VersionNumber(m_osvn.captures[1])  | 
 | 87 | +                end  | 
 | 88 | +                return nothing  | 
 | 89 | +            end  | 
 | 90 | +            os_version = nothing  | 
 | 91 | +            if os == "macos"  | 
 | 92 | +                os_version = extract_os_version("macos", r".*darwin([\d.]+)"sa)  | 
 | 93 | +            end  | 
 | 94 | +            if os == "freebsd"  | 
 | 95 | +                os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)"sa)  | 
 | 96 | +            end  | 
 | 97 | +            if os == "openbsd"  | 
 | 98 | +                os_version = extract_os_version("openbsd", r".*openbsd([\d.]+)"sa)  | 
 | 99 | +            end  | 
 | 100 | +      | 
 | 101 | +            return Platform(  | 
 | 102 | +                arch, os;  | 
 | 103 | +                validate_strict,  | 
 | 104 | +                libc,  | 
 | 105 | +                call_abi,  | 
 | 106 | +                libgfortran_version,  | 
 | 107 | +                cxxstring_abi,  | 
 | 108 | +                libstdcxx_version,  | 
 | 109 | +                os_version,  | 
 | 110 | +                tags...,  | 
 | 111 | +            )  | 
 | 112 | +        end  | 
 | 113 | +        throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform"))  | 
 | 114 | +    end  | 
 | 115 | + | 
 | 116 | +else  | 
 | 117 | +    # riscv64 is supported, all is fine  | 
 | 118 | + | 
 | 119 | +    const bbparse = parse  | 
 | 120 | + | 
 | 121 | +end  | 
 | 122 | + | 
 | 123 | + | 
 | 124 | +# Get "target triplet" from ARGS, if given (defaulting to the host triplet otherwise)  | 
 | 125 | +target_triplet = get(ARGS, 1, Base.BinaryPlatforms.host_triplet())  | 
 | 126 | + | 
 | 127 | +# Augment this platform object with any special tags we require  | 
 | 128 | +platform = augment_platform!(HostPlatform(bbparse(Platform, target_triplet)))  | 
 | 129 | + | 
 | 130 | +# Select all downloadable artifacts that match that platform  | 
 | 131 | +artifacts = select_downloadable_artifacts(artifacts_toml; platform, include_lazy=true)  | 
 | 132 | + | 
 | 133 | +# Output the result to `stdout` as a TOML dictionary  | 
 | 134 | +TOML.print(stdout, artifacts)  | 
0 commit comments