-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
156 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
module Linking | ||
|
||
# inlined LLD_jll | ||
# These get calculated in __init__() | ||
const PATH = Ref("") | ||
const LIBPATH = Ref("") | ||
const PATH_list = String[] | ||
const LIBPATH_list = String[] | ||
const lld_path = Ref{String}() | ||
const lld_exe = Sys.iswindows() ? "lld.exe" : "lld" | ||
|
||
if Sys.iswindows() | ||
const LIBPATH_env = "PATH" | ||
const LIBPATH_default = "" | ||
const pathsep = ';' | ||
elseif Sys.isapple() | ||
const LIBPATH_env = "DYLD_FALLBACK_LIBRARY_PATH" | ||
const LIBPATH_default = "~/lib:/usr/local/lib:/lib:/usr/lib" | ||
const pathsep = ':' | ||
else | ||
const LIBPATH_env = "LD_LIBRARY_PATH" | ||
const LIBPATH_default = "" | ||
const pathsep = ':' | ||
end | ||
|
||
function adjust_ENV!(env::Dict, PATH::String, LIBPATH::String, adjust_PATH::Bool, adjust_LIBPATH::Bool) | ||
if adjust_LIBPATH | ||
LIBPATH_base = get(env, LIBPATH_env, expanduser(LIBPATH_default)) | ||
if !isempty(LIBPATH_base) | ||
env[LIBPATH_env] = string(LIBPATH, pathsep, LIBPATH_base) | ||
else | ||
env[LIBPATH_env] = LIBPATH | ||
end | ||
end | ||
if adjust_PATH && (LIBPATH_env != "PATH" || !adjust_LIBPATH) | ||
if adjust_PATH | ||
if !isempty(get(env, "PATH", "")) | ||
env["PATH"] = string(PATH, pathsep, env["PATH"]) | ||
else | ||
env["PATH"] = PATH | ||
end | ||
end | ||
end | ||
return env | ||
end | ||
|
||
function __init__() | ||
# Prefer our own bundled lld, but if we don't have one, pick it up off of the PATH | ||
# If this is an in-tree build, `lld` will live in `tools`. Otherwise, it'll be in `libexec` | ||
for bundled_lld_path in (joinpath(Sys.BINDIR, Base.LIBEXECDIR, lld_exe), | ||
joinpath(Sys.BINDIR, "..", "tools", lld_exe), | ||
joinpath(Sys.BINDIR, lld_exe)) | ||
if isfile(bundled_lld_path) | ||
lld_path[] = abspath(bundled_lld_path) | ||
return | ||
end | ||
end | ||
lld_path[] = something(Sys.which(lld_exe), lld_exe) | ||
PATH[] = dirname(lld_path[]) | ||
if Sys.iswindows() | ||
# On windows, the dynamic libraries (.dll) are in Sys.BINDIR ("usr\\bin") | ||
append!(LIBPATH_list, [joinpath(Sys.BINDIR, Base.LIBDIR, "julia"), Sys.BINDIR]) | ||
else | ||
append!(LIBPATH_list, [joinpath(Sys.BINDIR, Base.LIBDIR, "julia"), joinpath(Sys.BINDIR, Base.LIBDIR)]) | ||
end | ||
LIBPATH[] = join(LIBPATH_list, pathsep) | ||
return | ||
end | ||
|
||
function lld(; adjust_PATH::Bool = true, adjust_LIBPATH::Bool = true) | ||
env = adjust_ENV!(copy(ENV), PATH[], LIBPATH[], adjust_PATH, adjust_LIBPATH) | ||
return Cmd(Cmd([lld_path[]]); env) | ||
end | ||
|
||
function ld() | ||
default_args = `` | ||
@static if Sys.iswindows() | ||
flavor = "link" | ||
elseif Sys.isapple() | ||
flavor = "darwin" | ||
arch = Sys.ARCH == :aarch64 ? :arm64 : Sys.ARCH | ||
# TODO: gently handle failure in `xcrun`/`sw_vers` (command not found, garbage being | ||
# returned, etc...). We probably also want to provide ways to override platform | ||
# version and SDK, for when we build the release binaries. | ||
sysroot = readchomp(`xcrun --sdk macosx --show-sdk-path`) | ||
platform_version = readchomp(`sw_vers -productVersion`) | ||
platform_sdk = readchomp(`xcrun --show-sdk-version`) | ||
default_args = `-arch $arch -syslibroot $(sysroot) -lSystem -platform_version macos $(platform_version) $(platform_sdk)` | ||
else | ||
flavor = "gnu" | ||
end | ||
|
||
`$(lld()) -flavor $flavor $default_args` | ||
end | ||
|
||
const WHOLE_ARCHIVE = if Sys.isapple() | ||
`-all_load` | ||
elseif Sys.iswindows() | ||
`/WHOLEARCHIVE` | ||
else | ||
`--whole-archive` | ||
end | ||
|
||
const NO_WHOLE_ARCHIVE = if Sys.isapple() || Sys.iswindows() | ||
`` | ||
else | ||
`--no-whole-archive` | ||
end | ||
|
||
const SHARED = if Sys.isapple() | ||
`-dylib` | ||
elseif Sys.iswindows() | ||
`/DLL` | ||
else | ||
`-shared` | ||
end | ||
|
||
function libdir(path) | ||
@static if Sys.iswindows() | ||
`/LIBPATH:$(path)` | ||
else | ||
`-L$(path)` | ||
end | ||
end | ||
|
||
function output(path) | ||
@static if Sys.isapple() | ||
`-o $(path)` | ||
elseif Sys.iswindows() | ||
`/OUT:$(path)` | ||
else | ||
`--output=$(path)` | ||
end | ||
end | ||
|
||
function l(path) | ||
@static if Sys.iswindows() | ||
path | ||
else | ||
"-l$path" | ||
end | ||
end | ||
|
||
is_debug() = ccall(:jl_is_debugbuild, Cint, ()) == 1 | ||
|
||
function link_image(path, out, internal_stderr::IO = stderr, internal_stdout::IO = stdout) | ||
LIBDIR = libdir(joinpath(Sys.BINDIR, "..", "lib")) | ||
libs = is_debug() ? ("julia-debug", "julia-internal-debug") : ("julia", "julia-internal") | ||
LIBS = map(l, libs) | ||
|
||
run(`$(ld()) $SHARED $(output(out)) $WHOLE_ARCHIVE $path $NO_WHOLE_ARCHIVE $LIBDIR $LIBS`, | ||
Base.DevNull(), internal_stdout, internal_stderr) | ||
end | ||
end # module Linking |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters