Open noraj opened 7 months ago
This is already supported. shards build
delegates all options following the build target name to crystal build
.
So indeed shards build --cross-compile
invokes crystal build ... --cross-compile
.
Hello folks,
There might be other problem with build
command, as it doesn't pass things transparently to crystal build
.
Take the example attempting to cross-compile drift
target:
name: drift
version: 0.3.2
license: Apache-2.0
crystal: ">= 1.4.0, < 2.0.0"
authors:
- Luis Lavena <luislavena@gmail.com>
targets:
drift:
main: src/cli.cr
dependencies:
db:
github: crystal-lang/crystal-db
version: ~> 0.13.1
sqlite3:
github: crystal-lang/crystal-sqlite3
version: ~> 0.21.0
$ uname -s -m
Linux aarch64
# native build
$ shards build drift
$ file bin/drift
bin/drift: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, BuildID[sha1]=14dbaf89b60cfdbf55b27f830753b856beb8ac8b, with debug_info, not stripped
Attempting to use --cross-compile
, --target
fails:
$ shards build drift --cross-compile --target x86_64-linux-musl
Dependencies are satisfied
Building: drift
Error target drift failed to compile:
Error: Missing option: --target
When run with --verbose
, we can see that platform arguments are not passed to build
:
$ shards build drift --verbose --cross-compile --target x86_64-linux-musl
db: checking...
sqlite3: checking...
db: checking...
Dependencies are satisfied
Building: drift
crystal build -o /app/bin/drift src/cli.cr --verbose --cross-compile --target
Error target drift failed to compile:
Error: Missing option: --target
Forcing you to use --target=x86_64-linux-musl
, at which points it works:
$ shards build drift --cross-compile --target=x86_64-linux-musl
Dependencies are satisfied
Building: drift
cc /app/bin/drift.o -o /app/bin/drift -rdynamic -L/usr/local/bin/../lib/crystal -lsqlite3 -lpcre2-8 -lgc -lpthread -ldl -levent
$ x86_64-linux-musl-cc bin/drift.o -o /app/bin/drift -lsqlite3 -lpcre2-8 -lgc -lpthread -ldl -levent -lunwind
$ file bin/drift
bin/drift: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
Cheers.
shards build
forwards all options it does not recognize. But x86_64-linux-musl
is recognized as a target name. I think it's generally a good idea to write a single option with key and value joined by =
.
Alternatively, you can also use double dash to tell shards build
that the following options are to be forwarded: shards build drift --verbose -- --cross-compile --target x86_64-linux-musl
.
It might be a good idea to change the forwarding behaviour so that any unrecognized option has the same effect as --
and all following options won't be parsed as options of shards build
.
This forces a certain order of options: all target names and options for shards build
itself need to go before any forwarded options. This is probably what most users do and expect to happen.
Related: crystal-lang/crystal#5845
Alternatively, you can also use double dash to tell
shards build
that the following options are to be forwarded:shards build drift --verbose -- --cross-compile --target x86_64-linux-musl
.
Sadly, that is not how build
has been coded, so that doesn't work:
$ shards build drift --verbose -- --cross-compile --target x86_64-linux-musl
db: checking...
sqlite3: checking...
db: checking...
Dependencies are satisfied
Building: drift
crystal build -o /app/bin/drift src/cli.cr --verbose
None of the options after --
are passed to crystal build
.
Only shards run
forwards options after --
: https://github.com/crystal-lang/shards/blob/master/src/cli.cr#L66-L69
Indeed. I had incorrectly inferred that to work. I'm pretty sure it should work, though.
I'm pretty sure it should work, though.
Yes, it definitely should.
shards build
is more convenient thancrystal build
for building multiple binaries. However,shards build
doesn't support--cross-compile
and--target
flags than are a must for static compilation since only Alpine is supported and so most people need to compile inside a docker.