Skip to content

Propagating the target compiler to subcommands #15145

Closed
@straight-shoota

Description

@straight-shoota

Since #14953 the compiler can run external executables as subcommands as an alternative to builtin commands.

This kind of subcommand delegation needs to ensure consistency in the compiler version being used.
For example, let's run path/to/crystal subcommand which calls crystal-subcommand from somewhere in $PATH. The subcommand needs to be aware that the target compiler is path/to/crystal, not whatever crystal is in $PATH.

The current solution from #14953 passes the environment variable $CRYSTAL to the subcommand which has the full path to the compiler.

I don't think it works very well. It requires the subcommand to recognize the environment variable. But it must also expect it to be unset when the command is executed directly (as crystal-subcommand). And this trickles down to other processes that the subcommand might spawn. They typically should also be aware of the target crystal compiler. This is practically impossible to realize with the $CRYSTAL environment variable.

git uses a similar mechanism to run subcommands and handles propagating the target instance in a different way: It prepends the path to the parent directory of the executable to $PATH. That means if the subcommand process calls git, it'll resolve to the original one. Path lookup just works when the subcommand is executed directly.

Additionally, git also puts this directory path in the environment variable $GIT_EXEC_PATH. I'm not familiar with the specific details when one is used over the other, but it looks like the prepended $PATH and $GIT_EXEC_PATH are identical.

I think we should add the compiler's parent directory to $PATH. This feature is still brand new and AFAIK not actively used, so I think it should be acceptable to replace the $CRYSTAL variable. We could consider keeping it along, but if we do that, we'll need to do that for a long time. I think it's better to drop it in order to avoid new subcommands ever depend on it.

Introducing a separate $CRYSTAL_EXEC_PATH could also be valuable. I believe it could be a more generic replacement to $CRYSTAL_SPEC_COMPILER_BIN which we use in the spec suite.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions