Skip to content

Commit 13dc99e

Browse files
giordanostaticfloat
authored andcommitted
[Runner] Push /opt/${target}/${target}/lib{,64} to linker search path
When compiling with GCC this makes sure its libraries have precedence over anything else, in particular other compiler libraries that may be elsewhere, for example `CompilerSupportLibraries_jll` used as dependency during the build.
1 parent c422448 commit 13dc99e

File tree

3 files changed

+76
-9
lines changed

3 files changed

+76
-9
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "BinaryBuilderBase"
22
uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e"
33
authors = ["Elliot Saba <staticfloat@gmail.com>"]
4-
version = "0.6.11"
4+
version = "0.6.12"
55

66
[deps]
77
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"

src/Runner.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,15 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr
348348
end
349349

350350
function gcc_compile_flags!(p::AbstractPlatform, flags::Vector{String} = String[])
351+
if Sys.islinux(p) || Sys.isfreebsd(p)
352+
# Help GCCBootstrap find its own libraries under
353+
# `/opt/${target}/${target}/lib{,64}`. Note: we need to push them directly in
354+
# the wrappers before any additional arguments because we want this path to have
355+
# precedence over anything else. In this way for example we avoid libraries
356+
# from `CompilerSupportLibraries_jll` in `${libdir}` are picked up by mistake.
357+
dir = "/opt/$(aatriplet(p))/$(aatriplet(p))/lib" * (nbits(p) == 32 ? "" : "64")
358+
append!(flags, ("-L$(dir)", "-Wl,-rpath-link,$(dir)"))
359+
end
351360
if lock_microarchitecture
352361
append!(flags, get_march_flags(arch(p), march(p), "gcc"))
353362
end

test/runners.jl

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Test
22
using BinaryBuilderBase
33
using BinaryBuilderBase: platform_dlext, platform_exeext
4+
using Pkg
45

56
@testset "Wrappers utilities" begin
67
@test nbits(Platform("i686", "linux")) == 32
@@ -105,13 +106,13 @@ end
105106
end
106107
end
107108

108-
# This tests that compilers for all Intel Linux platforms can build a simple
109-
# C program that we can also run
109+
# This tests that compilers for all Intel Linux platforms can build simple
110+
# C, C++, Fortran programs that we can also run
110111
@testset "Compilation and running" begin
111-
mktempdir() do dir
112-
platforms = filter(p -> Sys.islinux(p) && proc_family(p) == "intel", supported_platforms())
112+
platforms = filter(p -> Sys.islinux(p) && proc_family(p) == "intel", supported_platforms())
113113

114-
@testset "C - $(platform)" for platform in platforms
114+
@testset "C - $(platform)" for platform in platforms
115+
mktempdir() do dir
115116
ur = preferred_runner()(dir; platform=platform)
116117
iobuff = IOBuffer()
117118
test_c = """
@@ -127,10 +128,66 @@ end
127128
# Test that we get the output we expect
128129
@test endswith(readchomp(iobuff), "Hello World!")
129130
end
131+
end
132+
133+
@testset "C++ - $(platform)" for platform in platforms
134+
mktempdir() do dir
135+
# Use an old GCC with libgfortran3
136+
options = (preferred_gcc_version=v"4", compilers=[:c])
137+
shards = choose_shards(platform; options...)
138+
concrete_platform = get_concrete_platform(platform, shards)
139+
prefix = setup_workspace(
140+
dir,
141+
[],
142+
concrete_platform,
143+
default_host_platform;
144+
)
145+
# Install `CompilerSupportLibraries_jll` v0.5.0 in the `${prefix}` to make
146+
# sure it doesn't break compilation of the program for i686-linux-gnu, see
147+
# https://github.com/JuliaPackaging/BinaryBuilderBase.jl/issues/163
148+
artifact_paths =
149+
setup_dependencies(prefix,
150+
[PackageSpec(; name="CompilerSupportLibraries_jll", version="0.5.0")],
151+
concrete_platform, verbose=false)
152+
ur = preferred_runner()(prefix.path;
153+
platform=concrete_platform,
154+
shards = shards,
155+
options...)
156+
iobuff = IOBuffer()
157+
test_cpp = """
158+
#include <iostream>
159+
class breakCCompiler; // Courtesy of Meson
160+
int main() {
161+
std::cout << "Hello World!" << std::endl;
162+
return 0;
163+
}
164+
"""
165+
test_script = """
166+
set -e
167+
echo '$(test_cpp)' > test.cpp
168+
# Make sure we can compile successfully also when `\${libdir}` is in the
169+
# linker search path
170+
g++ -o test test.cpp -L\${libdir}
171+
./test
172+
"""
173+
cmd = `/bin/bash -c "$(test_script)"`
174+
if arch(platform) == "i686" && libc(platform) == "musl"
175+
# We can't run C++ programs for this platform
176+
@test_broken run(ur, cmd, iobuff; tee_stream=devnull)
177+
else
178+
@test run(ur, cmd, iobuff; tee_stream=devnull)
179+
seekstart(iobuff)
180+
# Test that we get the output we expect
181+
@test endswith(readchomp(iobuff), "Hello World!")
182+
end
183+
cleanup_dependencies(prefix, artifact_paths, concrete_platform)
184+
end
185+
end
130186

131-
# This tests that compilers for all Intel Linux platforms can build a simple
132-
# Fortran program that we can also run
133-
@testset "Fortran - $(platform)" for platform in filter(p -> Sys.islinux(p) && proc_family(p) == "intel", supported_platforms())
187+
# This tests that compilers for all Intel Linux platforms can build a simple
188+
# Fortran program that we can also run
189+
@testset "Fortran - $(platform)" for platform in platforms
190+
mktempdir() do dir
134191
ur = preferred_runner()(dir; platform=platform)
135192
iobuff = IOBuffer()
136193
test_f = """
@@ -140,6 +197,7 @@ end
140197
"""
141198
cmd = `/bin/bash -c "echo '$(test_f)' > test.f && gfortran -o test test.f && ./test"`
142199
if arch(platform) == "i686" && libc(platform) == "musl"
200+
# We can't run Fortran programs for this platform
143201
@test_broken run(ur, cmd, iobuff; tee_stream=devnull)
144202
else
145203
@test run(ur, cmd, iobuff; tee_stream=devnull)

0 commit comments

Comments
 (0)