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

Support for cross compilation #627

Open
noraj opened this issue Apr 21, 2024 · 8 comments
Open

Support for cross compilation #627

noraj opened this issue Apr 21, 2024 · 8 comments

Comments

@noraj
Copy link

noraj commented Apr 21, 2024

shards build is more convenient than crystal 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.

@straight-shoota
Copy link
Member

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.

@luislavena
Copy link
Contributor

luislavena commented May 20, 2024

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.

@straight-shoota
Copy link
Member

straight-shoota commented May 20, 2024

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.

@straight-shoota
Copy link
Member

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.

@HertzDevil
Copy link
Contributor

Related: crystal-lang/crystal#5845

@luislavena
Copy link
Contributor

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

@straight-shoota
Copy link
Member

straight-shoota commented May 20, 2024

Indeed. I had incorrectly inferred that to work. I'm pretty sure it should work, though.

@ysbaddaden
Copy link
Contributor

I'm pretty sure it should work, though.

Yes, it definitely should.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants