The /bin/crystal script is setting environment variables, then calling the compiler.
The questions are:
.bashrc or .zshrc?Issues:
I think exposing CRYSTAL_PATH=$CRYSTAL_ROOT/src:lib, and potentially other variables, through an API that can be used by shards and other projects (ameba?) would be a nice plus, instead of assuming the library path in each project and hard-coding it.
This isn't a problem.
This is a problem for the Windows port, or we create bin/crystal.bat. Whatever the solution chosen, something has to be done.
Prevents also to set i_know_what_im_doing when we think we know what we are doing like https://github.com/crystal-lang/crystal/issues/5835, but in fact not so much :sweat_smile:
I think we should keep bin/crystal as a developer tool. But I don't think the distribution packages should need it.
@straight-shoota Then who sets CRYSTAL_PATH to point it to the standard library?
For example look on Alpine, file $(which crystal) returns directly the binary.
docker run -it --rm -v $PWD:/app -w /app jrei/crystal-alpine sh -c 'ldd $(which crystal)'
/lib/ld-musl-x86_64.so.1 (0x7f1d127c1000)
libLLVM-5.0.so => /usr/lib/libLLVM-5.0.so (0x7f1d0f7d2000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7f1d0f67d000)
libpcre.so.1 => /usr/lib/libpcre.so.1 (0x7f1d0f620000)
libgc.so.1 => /usr/lib/libgc.so.1 (0x7f1d0f5b1000)
libevent-2.1.so.6 => /usr/lib/libevent-2.1.so.6 (0x7f1d0f566000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7f1d0f552000)
libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f1d127c1000)
libffi.so.6 => /usr/lib/libffi.so.6 (0x7f1d0f549000)
libz.so.1 => /lib/libz.so.1 (0x7f1d0f52f000
Environments variables:
docker run -it --rm -v $PWD:/app -w /app jrei/crystal-alpine crystal env
CRYSTAL_CACHE_DIR="/root/.cache/crystal"
CRYSTAL_PATH="lib:/usr/lib/crystal/shards:/usr/lib/crystal/core"
CRYSTAL_VERSION="0.27.2"
So it's definitely possible. I've pushed commits in this way. Here the CI won't run, the draft PR being closed.
The compiler can assign that itself. It would simply use the same default as the wrapper script, which is essentially #{File.dirname(File.dirname(File.real_path(PROGRAM_NAME)))}/src/:lib.
The wrapper script doesn't do anything else when used from the distribution package.
@j8r The value for CRYSTAL_PATH comes from CRYSTAL_CONFIG_PATH which is set at compile time (see build step in APKBUILD). A hard coded path is not portable.
Or just ~src:lib~ @straight-shoota when either CRYSTAL_PATH or CRYSTAL_CONFIG_PATH aren't set.
Edit: this works only when developing the compiler, not when using the tarball archive. Your #{File.dirname(File.dirname(File.real_path(PROGRAM_NAME)))}/src/:lib is perfectly fine :+1:
Distribution packages don't have to be portable, they know absolute paths so use CRYSTAL_CONFIG_PATH. The portable tar.gz uses a different bin/crystal to the one in this repo and needs to set CRYSTAL_PATH dynamically based on where it's run. The one in this repo needs the same since it needs to override the standard library location from the system location, and it needs additional logic to handle choosing a compiler.
Presumably if you're running gdb on a compiler, then you've built it using make crystal (otherwise the debugging information is likely not present, or it's an optimized binary) and so the correct CRYSTAL_PATH has already been compiled into the executable. So most of the pain is gone just by using gdb on .build/crystal
Ok, why @straight-shoota solution won't work? What prevents this logic to be in Crystal rather than in Shell, Python or Windows batch?
crystal thats takes the stdlib from ../src, from where the binary is located.build/crystal and the stdlib comes from again ../src. make use .build/crystal if present, else system's crystalA wrapper doesn't look like being needed to solve this problem.
@RX14 We could replace the crystal-wrapper fro distribution-scripts with a native crystal implementation as suggested in https://github.com/crystal-lang/crystal/issues/7391#issuecomment-486688064. This is immediately portable and doesn't require a separate solution for windows. Having one less piece in the puzzle is generally an improvement as well.
@j8r
makeuse.build/crystalif present, else system'scrystal
That's actually the primary job of bin/crystal. We shouldn't remove the development version from the repo. But the distribution version can be replaced.
What's the net benefit of doing this?
@asterite one less (possibly useless) file to support? (minus https://github.com/crystal-lang/distribution-scripts/commits/master/linux/files/crystal-wrapper).
It's also better to have less divergence between distributions. Some use this wrapper (tarball) , some don't (Alpine).
Another issue, the compiler is developed with a wrapper but the release is distributed with another one – not ideal.
The benefit is small, but the work is small too.
There are also confusion about this wrapper and the compiler binary.