-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add Crystal::Loader
#11434
Add Crystal::Loader
#11434
Conversation
Co-authored-by: Sijawusz Pur Rahnama <[email protected]>
Will (I saw this comment in the source code too, that's why I ask) |
I don't think it should be part of the public API. It's in the compiler source tree. Maybe that could change at some point, if there's demand for it. But that might need other alternations as well. |
Oh, if it's not meant to be publicly exposed than it's fine to leave the comment as is. |
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.
This looks awesome! One suggestion on automatically supporting Homebrew-based libs on ARM64
|
||
{% if flag?(:darwin) %} | ||
default_search_paths << "/usr/lib" | ||
default_search_paths << "/usr/local/lib" |
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.
Should we add the /opt/homebrew/lib
path for ARM64 Darwin? Or do that as a patch on the Homebrew-side? (This would mirror the behavior of the FFI gem, for example)
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.
We should keep the internals exactly as in ld
to avoid confusion between linking in interpreted and compiled mode. Any user-defined paths must be configured via DYLD_LIBRARY_PATH or CRYSTAL_LIBRARY_PATH.
How the |
Yes. Check the interpreter branch to see how it's done now. |
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 left some minor comments
# verions of the libraries that the compiler is linked against. | ||
# * A fully statically linked compiler may help dealing with the previous | ||
# issue. But using `libdl` in a non-dynamically loaded executable might cause | ||
# other issues. |
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.
What kind of issues? Or is it an unknown?
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.
It's unknown (at least to me).
There are projects such as https://github.com/mittorn/custom-linker to mitigate this. I did not encounter any problems in my (limited) tests with statically linked binaries, however. I guess we'll see how this plays out.
File.each_line(path) do |line| | ||
next if line.empty? || line.starts_with?("#") | ||
|
||
if include_path = line.lchop?("include ") |
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.
Is include <path>
(space before and/or after include
) considered invalid in ld.so.conf
?
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.
There is a space between include
and the path. I'm not sure if more whitespace is allowed or not. Couldn't find a proper format specification (if there even is one). All examples I've looked at have no extra whitespace.
# def find_symbol?(name : String) : Handle? | ||
# raise NotImplementedError.new("find_symbol?") | ||
# end | ||
|
||
# def load_file(path : String | ::Path) : Handle | ||
# raise NotImplementedError.new("load_file") | ||
# end | ||
|
||
# private def open_library(path : String) : Handle | ||
# raise NotImplementedError.new("open_library") | ||
# end | ||
|
||
# def self.default_search_paths : Array(String) | ||
# raise NotImplementedError.new("close_all") | ||
# end |
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.
This commented code should be removed, right?
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 added it there to define the interface that is expected to be implemented in the platform-specific files.
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.
We do the same thing in with platform-specific implementations in Crystal::System
.
Co-authored-by: Beta Ziliani <[email protected]>
if File.exists?(path) | ||
yield path | ||
end |
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.
Small stylistic suggestion:
if File.exists?(path) | |
yield path | |
end | |
yield path if File.exists?(path) |
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.
🚀
This patch adds a linker/loader component to the compiler. We need this for interpreted mode and it imitates the behaviour of
ld.so
/ld
for linking and loading dynamic libraries at runtime.It's a preparatory step for #11159 and adds nothing by itself. But it's an isolated non-trivial component that we can discuss it on its own.
It provides the following functionality:
-L/usr/local/mylibs -lfoo /path/to/libbar.so
)libdl
)The symbol addresses serve as a point to call in via
libffi
(not included in this PR).There are a number of differences compared to linking object files in a normal
object file linking process. Most are caused by limitations of
libdl
.are unsupported.
loaded in the compiler program itself may provide symbols to libraries
loaded with
Crystal::Loader
. Symbols may be available without explicitlymentioning their libraries. It might be impossible to link against other
verions of the libraries that the compiler is linked against.
issue. But using
libld
in a non-dynamically loaded executable might causeother issues.
Probably we'll discover more limitations and differences over time.
Resolves #11173