Skip to content

Commit e033966

Browse files
authored
[Runner] Move csl_paths(host_platform) at the beginning of LD_LIBRARY_PATH (#157)
* [Runner] Fix CSL paths * [Runner] Move `csl_paths(host_platform)` at the beginning of `LD_LIBRARY_PATH` This should make it easier to run applications we build with our toolchain. * [Rootfs] Update to fix CSL libraries * [Runner] Override `LD_LIBRARY_PATH` inside the compiler wrappers * [Runner] Generate CSL paths only for target and host platforms Having all Intel Linux platforms in the CSL paths was a mess hard to deal with. The simplest thing to do is to generate the paths only for target and host, and sort them correctly: if they have same architecture, have the host first, if the have different architectures, have the target first. * Simplify reading of some buffers in tests * [Runner] Add helper function to set `LD_LIBRARY_PATH` * [Runner] Have always `host` first in CSL paths for `LD_LIBRARY_PATH` Having `target` first would make C++ programs for `i686-linux-musl` work, but then we can't run C++ programs for the host. We really need to fix the musl loader.
1 parent 8333351 commit e033966

File tree

5 files changed

+133
-62
lines changed

5 files changed

+133
-62
lines changed

Artifacts.toml

+10-10
Original file line numberDiff line numberDiff line change
@@ -2814,27 +2814,27 @@ os = "linux"
28142814
sha256 = "d9bab2d2b19966509a070a92f6f982389d3ab418577a3a17dfbb0f03065216a6"
28152815
url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/PlatformSupport-v2021.1.28/PlatformSupport-x86_64-w64-mingw32.v2021.1.28.x86_64-linux-musl.unpacked.tar.gz"
28162816

2817-
[["Rootfs.v2021.7.12.x86_64-linux-musl.squashfs"]]
2817+
[["Rootfs.v2021.7.13.x86_64-linux-musl.squashfs"]]
28182818
arch = "x86_64"
2819-
git-tree-sha1 = "ff5285a07b28ff11026e779e042bf80283c30129"
2819+
git-tree-sha1 = "5795ee9f2eca2284bfb80611ac2accfc89998e0b"
28202820
lazy = true
28212821
libc = "musl"
28222822
os = "linux"
28232823

2824-
[["Rootfs.v2021.7.12.x86_64-linux-musl.squashfs".download]]
2825-
sha256 = "a1216c62617a80607bf21aff5e5ae40bb46e8602f6189c87ed8d151d1b59f87f"
2826-
url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/Rootfs-v2021.7.12/Rootfs.v2021.7.12.x86_64-linux-musl.squashfs.tar.gz"
2824+
[["Rootfs.v2021.7.13.x86_64-linux-musl.squashfs".download]]
2825+
sha256 = "1bb755ffdf003fa1a1457cfbc3ad44e770038181e5a1138a54b0d60de507f692"
2826+
url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/Rootfs-v2021.7.13/Rootfs.v2021.7.13.x86_64-linux-musl.squashfs.tar.gz"
28272827

2828-
[["Rootfs.v2021.7.12.x86_64-linux-musl.unpacked"]]
2828+
[["Rootfs.v2021.7.13.x86_64-linux-musl.unpacked"]]
28292829
arch = "x86_64"
2830-
git-tree-sha1 = "d40d6852338378ec860f6f78b93786bca64e21ca"
2830+
git-tree-sha1 = "56df63e8265adb2316d6599632113da025545434"
28312831
lazy = true
28322832
libc = "musl"
28332833
os = "linux"
28342834

2835-
[["Rootfs.v2021.7.12.x86_64-linux-musl.unpacked".download]]
2836-
sha256 = "fd628ee10bdfbd093e5ba245eb72a6a07759d5c175529e5d72c3867594db2870"
2837-
url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/Rootfs-v2021.7.12/Rootfs.v2021.7.12.x86_64-linux-musl.unpacked.tar.gz"
2835+
[["Rootfs.v2021.7.13.x86_64-linux-musl.unpacked".download]]
2836+
sha256 = "aa5aef6b4c68b28c135da87d3d0169e142a84b89d556748f3f37d30355b9ca17"
2837+
url = "https://github.com/JuliaPackaging/Yggdrasil/releases/download/Rootfs-v2021.7.13/Rootfs.v2021.7.13.x86_64-linux-musl.unpacked.tar.gz"
28382838

28392839
[["RustBase.v1.43.0.x86_64-linux-musl.squashfs"]]
28402840
arch = "x86_64"

Project.toml

+1-1
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 <[email protected]>"]
4-
version = "0.6.12"
4+
version = "0.6.13"
55

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

src/Rootfs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ consists of four shards, but that may not always be the case.
508508
"""
509509
function choose_shards(p::AbstractPlatform;
510510
compilers::Vector{Symbol} = [:c],
511-
rootfs_build::VersionNumber=v"2021.7.12",
511+
rootfs_build::VersionNumber=v"2021.7.13",
512512
ps_build::VersionNumber=v"2021.01.28",
513513
GCC_builds::Vector{GCCBuild}=available_gcc_builds,
514514
LLVM_builds::Vector{LLVMBuild}=available_llvm_builds,

src/Runner.jl

+62-44
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,63 @@ end
4747
# XXX: we want AnyPlatform to look like `x86_64-linux-musl` in the build environment.
4848
aatriplet(p::AnyPlatform) = aatriplet(default_host_platform)
4949

50+
function ld_library_path(target::AbstractPlatform,
51+
host::AbstractPlatform,
52+
prefix::String="",
53+
host_libdir::String="";
54+
csl_paths::Bool=true)
55+
# Helper for generating the library include path for a target. MacOS, as usual,
56+
# puts things in slightly different place.
57+
function target_lib_dir(p::AbstractPlatform)
58+
t = aatriplet(p)
59+
if Sys.isapple(p)
60+
return "/opt/$(t)/$(t)/lib:/opt/$(t)/lib"
61+
else
62+
return "/opt/$(t)/$(t)/lib64:/opt/$(t)/$(t)/lib"
63+
end
64+
end
65+
66+
# Let's start
67+
paths = String[]
68+
69+
# If requested, start with our CSL libraries for target/host, but only for architectures
70+
# that can natively run within this environment
71+
if csl_paths
72+
append!(paths,
73+
unique("/usr/lib/csl-$(libc(p))-$(arch(p))" for p in (host, target) if Sys.islinux(p) && proc_family(p) == "intel"),
74+
)
75+
end
76+
77+
push!(paths,
78+
# Then add default system paths
79+
"/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib",
80+
# Add our loader directories
81+
"/lib64:/lib",
82+
)
83+
84+
if !isempty(host_libdir)
85+
push!(paths,
86+
# Libdir of the host platform, to run programs in `HostBuildDependency`
87+
host_libdir,
88+
)
89+
end
90+
91+
push!(paths,
92+
# Add our target/host-specific library directories for compiler support libraries
93+
target_lib_dir(host),
94+
target_lib_dir(target),
95+
)
96+
97+
# Finally, add dependencies in the prefix
98+
if !isempty(prefix)
99+
push!(paths,
100+
"$(prefix)/lib64:$(prefix)/lib",
101+
)
102+
end
103+
104+
return join(paths, ":")
105+
end
106+
50107
"""
51108
generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::AbstractString,
52109
host_platform::AbstractPlatform = $(repr(default_host_platform)),
@@ -395,6 +452,8 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr
395452
hash_args = true,
396453
allow_ccache,
397454
no_soft_float=arch(p) in ("armv6l", "armv7l"),
455+
# Override `LD_LIBRARY_PATH` to avoid external settings mess it up.
456+
env=Dict("LD_LIBRARY_PATH"=>ld_library_path(platform, host_platform; csl_paths=false)),
398457
)
399458
end
400459

@@ -406,6 +465,8 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr
406465
compile_only_flags=clang_compile_flags!(p),
407466
link_only_flags=clang_link_flags!(p),
408467
no_soft_float=arch(p) in ("armv6l", "armv7l"),
468+
# Override `LD_LIBRARY_PATH` to avoid external settings mess it up.
469+
env=Dict("LD_LIBRARY_PATH"=>ld_library_path(platform, host_platform; csl_paths=false)),
409470
)
410471
end
411472

@@ -869,17 +930,6 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
869930
return mapping
870931
end
871932

872-
# Helper for generating the library include path for a target. MacOS, as usual,
873-
# puts things in slightly different place.
874-
function target_lib_dir(p::AbstractPlatform)
875-
t = aatriplet(p)
876-
if Sys.isapple(p)
877-
return "/opt/$(t)/$(t)/lib:/opt/$(t)/lib"
878-
else
879-
return "/opt/$(t)/$(t)/lib64:/opt/$(t)/$(t)/lib"
880-
end
881-
end
882-
883933
function GOARM(p::AbstractPlatform)
884934
# See https://github.com/golang/go/wiki/GoArm#supported-architectures
885935
if arch(p) == "armv6l"
@@ -891,24 +941,6 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
891941
end
892942
end
893943

894-
function csl_paths(p::AbstractPlatform)
895-
libcs = if Sys.islinux(p) && proc_family(p) == "intel" && libc(p) == "musl"
896-
# We need to push musl directories before glibc ones
897-
("musl", "glibc")
898-
else
899-
("glibc", "musl")
900-
end
901-
902-
archs = if Sys.islinux(p) && proc_family(p) == "intel" && arch(p) == "i686"
903-
# We need to push i686 directories before x86_64 ones
904-
("i686", "x86_64")
905-
else
906-
("x86", "i686_64")
907-
end
908-
909-
return join(["/usr/lib/csl-$(libc)-$(arch)" for libc in libcs, arch in archs], ":")
910-
end
911-
912944
merge!(mapping, Dict(
913945
"PATH" => join((
914946
# First things first, our compiler wrappers trump all
@@ -926,21 +958,7 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
926958
mapping["bindir"],
927959
), ":"),
928960

929-
"LD_LIBRARY_PATH" => join((
930-
# Start with a default path
931-
"/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib",
932-
# Add our loader directories
933-
"/lib64:/lib",
934-
# Add our CSL libraries for all architectures that can natively run within this environment
935-
csl_paths(host_platform),
936-
# Libdir of the host platform, to run programs in `HostBuildDependency`
937-
"$(host_libdir)",
938-
# Add our target/host-specific library directories for compiler support libraries
939-
target_lib_dir(host_platform),
940-
target_lib_dir(platform),
941-
# Finally, dependencies
942-
"$(prefix)/lib64:$(prefix)/lib",
943-
), ":"),
961+
"LD_LIBRARY_PATH" => ld_library_path(platform, host_platform, prefix, host_libdir),
944962

945963
# Default mappings for some tools
946964
"CC" => "cc",

test/runners.jl

+59-6
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ end
6565
@test run(ur, `/bin/bash -c "echo test"`, iobuff)
6666
seek(iobuff, 0)
6767
# Test that we get the output we expect (e.g. the second line is `test`)
68-
@test split(String(read(iobuff)), "\n")[2] == "test"
68+
@test readlines(iobuff)[2] == "test"
6969
end
7070
end
7171

@@ -96,11 +96,12 @@ end
9696
end
9797

9898
# This tests only that compilers for all platforms can build a simple C program
99-
@testset "Compilation - $(platform)" for platform in platforms
99+
# TODO: for the time being we only test `cc`, eventually we want to run `gcc` and `clang` separately
100+
@testset "Compilation - $(platform) - $(compiler)" for platform in platforms, compiler in ("cc",)
100101
mktempdir() do dir
101102
ur = preferred_runner()(dir; platform=platform)
102103
iobuff = IOBuffer()
103-
@test run(ur, `/bin/bash -c "echo 'int main() {return 0;}' | cc -x c -"`, iobuff; tee_stream=devnull)
104+
@test run(ur, `/bin/bash -c "echo 'int main() {return 0;}' | $(compiler) -x c -"`, iobuff; tee_stream=devnull)
104105
seekstart(iobuff)
105106
@test split(String(read(iobuff)), "\n")[2] == ""
106107
end
@@ -130,6 +131,58 @@ end
130131
end
131132
end
132133

134+
@testset "C and link to quadmath - $(platform)" for platform in platforms
135+
mktempdir() do dir
136+
# Use a recent GCC with libgfortran5
137+
options = (preferred_gcc_version=v"9", compilers=[:c])
138+
shards = choose_shards(platform; options...)
139+
concrete_platform = get_concrete_platform(platform, shards)
140+
prefix = setup_workspace(
141+
dir,
142+
[],
143+
concrete_platform,
144+
default_host_platform;
145+
)
146+
# Install `MPICH_jll` in the `${prefix}` to make sure we can link to
147+
# libquadmath without problems, see
148+
# https://github.com/JuliaPackaging/BinaryBuilderBase.jl/pull/157#issuecomment-879263820
149+
artifact_paths =
150+
setup_dependencies(prefix,
151+
[PackageSpec(; name="MPICH_jll", version="3.4.2")],
152+
concrete_platform, verbose=false)
153+
ur = preferred_runner()(prefix.path;
154+
platform=concrete_platform,
155+
shards = shards,
156+
options...)
157+
iobuff = IOBuffer()
158+
test_c = """
159+
#include <stdio.h>
160+
int main() {
161+
printf("Hello World!\\n");
162+
return 0;
163+
}
164+
"""
165+
test_script = """
166+
set -e
167+
echo '$(test_c)' > test.c
168+
# Make sure we can compile successfully also when linking to libmpifort
169+
cc -o test test.c -L\${libdir} -lmpifort -lquadmath
170+
./test
171+
"""
172+
cmd = `/bin/bash -c "$(test_script)"`
173+
if arch(platform) == "i686" && libc(platform) == "musl"
174+
# We can't run this program for this platform
175+
@test_broken run(ur, cmd, iobuff; tee_stream=devnull)
176+
else
177+
@test run(ur, cmd, iobuff; tee_stream=devnull)
178+
seekstart(iobuff)
179+
# Test that we get the output we expect
180+
@test endswith(readchomp(iobuff), "Hello World!")
181+
end
182+
cleanup_dependencies(prefix, artifact_paths, concrete_platform)
183+
end
184+
end
185+
133186
@testset "C++ - $(platform)" for platform in platforms
134187
mktempdir() do dir
135188
# Use an old GCC with libgfortran3
@@ -167,7 +220,7 @@ end
167220
echo '$(test_cpp)' > test.cpp
168221
# Make sure we can compile successfully also when `\${libdir}` is in the
169222
# linker search path
170-
g++ -o test test.cpp -L\${libdir}
223+
c++ -o test test.cpp -L\${libdir}
171224
./test
172225
"""
173226
cmd = `/bin/bash -c "$(test_script)"`
@@ -217,7 +270,7 @@ end
217270
iobuff = IOBuffer()
218271
@test !run(ur, cmd, iobuff; tee_stream=devnull)
219272
seekstart(iobuff)
220-
@test split(String(read(iobuff)), "\n")[2] == "Cannot force an architecture"
273+
@test readlines(iobuff)[2] == "Cannot force an architecture"
221274

222275
ur = preferred_runner()(dir; platform=platform, lock_microarchitecture=false)
223276
iobuff = IOBuffer()
@@ -235,7 +288,7 @@ end
235288
iobuff = IOBuffer()
236289
@test !run(ur, cmd, iobuff; tee_stream=devnull)
237290
seekstart(iobuff)
238-
lines = split(String(read(iobuff)), "\n")
291+
lines = readlines(iobuff)
239292
@test lines[2] == "You used one or more of the unsafe flags: -Ofast, -ffast-math, -funsafe-math-optimizations"
240293
@test lines[3] == "Please repent."
241294

0 commit comments

Comments
 (0)