Skip to content

Commit 60a8583

Browse files
committed
Support platform augmentation for riscv64
1 parent 6981412 commit 60a8583

File tree

2 files changed

+117
-5
lines changed

2 files changed

+117
-5
lines changed

src/AutoBuild.jl

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1424,11 +1424,124 @@ function build_jll_package(src_name::String,
14241424
include("./platform_augmentation.jl")
14251425
artifacts_toml = joinpath(dirname(@__DIR__), "Artifacts.toml")
14261426
1427+
# Update Base.parse for Julia <1.12 to support riscv64
1428+
@static if !haskey(BinaryPlatforms.arch_mapping, "riscv64")
1429+
1430+
function bbparse(::Type{Platform}, triplet::AbstractString; validate_strict::Bool = false)
1431+
# setup_riscv64()
1432+
1433+
arch_mapping = BinaryPlatforms.arch_mapping
1434+
os_mapping = BinaryPlatforms.os_mapping
1435+
libc_mapping = BinaryPlatforms.libc_mapping
1436+
call_abi_mapping = BinaryPlatforms.call_abi_mapping
1437+
libgfortran_version_mapping = BinaryPlatforms.libgfortran_version_mapping
1438+
cxxstring_abi_mapping = BinaryPlatforms.cxxstring_abi_mapping
1439+
libstdcxx_version_mapping = BinaryPlatforms.libstdcxx_version_mapping
1440+
1441+
# Helper function to collapse dictionary of mappings down into a regex of
1442+
# named capture groups joined by "|" operators
1443+
c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")")
1444+
1445+
# We're going to build a mondo regex here to parse everything:
1446+
triplet_regex = Regex(string(
1447+
"^",
1448+
# First, the core triplet; arch/os/libc/call_abi
1449+
c(arch_mapping),
1450+
c(os_mapping),
1451+
c(libc_mapping),
1452+
c(call_abi_mapping),
1453+
# Next, optional things, like libgfortran/libstdcxx/cxxstring abi
1454+
c(libgfortran_version_mapping),
1455+
c(cxxstring_abi_mapping),
1456+
c(libstdcxx_version_mapping),
1457+
# Finally, the catch-all for extended tags
1458+
"(?<tags>(?:-[^-]+\\+[^-]+)*)?",
1459+
"\$",
1460+
))
1461+
1462+
m = match(triplet_regex, triplet)
1463+
if m !== nothing
1464+
# Helper function to find the single named field within the giant regex
1465+
# that is not `nothing` for each mapping we give it.
1466+
get_field(m, mapping) = begin
1467+
for k in keys(mapping)
1468+
if m[k] !== nothing
1469+
# Convert our sentinel `nothing` values to actual `nothing`
1470+
if endswith(k, "_nothing")
1471+
return nothing
1472+
end
1473+
# Convert libgfortran/libstdcxx version numbers
1474+
if startswith(k, "libgfortran")
1475+
return VersionNumber(parse(Int,k[12:end]))
1476+
elseif startswith(k, "libstdcxx")
1477+
return VersionNumber(3, 4, parse(Int,m[k][11:end]))
1478+
else
1479+
return k
1480+
end
1481+
end
1482+
end
1483+
end
1484+
1485+
# Extract the information we're interested in:
1486+
arch = get_field(m, arch_mapping)
1487+
os = get_field(m, os_mapping)
1488+
libc = get_field(m, libc_mapping)
1489+
call_abi = get_field(m, call_abi_mapping)
1490+
libgfortran_version = get_field(m, libgfortran_version_mapping)
1491+
libstdcxx_version = get_field(m, libstdcxx_version_mapping)
1492+
cxxstring_abi = get_field(m, cxxstring_abi_mapping)
1493+
function split_tags(tagstr)
1494+
tag_fields = filter(!isempty, split(tagstr, "-"))
1495+
if isempty(tag_fields)
1496+
return Pair{String,String}[]
1497+
end
1498+
return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+"))
1499+
end
1500+
tags = split_tags(m["tags"])
1501+
1502+
# Special parsing of os version number, if any exists
1503+
function extract_os_version(os_name, pattern)
1504+
m_osvn = match(pattern, m[os_name])
1505+
if m_osvn !== nothing
1506+
return VersionNumber(m_osvn.captures[1])
1507+
end
1508+
return nothing
1509+
end
1510+
os_version = nothing
1511+
if os == "macos"
1512+
os_version = extract_os_version("macos", r".*darwin([\d\.]+)")
1513+
end
1514+
if os == "freebsd"
1515+
os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)")
1516+
end
1517+
1518+
return Platform(
1519+
arch, os;
1520+
validate_strict,
1521+
libc,
1522+
call_abi,
1523+
libgfortran_version,
1524+
cxxstring_abi,
1525+
libstdcxx_version,
1526+
os_version,
1527+
tags...,
1528+
)
1529+
end
1530+
throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform"))
1531+
end
1532+
1533+
else
1534+
# Julia ≥ 1.12, all is fine
1535+
1536+
const bbparse = Base.parse
1537+
1538+
end
1539+
14271540
# Get "target triplet" from ARGS, if given (defaulting to the host triplet otherwise)
14281541
target_triplet = get(ARGS, 1, Base.BinaryPlatforms.host_triplet())
14291542
14301543
# Augment this platform object with any special tags we require
1431-
platform = augment_platform!(HostPlatform(parse(Platform, target_triplet)))
1544+
platform = augment_platform!(HostPlatform(bbparse(Platform, target_triplet)))
14321545
14331546
# Select all downloadable artifacts that match that platform
14341547
artifacts = select_downloadable_artifacts(artifacts_toml; platform, include_lazy=true)

test/building.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,15 +116,14 @@ shards_to_test = expand_cxxstring_abis(expand_gfortran_versions(shards_to_test))
116116
if !(platforms_match(shard, Platform("i686", "windows")) ||
117117
platforms_match(shard, Platform("aarch64", "freebsd")) ||
118118
platforms_match(shard, Platform("riscv64", "linux")))
119-
# Rust is broken on 32-bit Windows and unavailable on FreeBSD AArch64 and RISC-V, let's skip it
119+
# Rust is broken on 32-bit Windows and unavailable on FreeBSD AArch64 and Linux RISC-V, let's skip it
120120
push!(products, ExecutableProduct("hello_world_rust", :hello_world_rust))
121121
end
122122

123123
compilers = [:c, :go]
124-
# Don't even ask for Rust on FreeBSD AArch64 or RISC-V
124+
# Don't even ask for Rust on FreeBSD AArch64 and Linux RISC-V
125125
if !(platforms_match(shard, Platform("aarch64", "freebsd")) ||
126-
platforms_match(shard, Platform("riscv64", "linux"))
127-
)
126+
platforms_match(shard, Platform("riscv64", "linux")))
128127
push!(compilers, :rust)
129128
end
130129

0 commit comments

Comments
 (0)