@@ -1416,6 +1416,124 @@ function build_jll_package(src_name::String,
14161416 ! ispath (pkg_dir) && mkdir (pkg_dir)
14171417 write (joinpath (pkg_dir, " platform_augmentation.jl" ), augment_platform_block)
14181418
1419+ overload_parse = raw """
1420+ # Update Base.parse to support riscv64, needed for Julia <1.12
1421+ @static if !haskey(BinaryPlatforms.arch_mapping, "riscv64")
1422+
1423+ BinaryPlatforms.arch_mapping["riscv64"] = "(rv64|riscv64)"
1424+
1425+ function bbparse(::Type{Platform}, triplet::AbstractString; validate_strict::Bool = false)
1426+ arch_mapping = BinaryPlatforms.arch_mapping
1427+ os_mapping = BinaryPlatforms.os_mapping
1428+ libc_mapping = BinaryPlatforms.libc_mapping
1429+ call_abi_mapping = BinaryPlatforms.call_abi_mapping
1430+ libgfortran_version_mapping = BinaryPlatforms.libgfortran_version_mapping
1431+ cxxstring_abi_mapping = BinaryPlatforms.cxxstring_abi_mapping
1432+ libstdcxx_version_mapping = BinaryPlatforms.libstdcxx_version_mapping
1433+
1434+ # Helper function to collapse dictionary of mappings down into a regex of
1435+ # named capture groups joined by "|" operators
1436+ c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")")
1437+
1438+ # We're going to build a mondo regex here to parse everything:
1439+ triplet_regex = Regex(string(
1440+ "^",
1441+ # First, the core triplet; arch/os/libc/call_abi
1442+ c(arch_mapping),
1443+ c(os_mapping),
1444+ c(libc_mapping),
1445+ c(call_abi_mapping),
1446+ # Next, optional things, like libgfortran/libstdcxx/cxxstring abi
1447+ c(libgfortran_version_mapping),
1448+ c(cxxstring_abi_mapping),
1449+ c(libstdcxx_version_mapping),
1450+ # Finally, the catch-all for extended tags
1451+ "(?<tags>(?:-[^-]+\\ +[^-]+)*)?",
1452+ "\$ ",
1453+ ))
1454+
1455+ m = match(triplet_regex, triplet)
1456+ if m !== nothing
1457+ # Helper function to find the single named field within the giant regex
1458+ # that is not `nothing` for each mapping we give it.
1459+ get_field(m, mapping) = begin
1460+ for k in keys(mapping)
1461+ if m[k] !== nothing
1462+ # Convert our sentinel `nothing` values to actual `nothing`
1463+ if endswith(k, "_nothing")
1464+ return nothing
1465+ end
1466+ # Convert libgfortran/libstdcxx version numbers
1467+ if startswith(k, "libgfortran")
1468+ return VersionNumber(parse(Int,k[12:end]))
1469+ elseif startswith(k, "libstdcxx")
1470+ return VersionNumber(3, 4, parse(Int,m[k][11:end]))
1471+ else
1472+ return k
1473+ end
1474+ end
1475+ end
1476+ end
1477+
1478+ # Extract the information we're interested in:
1479+ arch = get_field(m, arch_mapping)
1480+ os = get_field(m, os_mapping)
1481+ libc = get_field(m, libc_mapping)
1482+ call_abi = get_field(m, call_abi_mapping)
1483+ libgfortran_version = get_field(m, libgfortran_version_mapping)
1484+ libstdcxx_version = get_field(m, libstdcxx_version_mapping)
1485+ cxxstring_abi = get_field(m, cxxstring_abi_mapping)
1486+ function split_tags(tagstr)
1487+ tag_fields = filter(!isempty, split(tagstr, "-"))
1488+ if isempty(tag_fields)
1489+ return Pair{String,String}[]
1490+ end
1491+ return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+"))
1492+ end
1493+ tags = split_tags(m["tags"])
1494+
1495+ # Special parsing of os version number, if any exists
1496+ function extract_os_version(os_name, pattern)
1497+ m_osvn = match(pattern, m[os_name])
1498+ if m_osvn !== nothing
1499+ return VersionNumber(m_osvn.captures[1])
1500+ end
1501+ return nothing
1502+ end
1503+ os_version = nothing
1504+ if os == "macos"
1505+ os_version = extract_os_version("macos", r".*darwin([\d .]+)"sa)
1506+ end
1507+ if os == "freebsd"
1508+ os_version = extract_os_version("freebsd", r".*freebsd([\d .]+)"sa)
1509+ end
1510+ if os == "openbsd"
1511+ os_version = extract_os_version("openbsd", r".*openbsd([\d .]+)"sa)
1512+ end
1513+
1514+ return Platform(
1515+ arch, os;
1516+ validate_strict,
1517+ libc,
1518+ call_abi,
1519+ libgfortran_version,
1520+ cxxstring_abi,
1521+ libstdcxx_version,
1522+ os_version,
1523+ tags...,
1524+ )
1525+ end
1526+ throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform"))
1527+ end
1528+
1529+ else
1530+ # riscv64 is supported, all is fine
1531+
1532+ const bbparse = parse
1533+
1534+ end
1535+ """
1536+
14191537 write (joinpath (pkg_dir, " select_artifacts.jl" ),
14201538 """
14211539 push!(Base.LOAD_PATH, dirname(@__DIR__))
@@ -1424,16 +1542,18 @@ function build_jll_package(src_name::String,
14241542 include("./platform_augmentation.jl")
14251543 artifacts_toml = joinpath(dirname(@__DIR__), "Artifacts.toml")
14261544
1545+ $(overload_parse)
1546+
14271547 # Get "target triplet" from ARGS, if given (defaulting to the host triplet otherwise)
14281548 target_triplet = get(ARGS, 1, Base.BinaryPlatforms.host_triplet())
14291549
14301550 # Augment this platform object with any special tags we require
1431- platform = augment_platform!(HostPlatform(parse (Platform, target_triplet)))
1551+ platform = augment_platform!(HostPlatform(bbparse (Platform, target_triplet)))
14321552
14331553 # Select all downloadable artifacts that match that platform
14341554 artifacts = select_downloadable_artifacts(artifacts_toml; platform, include_lazy=true)
14351555
1436- #Output the result to `stdout` as a TOML dictionary
1556+ # Output the result to `stdout` as a TOML dictionary
14371557 TOML.print(stdout, artifacts)
14381558 """ )
14391559 end
0 commit comments