@@ -319,15 +319,78 @@ function select_closest_version(preferred::VersionNumber, versions::Vector{Versi
319
319
return versions[closest_idx]
320
320
end
321
321
322
- const available_gcc_builds = [v " 4.8.5" , v " 5.2.0" , v " 6.1.0" , v " 7.1.0" , v " 8.1.0" , v " 9.1.0" ]
323
- const available_llvm_builds = [v " 6.0.1" , v " 7.1.0" , v " 8.0.1" , v " 9.0.1" ]
322
+ abstract type CompilerBuild end
323
+
324
+ struct GCCBuild <: CompilerBuild
325
+ version:: VersionNumber
326
+ abi:: CompilerABI
327
+ end
328
+ GCCBuild (v:: VersionNumber ) = GCCBuild (v, CompilerABI ())
329
+
330
+ struct LLVMBuild <: CompilerBuild
331
+ version:: VersionNumber
332
+ abi:: CompilerABI
333
+ end
334
+ LLVMBuild (v:: VersionNumber ) = LLVMBuild (v, CompilerABI ())
335
+
336
+ getversion (c:: CompilerBuild ) = c. version
337
+ getabi (c:: CompilerBuild ) = c. abi
338
+
339
+ const available_gcc_builds = [GCCBuild (v " 4.8.5" , CompilerABI (libgfortran_version = v " 3" , libstdcxx_version = v " 3.4.19" , cxxstring_abi = :cxx03 )),
340
+ GCCBuild (v " 5.2.0" , CompilerABI (libgfortran_version = v " 3" , libstdcxx_version = v " 3.4.21" , cxxstring_abi = :cxx11 )),
341
+ GCCBuild (v " 6.1.0" , CompilerABI (libgfortran_version = v " 3" , libstdcxx_version = v " 3.4.22" , cxxstring_abi = :cxx11 )),
342
+ GCCBuild (v " 7.1.0" , CompilerABI (libgfortran_version = v " 4" , libstdcxx_version = v " 3.4.23" , cxxstring_abi = :cxx11 )),
343
+ GCCBuild (v " 8.1.0" , CompilerABI (libgfortran_version = v " 5" , libstdcxx_version = v " 3.4.25" , cxxstring_abi = :cxx11 )),
344
+ GCCBuild (v " 9.1.0" , CompilerABI (libgfortran_version = v " 5" , libstdcxx_version = v " 3.4.26" , cxxstring_abi = :cxx11 ))]
345
+ const available_llvm_builds = [LLVMBuild (v " 6.0.1" ),
346
+ LLVMBuild (v " 7.1.0" ),
347
+ LLVMBuild (v " 8.0.1" ),
348
+ LLVMBuild (v " 9.0.1" )]
349
+
350
+ """
351
+ gcc_version(cabi::CompilerABI, GCC_builds::Vector{GCCBuild})
352
+
353
+ Returns the closest matching GCC version number for the given CompilerABI
354
+ representing a particular platofrm, from the given set of options. If no match
355
+ is found, returns an empty list. This method assumes that `cabi` represents a
356
+ platform that binaries will be run on, and thus versions are always rounded
357
+ down; e.g. if the platform supports a `libstdc++` version that corresponds to
358
+ `GCC 5.1.0`, but the only GCC versions available to be picked from are `4.8.5`
359
+ and `5.2.0`, it will return `4.8.5`, as binaries compiled with that version
360
+ will run on this platform, whereas binaries compiled with `5.2.0` may not.
361
+ """
362
+ function gcc_version (cabi:: CompilerABI , GCC_builds:: Vector{GCCBuild} )
363
+ # First, filter by libgfortran version.
364
+ if cabi. libgfortran_version != = nothing
365
+ GCC_builds = filter (b -> getabi (b). libgfortran_version == cabi. libgfortran_version, GCC_builds)
366
+ end
367
+
368
+ # Next, filter by libstdc++ GLIBCXX symbol version. Note that this
369
+ # mapping is conservative; it is often the case that we return a
370
+ # version that is slightly lower than what is actually installed on
371
+ # a system. See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html
372
+ # for the whole list, as well as many other interesting factoids.
373
+ if cabi. libstdcxx_version != = nothing
374
+ GCC_builds = filter (b -> getabi (b). libstdcxx_version <= cabi. libstdcxx_version, GCC_builds)
375
+ end
376
+
377
+ # Finally, enforce cxxstring_abi guidelines. It is possible to build
378
+ # :cxx03 binaries on GCC 5+, (although increasingly rare) so the only
379
+ # filtering we do is that if the platform is explicitly :cxx11, we
380
+ # disallow running on < GCC 5.
381
+ if cabi. cxxstring_abi != = nothing && cabi. cxxstring_abi === :cxx11
382
+ GCC_builds = filter (b -> getversion (b) >= v " 5" , GCC_builds)
383
+ end
384
+
385
+ return getversion .(GCC_builds)
386
+ end
324
387
325
388
function select_gcc_version (p:: Platform ,
326
- GCC_builds:: Vector{VersionNumber } = available_gcc_builds,
327
- preferred_gcc_version:: VersionNumber = GCC_builds[1 ],
389
+ GCC_builds:: Vector{GCCBuild } = available_gcc_builds,
390
+ preferred_gcc_version:: VersionNumber = getversion ( GCC_builds[1 ]) ,
328
391
)
329
392
# Determine which GCC build we're going to match with this CompilerABI:
330
- GCC_builds = Pkg . BinaryPlatforms . gcc_version (compiler_abi (p), GCC_builds)
393
+ GCC_builds = gcc_version (compiler_abi (p), GCC_builds)
331
394
332
395
if isempty (GCC_builds)
333
396
error (" Impossible CompilerABI constraints $(cabi) !" )
@@ -350,19 +413,22 @@ function choose_shards(p::Platform;
350
413
compilers:: Vector{Symbol} = [:c ],
351
414
rootfs_build:: VersionNumber = v " 2020.01.07" ,
352
415
ps_build:: VersionNumber = v " 2020.01.15" ,
353
- GCC_builds:: Vector{VersionNumber } = available_gcc_builds,
354
- LLVM_builds:: Vector{VersionNumber } = available_llvm_builds,
416
+ GCC_builds:: Vector{GCCBuild } = available_gcc_builds,
417
+ LLVM_builds:: Vector{LLVMBuild } = available_llvm_builds,
355
418
Rust_build:: VersionNumber = v " 1.18.3" ,
356
419
Go_build:: VersionNumber = v " 1.13" ,
357
420
archive_type:: Symbol = (use_squashfs ? :squashfs : :unpacked ),
358
421
bootstrap_list:: Vector{Symbol} = bootstrap_list,
359
- # We prefer the oldest GCC version by default
360
- preferred_gcc_version:: VersionNumber = GCC_builds[1 ],
361
- preferred_llvm_version:: VersionNumber = LLVM_builds[end ],
422
+ # Because GCC has lots of compatibility issues, we always default to
423
+ # the earliest version possible.
424
+ preferred_gcc_version:: VersionNumber = getversion (GCC_builds[1 ]),
425
+ # Because LLVM doesn't have compatibilty issues, we always default
426
+ # to the newest version possible.
427
+ preferred_llvm_version:: VersionNumber = getversion (LLVM_builds[end ]),
362
428
)
363
429
364
430
GCC_build = select_gcc_version (p, GCC_builds, preferred_gcc_version)
365
- LLVM_build = select_closest_version (preferred_llvm_version, LLVM_builds)
431
+ LLVM_build = select_closest_version (preferred_llvm_version, getversion .( LLVM_builds) )
366
432
# Our host platform is x86_64-linux-musl
367
433
host_platform = Linux (:x86_64 ; libc= :musl )
368
434
@@ -531,6 +597,58 @@ function expand_cxxstring_abis(ps::Vector{<:Platform})
531
597
return Platform[p for p in Iterators. flatten (expand_cxxstring_abis .(ps))]
532
598
end
533
599
600
+ """
601
+ preferred_libgfortran_version(platform::Platform, shard::CompilerShard)
602
+
603
+ Return the libgfortran version preferred by the given platform or GCCBootstrap shard.
604
+ """
605
+ function preferred_libgfortran_version (platform:: Platform , shard:: CompilerShard )
606
+ # Some input validation
607
+ if shard. name != " GCCBootstrap"
608
+ error (" Shard must be `GCCBootstrap`" )
609
+ end
610
+ if shard. target. arch != platform. arch || shard. target. libc != platform. libc
611
+ error (" Incompatible platform and shard target" )
612
+ end
613
+
614
+ if compiler_abi (platform). libgfortran_version != nothing
615
+ # Here we can't use `shard.target` because the shard always has the
616
+ # target as ABI-agnostic, thus we have also to ask for the platform.
617
+ return compiler_abi (platform). libgfortran_version
618
+ elseif shard. version < v " 7"
619
+ return v " 3"
620
+ elseif v " 7" <= shard. version < v " 8"
621
+ return v " 4"
622
+ else
623
+ return v " 5"
624
+ end
625
+ end
626
+
627
+ """
628
+ preferred_cxxstring_abi(platform::Platform, shard::CompilerShard)
629
+
630
+ Return the C++ string ABI preferred by the given platform or GCCBootstrap shard.
631
+ """
632
+ function preferred_cxxstring_abi (platform:: Platform , shard:: CompilerShard )
633
+ # Some input validation
634
+ if shard. name != " GCCBootstrap"
635
+ error (" Shard must be `GCCBootstrap`" )
636
+ end
637
+ if shard. target. arch != platform. arch || shard. target. libc != platform. libc
638
+ error (" Incompatible platform and shard target" )
639
+ end
640
+
641
+ if compiler_abi (platform). cxxstring_abi != nothing
642
+ # Here we can't use `shard.target` because the shard always has the
643
+ # target as ABI-agnostic, thus we have also to ask for the platform.
644
+ return compiler_abi (platform). cxxstring_abi
645
+ elseif shard. version < v " 5"
646
+ return :cxx03
647
+ else
648
+ return :cxx11
649
+ end
650
+ end
651
+
534
652
"""
535
653
download_all_shards(; verbose::Bool=false)
536
654
0 commit comments