diff --git a/Artifacts.toml b/Artifacts.toml index 5a871359..88040fa2 100644 --- a/Artifacts.toml +++ b/Artifacts.toml @@ -1956,6 +1956,94 @@ os = "linux" sha256 = "d49106316ef5a4dc8cbce8665e720526a921cbba89dc38be41d53fc65c18007f" url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v9.1.0+2/GCCBootstrap-powerpc64le-linux-gnu.v9.1.0.x86_64-linux-musl.unpacked.tar.gz" +[["GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "0e0e172850698ee5784355eebeaf661278cfc489" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.squashfs".download]] + sha256 = "a51037a3b4eff64d08f63c48d16a5b873833d83a2085ac365cf11b0918c503cf" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v12.1.0/GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.squashfs.tar.gz" + +[["GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "55460cf13be2ec9fe829768b49ea5b2ba49954ef" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.unpacked".download]] + sha256 = "671879f013264f1627b5bff6ec246fd2806b4bc1ae9db74390df7004e00891d5" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v12.1.0/GCCBootstrap-riscv64-linux-gnu.v12.1.0.x86_64-linux-musl.unpacked.tar.gz" + +[["GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "83e2aeef1b7ff0abe246d83065877e36f270bb32" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.squashfs".download]] + sha256 = "a23f65e83be13b0eed7614b77e484dced1db4192732000edc1d4e52e39e4732e" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v13.2.0/GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.squashfs.tar.gz" + +[["GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "f62985d28a28baf1017c91dbd9f7fe504a718c12" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.unpacked".download]] + sha256 = "fc2b0c57b83c22416cdab285b8e3efaa3c55988d1a771e2ade6308d6b24674f5" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v13.2.0/GCCBootstrap-riscv64-linux-gnu.v13.2.0.x86_64-linux-musl.unpacked.tar.gz" + +[["GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "0a988108fd945733a2b493ae398b67588abc0e32" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.squashfs".download]] + sha256 = "2fe11e0f794df6af2ab39b8e6d1c4efc32cdb792fd045409cdcedd96d643a1c5" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v12.1.0/GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.squashfs.tar.gz" + +[["GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "a10265906d9a12bbc7a2a9a6ed0a4d67cb6a3ad0" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.unpacked".download]] + sha256 = "d958a67682d30ea9e04116db4f463c17f0bf63823e352692d5fe7982da86e220" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v12.1.0/GCCBootstrap-riscv64-linux-musl.v12.1.0.x86_64-linux-musl.unpacked.tar.gz" + +[["GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "fa8d3617b8a7a823076c43315b19eea746e61ea0" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.squashfs".download]] + sha256 = "0b1e047575add41887b4706971bc36d34c235a0561e8e03b03698d76b61c7262" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v13.2.0/GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.squashfs.tar.gz" + +[["GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "87d33912a955c60bda8476493049f905092cd1db" +lazy = true +libc = "musl" +os = "linux" + + [["GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.unpacked".download]] + sha256 = "a45d64532488eccb57d65b1dc3fbc5aa65b1204a327f05a0db14d4ff582b2b59" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/GCCBootstrap-v13.2.0/GCCBootstrap-riscv64-linux-musl.v13.2.0.x86_64-linux-musl.unpacked.tar.gz" + [["GCCBootstrap-x86_64-apple-darwin14.v10.2.0.x86_64-linux-musl.squashfs"]] arch = "x86_64" git-tree-sha1 = "ceb591a6cf8b32224a2a62cf3d8a9572c1c83e62" @@ -4068,6 +4156,50 @@ os = "linux" sha256 = "5368cefab3e9ebd704d60f13fa5982d1d8566d9025c47ad6288c0c4f3f02efb7" url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2024.8.10/PlatformSupport-powerpc64le-linux-gnu.v2024.8.10.x86_64-linux-musl.unpacked.tar.gz" +[["PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "b176fca4332dbcd60e0f4195feafef712394be6d" +lazy = true +libc = "musl" +os = "linux" + + [["PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.squashfs".download]] + sha256 = "6348339e933ca990739e4328a4bcf449cb2944feea590f84ca9b25a6dfba6cb4" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2024.12.21/PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.squashfs.tar.gz" + +[["PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "5b9695b4efe229b51926b4c9ffb9a0c891e8ccdd" +lazy = true +libc = "musl" +os = "linux" + + [["PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.unpacked".download]] + sha256 = "757fe58ba7561cb61051ef22e8a36f3066fb63b0978cf14ad276313368c43a5f" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2024.12.21/PlatformSupport-riscv64-linux-gnu.v2024.12.21.x86_64-linux-musl.unpacked.tar.gz" + +[["PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.squashfs"]] +arch = "x86_64" +git-tree-sha1 = "72708b43067d2c5b35e46fee91fc1f1164f540af" +lazy = true +libc = "musl" +os = "linux" + + [["PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.squashfs".download]] + sha256 = "a8330a71a91ada1eebad7874911ca51cdba7cef5ad0512495384e44fea564507" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2024.12.21/PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.squashfs.tar.gz" + +[["PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.unpacked"]] +arch = "x86_64" +git-tree-sha1 = "e15c076bcd4f0ed54f8c7db8bded7da61d6eab30" +lazy = true +libc = "musl" +os = "linux" + + [["PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.unpacked".download]] + sha256 = "e9f16e6893bf2815a975ffd37ae12b8f74f81e2da5b2d061126fee62833a2bab" + url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2024.12.21/PlatformSupport-riscv64-linux-musl.v2024.12.21.x86_64-linux-musl.unpacked.tar.gz" + [["PlatformSupport-x86_64-apple-darwin14.v2021.8.10.x86_64-linux-musl.squashfs"]] arch = "x86_64" git-tree-sha1 = "bc7f1d08ee0ff50a8665304159d0038d4ece04eb" diff --git a/Project.toml b/Project.toml index bcf96a91..4661b4c1 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "BinaryBuilderBase" uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e" authors = ["Elliot Saba "] -version = "1.32.0" +version = "1.33.0" [deps] Bzip2_jll = "6e34b625-4abd-537c-b88f-471c36dfa7a0" diff --git a/src/BinaryBuilderBase.jl b/src/BinaryBuilderBase.jl index e8f91a07..e51cf27b 100644 --- a/src/BinaryBuilderBase.jl +++ b/src/BinaryBuilderBase.jl @@ -27,6 +27,8 @@ export AbstractSource, AbstractDependency, SetupSource, PatchSource, include("compat.jl") +include("riscv64.jl") + include("ArchiveUtils.jl") include("Sources.jl") include("Dependencies.jl") diff --git a/src/BuildToolchains.jl b/src/BuildToolchains.jl index c655a40f..bef4ddba 100644 --- a/src/BuildToolchains.jl +++ b/src/BuildToolchains.jl @@ -170,6 +170,8 @@ function meson_cpu_family(p::AbstractPlatform) return "aarch64" elseif startswith(arch(p)::String, "arm") return "arm" + elseif arch(p) == "riscv64" + return "riscv64" end end diff --git a/src/Platforms.jl b/src/Platforms.jl index e2ab18ea..f822b67c 100644 --- a/src/Platforms.jl +++ b/src/Platforms.jl @@ -135,7 +135,7 @@ const ARCHITECTURE_FLAGS = Dict( "arm1176jzfs" => ["-mcpu=arm1176jzf-s", "-mfpu=vfp", "-mfloat-abi=hard"], ), "armv7l" => OrderedDict( - # Base armv7l architecture, with the most basic of FPU's + # Base armv7l architecture, with the most basic of FPUs "armv7l" => ["-march=armv7-a", "-mtune=generic-armv7-a", "-mfpu=vfpv3", "-mfloat-abi=hard"], # armv7l plus NEON and vfpv4, (Raspberry Pi 2B+, RK3328, most boards Elliot has access to) "neonvfpv4" => ["-mcpu=cortex-a53", "-mfpu=neon-vfpv4", "-mfloat-abi=hard"], @@ -158,7 +158,10 @@ const ARCHITECTURE_FLAGS = Dict( #"power9" => ["-mcpu=power9", "-mtune=power9"], # Eventually, we'll support power10, once we have compilers that support it. #"power10" => ["-mcpu=power10", "-mtune=power10"], - ) + ), + "riscv64" => OrderedDict( + "riscv64" => ["-march=rv64gc", "-mabi=lp64d"], + ), ), "gcc" => Dict( "aarch64" => OrderedDict( diff --git a/src/Rootfs.jl b/src/Rootfs.jl index a0d2e4df..8a891856 100644 --- a/src/Rootfs.jl +++ b/src/Rootfs.jl @@ -431,7 +431,8 @@ the only GCC versions available to be picked from are `4.8.5` and `5.2.0`, it will return `4.8.5`, as binaries compiled with that version will run on this platform, whereas binaries compiled with `5.2.0` may not. """ -function gcc_version(p::AbstractPlatform,GCC_builds::Vector{GCCBuild}, +function gcc_version(p::AbstractPlatform, + GCC_builds::Vector{GCCBuild}, compilers::Vector{Symbol}=[:c]; llvm_version::Union{Nothing,VersionNumber}=nothing) # First, filter by libgfortran version. @@ -471,6 +472,12 @@ function gcc_version(p::AbstractPlatform,GCC_builds::Vector{GCCBuild}, GCC_builds = filter(b -> getversion(b) ≥ v"7", GCC_builds) end + # We only have GCC 12 or newer for RISC-V. + # (This could be changed down to GCC 7.1.) + if arch(p) == "riscv64" + GCC_builds = filter(b -> getversion(b) ≥ v"12", GCC_builds) + end + # Rust on Windows requires binutils 2.25 (it invokes `ld` with `--high-entropy-va`), # which we bundle with GCC 5. if :rust in compilers && Sys.iswindows(p) @@ -525,6 +532,7 @@ function llvm_version(p::AbstractPlatform, LLVM_builds::Vector{LLVMBuild}) # The target `apple-m1` was introduced in LLVM 13 LLVM_builds = filter(b -> getversion(b) >= v"13.0", LLVM_builds) end + return getversion.(LLVM_builds) end @@ -631,9 +639,11 @@ function choose_shards(p::AbstractPlatform; ) # We _always_ need Rootfs and PlatformSupport for our target, at least + # We don't have old platform support for riscv64. Remove this once all platform support is aligned in time. + ps_build_new = arch(p) == "riscv64" ? max(ps_build, v"2024.12.21") : ps_build append!(shards, [ find_shard("Rootfs", rootfs_build, archive_type), - find_shard("PlatformSupport", ps_build, archive_type; target=p) + find_shard("PlatformSupport", ps_build_new, archive_type; target=p) ]) if :c in compilers @@ -719,6 +729,7 @@ function supported_platforms(;exclude::Union{Vector{<:Platform},Function}=Return Platform("armv6l", "linux"), Platform("armv7l", "linux"), Platform("powerpc64le", "linux"), + Platform("riscv64", "linux"), # musl Linuces Platform("i686", "linux"; libc="musl"), @@ -773,6 +784,9 @@ function expand_gfortran_versions(platform::AbstractPlatform) libgfortran_versions = [v"5"] elseif Sys.isfreebsd(platform) && arch(platform) == "aarch64" libgfortran_versions = [v"4", v"5"] + elseif arch(platform) == "riscv64" + # We don't have older GCC versions + libgfortran_versions = [v"5"] else libgfortran_versions = [v"3", v"4", v"5"] end @@ -810,7 +824,7 @@ function expand_cxxstring_abis(platform::AbstractPlatform; skip=Sys.isbsd) if sanitize(platform) == "memory" p = deepcopy(platform) - p["cxxstring_abi"] = "cxx11" #Clang only seems to generate cxx11 abi + p["cxxstring_abi"] = "cxx11" # Clang only seems to generate cxx11 abi return [p] end @@ -913,7 +927,7 @@ argument. julia> using BinaryBuilderBase julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glibc", supported_platforms())) -14-element Vector{Platform}: +15-element Vector{Platform}: Linux i686 {libc=glibc, march=pentium4} Linux i686 {libc=glibc, march=prescott} Linux x86_64 {libc=glibc, march=x86_64} @@ -928,9 +942,10 @@ julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glib Linux armv7l {call_abi=eabihf, libc=glibc, march=armv7l} Linux armv7l {call_abi=eabihf, libc=glibc, march=neonvfpv4} Linux powerpc64le {libc=glibc, march=power8} + Linux riscv64 {libc=glibc, march=riscv64} julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glibc", supported_platforms()), ["x86_64", "avx2"]) -7-element Vector{Platform}: +8-element Vector{Platform}: Linux i686 {libc=glibc} Linux x86_64 {libc=glibc, march=x86_64} Linux x86_64 {libc=glibc, march=avx2} @@ -938,9 +953,10 @@ julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glib Linux armv6l {call_abi=eabihf, libc=glibc} Linux armv7l {call_abi=eabihf, libc=glibc} Linux powerpc64le {libc=glibc} + Linux riscv64 {libc=glibc} julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glibc", supported_platforms()); filter=p->arch(p)=="x86_64") -9-element Vector{Platform}: +10-element Vector{Platform}: Linux i686 {libc=glibc} Linux x86_64 {libc=glibc, march=x86_64} Linux x86_64 {libc=glibc, march=avx} @@ -950,6 +966,7 @@ julia> expand_microarchitectures(filter!(p -> Sys.islinux(p) && libc(p) == "glib Linux armv6l {call_abi=eabihf, libc=glibc} Linux armv7l {call_abi=eabihf, libc=glibc} Linux powerpc64le {libc=glibc} + Linux riscv64 {libc=glibc} ``` """ function expand_microarchitectures(ps::Vector{<:AbstractPlatform}, diff --git a/src/Runner.jl b/src/Runner.jl index 8106cc09..54a1a18a 100644 --- a/src/Runner.jl +++ b/src/Runner.jl @@ -18,7 +18,7 @@ const default_host_platform = Platform("x86_64", "linux"; libc="musl", cxxstring function nbits(p::AbstractPlatform) if arch(p) in ("i686", "armv6l", "armv7l") return 32 - elseif arch(p) in ("x86_64", "aarch64", "powerpc64le") + elseif arch(p) in ("x86_64", "aarch64", "powerpc64le", "riscv64") return 64 else error("Unknown bitwidth for architecture $(arch(p))") @@ -32,6 +32,8 @@ function proc_family(p::AbstractPlatform) return "arm" elseif arch(p) == "powerpc64le" return "power" + elseif arch(p) == "riscv64" + return "riscv" else error("Unknown processor family for architecture $(arch(p))") end @@ -662,6 +664,7 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr "x86_64" => "amd64", "i686" => "386", "powerpc64le" => "ppc64le", + "riscv64" => "riscv64", ) return arch_mapping[arch(p)] end @@ -1288,6 +1291,8 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString; mapping["GNU_LIBC_VERSION"] = "glibc 2.19" elseif arch(platform) in ("x86_64", "i686", "powerpc64le") mapping["GNU_LIBC_VERSION"] = "glibc 2.17" + elseif arch(platform) in ("riscv64",) + mapping["GNU_LIBC_VERSION"] = "glibc 2.35" end end diff --git a/src/riscv64.jl b/src/riscv64.jl new file mode 100644 index 00000000..7f9ca93f --- /dev/null +++ b/src/riscv64.jl @@ -0,0 +1,195 @@ +using Base: BinaryPlatforms + +@static if !haskey(BinaryPlatforms.arch_mapping, "riscv64") + +# We pirate a few functions and global variables from Base.BinaryPlatforms. +# These changes have been upstreamed to newer Julia versions, but we are stuck with Julia 1.7. +# This is not pretty. It seems to work. + +function setup_riscv64() + BinaryPlatforms.CPUID.ISAs_by_family["riscv64"] = [ + # We have no way to test riscv64 features yet, so we're only going to declare the lowest ISA: + "riscv64" => BinaryPlatforms.CPUID.ISA(Set{UInt32}()), + ] + + BinaryPlatforms.arch_mapping["riscv64"] = "(rv64|riscv64)" + + function get_set(arch, name) + all = BinaryPlatforms.CPUID.ISAs_by_family[arch] + return all[findfirst(x -> x.first == name, all)].second + end + BinaryPlatforms.arch_march_isa_mapping["riscv64"] = ["riscv64" => get_set("riscv64", "riscv64")] +end + +__init__() = setup_riscv64() + + + +function Base.BinaryPlatforms.validate_tags(tags::Dict) + throw_invalid_key(k) = throw(ArgumentError("Key \"$(k)\" cannot have value \"$(tags[k])\"")) + # Validate `arch` + if tags["arch"] ∉ ("x86_64", "i686", "armv7l", "armv6l", "aarch64", "powerpc64le", "riscv64") + throw_invalid_key("arch") + end + # Validate `os` + if tags["os"] ∉ ("linux", "macos", "freebsd", "windows") + throw_invalid_key("os") + end + # Validate `os`/`arch` combination + throw_os_mismatch() = throw(ArgumentError("Invalid os/arch combination: $(tags["os"])/$(tags["arch"])")) + if tags["os"] == "windows" && tags["arch"] ∉ ("x86_64", "i686", "armv7l", "aarch64") + throw_os_mismatch() + end + if tags["os"] == "macos" && tags["arch"] ∉ ("x86_64", "aarch64") + throw_os_mismatch() + end + + # Validate `os`/`libc` combination + throw_libc_mismatch() = throw(ArgumentError("Invalid os/libc combination: $(tags["os"])/$(tags["libc"])")) + if tags["os"] == "linux" + # Linux always has a `libc` entry + if tags["libc"] ∉ ("glibc", "musl") + throw_libc_mismatch() + end + else + # Nothing else is allowed to have a `libc` entry + if haskey(tags, "libc") + throw_libc_mismatch() + end + end + + # Validate `os`/`arch`/`call_abi` combination + throw_call_abi_mismatch() = throw(ArgumentError("Invalid os/arch/call_abi combination: $(tags["os"])/$(tags["arch"])/$(tags["call_abi"])")) + if tags["os"] == "linux" && tags["arch"] ∈ ("armv7l", "armv6l") + # If an ARM linux has does not have `call_abi` set to something valid, be sad. + if !haskey(tags, "call_abi") || tags["call_abi"] ∉ ("eabihf", "eabi") + throw_call_abi_mismatch() + end + else + # Nothing else should have a `call_abi`. + if haskey(tags, "call_abi") + throw_call_abi_mismatch() + end + end + + # Validate `libgfortran_version` is a parsable `VersionNumber` + throw_version_number(k) = throw(ArgumentError("\"$(k)\" cannot have value \"$(tags[k])\", must be a valid VersionNumber")) + if "libgfortran_version" in keys(tags) && tryparse(VersionNumber, tags["libgfortran_version"]) === nothing + throw_version_number("libgfortran_version") + end + + # Validate `cxxstring_abi` is one of the two valid options: + if "cxxstring_abi" in keys(tags) && tags["cxxstring_abi"] ∉ ("cxx03", "cxx11") + throw_invalid_key("cxxstring_abi") + end + + # Validate `libstdcxx_version` is a parsable `VersionNumber` + if "libstdcxx_version" in keys(tags) && tryparse(VersionNumber, tags["libstdcxx_version"]) === nothing + throw_version_number("libstdcxx_version") + end +end + +function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict::Bool = false) + setup_riscv64() + + arch_mapping = BinaryPlatforms.arch_mapping + os_mapping = BinaryPlatforms.os_mapping + libc_mapping = BinaryPlatforms.libc_mapping + call_abi_mapping = BinaryPlatforms.call_abi_mapping + libgfortran_version_mapping = BinaryPlatforms.libgfortran_version_mapping + cxxstring_abi_mapping = BinaryPlatforms.cxxstring_abi_mapping + libstdcxx_version_mapping = BinaryPlatforms.libstdcxx_version_mapping + + # Helper function to collapse dictionary of mappings down into a regex of + # named capture groups joined by "|" operators + c(mapping) = string("(",join(["(?<$k>$v)" for (k, v) in mapping], "|"), ")") + + # We're going to build a mondo regex here to parse everything: + triplet_regex = Regex(string( + "^", + # First, the core triplet; arch/os/libc/call_abi + c(arch_mapping), + c(os_mapping), + c(libc_mapping), + c(call_abi_mapping), + # Next, optional things, like libgfortran/libstdcxx/cxxstring abi + c(libgfortran_version_mapping), + c(cxxstring_abi_mapping), + c(libstdcxx_version_mapping), + # Finally, the catch-all for extended tags + "(?(?:-[^-]+\\+[^-]+)*)?", + "\$", + )) + + m = match(triplet_regex, triplet) + if m !== nothing + # Helper function to find the single named field within the giant regex + # that is not `nothing` for each mapping we give it. + get_field(m, mapping) = begin + for k in keys(mapping) + if m[k] !== nothing + # Convert our sentinel `nothing` values to actual `nothing` + if endswith(k, "_nothing") + return nothing + end + # Convert libgfortran/libstdcxx version numbers + if startswith(k, "libgfortran") + return VersionNumber(parse(Int,k[12:end])) + elseif startswith(k, "libstdcxx") + return VersionNumber(3, 4, parse(Int,m[k][11:end])) + else + return k + end + end + end + end + + # Extract the information we're interested in: + arch = get_field(m, arch_mapping) + os = get_field(m, os_mapping) + libc = get_field(m, libc_mapping) + call_abi = get_field(m, call_abi_mapping) + libgfortran_version = get_field(m, libgfortran_version_mapping) + libstdcxx_version = get_field(m, libstdcxx_version_mapping) + cxxstring_abi = get_field(m, cxxstring_abi_mapping) + function split_tags(tagstr) + tag_fields = filter(!isempty, split(tagstr, "-")) + if isempty(tag_fields) + return Pair{String,String}[] + end + return map(v -> Symbol(v[1]) => v[2], split.(tag_fields, "+")) + end + tags = split_tags(m["tags"]) + + # Special parsing of os version number, if any exists + function extract_os_version(os_name, pattern) + m_osvn = match(pattern, m[os_name]) + if m_osvn !== nothing + return VersionNumber(m_osvn.captures[1]) + end + return nothing + end + os_version = nothing + if os == "macos" + os_version = extract_os_version("macos", r".*darwin([\d\.]+)") + end + if os == "freebsd" + os_version = extract_os_version("freebsd", r".*freebsd([\d.]+)") + end + + return Platform( + arch, os; + validate_strict, + libc, + call_abi, + libgfortran_version, + cxxstring_abi, + libstdcxx_version, + os_version, + tags..., + ) + end + throw(ArgumentError("Platform `$(triplet)` is not an officially supported platform")) +end + +end diff --git a/test/platforms.jl b/test/platforms.jl index 19837b7d..1412acf2 100644 --- a/test/platforms.jl +++ b/test/platforms.jl @@ -65,7 +65,7 @@ end end for p in [Platform("x86_64", "linux"), Platform("x86_64", "windows"), Platform("aarch64", "linux"), - Platform("powerpc64le", "linux"), Platform("x86_64", "macos")] + Platform("powerpc64le", "linux"), Platform("riscv64", "linux"), Platform("x86_64", "macos")] @test nbits(p) == 64 end @@ -76,8 +76,10 @@ end @test proc_family(p) == "arm" end @test proc_family(Platform("powerpc64le", "linux")) == "power" + @test proc_family(Platform("riscv64", "linux")) == "riscv" - for p in [Platform("x86_64", "linux"), Platform("x86_64", "freebsd"), Platform("powerpc64le", "linux"), Platform("x86_64", "macos")] + for p in [Platform("x86_64", "linux"), Platform("x86_64", "freebsd"), Platform("powerpc64le", "linux"), + Platform("riscv64", "linux"), Platform("x86_64", "macos")] @test platform_exeext(p) == "" end @test platform_exeext(Platform("x86_64", "windows")) == ".exe" @@ -107,7 +109,7 @@ using BinaryBuilderBase: get_march_flags, get_all_arch_names, get_all_march_name end # Get all architectures and all microarchitectures for the different architectures - @test sort(get_all_arch_names()) == ["aarch64", "armv6l", "armv7l", "i686", "powerpc64le", "x86_64"] + @test sort(get_all_arch_names()) == ["aarch64", "armv6l", "armv7l", "i686", "powerpc64le", "riscv64", "x86_64"] @test sort(get_all_march_names("x86_64")) == ["avx", "avx2", "avx512", "x86_64"] @test sort(get_all_march_names("armv7l")) == ["armv7l", "neonvfpv4"] end diff --git a/test/rootfs.jl b/test/rootfs.jl index 9007559f..77f5f065 100644 --- a/test/rootfs.jl +++ b/test/rootfs.jl @@ -86,6 +86,7 @@ using BinaryBuilderBase Platform("i686", "linux"; libc="glibc", march="pentium4"), Platform("i686", "linux"; libc="glibc", march="prescott"), Platform("powerpc64le", "linux"; libc="glibc", march="power8"), + Platform("riscv64", "linux"; libc="glibc", march="riscv64"), Platform("x86_64", "linux"; libc="glibc", march="avx"), Platform("x86_64", "linux"; libc="glibc", march="avx2"), Platform("x86_64", "linux"; libc="glibc", march="avx512"), diff --git a/test/runners.jl b/test/runners.jl index 75b9c075..95698207 100644 --- a/test/runners.jl +++ b/test/runners.jl @@ -9,6 +9,7 @@ using Pkg @test nbits(Platform("armv7l", "linux")) == 32 @test nbits(Platform("aarch64", "linux"; cuda="10.1")) == 64 @test nbits(Platform("powerpc64le", "linux")) == 64 + @test nbits(Platform("riscv64", "linux")) == 64 @test nbits(AnyPlatform()) == 64 @test proc_family(Platform("i686", "linux")) == "intel" @@ -16,6 +17,7 @@ using Pkg @test proc_family(Platform("armv7l", "linux")) == "arm" @test proc_family(Platform("aarch64", "linux"; cuda="10.1")) == "arm" @test proc_family(Platform("powerpc64le", "linux")) == "power" + @test proc_family(Platform("riscv64", "linux")) == "riscv" @test proc_family(AnyPlatform()) == "any" @test platform_exeext(Platform("i686", "linux")) == "" @@ -28,6 +30,8 @@ using Pkg @test prefer_clang(Platform("x86_64", "freebsd")) @test prefer_clang(Platform("aarch64", "macos")) + @test !prefer_clang(Platform("powerpc64le", "linux")) + @test !prefer_clang(Platform("riscv64", "linux")) @test !prefer_clang(Platform("x86_64", "linux")) @test prefer_clang(Platform("x86_64", "linux"; sanitize="memory")) @test !prefer_clang(Platform("x86_64", "linux"; sanitize="thread"))