aboutsummaryrefslogtreecommitdiffstats
path: root/community/crystal
diff options
context:
space:
mode:
authorJakub Jirutka <jakub@jirutka.cz>2018-04-02 23:38:36 +0200
committerJakub Jirutka <jakub@jirutka.cz>2018-04-02 23:39:59 +0200
commit63900f59e4fd1c6d98030562281626efabe4c08f (patch)
treebb7e11b6b0641794bc36116800719af4f2056605 /community/crystal
parentba92e1b07a254797cd28ebc642e921691e0e8db3 (diff)
downloadaports-63900f59e4fd1c6d98030562281626efabe4c08f.tar.bz2
aports-63900f59e4fd1c6d98030562281626efabe4c08f.tar.xz
community/crystal: move from testing
Diffstat (limited to 'community/crystal')
-rw-r--r--community/crystal/APKBUILD138
-rw-r--r--community/crystal/aarch64-linux-musl.patch940
-rw-r--r--community/crystal/alpine-shards-help.patch13
-rw-r--r--community/crystal/disable-specs-using-GB2312-encoding.patch282
-rw-r--r--community/crystal/fix-codegen-specs.patch117
-rw-r--r--community/crystal/fix-makefile-stderr-redirect.patch29
-rw-r--r--community/crystal/libressl.patch120
-rw-r--r--community/crystal/makefile-allow-extra-flags.patch23
-rw-r--r--community/crystal/makefile-shell.patch78
-rw-r--r--community/crystal/paxmark.patch22
10 files changed, 1762 insertions, 0 deletions
diff --git a/community/crystal/APKBUILD b/community/crystal/APKBUILD
new file mode 100644
index 0000000000..dbdbb73c4d
--- /dev/null
+++ b/community/crystal/APKBUILD
@@ -0,0 +1,138 @@
+# Contributor: Jakub Jirutka <jakub@jirutka.cz>
+# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
+pkgname=crystal
+pkgver=0.24.2
+pkgrel=5
+_bootver=0.24.2
+_llvmver=5
+pkgdesc="The Crystal Programming Language"
+url="https://crystal-lang.org/"
+arch="x86_64 aarch64"
+license="Apache-2.0"
+depends="gc-dev libatomic_ops libevent-dev gcc gmp-dev pcre-dev"
+checkdepends="libressl-dev libxml2-dev paxmark readline-dev tzdata yaml-dev zlib-dev"
+makedepends="llvm$_llvmver-dev ${BUILD_STATIC:+"llvm$_llvmver-static"}"
+subpackages="$pkgname-doc
+ $pkgname-bash-completion:bashcomp:noarch
+ $pkgname-zsh-completion:zshcomp:noarch
+ "
+source="$pkgname-$pkgver.tar.gz::https://github.com/crystal-lang/$pkgname/archive/$pkgver.tar.gz
+ https://dev.alpinelinux.org/archive/crystal/crystal-$_bootver-x86_64-alpine-linux-musl.tar.gz
+ https://dev.alpinelinux.org/archive/crystal/crystal-$_bootver-aarch64-alpine-linux-musl.tar.gz
+ makefile-shell.patch
+ fix-makefile-stderr-redirect.patch
+ makefile-allow-extra-flags.patch
+ paxmark.patch
+ aarch64-linux-musl.patch
+ fix-codegen-specs.patch
+ disable-specs-using-GB2312-encoding.patch
+ libressl.patch
+ alpine-shards-help.patch
+ "
+builddir="$srcdir/$pkgname-$pkgver"
+
+_coredir="/usr/lib/$pkgname/core"
+_shardsdir="/usr/lib/$pkgname/shards"
+
+export CRYSTAL_CONFIG_VERSION="$pkgver"
+export CRYSTAL_CACHE_DIR="$srcdir/.cache"
+
+# Build static crystal binary and upload it to dev.a.o, so it can be used
+# for building crystal next time (needed for bootstrapping).
+# NOTE: After https://github.com/crystal-lang/crystal/issues/5689 is fixed,
+# we can also use prebuilt binary from upstream if needed.
+snapshot() {
+ local binary="$builddir/.build/crystal"
+ local tarname="$pkgname-$pkgver-$CTARGET"
+
+ if [ ! -f "$binary" ] || ! file "$binary" | grep -qw 'statically linked'; then
+ msg "Building statically linked crystal..."
+ BUILD_STATIC=1 abuild clean deps unpack prepare build
+ fi
+
+ cd "$srcdir"
+
+ strip "$builddir"/.build/crystal
+ install -D -m 755 "$builddir"/.build/crystal "$tarname"/bin/crystal
+ tar -czf "$tarname.tar.gz" "$tarname"
+
+ msg "Uploading $tarname.tar.gz to dev.alpinelinux.org"
+ scp "$tarname.tar.gz" dev.alpinelinux.org:/archive/$pkgname/
+
+ APKBUILD="../APKBUILD" abuild undeps
+}
+
+prepare() {
+ default_prepare
+ cd "$builddir"
+
+ cat > Makefile.local <<-EOF
+ progress = 1
+ threads = ${JOBS:-2}
+ verbose = 1
+ EXTRA_FLAGS = --verbose --target $CTARGET ${BUILD_STATIC:+"--link-flags=-no-pie"}
+ LLVM_CONFIG = /usr/lib/llvm$_llvmver/bin/llvm-config
+ EOF
+}
+
+build() {
+ cd "$builddir"
+
+ make crystal \
+ CRYSTAL_CONFIG_PATH="lib:$_shardsdir:$_coredir" \
+ PATH="$srcdir/$pkgname-$_bootver-$CBUILD/bin:$PATH" \
+ release=1 \
+ static=${BUILD_STATIC:-}
+}
+
+check() {
+ cd "$builddir"
+
+ make spec PATH=".build:$PATH" SPEC_FLAGS="--no-color --verbose"
+}
+
+package() {
+ cd "$builddir"
+
+ install -D -m 755 .build/crystal "$pkgdir"/usr/bin/crystal
+ install -D -m 644 man/crystal.1 "$pkgdir"/usr/share/man/man1/crystal.1
+
+ mkdir -p "$pkgdir$_coredir" "$pkgdir$_shardsdir"
+ cp -r src/* "$pkgdir$_coredir"/
+
+ cd "$pkgdir$_coredir"
+ rm ext/sigfault.* llvm/ext/llvm_ext.o
+}
+
+bashcomp() {
+ pkgdesc="Bash completions for $pkgname"
+ depends=""
+ install_if="$pkgname=$pkgver-r$pkgrel bash-completion"
+
+ cd "$builddir"
+ install -D -m 644 etc/completion.bash \
+ "$subpkgdir"/usr/share/bash-completion/completions/$pkgname
+}
+
+zshcomp() {
+ pkgdesc="ZSH completions for $pkgname"
+ depends=""
+ install_if="$pkgname=$pkgver-r$pkgrel zsh"
+
+ cd "$builddir"
+ install -D -m 644 etc/completion.zsh \
+ "$subpkgdir"/usr/share/zsh/site-functions/_$pkgname
+}
+
+sha512sums="db9fb973eeb2bc72ef91bb894b7c5aea73e727ff46e739aa431d68e556238f346a688a7a43de284afb4667b49366afce3ca423a523bea521180fa8f19ba6862d crystal-0.24.2.tar.gz
+6d7ee01ff5bfaaf79fa80c15575ae4496e17629ed18cb0577db6734266c2dbf5b0bf0a554c7c153e1b81f4c71e62bb803fd4b6513e3d039571ee4f953d85ecf4 crystal-0.24.2-x86_64-alpine-linux-musl.tar.gz
+d6ed122a5ddb4e1ea772357cd3115dcf8cd92a75f973b6f7e4b8b6135fb4123fb98334495f6f312da7ab7ba3bda57bd3cb4f06c0f421df2c09d19c0ab1b8b67b crystal-0.24.2-aarch64-alpine-linux-musl.tar.gz
+2a81b6eaeb934ef5d4435a80a346425a760a602d04bccc89068dde7ed48a6099c4ea59a291f444127e91e81acde0ee42d857481041869cf6094a2e29f0de184a makefile-shell.patch
+2f995903093da9af4263bf2d7fde75715a114b02b74ba26c8290d7b20042be8a2db305a2ea144925f054354f6f6a430750d19fa036bf764562dedb56da12866a fix-makefile-stderr-redirect.patch
+d1641f538cb1ae9f817b57e19800b0af91e3723c752fba38b2644b8acc66d80862c6bef22194f1f4c64ae7d8393c2772f0a0ea0a76a199151ef8c74c686ea49f makefile-allow-extra-flags.patch
+dec4ed7abfd215eec825bed97b1e40bf3aa8bd959a4ec7153ea1bc51d409d892ebec19ddb0372e3a543e74c7018aca0c1f3cf956fa1d95efb946c8c3417c8749 paxmark.patch
+0252e850b79d622fe69329fac3653128b1cc0108961c928a9efa8fa5df1bce13692b6a520697c45c37791a9e6547d5ec7f0f11905e8299902055ab3dbdfd7556 aarch64-linux-musl.patch
+702927a86c2e934511415e97093fb6fe04e2e63dd5a4e2e2b1fcc772c7f02e037f1b05e516943222f282515fc562618a83442e2d53cc899933a2b2e8ad8dd53d fix-codegen-specs.patch
+269976fbc990dde075769e651c9fac6e7e0b39681e55cbd067c6d2a790c58a096bdc9981f62ae69b5217623025ba768daa63bc5316bd8ddd18192d88839aedcb disable-specs-using-GB2312-encoding.patch
+b5c9c03ad6b648759262a896da3dfbe530ea2d626a5d18fbade08af14a32f8556cdcaf593504db405ff6e5772d3bf00d9d1a8af82f677436602c5bbcbf69b1c6 libressl.patch
+2aa476a2077679a72b94c220bbca6a157555f4751227cb34da1f67b1f8a9a549e00ccb2a8b939ee516f31a429f25b67dbb048984ec49a0c01f092385651daf32 alpine-shards-help.patch"
diff --git a/community/crystal/aarch64-linux-musl.patch b/community/crystal/aarch64-linux-musl.patch
new file mode 100644
index 0000000000..bc6d904079
--- /dev/null
+++ b/community/crystal/aarch64-linux-musl.patch
@@ -0,0 +1,940 @@
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Sun, 25 Mar 2018 00:43:00 +0100
+Subject: [PATCH] Add support for target aarch64-linux-musl
+
+This patch is backported for 0.24.2.
+
+Upstream-Issue: https://github.com/crystal-lang/crystal/pull/5861
+
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/arpa/inet.cr
+@@ -0,0 +1,9 @@
++require "../netinet/in"
++require "../stdint"
++
++lib LibC
++ fun htons(x0 : UInt16T) : UInt16T
++ fun ntohs(x0 : UInt16T) : UInt16T
++ fun inet_ntop(x0 : Int, x1 : Void*, x2 : Char*, x3 : SocklenT) : Char*
++ fun inet_pton(x0 : Int, x1 : Char*, x2 : Void*) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/dirent.cr
+@@ -0,0 +1,18 @@
++require "./sys/types"
++
++lib LibC
++ type DIR = Void
++
++ struct Dirent
++ d_ino : InoT
++ d_off : OffT
++ d_reclen : UShort
++ d_type : Char
++ d_name : StaticArray(Char, 256)
++ end
++
++ fun closedir(x0 : DIR*) : Int
++ fun opendir(x0 : Char*) : DIR*
++ fun readdir(x0 : DIR*) : Dirent*
++ fun rewinddir(x0 : DIR*) : Void
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/dlfcn.cr
+@@ -0,0 +1,21 @@
++lib LibC
++ RTLD_LAZY = 1
++ RTLD_NOW = 2
++ RTLD_GLOBAL = 256
++ RTLD_LOCAL = 0
++ RTLD_DEFAULT = Pointer(Void).new(0)
++ RTLD_NEXT = Pointer(Void).new(-1)
++
++ struct DlInfo
++ dli_fname : Char*
++ dli_fbase : Void*
++ dli_sname : Char*
++ dli_saddr : Void*
++ end
++
++ fun dlclose(x0 : Void*) : Int
++ fun dlerror : Char*
++ fun dlopen(x0 : Char*, x1 : Int) : Void*
++ fun dlsym(x0 : Void*, x1 : Char*) : Void*
++ fun dladdr(x0 : Void*, x1 : DlInfo*) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/errno.cr
+@@ -0,0 +1,83 @@
++lib LibC
++ E2BIG = 7
++ EACCES = 13
++ EADDRINUSE = 98
++ EADDRNOTAVAIL = 99
++ EAFNOSUPPORT = 97
++ EAGAIN = 11
++ EALREADY = 114
++ EBADF = 9
++ EBADMSG = 74
++ EBUSY = 16
++ ECANCELED = 125
++ ECHILD = 10
++ ECONNABORTED = 103
++ ECONNREFUSED = 111
++ ECONNRESET = 104
++ EDEADLK = 35
++ EDESTADDRREQ = 89
++ EDOM = 33
++ EDQUOT = 122
++ EEXIST = 17
++ EFAULT = 14
++ EFBIG = 27
++ EHOSTUNREACH = 113
++ EIDRM = 43
++ EILSEQ = 84
++ EINPROGRESS = 115
++ EINTR = 4
++ EINVAL = 22
++ EIO = 5
++ EISCONN = 106
++ EISDIR = 21
++ ELOOP = 40
++ EMFILE = 24
++ EMLINK = 31
++ EMSGSIZE = 90
++ EMULTIHOP = 72
++ ENAMETOOLONG = 36
++ ENETDOWN = 100
++ ENETRESET = 102
++ ENETUNREACH = 101
++ ENFILE = 23
++ ENOBUFS = 105
++ ENODEV = 19
++ ENOENT = 2
++ ENOEXEC = 8
++ ENOLCK = 37
++ ENOLINK = 67
++ ENOMEM = 12
++ ENOMSG = 42
++ ENOPROTOOPT = 92
++ ENOSPC = 28
++ ENOSYS = 38
++ ENOTCONN = 107
++ ENOTDIR = 20
++ ENOTEMPTY = 39
++ ENOTRECOVERABLE = 131
++ ENOTSOCK = 88
++ ENOTSUP = LibC::EOPNOTSUPP
++ ENOTTY = 25
++ ENXIO = 6
++ EOPNOTSUPP = 95
++ EOVERFLOW = 75
++ EOWNERDEAD = 130
++ EPERM = 1
++ EPIPE = 32
++ EPROTO = 71
++ EPROTONOSUPPORT = 93
++ EPROTOTYPE = 91
++ ERANGE = 34
++ EROFS = 30
++ ESPIPE = 29
++ ESRCH = 3
++ ESTALE = 116
++ ETIMEDOUT = 110
++ ETXTBSY = 26
++ EWOULDBLOCK = LibC::EAGAIN
++ EXDEV = 18
++ ENODATA = 61
++ ENOSR = 63
++ ENOSTR = 60
++ ETIME = 62
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/fcntl.cr
+@@ -0,0 +1,32 @@
++require "./sys/types"
++require "./sys/stat"
++require "./unistd"
++
++lib LibC
++ F_GETFD = 1
++ F_SETFD = 2
++ F_GETFL = 3
++ F_SETFL = 4
++ FD_CLOEXEC = 1
++ O_CLOEXEC = 0o2000000
++ O_CREAT = 0o100
++ O_NOFOLLOW = 0o100000
++ O_TRUNC = 0o1000
++ O_APPEND = 0o2000
++ O_NONBLOCK = 0o4000
++ O_SYNC = 0o4010000
++ O_RDONLY = 0o0
++ O_RDWR = 0o2
++ O_WRONLY = 0o1
++
++ struct Flock
++ l_type : Short
++ l_whence : Short
++ l_start : OffT
++ l_len : OffT
++ l_pid : PidT
++ end
++
++ fun fcntl(x0 : Int, x1 : Int, ...) : Int
++ fun open(x0 : Char*, x1 : Int, ...) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/iconv.cr
+@@ -0,0 +1,9 @@
++require "./stddef"
++
++lib LibC
++ type IconvT = Void*
++
++ fun iconv(x0 : IconvT, x1 : Char**, x2 : SizeT*, x3 : Char**, x4 : SizeT*) : SizeT
++ fun iconv_close(x0 : IconvT) : Int
++ fun iconv_open(x0 : Char*, x1 : Char*) : IconvT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/netdb.cr
+@@ -0,0 +1,39 @@
++require "./netinet/in"
++require "./sys/socket"
++require "./stdint"
++
++lib LibC
++ AI_PASSIVE = 0x01
++ AI_CANONNAME = 0x02
++ AI_NUMERICHOST = 0x04
++ AI_NUMERICSERV = 0x400
++ AI_V4MAPPED = 0x08
++ AI_ALL = 0x10
++ AI_ADDRCONFIG = 0x20
++ EAI_AGAIN = -3
++ EAI_BADFLAGS = -1
++ EAI_FAIL = -4
++ EAI_FAMILY = -6
++ EAI_MEMORY = -10
++ EAI_NONAME = -2
++ EAI_SERVICE = -8
++ EAI_SOCKTYPE = -7
++ EAI_SYSTEM = -11
++ EAI_OVERFLOW = -12
++
++ struct Addrinfo
++ ai_flags : Int
++ ai_family : Int
++ ai_socktype : Int
++ ai_protocol : Int
++ ai_addrlen : SocklenT
++ ai_addr : Sockaddr*
++ ai_canonname : Char*
++ ai_next : Addrinfo*
++ end
++
++ fun freeaddrinfo(x0 : Addrinfo*) : Void
++ fun gai_strerror(x0 : Int) : Char*
++ fun getaddrinfo(x0 : Char*, x1 : Char*, x2 : Addrinfo*, x3 : Addrinfo**) : Int
++ fun getnameinfo(x0 : Sockaddr*, x1 : SocklenT, x2 : Char*, x3 : SocklenT, x4 : Char*, x5 : SocklenT, x6 : Int) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/netinet/in.cr
+@@ -0,0 +1,42 @@
++require "../sys/socket"
++require "../stdint"
++
++lib LibC
++ IPPROTO_IP = 0
++ IPPROTO_ICMP = 1
++ IPPROTO_RAW = 255
++ IPPROTO_TCP = 6
++ IPPROTO_UDP = 17
++
++ alias InPortT = UInt16T
++ alias InAddrT = UInt32T
++
++ struct InAddr
++ s_addr : InAddrT
++ end
++
++ union In6AddrIn6Union
++ __s6_addr : StaticArray(UInt8T, 16)
++ __s6_addr16 : StaticArray(UInt16T, 8)
++ __s6_addr32 : StaticArray(UInt32T, 4)
++ end
++
++ struct In6Addr
++ __in6_union : In6AddrIn6Union
++ end
++
++ struct SockaddrIn
++ sin_family : SaFamilyT
++ sin_port : InPortT
++ sin_addr : InAddr
++ sin_zero : StaticArray(UInt8T, 8)
++ end
++
++ struct SockaddrIn6
++ sin6_family : SaFamilyT
++ sin6_port : InPortT
++ sin6_flowinfo : UInt32T
++ sin6_addr : In6Addr
++ sin6_scope_id : UInt32T
++ end
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/netinet/tcp.cr
+@@ -0,0 +1,6 @@
++lib LibC
++ TCP_NODELAY = 1
++ TCP_KEEPIDLE = 4
++ TCP_KEEPINTVL = 5
++ TCP_KEEPCNT = 6
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/pthread.cr
+@@ -0,0 +1,18 @@
++require "./sys/types"
++
++lib LibC
++ fun pthread_cond_broadcast(x0 : PthreadCondT*) : Int
++ fun pthread_cond_destroy(x0 : PthreadCondT*) : Int
++ fun pthread_cond_init(x0 : PthreadCondT*, x1 : PthreadCondattrT*) : Int
++ fun pthread_cond_signal(x0 : PthreadCondT*) : Int
++ fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int
++ fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int
++ fun pthread_detach(x0 : PthreadT) : Int
++ fun pthread_join(x0 : PthreadT, x1 : Void**) : Int
++ fun pthread_mutex_destroy(x0 : PthreadMutexT*) : Int
++ fun pthread_mutex_init(x0 : PthreadMutexT*, x1 : PthreadMutexattrT*) : Int
++ fun pthread_mutex_lock(x0 : PthreadMutexT*) : Int
++ fun pthread_mutex_trylock(x0 : PthreadMutexT*) : Int
++ fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int
++ fun pthread_self : PthreadT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/signal.cr
+@@ -0,0 +1,40 @@
++require "./sys/types"
++require "./time"
++
++lib LibC
++ SIGHUP = 1
++ SIGINT = 2
++ SIGQUIT = 3
++ SIGILL = 4
++ SIGTRAP = 5
++ SIGIOT = LibC::SIGABRT
++ SIGABRT = 6
++ SIGFPE = 8
++ SIGKILL = 9
++ SIGBUS = 7
++ SIGSEGV = 11
++ SIGSYS = 31
++ SIGPIPE = 13
++ SIGALRM = 14
++ SIGTERM = 15
++ SIGURG = 23
++ SIGSTOP = 19
++ SIGTSTP = 20
++ SIGCONT = 18
++ SIGCHLD = 17
++ SIGTTIN = 21
++ SIGTTOU = 22
++ SIGIO = 29
++ SIGXCPU = 24
++ SIGXFSZ = 25
++ SIGVTALRM = 26
++ SIGUSR1 = 10
++ SIGUSR2 = 12
++ SIGWINCH = 28
++ SIGPWR = 30
++ SIGSTKFLT = 16
++ SIGUNUSED = LibC::SIGSYS
++
++ fun kill(x0 : PidT, x1 : Int) : Int
++ fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/stddef.cr
+@@ -0,0 +1,3 @@
++lib LibC
++ alias SizeT = ULong
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/stdint.cr
+@@ -0,0 +1,10 @@
++lib LibC
++ alias Int8T = SChar
++ alias Int16T = Short
++ alias Int32T = Int
++ alias Int64T = Long
++ alias UInt8T = Char
++ alias UInt16T = UShort
++ alias UInt32T = UInt
++ alias UInt64T = ULong
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/stdio.cr
+@@ -0,0 +1,9 @@
++require "./sys/types"
++require "./stddef"
++
++lib LibC
++ fun printf(x0 : Char*, ...) : Int
++ fun dprintf(fd : Int, format : Char*, ...) : Int
++ fun rename(x0 : Char*, x1 : Char*) : Int
++ fun snprintf(x0 : Char*, x1 : SizeT, x2 : Char*, ...) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/stdlib.cr
+@@ -0,0 +1,25 @@
++require "./stddef"
++require "./sys/wait"
++
++lib LibC
++ struct DivT
++ quot : Int
++ rem : Int
++ end
++
++ fun atof(x0 : Char*) : Double
++ fun div(x0 : Int, x1 : Int) : DivT
++ fun exit(x0 : Int) : NoReturn
++ fun free(x0 : Void*) : Void
++ fun getenv(x0 : Char*) : Char*
++ fun malloc(x0 : SizeT) : Void*
++ fun mkstemp(x0 : Char*) : Int
++ fun mkstemps(x0 : Char*, x1 : Int) : Int
++ fun putenv(x0 : Char*) : Int
++ fun realloc(x0 : Void*, x1 : SizeT) : Void*
++ fun realpath(x0 : Char*, x1 : Char*) : Char*
++ fun setenv(x0 : Char*, x1 : Char*, x2 : Int) : Int
++ fun strtof(x0 : Char*, x1 : Char**) : Float
++ fun strtod(x0 : Char*, x1 : Char**) : Double
++ fun unsetenv(x0 : Char*) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/string.cr
+@@ -0,0 +1,9 @@
++require "./stddef"
++
++lib LibC
++ fun memchr(x0 : Void*, c : Int, n : SizeT) : Void*
++ fun memcmp(x0 : Void*, x1 : Void*, x2 : SizeT) : Int
++ fun strcmp(x0 : Char*, x1 : Char*) : Int
++ fun strerror(x0 : Int) : Char*
++ fun strlen(x0 : Char*) : SizeT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/mman.cr
+@@ -0,0 +1,31 @@
++require "./types"
++
++lib LibC
++ PROT_EXEC = 4
++ PROT_NONE = 0
++ PROT_READ = 1
++ PROT_WRITE = 2
++ MAP_FIXED = 0x10
++ MAP_PRIVATE = 0x02
++ MAP_SHARED = 0x01
++ MAP_ANON = 0x20
++ MAP_ANONYMOUS = LibC::MAP_ANON
++ MAP_FAILED = Pointer(Void).new(-1)
++ POSIX_MADV_DONTNEED = 0
++ POSIX_MADV_NORMAL = 0
++ POSIX_MADV_RANDOM = 1
++ POSIX_MADV_SEQUENTIAL = 2
++ POSIX_MADV_WILLNEED = 3
++ MADV_DONTNEED = 4
++ MADV_NORMAL = 0
++ MADV_RANDOM = 1
++ MADV_SEQUENTIAL = 2
++ MADV_WILLNEED = 3
++ MADV_HUGEPAGE = 14
++ MADV_NOHUGEPAGE = 15
++
++ fun mmap(x0 : Void*, x1 : SizeT, x2 : Int, x3 : Int, x4 : Int, x5 : OffT) : Void*
++ fun mprotect(x0 : Void*, x1 : SizeT, x2 : Int) : Int
++ fun munmap(x0 : Void*, x1 : SizeT) : Int
++ fun madvise(x0 : Void*, x1 : SizeT, x2 : Int) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/select.cr
+@@ -0,0 +1,14 @@
++require "./types"
++require "./time"
++require "../time"
++require "../signal"
++
++lib LibC
++ alias FdMask = ULong
++
++ struct FdSet
++ fds_bits : StaticArray(ULong, 16)
++ end
++
++ fun select(x0 : Int, x1 : FdSet*, x2 : FdSet*, x3 : FdSet*, x4 : Timeval*) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/socket.cr
+@@ -0,0 +1,65 @@
++require "./types"
++
++lib LibC
++ SOCK_DGRAM = 2
++ SOCK_RAW = 3
++ SOCK_SEQPACKET = 5
++ SOCK_STREAM = 1
++ SOL_SOCKET = 1
++ SO_BROADCAST = 6
++ SO_KEEPALIVE = 9
++ SO_LINGER = 13
++ SO_RCVBUF = 8
++ SO_REUSEADDR = 2
++ SO_REUSEPORT = 15
++ SO_SNDBUF = 7
++ PF_INET = 2
++ PF_INET6 = 10
++ PF_UNIX = LibC::PF_LOCAL
++ PF_UNSPEC = 0
++ PF_LOCAL = 1
++ AF_INET = LibC::PF_INET
++ AF_INET6 = LibC::PF_INET6
++ AF_UNIX = LibC::AF_LOCAL
++ AF_UNSPEC = LibC::PF_UNSPEC
++ AF_LOCAL = LibC::PF_LOCAL
++ SHUT_RD = 0
++ SHUT_RDWR = 2
++ SHUT_WR = 1
++ SOCK_CLOEXEC = 0o2000000
++
++ alias SocklenT = UInt
++ alias SaFamilyT = UShort
++
++ struct Sockaddr
++ sa_family : SaFamilyT
++ sa_data : StaticArray(Char, 14)
++ end
++
++ struct SockaddrStorage
++ ss_family : SaFamilyT
++ __ss_align : ULong
++ __ss_padding : StaticArray(Char, 112)
++ end
++
++ struct Linger
++ l_onoff : Int
++ l_linger : Int
++ end
++
++ fun accept(x0 : Int, x1 : Sockaddr*, x2 : SocklenT*) : Int
++ fun bind(x0 : Int, x1 : Sockaddr*, x2 : SocklenT) : Int
++ fun connect(x0 : Int, x1 : Sockaddr*, x2 : SocklenT) : Int
++ fun getpeername(x0 : Int, x1 : Sockaddr*, x2 : SocklenT*) : Int
++ fun getsockname(x0 : Int, x1 : Sockaddr*, x2 : SocklenT*) : Int
++ fun getsockopt(x0 : Int, x1 : Int, x2 : Int, x3 : Void*, x4 : SocklenT*) : Int
++ fun listen(x0 : Int, x1 : Int) : Int
++ fun recv(x0 : Int, x1 : Void*, x2 : SizeT, x3 : Int) : SSizeT
++ fun recvfrom(x0 : Int, x1 : Void*, x2 : SizeT, x3 : Int, x4 : Sockaddr*, x5 : SocklenT*) : SSizeT
++ fun send(x0 : Int, x1 : Void*, x2 : SizeT, x3 : Int) : SSizeT
++ fun sendto(x0 : Int, x1 : Void*, x2 : SizeT, x3 : Int, x4 : Sockaddr*, x5 : SocklenT) : SSizeT
++ fun setsockopt(x0 : Int, x1 : Int, x2 : Int, x3 : Void*, x4 : SocklenT) : Int
++ fun shutdown(x0 : Int, x1 : Int) : Int
++ fun socket(x0 : Int, x1 : Int, x2 : Int) : Int
++ fun socketpair(x0 : Int, x1 : Int, x2 : Int, x3 : StaticArray(Int, 2)) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/stat.cr
+@@ -0,0 +1,56 @@
++require "./types"
++require "../time"
++
++lib LibC
++ S_IFMT = 0o170000
++ S_IFBLK = 0o060000
++ S_IFCHR = 0o020000
++ S_IFIFO = 0o010000
++ S_IFREG = 0o100000
++ S_IFDIR = 0o040000
++ S_IFLNK = 0o120000
++ S_IFSOCK = 0o140000
++ S_IRUSR = 0o400
++ S_IWUSR = 0o200
++ S_IXUSR = 0o100
++ S_IRWXU = 0o700
++ S_IRGRP = 0o040
++ S_IWGRP = 0o020
++ S_IXGRP = 0o010
++ S_IRWXG = 0o070
++ S_IROTH = 0o004
++ S_IWOTH = 0o002
++ S_IXOTH = 0o001
++ S_IRWXO = 0o007
++ S_ISUID = 0o4000
++ S_ISGID = 0o2000
++ S_ISVTX = 0o1000
++
++ struct Stat
++ st_dev : DevT
++ st_ino : InoT
++ st_mode : ModeT
++ st_nlink : NlinkT
++ st_uid : UidT
++ st_gid : GidT
++ st_rdev : DevT
++ __pad : ULong
++ st_size : OffT
++ st_blksize : BlksizeT
++ __pad2 : Int
++ st_blocks : BlkcntT
++ st_atim : Timespec
++ st_mtim : Timespec
++ st_ctim : Timespec
++ __unused : StaticArray(UInt, 2)
++ end
++
++ fun chmod(x0 : Char*, x1 : ModeT) : Int
++ fun fstat(x0 : Int, x1 : Stat*) : Int
++ fun lstat(x0 : Char*, x1 : Stat*) : Int
++ fun mkdir(x0 : Char*, x1 : ModeT) : Int
++ fun mkfifo(x0 : Char*, x1 : ModeT) : Int
++ fun mknod(x0 : Char*, x1 : ModeT, x2 : DevT) : Int
++ fun stat(x0 : Char*, x1 : Stat*) : Int
++ fun umask(x0 : ModeT) : ModeT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/syscall.cr
+@@ -0,0 +1,3 @@
++lib LibC
++ SYS_getrandom = 278
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/time.cr
+@@ -0,0 +1,16 @@
++require "./types"
++
++lib LibC
++ struct Timeval
++ tv_sec : TimeT
++ tv_usec : SusecondsT
++ end
++
++ struct Timezone
++ tz_minuteswest : Int
++ tz_dsttime : Int
++ end
++
++ fun gettimeofday(x0 : Timeval*, x1 : Void*) : Int
++ fun utimes(path : Char*, times : Timeval[2]) : Int
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/times.cr
+@@ -0,0 +1,12 @@
++require "./types"
++
++lib LibC
++ struct Tms
++ tms_utime : ClockT
++ tms_stime : ClockT
++ tms_cutime : ClockT
++ tms_cstime : ClockT
++ end
++
++ fun times(x0 : Tms*) : ClockT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/types.cr
+@@ -0,0 +1,61 @@
++require "../stddef"
++require "../stdint"
++
++lib LibC
++ alias BlkcntT = Long
++ alias BlksizeT = Int
++ alias ClockT = Long
++ alias ClockidT = Int
++ alias DevT = ULong
++ alias GidT = UInt
++ alias IdT = UInt
++ alias InoT = ULong
++ alias ModeT = UInt
++ alias NlinkT = UInt
++ alias OffT = Long
++ alias PidT = Int
++
++ union PthreadAttrTU
++ __i : StaticArray(Int, 14)
++ __vi : StaticArray(Int, 14)
++ __s : StaticArray(ULong, 7)
++ end
++
++ struct PthreadAttrT
++ __u : PthreadAttrTU
++ end
++
++ union PthreadCondTU
++ __i : StaticArray(Int, 12)
++ __vi : StaticArray(Int, 12)
++ __p : StaticArray(Void*, 6)
++ end
++
++ struct PthreadCondT
++ __u : PthreadCondTU
++ end
++
++ struct PthreadCondattrT
++ __attr : UInt
++ end
++
++ union PthreadMutexTU
++ __i : StaticArray(Int, 10)
++ __vi : StaticArray(Int, 10)
++ __p : StaticArray(Void*, 5)
++ end
++
++ struct PthreadMutexT
++ __u : PthreadMutexTU
++ end
++
++ struct PthreadMutexattrT
++ __attr : UInt
++ end
++
++ type PthreadT = Void*
++ alias SSizeT = Long
++ alias SusecondsT = Long
++ alias TimeT = Long
++ alias UidT = UInt
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/un.cr
+@@ -0,0 +1,8 @@
++require "./socket"
++
++lib LibC
++ struct SockaddrUn
++ sun_family : SaFamilyT
++ sun_path : StaticArray(Char, 108)
++ end
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/sys/wait.cr
+@@ -0,0 +1,8 @@
++require "./types"
++require "../signal"
++
++lib LibC
++ WNOHANG = 1
++
++ fun waitpid(x0 : PidT, x1 : Int*, x2 : Int) : PidT
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/termios.cr
+@@ -0,0 +1,120 @@
++require "./sys/types"
++
++lib LibC
++ VEOF = 4
++ VEOL = 11
++ VERASE = 2
++ VINTR = 0
++ VKILL = 3
++ VMIN = 6
++ VQUIT = 1
++ VSTART = 8
++ VSTOP = 9
++ VSUSP = 10
++ BRKINT = 0o000002
++ ICRNL = 0o000400
++ IGNBRK = 0o000001
++ IGNCR = 0o000200
++ IGNPAR = 0o000004
++ INLCR = 0o000100
++ INPCK = 0o000020
++ ISTRIP = 0o000040
++ IXANY = 0o004000
++ IXOFF = 0o010000
++ IXON = 0o002000
++ PARMRK = 0o000010
++ OPOST = 0o000001
++ ONLCR = 0o000004
++ OCRNL = 0o000010
++ ONOCR = 0o000020
++ ONLRET = 0o000040
++ OFDEL = 0o000200
++ OFILL = 0o000100
++ CRDLY = 0o003000
++ CR0 = 0o000000
++ CR1 = 0o001000
++ CR2 = 0o002000
++ CR3 = 0o003000
++ TABDLY = 0o014000
++ TAB0 = 0o000000
++ TAB1 = 0o004000
++ TAB2 = 0o010000
++ TAB3 = 0o014000
++ BSDLY = 0o020000
++ BS0 = 0o000000
++ BS1 = 0o020000
++ VTDLY = 0o040000
++ VT0 = 0o000000
++ VT1 = 0o040000
++ FFDLY = 0o100000
++ FF0 = 0o000000
++ FF1 = 0o100000
++ NLDLY = 0o000400
++ NL0 = 0o000000
++ NL1 = 0o000400
++ B0 = 0o000000
++ B50 = 0o000001
++ B75 = 0o000002
++ B110 = 0o000003
++ B134 = 0o000004
++ B150 = 0o000005
++ B200 = 0o000006
++ B300 = 0o000007
++ B600 = 0o000010
++ B1200 = 0o000011
++ B1800 = 0o000012
++ B2400 = 0o000013
++ B4800 = 0o000014
++ B9600 = 0o000015
++ B19200 = 0o000016
++ B38400 = 0o000017
++ CSIZE = 0o000060
++ CS5 = 0o000000
++ CS6 = 0o000020
++ CS7 = 0o000040
++ CS8 = 0o000060
++ CSTOPB = 0o000100
++ CREAD = 0o000200
++ PARENB = 0o000400
++ PARODD = 0o001000
++ HUPCL = 0o002000
++ CLOCAL = 0o004000
++ ECHO = 0o000010
++ ECHOE = 0o000020
++ ECHOK = 0o000040
++ ECHONL = 0o000100
++ ICANON = 0o000002
++ IEXTEN = 0o100000
++ ISIG = 0o000001
++ NOFLSH = 0o000200
++ TOSTOP = 0o000400
++ TCSANOW = 0
++ TCSADRAIN = 1
++ TCSAFLUSH = 2
++ TCIFLUSH = 0
++ TCIOFLUSH = 2
++ TCOFLUSH = 1
++ TCIOFF = 2
++ TCION = 3
++ TCOOFF = 0
++ TCOON = 1
++
++ alias CcT = Char
++ alias SpeedT = UInt
++ alias TcflagT = UInt
++
++ struct Termios
++ c_iflag : TcflagT
++ c_oflag : TcflagT
++ c_cflag : TcflagT
++ c_lflag : TcflagT
++ c_line : CcT
++ c_cc : StaticArray(CcT, 32)
++ __c_ispeed : SpeedT
++ __c_ospeed : SpeedT
++ end
++
++ fun tcgetattr(x0 : Int, x1 : Termios*) : Int
++ fun tcsetattr(x0 : Int, x1 : Int, x2 : Termios*) : Int
++ fun cfmakeraw(x0 : Termios*) : Void
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/time.cr
+@@ -0,0 +1,37 @@
++require "./sys/types"
++
++lib LibC
++ CLOCK_MONOTONIC = 1
++ CLOCK_REALTIME = 0
++
++ struct Tm
++ tm_sec : Int
++ tm_min : Int
++ tm_hour : Int
++ tm_mday : Int
++ tm_mon : Int
++ tm_year : Int
++ tm_wday : Int
++ tm_yday : Int
++ tm_isdst : Int
++ tm_gmtoff : Long
++ tm_zone : Char*
++ end
++
++ struct Timespec
++ tv_sec : TimeT
++ tv_nsec : Long
++ end
++
++ fun clock_gettime(x0 : ClockidT, x1 : Timespec*) : Int
++ fun clock_settime(x0 : ClockidT, x1 : Timespec*) : Int
++ fun gmtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
++ fun localtime_r(x0 : TimeT*, x1 : Tm*) : Tm*
++ fun mktime(x0 : Tm*) : TimeT
++ fun tzset : Void
++ fun timegm(x0 : Tm*) : TimeT
++
++ $daylight : Int
++ $timezone : Long
++ $tzname : StaticArray(Char*, 2)
++end
+--- /dev/null
++++ b/src/lib_c/aarch64-linux-musl/c/unistd.cr
+@@ -0,0 +1,41 @@
++require "./sys/types"
++require "./stdint"
++
++lib LibC
++ F_OK = 0
++ R_OK = 4
++ W_OK = 2
++ X_OK = 1
++ SC_CLK_TCK = 2
++ SC_NPROCESSORS_ONLN = 84
++
++ fun access(x0 : Char*, x1 : Int) : Int
++ fun chdir(x0 : Char*) : Int
++ fun chown(x0 : Char*, x1 : UidT, x2 : GidT) : Int
++ fun close(x0 : Int) : Int
++ fun dup2(x0 : Int, x1 : Int) : Int
++ fun _exit(x0 : Int) : NoReturn
++ fun execvp(x0 : Char*, x1 : Char**) : Int
++ @[ReturnsTwice]
++ fun fork : PidT
++ fun ftruncate(x0 : Int, x1 : OffT) : Int
++ fun getcwd(x0 : Char*, x1 : SizeT) : Char*
++ fun gethostname(x0 : Char*, x1 : SizeT) : Int
++ fun getpgid(x0 : PidT) : PidT
++ fun getpid : PidT
++ fun getppid : PidT
++ fun isatty(x0 : Int) : Int
++ fun lchown(x0 : Char*, x1 : UidT, x2 : GidT) : Int
++ fun link(x0 : Char*, x1 : Char*) : Int
++ fun lockf(x0 : Int, x1 : Int, x2 : OffT) : Int
++ fun lseek(x0 : Int, x1 : OffT, x2 : Int) : OffT
++ fun pipe(x0 : StaticArray(Int, 2)) : Int
++ fun read(x0 : Int, x1 : Void*, x2 : SizeT) : SSizeT
++ fun pread(x0 : Int, x1 : Void*, x2 : SizeT, x3 : OffT) : SSizeT
++ fun rmdir(x0 : Char*) : Int
++ fun symlink(x0 : Char*, x1 : Char*) : Int
++ fun syscall(x0 : Long, ...) : Long
++ fun sysconf(x0 : Int) : Long
++ fun unlink(x0 : Char*) : Int
++ fun write(x0 : Int, x1 : Void*, x2 : SizeT) : SSizeT
++end
diff --git a/community/crystal/alpine-shards-help.patch b/community/crystal/alpine-shards-help.patch
new file mode 100644
index 0000000000..7510d0a144
--- /dev/null
+++ b/community/crystal/alpine-shards-help.patch
@@ -0,0 +1,13 @@
+This is downstream patch only.
+
+--- a/src/compiler/crystal/command/deps.cr
++++ b/src/compiler/crystal/command/deps.cr
+@@ -5,7 +5,7 @@
+ private def deps
+ path_to_shards = `which shards`.chomp
+ if path_to_shards.empty?
+- error "`shards` executable is missing. Please install shards: https://github.com/crystal-lang/shards"
++ error "`shards` executable is missing. Please install shards: apk add shards"
+ end
+
+ status = Process.run(path_to_shards, args: options, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit)
diff --git a/community/crystal/disable-specs-using-GB2312-encoding.patch b/community/crystal/disable-specs-using-GB2312-encoding.patch
new file mode 100644
index 0000000000..74d244cca8
--- /dev/null
+++ b/community/crystal/disable-specs-using-GB2312-encoding.patch
@@ -0,0 +1,282 @@
+From 774c93390cfa5af0675b398b308f90cd692b4af6 Mon Sep 17 00:00:00 2001
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Mon, 26 Mar 2018 02:20:06 +0200
+Subject: [PATCH] Disable specs using GB2312 encoding on musl
+
+Musl libc does not support GB2312 encoding.
+
+Fixes #3976
+
+Upstream-Issue: https://github.com/crystal-lang/crystal/pull/5867
+---
+ spec/std/io/buffered_spec.cr | 19 ++++---
+ spec/std/io/io_spec.cr | 133 +++++++++++++++++++++++--------------------
+ spec/std/string_spec.cr | 41 ++++++-------
+ 3 files changed, 104 insertions(+), 89 deletions(-)
+
+diff --git a/spec/std/io/buffered_spec.cr b/spec/std/io/buffered_spec.cr
+index 1e4d4a473f..6e34c994ea 100644
+--- a/spec/std/io/buffered_spec.cr
++++ b/spec/std/io/buffered_spec.cr
+@@ -374,15 +374,18 @@ describe "IO::Buffered" do
+ end
+ end
+
+- it "gets big GB2312 string" do
+- str = ("你好我是人\n" * 1000).encode("GB2312")
+- base_io = IO::Memory.new(str)
+- io = BufferedWrapper.new(base_io)
+- io.set_encoding("GB2312")
+- 1000.times do
+- io.gets(chomp: false).should eq("你好我是人\n")
++ # Musl does not support GB2312 encoding.
++ {% unless flag?(:musl) %}
++ it "gets big GB2312 string" do
++ str = ("你好我是人\n" * 1000).encode("GB2312")
++ base_io = IO::Memory.new(str)
++ io = BufferedWrapper.new(base_io)
++ io.set_encoding("GB2312")
++ 1000.times do
++ io.gets(chomp: false).should eq("你好我是人\n")
++ end
+ end
+- end
++ {% end %}
+
+ it "reads char" do
+ str = "x\nHello world" + ("1234567890" * 1000)
+diff --git a/spec/std/io/io_spec.cr b/spec/std/io/io_spec.cr
+index 01e829c800..946bfa70ac 100644
+--- a/spec/std/io/io_spec.cr
++++ b/spec/std/io/io_spec.cr
+@@ -550,16 +550,19 @@ describe IO do
+ end
+ end
+
+- it "gets big GB2312 string" do
+- 2.times do
+- str = ("你好我是人\n" * 1000).encode("GB2312")
+- io = SimpleIOMemory.new(str)
+- io.set_encoding("GB2312")
+- 1000.times do
+- io.gets.should eq("你好我是人")
++ # Musl does not support GB2312 encoding.
++ {% unless flag?(:musl) %}
++ it "gets big GB2312 string" do
++ 2.times do
++ str = ("你好我是人\n" * 1000).encode("GB2312")
++ io = SimpleIOMemory.new(str)
++ io.set_encoding("GB2312")
++ 1000.times do
++ io.gets.should eq("你好我是人")
++ end
+ end
+ end
+- end
++ {% end %}
+
+ it "does gets on unicode with char and limit without off-by-one" do
+ io = SimpleIOMemory.new("test\nabc".encode("UCS-2LE"))
+@@ -635,51 +638,54 @@ describe IO do
+ io.read_utf8_byte.should be_nil
+ end
+
+- it "reads utf8" do
+- io = IO::Memory.new("你".encode("GB2312"))
+- io.set_encoding("GB2312")
++ # Musl does not support GB2312 encoding.
++ {% unless flag?(:musl) %}
++ it "reads utf8" do
++ io = IO::Memory.new("你".encode("GB2312"))
++ io.set_encoding("GB2312")
+
+- buffer = uninitialized UInt8[1024]
+- bytes_read = io.read_utf8(buffer.to_slice) # => 3
+- bytes_read.should eq(3)
+- buffer.to_slice[0, bytes_read].to_a.should eq("你".bytes)
+- end
++ buffer = uninitialized UInt8[1024]
++ bytes_read = io.read_utf8(buffer.to_slice) # => 3
++ bytes_read.should eq(3)
++ buffer.to_slice[0, bytes_read].to_a.should eq("你".bytes)
++ end
+
+- it "raises on incomplete byte sequence" do
+- io = SimpleIOMemory.new("好".byte_slice(0, 1))
+- io.set_encoding("GB2312")
+- expect_raises ArgumentError, "Incomplete multibyte sequence" do
+- io.read_char
++ it "raises on incomplete byte sequence" do
++ io = SimpleIOMemory.new("好".byte_slice(0, 1))
++ io.set_encoding("GB2312")
++ expect_raises ArgumentError, "Incomplete multibyte sequence" do
++ io.read_char
++ end
+ end
+- end
+
+- it "says invalid byte sequence" do
+- io = SimpleIOMemory.new(Slice.new(1, 140_u8))
+- io.set_encoding("GB2312")
+- expect_raises ArgumentError, "Invalid multibyte sequence" do
+- io.read_char
++ it "says invalid byte sequence" do
++ io = SimpleIOMemory.new(Slice.new(1, 140_u8))
++ io.set_encoding("GB2312")
++ expect_raises ArgumentError, "Invalid multibyte sequence" do
++ io.read_char
++ end
+ end
+- end
+
+- it "skips invalid byte sequences" do
+- string = String.build do |str|
+- str.write "好".encode("GB2312")
+- str.write_byte 140_u8
+- str.write "是".encode("GB2312")
++ it "skips invalid byte sequences" do
++ string = String.build do |str|
++ str.write "好".encode("GB2312")
++ str.write_byte 140_u8
++ str.write "是".encode("GB2312")
++ end
++ io = SimpleIOMemory.new(string)
++ io.set_encoding("GB2312", invalid: :skip)
++ io.read_char.should eq('好')
++ io.read_char.should eq('是')
++ io.read_char.should be_nil
+ end
+- io = SimpleIOMemory.new(string)
+- io.set_encoding("GB2312", invalid: :skip)
+- io.read_char.should eq('好')
+- io.read_char.should eq('是')
+- io.read_char.should be_nil
+- end
+
+- it "says invalid 'invalid' option" do
+- io = SimpleIOMemory.new
+- expect_raises ArgumentError, "Valid values for `invalid` option are `nil` and `:skip`, not :foo" do
+- io.set_encoding("GB2312", invalid: :foo)
++ it "says invalid 'invalid' option" do
++ io = SimpleIOMemory.new
++ expect_raises ArgumentError, "Valid values for `invalid` option are `nil` and `:skip`, not :foo" do
++ io.set_encoding("GB2312", invalid: :foo)
++ end
+ end
+- end
++ {% end %}
+
+ it "says invalid encoding" do
+ io = SimpleIOMemory.new("foo")
+@@ -803,28 +809,31 @@ describe IO do
+ slice.should eq("hi-123-45.67".encode("UCS-2LE"))
+ end
+
+- it "raises on invalid byte sequence" do
+- io = SimpleIOMemory.new
+- io.set_encoding("GB2312")
+- expect_raises ArgumentError, "Invalid multibyte sequence" do
+- io.print "ñ"
++ # Musl does not support GB2312 encoding.
++ {% unless flag?(:musl) %}
++ it "raises on invalid byte sequence" do
++ io = SimpleIOMemory.new
++ io.set_encoding("GB2312")
++ expect_raises ArgumentError, "Invalid multibyte sequence" do
++ io.print "ñ"
++ end
+ end
+- end
+
+- it "skips on invalid byte sequence" do
+- io = SimpleIOMemory.new
+- io.set_encoding("GB2312", invalid: :skip)
+- io.print "ñ"
+- io.print "foo"
+- end
++ it "skips on invalid byte sequence" do
++ io = SimpleIOMemory.new
++ io.set_encoding("GB2312", invalid: :skip)
++ io.print "ñ"
++ io.print "foo"
++ end
+
+- it "raises on incomplete byte sequence" do
+- io = SimpleIOMemory.new
+- io.set_encoding("GB2312")
+- expect_raises ArgumentError, "Incomplete multibyte sequence" do
+- io.print "好".byte_slice(0, 1)
++ it "raises on incomplete byte sequence" do
++ io = SimpleIOMemory.new
++ io.set_encoding("GB2312")
++ expect_raises ArgumentError, "Incomplete multibyte sequence" do
++ io.print "好".byte_slice(0, 1)
++ end
+ end
+- end
++ {% end %}
+
+ it "says invalid encoding" do
+ io = SimpleIOMemory.new
+diff --git a/spec/std/string_spec.cr b/spec/std/string_spec.cr
+index 6fbdebc7d0..761398fb8f 100644
+--- a/spec/std/string_spec.cr
++++ b/spec/std/string_spec.cr
+@@ -2285,35 +2285,38 @@ describe "String" do
+ end
+ end
+
+- it "raises if illegal byte sequence" do
+- expect_raises ArgumentError, "Invalid multibyte sequence" do
+- "ñ".encode("GB2312")
++ # Musl does not support GB2312 encoding.
++ {% unless flag?(:musl) %}
++ it "raises if illegal byte sequence" do
++ expect_raises ArgumentError, "Invalid multibyte sequence" do
++ "ñ".encode("GB2312")
++ end
+ end
+- end
+
+- it "doesn't raise on invalid byte sequence" do
+- "好ñ是".encode("GB2312", invalid: :skip).to_a.should eq([186, 195, 202, 199])
+- end
++ it "doesn't raise on invalid byte sequence" do
++ "好ñ是".encode("GB2312", invalid: :skip).to_a.should eq([186, 195, 202, 199])
++ end
+
+- it "raises if incomplete byte sequence" do
+- expect_raises ArgumentError, "Incomplete multibyte sequence" do
+- "好".byte_slice(0, 1).encode("GB2312")
++ it "raises if incomplete byte sequence" do
++ expect_raises ArgumentError, "Incomplete multibyte sequence" do
++ "好".byte_slice(0, 1).encode("GB2312")
++ end
+ end
+- end
+
+- it "doesn't raise if incomplete byte sequence" do
+- ("好".byte_slice(0, 1) + "是").encode("GB2312", invalid: :skip).to_a.should eq([202, 199])
+- end
++ it "doesn't raise if incomplete byte sequence" do
++ ("好".byte_slice(0, 1) + "是").encode("GB2312", invalid: :skip).to_a.should eq([202, 199])
++ end
++
++ it "decodes with skip" do
++ bytes = Bytes[186, 195, 140, 202, 199]
++ String.new(bytes, "GB2312", invalid: :skip).should eq("好是")
++ end
++ {% end %}
+
+ it "decodes" do
+ bytes = "Hello".encode("UTF-16LE")
+ String.new(bytes, "UTF-16LE").should eq("Hello")
+ end
+-
+- it "decodes with skip" do
+- bytes = Bytes[186, 195, 140, 202, 199]
+- String.new(bytes, "GB2312", invalid: :skip).should eq("好是")
+- end
+ end
+
+ it "inserts" do
diff --git a/community/crystal/fix-codegen-specs.patch b/community/crystal/fix-codegen-specs.patch
new file mode 100644
index 0000000000..6198f392e0
--- /dev/null
+++ b/community/crystal/fix-codegen-specs.patch
@@ -0,0 +1,117 @@
+From 19bad9d05b723980551eb203715456e700b06002 Mon Sep 17 00:00:00 2001
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Mon, 26 Mar 2018 00:44:52 +0200
+Subject: [PATCH 1/2] Fix codegen/asm specs to run x86 ASM only on x86_64 and
+ i686
+
+See https://github.com/crystal-lang/crystal/pull/5861#issuecomment-376006679
+
+Upstream-Issue: https://github.com/crystal-lang/crystal/pull/5866
+---
+ spec/compiler/codegen/asm_spec.cr | 59 ++++++++++++++++++++-------------------
+ 1 file changed, 31 insertions(+), 28 deletions(-)
+
+diff --git a/spec/compiler/codegen/asm_spec.cr b/spec/compiler/codegen/asm_spec.cr
+index 6fe8cbc26e..bc68d0f0cc 100644
+--- a/spec/compiler/codegen/asm_spec.cr
++++ b/spec/compiler/codegen/asm_spec.cr
+@@ -1,34 +1,37 @@
+ require "../../spec_helper"
+
+ describe "Code gen: asm" do
+- it "codegens without inputs" do
+- run(%(
+- dst = uninitialized Int32
+- asm("mov $$1234, $0" : "=r"(dst))
+- dst
+- )).to_i.should eq(1234)
+- end
++ # TODO: arm asm tests
++ {% if flag?(:i686) || flag?(:x86_64) %}
++ it "codegens without inputs" do
++ run(%(
++ dst = uninitialized Int32
++ asm("mov $$1234, $0" : "=r"(dst))
++ dst
++ )).to_i.should eq(1234)
++ end
+
+- it "codegens with one input" do
+- run(%(
+- src = 1234
+- dst = uninitialized Int32
+- asm("mov $1, $0" : "=r"(dst) : "r"(src))
+- dst
+- )).to_i.should eq(1234)
+- end
++ it "codegens with one input" do
++ run(%(
++ src = 1234
++ dst = uninitialized Int32
++ asm("mov $1, $0" : "=r"(dst) : "r"(src))
++ dst
++ )).to_i.should eq(1234)
++ end
+
+- it "codegens with two inputs" do
+- run(%(
+- c = uninitialized Int32
+- a = 20
+- b = 22
+- asm(
+- "add $2, $0"
+- : "=r"(c)
+- : "0"(a), "r"(b)
+- )
+- c
+- )).to_i.should eq(42)
+- end
++ it "codegens with two inputs" do
++ run(%(
++ c = uninitialized Int32
++ a = 20
++ b = 22
++ asm(
++ "add $2, $0"
++ : "=r"(c)
++ : "0"(a), "r"(b)
++ )
++ c
++ )).to_i.should eq(42)
++ end
++ {% end %}
+ end
+
+From bde57387cf7239dea152b870471500da8faaec6f Mon Sep 17 00:00:00 2001
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Mon, 26 Mar 2018 00:48:14 +0200
+Subject: [PATCH 2/2] Fix codegen/sizeof specs for aarch64 (and other 64bit
+ arches)
+
+See https://github.com/crystal-lang/crystal/pull/5861#issuecomment-376006679
+---
+ spec/compiler/codegen/sizeof_spec.cr | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/spec/compiler/codegen/sizeof_spec.cr b/spec/compiler/codegen/sizeof_spec.cr
+index 2f703abd1c..bc4a2d5b9a 100644
+--- a/spec/compiler/codegen/sizeof_spec.cr
++++ b/spec/compiler/codegen/sizeof_spec.cr
+@@ -48,7 +48,7 @@ describe "Code gen: sizeof" do
+ # be struct { 8 bytes, 8 bytes }.
+ #
+ # In 32 bits structs are aligned to 4 bytes, so it remains the same.
+- {% if flag?(:x86_64) %}
++ {% if flag?(:bits64) %}
+ size.should eq(16)
+ {% else %}
+ size.should eq(12)
+@@ -137,7 +137,7 @@ describe "Code gen: sizeof" do
+ sizeof(typeof(foo))
+ )).to_i
+
+- {% if flag?(:x86_64) %}
++ {% if flag?(:bits64) %}
+ size.should eq(8)
+ {% else %}
+ size.should eq(4)
diff --git a/community/crystal/fix-makefile-stderr-redirect.patch b/community/crystal/fix-makefile-stderr-redirect.patch
new file mode 100644
index 0000000000..5c5ccb925b
--- /dev/null
+++ b/community/crystal/fix-makefile-stderr-redirect.patch
@@ -0,0 +1,29 @@
+From 2d5bc81866affe7a625da96161644d17c50cf675 Mon Sep 17 00:00:00 2001
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Sat, 24 Mar 2018 18:15:46 +0100
+Subject: [PATCH] Makefile: Fix redirect to stderr to be more portable
+
+`>/dev/stderr` does not work in some environments. Moreover, all POSIX
+compliant shells supports standard `>&2` for redirect stdout to stderr.
+
+Upstream-Issue: https://github.com/crystal-lang/crystal/pull/5859
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 2aa2e4f..a034f44 100644
+--- a/Makefile
++++ b/Makefile
+@@ -55,7 +55,7 @@ CXXFLAGS += $(if $(debug),-g -O0)
+ ifeq (${LLVM_CONFIG},)
+ $(error Could not locate llvm-config, make sure it is installed and in your PATH, or set LLVM_CONFIG)
+ else
+- $(shell echo $(shell printf '\033[33m')Using $(LLVM_CONFIG) [version=$(shell $(LLVM_CONFIG) --version)]$(shell printf '\033[0m') >/dev/stderr)
++ $(shell echo $(shell printf '\033[33m')Using $(LLVM_CONFIG) [version=$(shell $(LLVM_CONFIG) --version)]$(shell printf '\033[0m') >&2)
+ endif
+
+ .PHONY: all
+--
+2.10.1 (Apple Git-78)
+
diff --git a/community/crystal/libressl.patch b/community/crystal/libressl.patch
new file mode 100644
index 0000000000..680c50e5e5
--- /dev/null
+++ b/community/crystal/libressl.patch
@@ -0,0 +1,120 @@
+From a834b9a274b5dcb076b64ca855bcccc322cdd07c Mon Sep 17 00:00:00 2001
+From: lvmbdv <ata.kuyumcu@protonmail.com>
+Date: Fri, 2 Feb 2018 23:31:19 +0300
+Subject: [PATCH] Fixed OpenSSL bindings to recognize LibreSSL
+
+This patch is ported from https://github.com/crystal-lang/crystal/pull/5676.
+
+diff --git a/src/openssl/lib_crypto.cr b/src/openssl/lib_crypto.cr
+index 458ad13..7e42604 100644
+--- a/src/openssl/lib_crypto.cr
++++ b/src/openssl/lib_crypto.cr
+@@ -1,11 +1,23 @@
+ {% begin %}
+ lib LibCrypto
+- OPENSSL_110 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libcrypto || printf %s false`.stringify != "false" }}
+- OPENSSL_102 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libcrypto || printf %s false`.stringify != "false" }}
++ # An extra zero is appended to the output of LIBRESSL_VERSION to make it 0 when LibreSSL does not exist on the system.
++ # Any comparisons to it should be affixed with an extra zero as well e.g. `(LIBRESSL_VERSION_NUMBER >= 0x2050500F0)`.
++ LIBRESSL_VERSION = {{ system("echo \"#include <openssl/opensslv.h>\nLIBRESSL_VERSION_NUMBER\" | " +
++ (env("CC") || "cc") + " " + `pkg-config --cflags --silence-errors libssl || true`.chomp.stringify + " -E -").chomp.split('\n').last.split('L').first.id + "0" }}
++ OPENSSL_VERSION = {{ system("echo \"#include <openssl/opensslv.h>\nOPENSSL_VERSION_NUMBER\" | " +
++ (env("CC") || "cc") + " " + `pkg-config --cflags --silence-errors libssl || true`.chomp.stringify + " -E -").chomp.split('\n').last.split('L').first.id }}
+ end
+ {% end %}
+
+-@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs libcrypto || printf %s '-lcrypto'`")]
++{% begin %}
++ lib LibCrypto
++ OPENSSL_110 = {{ (LibCrypto::LIBRESSL_VERSION == 0) && (LibCrypto::OPENSSL_VERSION >= 0x10101000) }}
++ OPENSSL_102 = {{ (LibCrypto::LIBRESSL_VERSION == 0) && (LibCrypto::OPENSSL_VERSION >= 0x10002000) }}
++ LIBRESSL_250 = {{ LibCrypto::LIBRESSL_VERSION >= 0x205000000 }}
++ end
++{% end %}
++
++@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libcrypto || printf %s ' -lcrypto'`")]
+ lib LibCrypto
+ alias Char = LibC::Char
+ alias Int = LibC::Int
+diff --git a/src/openssl/lib_ssl.cr b/src/openssl/lib_ssl.cr
+index e69f82b..b8786b8 100644
+--- a/src/openssl/lib_ssl.cr
++++ b/src/openssl/lib_ssl.cr
+@@ -2,12 +2,13 @@ require "./lib_crypto"
+
+ {% begin %}
+ lib LibSSL
+- OPENSSL_110 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.1.0 libssl || printf %s false`.stringify != "false" }}
+- OPENSSL_102 = {{ `command -v pkg-config > /dev/null && pkg-config --atleast-version=1.0.2 libssl || printf %s false`.stringify != "false" }}
++ OPENSSL_110 = {{ LibCrypto::OPENSSL_110 }}
++ OPENSSL_102 = {{ LibCrypto::OPENSSL_102 }}
++ LIBRESSL_250 = {{ LibCrypto::LIBRESSL_250 }}
+ end
+ {% end %}
+
+-@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs libssl || printf %s '-lssl -lcrypto'`")]
++@[Link(ldflags: "`command -v pkg-config > /dev/null && pkg-config --libs --silence-errors libssl || printf %s '-lssl -lcrypto'`")]
+ lib LibSSL
+ alias Int = LibC::Int
+ alias Char = LibC::Char
+@@ -198,13 +199,17 @@ lib LibSSL
+ fun sslv23_method = SSLv23_method : SSLMethod
+ {% end %}
+
+- {% if OPENSSL_102 %}
++ {% if OPENSSL_102 || LIBRESSL_250 %}
+ alias ALPNCallback = (SSL, Char**, Char*, Char*, Int, Void*) -> Int
+- alias X509VerifyParam = LibCrypto::X509VerifyParam
+
+- fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
+ fun ssl_get0_alpn_selected = SSL_get0_alpn_selected(handle : SSL, data : Char**, len : LibC::UInt*) : Void
+ fun ssl_ctx_set_alpn_select_cb = SSL_CTX_set_alpn_select_cb(ctx : SSLContext, cb : ALPNCallback, arg : Void*) : Void
++ {% end %}
++
++ {% if OPENSSL_102 %}
++ alias X509VerifyParam = LibCrypto::X509VerifyParam
++
++ fun ssl_get0_param = SSL_get0_param(handle : SSL) : X509VerifyParam
+ fun ssl_ctx_get0_param = SSL_CTX_get0_param(ctx : SSLContext) : X509VerifyParam
+ fun ssl_ctx_set1_param = SSL_CTX_set1_param(ctx : SSLContext, param : X509VerifyParam) : Int
+ {% end %}
+diff --git a/src/openssl/ssl/context.cr b/src/openssl/ssl/context.cr
+index b21568d..a694abd 100644
+--- a/src/openssl/ssl/context.cr
++++ b/src/openssl/ssl/context.cr
+@@ -304,7 +304,7 @@ abstract class OpenSSL::SSL::Context
+ LibSSL.ssl_ctx_set_verify(@handle, mode, nil)
+ end
+
+- {% if LibSSL::OPENSSL_102 %}
++ {% if LibSSL::OPENSSL_102 || LibSSL::LIBRESSL_250 %}
+
+ @alpn_protocol : Pointer(Void)?
+
+@@ -337,6 +337,10 @@ abstract class OpenSSL::SSL::Context
+ LibSSL.ssl_ctx_set_alpn_select_cb(@handle, alpn_cb, alpn_protocol)
+ end
+
++ {% end %}
++
++ {% if LibSSL::OPENSSL_102 %}
++
+ # Set this context verify param to the default one of the given name.
+ #
+ # Depending on the OpenSSL version, the available defaults are
+diff --git a/src/openssl/ssl/socket.cr b/src/openssl/ssl/socket.cr
+index 10fc100..14c3c16 100644
+--- a/src/openssl/ssl/socket.cr
++++ b/src/openssl/ssl/socket.cr
+@@ -119,7 +119,7 @@ abstract class OpenSSL::SSL::Socket < IO
+ @bio.io.flush
+ end
+
+- {% if LibSSL::OPENSSL_102 %}
++ {% if LibSSL::OPENSSL_102 || LibSSL::LIBRESSL_250 %}
+ # Returns the negotiated ALPN protocol (eg: `"h2"`) of `nil` if no protocol was
+ # negotiated.
+ def alpn_protocol
+--
+2.10.1 (Apple Git-78)
+
diff --git a/community/crystal/makefile-allow-extra-flags.patch b/community/crystal/makefile-allow-extra-flags.patch
new file mode 100644
index 0000000000..c3a004592e
--- /dev/null
+++ b/community/crystal/makefile-allow-extra-flags.patch
@@ -0,0 +1,23 @@
+From 746da810fd045ae2ccad8cecfd746375788b6bfb Mon Sep 17 00:00:00 2001
+From: Jakub Jirutka <jakub@jirutka.cz>
+Date: Sat, 24 Mar 2018 18:20:59 +0100
+Subject: [PATCH] Makefile: Allow to add EXTRA_FLAGS to FLAGS
+
+Upstream-Issue: https://github.com/crystal-lang/crystal/pull/5860
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 2aa2e4fbdb..d18cd58e22 100644
+--- a/Makefile
++++ b/Makefile
+@@ -27,7 +27,7 @@
+ O := .build
+ SOURCES := $(shell find src -name '*.cr')
+ SPEC_SOURCES := $(shell find spec -name '*.cr')
+-FLAGS := $(if $(release),--release )$(if $(stats),--stats )$(if $(progress),--progress )$(if $(threads),--threads $(threads) )$(if $(debug),-d )$(if $(static),--static )
++FLAGS := $(if $(release),--release )$(if $(stats),--stats )$(if $(progress),--progress )$(if $(threads),--threads $(threads) )$(if $(debug),-d )$(if $(static),--static ) $(EXTRA_FLAGS)
+ SPEC_FLAGS := $(if $(verbose),-v )$(if $(junit_output),--junit_output $(junit_output) )
+ EXPORTS := $(if $(release),,CRYSTAL_CONFIG_PATH=`pwd`/src)
+ SHELL = bash
diff --git a/community/crystal/makefile-shell.patch b/community/crystal/makefile-shell.patch
new file mode 100644
index 0000000000..84b2b79848
--- /dev/null
+++ b/community/crystal/makefile-shell.patch
@@ -0,0 +1,78 @@
+From 80f94f33956a758444f6c6918036b41288cd4da9 Mon Sep 17 00:00:00 2001
+From: Julien Reichardt <mi@jrei.ch>
+Date: Tue, 2 Jan 2018 14:52:14 +0100
+Subject: [PATCH] Change from `bash` to `sh` (#5468)
+
+* Removes bash as a dependency
+* Better compliance to POSIX
+
+diff --git a/Makefile b/Makefile
+index a4b2281dc1..a6b2f5d1d4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -29,8 +29,8 @@ SOURCES := $(shell find src -name '*.cr')
+ SPEC_SOURCES := $(shell find spec -name '*.cr')
+ FLAGS := $(if $(release),--release )$(if $(stats),--stats )$(if $(progress),--progress )$(if $(threads),--threads $(threads) )$(if $(debug),-d )$(if $(static),--static )
+ SPEC_FLAGS := $(if $(verbose),-v )$(if $(junit_output),--junit_output $(junit_output) )
+-EXPORTS := $(if $(release),,CRYSTAL_CONFIG_PATH=`pwd`/src)
+-SHELL = bash
++EXPORTS := $(if $(release),,CRYSTAL_CONFIG_PATH=$PWD/src)
++SHELL = sh
+ LLVM_CONFIG_FINDER := \
+ [ -n "$(LLVM_CONFIG)" ] && command -v "$(LLVM_CONFIG)" || \
+ command -v llvm-config-4.0 || command -v llvm-config40 || \
+@@ -118,7 +118,7 @@ $(O)/crystal: $(DEPS) $(SOURCES)
+ $(BUILD_PATH) $(EXPORTS) ./bin/crystal build $(FLAGS) -o $@ src/compiler/crystal.cr -D without_openssl -D without_zlib
+
+ $(LLVM_EXT_OBJ): $(LLVM_EXT_DIR)/llvm_ext.cc
+- $(CXX) -c $(CXXFLAGS) -o $@ $< `$(LLVM_CONFIG) --cxxflags`
++ $(CXX) -c $(CXXFLAGS) -o $@ $< $(shell $(LLVM_CONFIG) --cxxflags)
+
+ $(LIB_CRYSTAL_TARGET): $(LIB_CRYSTAL_OBJS)
+ $(AR) -rcs $@ $^
+diff --git a/Vagrantfile b/Vagrantfile
+index 83bcf8c3ce..859f682dbf 100644
+--- a/Vagrantfile
++++ b/Vagrantfile
+@@ -15,7 +15,7 @@ Vagrant.configure("2") do |config|
+ c.vm.box = "ubuntu/#{box_name}"
+
+ c.vm.provision :shell, inline: %(
+- curl -s https://dist.crystal-lang.org/apt/setup.sh | bash
++ curl -s https://dist.crystal-lang.org/apt/setup.sh | sh
+ apt-get install -y crystal git libgmp3-dev zlib1g-dev libedit-dev libxml2-dev libssl-dev libyaml-dev libreadline-dev g++
+ curl -s https://crystal-lang.s3.amazonaws.com/llvm/llvm-3.5.0-1-linux-`uname -m`.tar.gz | tar xz -C /opt
+ echo 'export LIBRARY_PATH="/opt/crystal/embedded/lib"' > /etc/profile.d/crystal.sh
+diff --git a/bin/crystal b/bin/crystal
+index 698ed9b2b3..c901d9b37f 100755
+--- a/bin/crystal
++++ b/bin/crystal
+@@ -37,7 +37,7 @@ _resolve_symlinks() {
+
+ local dir_context path
+ path=$(readlink -- "$1")
+- if [ $? -eq 0 ]; then
++ if [ $? = 0 ]; then
+ dir_context=$(dirname -- "$1")
+ _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@"
+ else
+@@ -141,16 +141,13 @@ CRYSTAL_DIR="$CRYSTAL_ROOT/.build"
+ export CRYSTAL_PATH=$CRYSTAL_ROOT/src:lib
+ export CRYSTAL_HAS_WRAPPER=true
+
+-if [ -x "$CRYSTAL_DIR/crystal" ]
+-then
++if [ -x "$CRYSTAL_DIR/crystal" ]; then
+ __warning_msg "Using compiled compiler at \`.build/crystal'"
+ exec "$CRYSTAL_DIR/crystal" "$@"
+-elif ! command -v crystal > /dev/null
+-then
++elif ! command -v crystal > /dev/null; then
+ __error_msg 'You need to have a crystal executable in your path!'
+ exit 1
+-elif [ "$(command -v crystal)" = "$SCRIPT_PATH" ] || [ "$(command -v crystal)" = "bin/crystal" ]
+-then
++elif [ "$(command -v crystal)" = "$SCRIPT_PATH" ] || [ "$(command -v crystal)" = "bin/crystal" ]; then
+ export PATH="$(remove_path_item "$(remove_path_item "$PATH" "$SCRIPT_ROOT")" "bin")"
+ exec "$SCRIPT_PATH" "$@"
+ else
diff --git a/community/crystal/paxmark.patch b/community/crystal/paxmark.patch
new file mode 100644
index 0000000000..db6efd89db
--- /dev/null
+++ b/community/crystal/paxmark.patch
@@ -0,0 +1,22 @@
+Make tests run on Grsecurity system. This patch is downstream only.
+
+--- a/Makefile
++++ b/Makefile
+@@ -104,14 +104,17 @@
+ $(O)/all_spec: $(DEPS) $(SOURCES) $(SPEC_SOURCES)
+ @mkdir -p $(O)
+ $(BUILD_PATH) ./bin/crystal build $(FLAGS) -o $@ spec/all_spec.cr
++ paxmark m $(O)/all_spec
+
+ $(O)/std_spec: $(DEPS) $(SOURCES) $(SPEC_SOURCES)
+ @mkdir -p $(O)
+ $(BUILD_PATH) ./bin/crystal build $(FLAGS) -o $@ spec/std_spec.cr
++ paxmark m $(O)/std_spec
+
+ $(O)/compiler_spec: $(DEPS) $(SOURCES) $(SPEC_SOURCES)
+ @mkdir -p $(O)
+ $(BUILD_PATH) ./bin/crystal build $(FLAGS) -o $@ spec/compiler_spec.cr
++ paxmark m $(O)/compiler_spec
+
+ $(O)/crystal: $(DEPS) $(SOURCES)
+ @mkdir -p $(O)