Skip to content

Conversation

@Keno
Copy link
Member

@Keno Keno commented Aug 31, 2023

I've written this code probably three times at this point, but for some reason it never made it into a PR. This allows loading a system image that has already been loaded into memory. This happen when wanting to distribute a static or mostly-static binary of julia code where the system image (and optionally other libraries like libjulia, etc.) are linked directly into the main executable. It is also useful for deployment to environments that do not have (or have incomplete) support for dynamic linking (e.g. wasm or embedded).

@Keno
Copy link
Member Author

Keno commented Aug 31, 2023

I guess weak externals are supposed to work on windows, but are broken in the compiler https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90826 (issue by our very own @yuyichao). I think I'm gonna disable the weak symbol fast path on windows for the time being.

@Keno
Copy link
Member Author

Keno commented Aug 31, 2023

Leaving this here for my own future reference to take another look: https://maskray.me/blog/2021-04-25-weak-symbol

@gbaraldi
Copy link
Member

By already in memory you mean linking sys.so statically into the julia executable?

@Keno
Copy link
Member Author

Keno commented Aug 31, 2023

Essentially yes. There's various other configurations, but that's the prototypical one

src/init.c Outdated
// loads sysimg if available, and conditionally sets jl_options.cpu_target
if (jl_options.image_file)
if (rel == JL_IMAGE_IN_MEMORY)
jl_set_sysimg_so(jl_RTLD_DEFAULT_handle);
Copy link
Member

Choose a reason for hiding this comment

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

This is normally an alias for jl_libjulia_internal_handle, but I think you wanted to assume jl_exe_handle here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, I wanted RTLD_DEFAULT, but I'm only testing Linux for now, so it doesn't make a difference. I'll switch this to jl_exe_handle (assuming nothing breaks), but of course we may need extra options in the future potentially.

Copy link
Member

@vtjnash vtjnash left a comment

Choose a reason for hiding this comment

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

Seems like a reasonable approach. I have done this a few times too. I think usually I had altered the jl_options struct to take the handle(s) as an argument (since I think jl_preload_sysimg_so would early-exit if it was already populated), so that relying on the behaviors of notoriously different semantics for weak wasn't necessary. But it has been a while since I experimented with it, and that particular trick is probably broken now.

@vtjnash
Copy link
Member

vtjnash commented Aug 31, 2023

There is a comment in the code still that says you were supposed to do this by calling jl_set_sysimg_so early in initialization (e.g. before init). Is that advice still valid? (staticdata.c:2809)

src/init.c Outdated
free(free_path);
free_path = NULL;
if (jl_options.image_file) {
if (jl_options.image_file && rel != JL_IMAGE_IN_MEMORY) {
Copy link
Member

Choose a reason for hiding this comment

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

I think you still need to process this field, as julia expects it to hold a valid value in various places (for Distributed, precompilation, and other similar optimizations).

@Keno
Copy link
Member Author

Keno commented Aug 31, 2023

There is a comment in the code still that says you were supposed to do this by calling jl_set_sysimg_so early in initialization (e.g. before init). Is that advice still valid? (staticdata.c:2809)

I think it'd probably still work, but it still assumes that you have a dynamic linking environment, which you may not (hence the weak symbols here). I think this API is cleaner, but the other API is useful for the use case where you're embedding into a big host C/C++ environment and you already loaded the sysimage as a shared library.

Keno added 5 commits September 1, 2023 04:56
I've written this code probably three times at this point, but for some
reason it never made it into a PR. This allows loading a system image
that has already been loaded into memory. This happen when wanting to
distribute a static or mostly-static binary of julia code where the
system image (and optionally other libraries like libjulia, etc.) are
linked directly into the main executable. It is also useful for deployment
to environments that do not have (or have incomplete) support for dynamic
linking (e.g. wasm or embedded).
Aliases are not supported on mac it turns out.
@Keno Keno force-pushed the kf/sysimgselfload branch from bf93cb8 to c83fa3c Compare September 1, 2023 05:09
@Keno Keno merged commit 70000ac into master Sep 3, 2023
@Keno Keno deleted the kf/sysimgselfload branch September 3, 2023 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants