Skip to content

Commit

Permalink
[Runner] Move csl_paths(host_platform) at the beginning of `LD_LIBR…
Browse files Browse the repository at this point in the history
…ARY_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.
  • Loading branch information
giordano authored Jul 14, 2021
1 parent 8333351 commit e033966
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 62 deletions.
20 changes: 10 additions & 10 deletions Artifacts.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2814,27 +2814,27 @@ os = "linux"
sha256 = "d9bab2d2b19966509a070a92f6f982389d3ab418577a3a17dfbb0f03065216a6"
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"

[["Rootfs.v2021.7.12.x86_64-linux-musl.squashfs"]]
[["Rootfs.v2021.7.13.x86_64-linux-musl.squashfs"]]
arch = "x86_64"
git-tree-sha1 = "ff5285a07b28ff11026e779e042bf80283c30129"
git-tree-sha1 = "5795ee9f2eca2284bfb80611ac2accfc89998e0b"
lazy = true
libc = "musl"
os = "linux"

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

[["Rootfs.v2021.7.12.x86_64-linux-musl.unpacked"]]
[["Rootfs.v2021.7.13.x86_64-linux-musl.unpacked"]]
arch = "x86_64"
git-tree-sha1 = "d40d6852338378ec860f6f78b93786bca64e21ca"
git-tree-sha1 = "56df63e8265adb2316d6599632113da025545434"
lazy = true
libc = "musl"
os = "linux"

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

[["RustBase.v1.43.0.x86_64-linux-musl.squashfs"]]
arch = "x86_64"
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BinaryBuilderBase"
uuid = "7f725544-6523-48cd-82d1-3fa08ff4056e"
authors = ["Elliot Saba <[email protected]>"]
version = "0.6.12"
version = "0.6.13"

[deps]
CodecZlib = "944b1d66-785c-5afd-91f1-9de20f533193"
Expand Down
2 changes: 1 addition & 1 deletion src/Rootfs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ consists of four shards, but that may not always be the case.
"""
function choose_shards(p::AbstractPlatform;
compilers::Vector{Symbol} = [:c],
rootfs_build::VersionNumber=v"2021.7.12",
rootfs_build::VersionNumber=v"2021.7.13",
ps_build::VersionNumber=v"2021.01.28",
GCC_builds::Vector{GCCBuild}=available_gcc_builds,
LLVM_builds::Vector{LLVMBuild}=available_llvm_builds,
Expand Down
106 changes: 62 additions & 44 deletions src/Runner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,63 @@ end
# XXX: we want AnyPlatform to look like `x86_64-linux-musl` in the build environment.
aatriplet(p::AnyPlatform) = aatriplet(default_host_platform)

function ld_library_path(target::AbstractPlatform,
host::AbstractPlatform,
prefix::String="",
host_libdir::String="";
csl_paths::Bool=true)
# Helper for generating the library include path for a target. MacOS, as usual,
# puts things in slightly different place.
function target_lib_dir(p::AbstractPlatform)
t = aatriplet(p)
if Sys.isapple(p)
return "/opt/$(t)/$(t)/lib:/opt/$(t)/lib"
else
return "/opt/$(t)/$(t)/lib64:/opt/$(t)/$(t)/lib"
end
end

# Let's start
paths = String[]

# If requested, start with our CSL libraries for target/host, but only for architectures
# that can natively run within this environment
if csl_paths
append!(paths,
unique("/usr/lib/csl-$(libc(p))-$(arch(p))" for p in (host, target) if Sys.islinux(p) && proc_family(p) == "intel"),
)
end

push!(paths,
# Then add default system paths
"/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib",
# Add our loader directories
"/lib64:/lib",
)

if !isempty(host_libdir)
push!(paths,
# Libdir of the host platform, to run programs in `HostBuildDependency`
host_libdir,
)
end

push!(paths,
# Add our target/host-specific library directories for compiler support libraries
target_lib_dir(host),
target_lib_dir(target),
)

# Finally, add dependencies in the prefix
if !isempty(prefix)
push!(paths,
"$(prefix)/lib64:$(prefix)/lib",
)
end

return join(paths, ":")
end

"""
generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::AbstractString,
host_platform::AbstractPlatform = $(repr(default_host_platform)),
Expand Down Expand Up @@ -395,6 +452,8 @@ function generate_compiler_wrappers!(platform::AbstractPlatform; bin_path::Abstr
hash_args = true,
allow_ccache,
no_soft_float=arch(p) in ("armv6l", "armv7l"),
# Override `LD_LIBRARY_PATH` to avoid external settings mess it up.
env=Dict("LD_LIBRARY_PATH"=>ld_library_path(platform, host_platform; csl_paths=false)),
)
end

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

Expand Down Expand Up @@ -869,17 +930,6 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
return mapping
end

# Helper for generating the library include path for a target. MacOS, as usual,
# puts things in slightly different place.
function target_lib_dir(p::AbstractPlatform)
t = aatriplet(p)
if Sys.isapple(p)
return "/opt/$(t)/$(t)/lib:/opt/$(t)/lib"
else
return "/opt/$(t)/$(t)/lib64:/opt/$(t)/$(t)/lib"
end
end

function GOARM(p::AbstractPlatform)
# See https://github.com/golang/go/wiki/GoArm#supported-architectures
if arch(p) == "armv6l"
Expand All @@ -891,24 +941,6 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
end
end

function csl_paths(p::AbstractPlatform)
libcs = if Sys.islinux(p) && proc_family(p) == "intel" && libc(p) == "musl"
# We need to push musl directories before glibc ones
("musl", "glibc")
else
("glibc", "musl")
end

archs = if Sys.islinux(p) && proc_family(p) == "intel" && arch(p) == "i686"
# We need to push i686 directories before x86_64 ones
("i686", "x86_64")
else
("x86", "i686_64")
end

return join(["/usr/lib/csl-$(libc)-$(arch)" for libc in libcs, arch in archs], ":")
end

merge!(mapping, Dict(
"PATH" => join((
# First things first, our compiler wrappers trump all
Expand All @@ -926,21 +958,7 @@ function platform_envs(platform::AbstractPlatform, src_name::AbstractString;
mapping["bindir"],
), ":"),

"LD_LIBRARY_PATH" => join((
# Start with a default path
"/usr/local/lib64:/usr/local/lib:/usr/lib64:/usr/lib",
# Add our loader directories
"/lib64:/lib",
# Add our CSL libraries for all architectures that can natively run within this environment
csl_paths(host_platform),
# Libdir of the host platform, to run programs in `HostBuildDependency`
"$(host_libdir)",
# Add our target/host-specific library directories for compiler support libraries
target_lib_dir(host_platform),
target_lib_dir(platform),
# Finally, dependencies
"$(prefix)/lib64:$(prefix)/lib",
), ":"),
"LD_LIBRARY_PATH" => ld_library_path(platform, host_platform, prefix, host_libdir),

# Default mappings for some tools
"CC" => "cc",
Expand Down
65 changes: 59 additions & 6 deletions test/runners.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ end
@test run(ur, `/bin/bash -c "echo test"`, iobuff)
seek(iobuff, 0)
# Test that we get the output we expect (e.g. the second line is `test`)
@test split(String(read(iobuff)), "\n")[2] == "test"
@test readlines(iobuff)[2] == "test"
end
end

Expand Down Expand Up @@ -96,11 +96,12 @@ end
end

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

@testset "C and link to quadmath - $(platform)" for platform in platforms
mktempdir() do dir
# Use a recent GCC with libgfortran5
options = (preferred_gcc_version=v"9", compilers=[:c])
shards = choose_shards(platform; options...)
concrete_platform = get_concrete_platform(platform, shards)
prefix = setup_workspace(
dir,
[],
concrete_platform,
default_host_platform;
)
# Install `MPICH_jll` in the `${prefix}` to make sure we can link to
# libquadmath without problems, see
# https://github.com/JuliaPackaging/BinaryBuilderBase.jl/pull/157#issuecomment-879263820
artifact_paths =
setup_dependencies(prefix,
[PackageSpec(; name="MPICH_jll", version="3.4.2")],
concrete_platform, verbose=false)
ur = preferred_runner()(prefix.path;
platform=concrete_platform,
shards = shards,
options...)
iobuff = IOBuffer()
test_c = """
#include <stdio.h>
int main() {
printf("Hello World!\\n");
return 0;
}
"""
test_script = """
set -e
echo '$(test_c)' > test.c
# Make sure we can compile successfully also when linking to libmpifort
cc -o test test.c -L\${libdir} -lmpifort -lquadmath
./test
"""
cmd = `/bin/bash -c "$(test_script)"`
if arch(platform) == "i686" && libc(platform) == "musl"
# We can't run this program for this platform
@test_broken run(ur, cmd, iobuff; tee_stream=devnull)
else
@test run(ur, cmd, iobuff; tee_stream=devnull)
seekstart(iobuff)
# Test that we get the output we expect
@test endswith(readchomp(iobuff), "Hello World!")
end
cleanup_dependencies(prefix, artifact_paths, concrete_platform)
end
end

@testset "C++ - $(platform)" for platform in platforms
mktempdir() do dir
# Use an old GCC with libgfortran3
Expand Down Expand Up @@ -167,7 +220,7 @@ end
echo '$(test_cpp)' > test.cpp
# Make sure we can compile successfully also when `\${libdir}` is in the
# linker search path
g++ -o test test.cpp -L\${libdir}
c++ -o test test.cpp -L\${libdir}
./test
"""
cmd = `/bin/bash -c "$(test_script)"`
Expand Down Expand Up @@ -217,7 +270,7 @@ end
iobuff = IOBuffer()
@test !run(ur, cmd, iobuff; tee_stream=devnull)
seekstart(iobuff)
@test split(String(read(iobuff)), "\n")[2] == "Cannot force an architecture"
@test readlines(iobuff)[2] == "Cannot force an architecture"

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

Expand Down

2 comments on commit e033966

@giordano
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/40878

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.13 -m "<description of version>" e033966fb1e8492ec7ec87e44b171e80b0728a17
git push origin v0.6.13

Please sign in to comment.