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

crystal build --cross-compile should generate a helpful target script #13379

Open
skull-squadron opened this issue Apr 22, 2023 · 2 comments
Open

Comments

@skull-squadron
Copy link

skull-squadron commented Apr 22, 2023

Feature Request

Problem statement

  • {shards|crystal} build --cross-compile --target ... produces an incomplete solution

Compounding factors

  • Creaky, brittle, manual steps should be avoided
  • The doc for cross-compilation is also currently out-of-date (missing libevent)

Solution

  • It's genericide-able :) by dropping a target-specific script into ./bin
Linux
#!/usr/bin/env bash
set -euo pipefail
warn() { echo >&2 "$@"; }
die() { warn "$@"; exit 1; }
help() {
  die "$(cat<<HELP
Usage: $0 {command} ...

Commands

   install-depends

   link TARGET
HELP
)

"
}

linux::link() {
  set -x
  exec "${CC:-cc}" "$1.o" -o "$1" -lpcre -lrt -lm -lgc -lunwind -levent ${CFLAGS-}
}

_sudo() {
  local SUDO
  if [ $UID = 0 ]; then
    SUDO=
  else
    SUDO=${SUDO:-sudo}
  fi
  set -x
  exec $SUDO "$@"
}

_apt() {
  _sudo env DEBIAN_FRONTEND=noninteractive apt-get "$@"
}


#### Distro-specific code

debian::install-depends() {
  _apt update
  _apt -y --no-install-recommends \
    build-essential libevent-dev libpcre3-dev libgc-dev libunwind-dev
}

debian::link() {
  linux::link "$@"
}

ubuntu::install-depends() {
  debian::install_depends "$@"
}

ubuntu::link() {
  linux_link "$@"
}

# fedora::install-depends() {
#   _sudo dnf install -y ...
# }
#
# fedora::link() {
#   linux::link "$@"
# }
#
# ...

#### Main

# Detect distro ID
REGEX=(
  '/^ID=/!d'
  's/^ID=//'
  's/'\''\(.*\)'\''/\1/'
  's/"\(.*\)"/\1/'
)
if ID=$(IFS=';'; sed "${REGEX[*]}" /etc/os-release 2>/dev/null); then
  :
elif [ -n "$(command -v lsb_release 2>/dev/null)" ]; then
  ID=$(lsb_release -is | tr A-Z a-z)
fi

# Validate distro ID
[ -n "$ID" ] || die 'Error: Unknown Linux distro'

# Validate CLI args and dispatch to distro-specific function
CMD="${1-}"; shift || true
case "$CMD" in
  install-depends) ;;
  link)            [[ -e "${1-}" ]] || help ;;
  *)               help ;;
esac
CMD="${ID}::${CMD}"
command "$CMD" || die "Unsupported Linux distro $ID"
"${CMD}" "$@"

and then macOS, Windows, FreeBSD, {{your_os_here}} ...

Long-term solution

  • Vendor static libraries and cross-platform linker (lld?)
    • Problems
      • hosts x targets = N^2
      • Needs continuous builds against libraries' upstream stable
      • Disk space
    • Possible partial solution
@skull-squadron skull-squadron changed the title crystal build --cross-compile should generate a target dependencies setup and link system script crystal build --cross-compile should generate a helpful target script Apr 22, 2023
@straight-shoota
Copy link
Member

Could you please describe the problem more specifically? I don't follow what you mean with "incomplete".

Judging from the example solution for linux I might guess that you're missing a method to automatically install library dependencies?
But I'm pretty sure that's way out of scope for the compiler to worry about.

@straight-shoota
Copy link
Member

/ping @steakknife Could you add some information?

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

2 participants