-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement support for object caching through pkgimages #47184
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
0a8e063
Cache objectcode in pkgimages
vchuravy 0f135a3
Improve wording, fix whitespace
timholy 90db48c
Can't reference devdocs from manual
timholy 5043270
Capitalize Xcode correctly
timholy 4e97943
Clarify documentation
timholy 22233f6
Docs: command-line options
timholy b8872d1
Expand "link" to devdocs
timholy 8b308f1
Update doc/src/manual/command-line-interface.md
timholy 03fe8d7
Merge branch 'master' into vc/external_functions
timholy 58b4ac1
Mixin cpu_target
vchuravy 1785d51
Don't overcount
vchuravy 5c114ba
Update the documentation a bit
vchuravy 71622a1
Reject .ji on pkgimage
vchuravy 6ff3284
fixup! Don't overcount
vchuravy cb2cd68
Merge branch 'master' into vc/external_functions
timholy c405552
Fix & test PkgCacheInspector
timholy 6373b89
Split post-load work into separate function
timholy 23ce9aa
Merge branch 'master' into vc/external_functions
IanButterworth 9b6bc2b
fix 32bit test failure
IanButterworth bb10c8c
Rename command line flag
vchuravy 313bb9a
Apply suggestions from code review
vchuravy 0d469bd
[CompilerSupportLibraries_jll] Upgrade to v1.0.2 and install `libsspd…
giordano 692aa52
Merge branch 'master' into vc/external_functions
timholy 17ff877
Find native code in non-worklist modules
timholy 6e9a670
bump Pkg to a version that does not precompile on add
KristofferC 9f2f0d1
Revert "bump Pkg to a version that does not precompile on add"
KristofferC 0365526
Add MWE for DynamicExpressions failure
timholy f33c2a6
Simplify test
KristofferC 5fe7c05
Change interposers from weak to internal
vchuravy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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,147 @@ | ||
# This file is a part of Julia. License is MIT: https://julialang.org/license | ||
module Linking | ||
|
||
import Base.Libc: Libdl | ||
|
||
# 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) | ||
vchuravy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 !isempty(get(env, "PATH", "")) | ||
env["PATH"] = string(PATH, pathsep, env["PATH"]) | ||
else | ||
env["PATH"] = PATH | ||
end | ||
end | ||
return env | ||
end | ||
|
||
function __init_lld_path() | ||
# 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) | ||
return | ||
end | ||
|
||
const VERBOSE = Ref{Bool}(false) | ||
|
||
function __init__() | ||
VERBOSE[] = parse(Bool, get(ENV, "JULIA_VERBOSE_LINKING", "false")) | ||
timholy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
__init_lld_path() | ||
PATH[] = dirname(lld_path[]) | ||
if Sys.iswindows() | ||
# On windows, the dynamic libraries (.dll) are in Sys.BINDIR ("usr\\bin") | ||
append!(LIBPATH_list, [abspath(Sys.BINDIR, Base.LIBDIR, "julia"), Sys.BINDIR]) | ||
else | ||
append!(LIBPATH_list, [abspath(Sys.BINDIR, Base.LIBDIR, "julia"), abspath(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() | ||
# LLD supports mingw style linking | ||
flavor = "gnu" | ||
m = Sys.ARCH == :x86_64 ? "i386pep" : "i386pe" | ||
default_args = `-m $m -Bdynamic --enable-auto-image-base --allow-multiple-definition` | ||
elseif Sys.isapple() | ||
flavor = "darwin" | ||
arch = Sys.ARCH == :aarch64 ? :arm64 : Sys.ARCH | ||
default_args = `-arch $arch -undefined dynamic_lookup -platform_version macos $(Base.MACOS_PRODUCT_VERSION) $(Base.MACOS_PLATFORM_VERSION)` | ||
vchuravy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
flavor = "gnu" | ||
end | ||
|
||
`$(lld()) -flavor $flavor $default_args` | ||
end | ||
|
||
const WHOLE_ARCHIVE = if Sys.isapple() | ||
"-all_load" | ||
else | ||
"--whole-archive" | ||
end | ||
|
||
const NO_WHOLE_ARCHIVE = if Sys.isapple() | ||
"" | ||
else | ||
"--no-whole-archive" | ||
end | ||
|
||
const SHARED = if Sys.isapple() | ||
"-dylib" | ||
else | ||
"-shared" | ||
end | ||
|
||
is_debug() = ccall(:jl_is_debugbuild, Cint, ()) == 1 | ||
libdir() = abspath(Sys.BINDIR, Base.LIBDIR) | ||
private_libdir() = abspath(Sys.BINDIR, Base.PRIVATE_LIBDIR) | ||
if Sys.iswindows() | ||
shlibdir() = Sys.BINDIR | ||
else | ||
shlibdir() = libdir() | ||
end | ||
|
||
function link_image_cmd(path, out) | ||
LIBDIR = "-L$(libdir())" | ||
PRIVATE_LIBDIR = "-L$(private_libdir())" | ||
SHLIBDIR = "-L$(shlibdir())" | ||
LIBS = is_debug() ? ("-ljulia-debug", "-ljulia-internal-debug") : ("-ljulia", "-ljulia-internal") | ||
@static if Sys.iswindows() | ||
LIBS = (LIBS..., "-lopenlibm", "-lssp", "-lgcc_s", "-lgcc", "-lmsvcrt") | ||
end | ||
|
||
V = VERBOSE[] ? "--verbose" : "" | ||
`$(ld()) $V $SHARED -o $out $WHOLE_ARCHIVE $path $NO_WHOLE_ARCHIVE $LIBDIR $PRIVATE_LIBDIR $SHLIBDIR $LIBS` | ||
end | ||
|
||
function link_image(path, out, internal_stderr::IO = stderr, internal_stdout::IO = stdout) | ||
run(link_image_cmd(path, out), Base.DevNull(), stderr, stdout) | ||
end | ||
|
||
end # module Linking |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the caching here, I think the first cache should definitely be done.
I'm okay with the second cache, although I think there's an argument for not including them in the default download, as they're mostly only useful for CI/running
Base.runtests()
. The main downside is that they do generate some amount of extra data that must be transferred over the internet many times, but it's pretty small, like ~1MB.I think 1MB is probably okay for us to just ship unconditionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another reason to eagerly precompile is to avoid having testing processes suddenly try to precompile these files multiple times. However, we will still run into multiple processes trying to smash these out if someone does a
Base.runtests()
from within the development directory (before runningmake install
), right? Perhaps it's better to add these into a function that gets invoked from within Julia itself upon the running ofBase.runtests()
?Pkg.test()
will already precompile everything it needs to, so I don't think we need to worry about user package tests running into this problem.