Skip to content
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 support for CRYSTAL_PATH resolution relative to compiler #10877

Conversation

straight-shoota
Copy link
Member

Resolves #7391

This patch adds support for runtime expansion of the CRYSTAL_PATH environment variable. It allows resolving the path to the standard library relative to the compiler location at runtime. This avoids the need to bake absolute paths into the compiler and using a wrapper script for distribution (https://github.com/crystal-lang/distribution-scripts/blob/8bc01e26291dc518390129e15df8f757d687871c/linux/files/crystal-wrapper). In fact, this essentially replicates the behaviour of the wrapper script, just embedded in the compiler directly.

It integrates perfectly with all existing usage. The new behaviour only becomes active when CRYSTAL_PATH includes the pattern %{COMPILER_DIR}. Existing use cases such as the wrapper script or baking ing absolute paths continue to work and will continue to do so.

The real value comes when this is baked in via CRYSTAL_CONFIG_PATH because that makes the compiler binary work standalone, as long as it finds the standard library in the designated path relative to its location.
So the default path %{COMPILER_DIR}/../share/crystal/src is configured in the Makefile. This location fits the typical install paths /usr/bin/crystal and /usr/share/crystal/src. This will become even more useful with make install (#10702) and adaptation in distribution-scripts.

Copy link
Member

@asterite asterite left a comment

Choose a reason for hiding this comment

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

Really nice! 👏

# to produce a portable binary that resolves the standard library path
# relative to the compiler location, independent of the absolute path.
if executable_path = Process.executable_path
path %= {"COMPILER_DIR": File.dirname(executable_path)}
Copy link
Member

Choose a reason for hiding this comment

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

This makes any path that happens to contain % blow up. Also could have security implications because the format string is taken from user input.

I think at the very least this needs a different implementation for the substitution. (e.g. literally replacing %{COMPILER_DIR} would probably already be better). But I'd hope that there would be some placeholder that's more or less guaranteed to not be encountered.

There is precedent in LD_LIBRARY_PATH to specially understand the exact string $ORIGIN at the beginning of the path, and I don't see any reason to prefer a completely new convention over that one.
https://www.google.com/search?q=rpath+origin

And I would like to stress that I think it's quite important to recognize the string only at the beginning of a path.

Copy link
Member Author

Choose a reason for hiding this comment

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

Using an already established mechanism is a great suggestions. I suppose @executable_path (from macos' linker) could also be an option for this. But I'm fine with $ORIGIN.

You're absolutely right about the implications of sprintf expansion. I'll change that.

@straight-shoota
Copy link
Member Author

I suppose we should add the same relative path resolution mechanism for CRYSTAL_LIBRARY_PATH as well.

@straight-shoota
Copy link
Member Author

Closing. I created a fresh PR at #11030 which should be easier to review.

The final diff isn't that much different but it's bit cleaner now.

@straight-shoota straight-shoota deleted the feature/crystal-path-resolution branch July 27, 2021 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merge the /bin/crystal Shell script in the compiler?
3 participants