diff --git a/src/Rootfs.jl b/src/Rootfs.jl index 270221b5..28d9c042 100644 --- a/src/Rootfs.jl +++ b/src/Rootfs.jl @@ -397,14 +397,18 @@ const available_llvm_builds = [ ] """ - gcc_version(p::AbstractPlatform, , GCC_builds::Vector{GCCBuild}; + gcc_version(p::AbstractPlatform, + GCC_builds::Vector{GCCBuild}, + compilers::Vector{Symbol}; llvm_version::Union{Nothing,VersionNumber}=nothing) Returns the closest matching GCC version number for the given particular platform, from the given set of options. The compiler ABI and the microarchitecture of the platform will be taken into account. If no match is -found, returns an empty list. If the keyword argument `llvm_version` is passed, -it is used to filter the version of GCC for FreeBSD platforms. +found, returns an empty list. `compilers` is the list of compilers used in the +build, to choose the right version of GCC to couple with them if necessary. If +the keyword argument `llvm_version` is passed, it is used to filter the version +of GCC for FreeBSD platforms. This method assumes that the compiler ABI of the platform represents a platform that binaries will be run on, and thus versions are always rounded down; e.g. if @@ -413,7 +417,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}; llvm_version::Union{Nothing,VersionNumber}=nothing) # First, filter by libgfortran version. if libgfortran_version(p) !== nothing @@ -447,6 +452,12 @@ function gcc_version(p::AbstractPlatform, GCC_builds::Vector{GCCBuild}; GCC_builds = filter(b -> getversion(b) ≥ v"6", 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) + GCC_builds = filter(b -> getversion(b) >= v"5", GCC_builds) + end + # Filter the possible GCC versions depending on the microarchitecture if march(p) in ("avx", "avx2", "neonvfpv4") # "sandybridge", "haswell", "cortex-a53" introduced in GCC v4.9.0: @@ -477,6 +488,7 @@ function llvm_version(p::AbstractPlatform, LLVM_builds::Vector{LLVMBuild}) end function select_compiler_versions(p::AbstractPlatform, + compilers::Vector{Symbol}, GCC_builds::Vector{GCCBuild} = available_gcc_builds, LLVM_builds::Vector{LLVMBuild} = available_llvm_builds, preferred_gcc_version::VersionNumber = getversion(GCC_builds[1]), @@ -490,7 +502,7 @@ function select_compiler_versions(p::AbstractPlatform, end llvmv = select_closest_version(preferred_llvm_version, filtered_llvm_builds) - filtered_gcc_builds = gcc_version(p, GCC_builds; llvm_version=llvmv) + filtered_gcc_builds = gcc_version(p, GCC_builds, compilers; llvm_version=llvmv) if isempty(filtered_gcc_builds) error("Impossible compiler constraints $(p) upon $(GCC_builds)!") end @@ -569,6 +581,7 @@ function choose_shards(p::AbstractPlatform; if isempty(bootstrap_list) # Select GCC and LLVM versions given the compiler ABI and target requirements given in `p` GCC_build, LLVM_build = select_compiler_versions(p, + compilers, this_platform_GCC_builds, LLVM_builds, preferred_gcc_version, diff --git a/src/Runner.jl b/src/Runner.jl index 6fea064b..a2623996 100644 --- a/src/Runner.jl +++ b/src/Runner.jl @@ -372,7 +372,7 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr function macos_gcc_flags!(p::AbstractPlatform, flags::Vector{String} = String[]) # On macOS, if we're on an old GCC, the default -syslibroot that gets # passed to the linker isn't calculated correctly, so we have to manually set it. - gcc_version, llvm_version = select_compiler_versions(p) + gcc_version, llvm_version = select_compiler_versions(p, compilers) if gcc_version.major in (4, 5) push!(flags, "-Wl,-syslibroot,/opt/$(aatriplet(p))/$(aatriplet(p))/sys-root") end @@ -423,7 +423,7 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr function gcc_link_flags!(p::AbstractPlatform, flags::Vector{String} = String[]) # Yes, it does seem that the inclusion of `/lib64` on `powerpc64le` was fixed # in GCC 6, broken again in GCC 7, and then fixed again for GCC 8 and 9 - gcc_version, llvm_version = select_compiler_versions(p) + gcc_version, llvm_version = select_compiler_versions(p, compilers) if arch(p) == "powerpc64le" && Sys.islinux(p) && gcc_version.major in (4, 5, 7) append!(flags, String[ "-L/opt/$(aatriplet(p))/$(aatriplet(p))/sys-root/lib64",