diff --git a/Project.toml b/Project.toml index 7355e3a8..c7c8249e 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "BinaryBuilderBase" uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e" authors = ["Elliot Saba "] -version = "1.39.1" +version = "1.40.0" [deps] Bzip2_jll = "6e34b625-4abd-537c-b88f-471c36dfa7a0" diff --git a/src/Runner.jl b/src/Runner.jl index b9a17726..400f3001 100644 --- a/src/Runner.jl +++ b/src/Runner.jl @@ -436,6 +436,17 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr end end + function buildid_link_flags!(p::AbstractPlatform, flags::Vector{String}) + # build-id is not supported on macOS compilers + if !Sys.isapple(p) + # Windows build-id requires binutils 2.25+, which we only have for GCC 5+ + if !Sys.iswindows(p) || (Sys.iswindows(p) && gcc_version ≥ v"5") + # Use a known algorithm to embed the build-id for reproducibility + push!(flags, "-Wl,--build-id=sha1") + end + end + end + function clang_compile_flags!(p::AbstractPlatform, flags::Vector{String} = String[]) if lock_microarchitecture append!(flags, get_march_flags(arch(p), march(p), "clang")) @@ -540,6 +551,9 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr append!(flags, min_macos_version_linker_flags()) end end + + buildid_link_flags!(p, flags) + return flags end @@ -630,6 +644,7 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr push!(flags, "-Wl,--no-insert-timestamp") end sanitize_link_flags!(p, flags) + buildid_link_flags!(p, flags) return flags end diff --git a/test/runners.jl b/test/runners.jl index 4cfeeb40..22519bd3 100644 --- a/test/runners.jl +++ b/test/runners.jl @@ -2,6 +2,7 @@ using Test using BinaryBuilderBase using BinaryBuilderBase: platform_dlext, platform_exeext, prefer_clang using Pkg +using ObjectFile @testset "Wrappers utilities" begin @test nbits(Platform("i686", "linux")) == 32 @@ -130,8 +131,12 @@ end if lowercase(get(ENV, "BINARYBUILDER_FULL_SHARD_TEST", "false")) == "true" @info("Beginning full shard test... (this can take a while)") platforms = supported_platforms() + elf_platforms = filter(p -> Sys.islinux(p) || Sys.isfreebsd(p), supported_platforms()) + win_platforms = filter(p -> Sys.iswindows(p), supported_platforms()) else platforms = (default_host_platform,) + elf_platforms = (default_host_platform,) + win_platforms = (Platform("x86_64", "windows"),) end # Checks that the wrappers provide the correct C++ string ABI @@ -153,6 +158,80 @@ end end end + # Checks that the compiler/linker include a build-id + # This is only available on ELF-based platforms + @testset "Compilation - Linux build-id note $(platform) - $(compiler)" for platform in elf_platforms, compiler in ("cc", "gcc", "clang", "c++", "g++", "clang++") + mktempdir() do dir + ur = preferred_runner()(dir; platform=platform) + iobuff = IOBuffer() + test_c = """ + #include + int test(void) { + return 0; + } + """ + test_script = """ + set -e + cd /workspace + # Make sure setting `CCACHE` doesn't affect the compiler wrappers. + export CCACHE=pwned + export USE_CCACHE=false + echo '$(test_c)' > test.c + # Build shared library + $(compiler) -shared test.c -o libtest.\${dlext} + """ + cmd = `/bin/bash -c "$(test_script)"` + @test run(ur, cmd, iobuff) + + # Load the library file and test it for the build-id + lib_path = joinpath(dir, "libtest."*platform_dlext(platform)) + lib = open(lib_path) + obj_handles = readmeta(lib) + obj = first(obj_handles) + secs = Sections(obj) + + # The section must exist for the build-id to be present + @test !isnothing(findfirst(s -> section_name(s) == ".note.gnu.build-id", secs)) + end + end + + # Checks that Windows can include a build-id + @testset "Compilation - Windows build-id note $(platform) - $(compiler)" for platform in win_platforms, compiler in ("cc", "gcc", "clang", "c++", "g++", "clang++") + mktempdir() do dir + # Windows build-id support requires binutils 2.25, which is part of our GCC 5 + ur = preferred_runner()(dir; platform=platform, preferred_gcc_version=v"5") + iobuff = IOBuffer() + test_c = """ + #include + int test(void) { + return 0; + } + """ + test_script = """ + set -e + cd /workspace + # Make sure setting `CCACHE` doesn't affect the compiler wrappers. + export CCACHE=pwned + export USE_CCACHE=false + echo '$(test_c)' > test.c + # Build shared library + $(compiler) -shared test.c -o libtest.\${dlext} + """ + cmd = `/bin/bash -c "$(test_script)"` + @test run(ur, cmd, iobuff) + + # Load the library file and test it for the build-id + lib_path = joinpath(dir, "libtest."*platform_dlext(platform)) + lib = open(lib_path) + obj_handles = readmeta(lib) + obj = first(obj_handles) + secs = Sections(obj) + + # The section must exist for the build-id to be present + @test !isnothing(findfirst(s -> section_name(s) == ".buildid", secs)) + end + end + # This tests only that compilers for all platforms can build and link simple C code @testset "Compilation - $(platform) - $(compiler)" for platform in platforms, compiler in ("cc", "gcc", "clang") mktempdir() do dir