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 Ubuntu Linux on ARM64 (aarch64) #4119

Closed
jbeker opened this issue Mar 29, 2021 · 59 comments · Fixed by #7718
Closed

Support for Ubuntu Linux on ARM64 (aarch64) #4119

jbeker opened this issue Mar 29, 2021 · 59 comments · Fixed by #7718
Labels
enhancement New feature or surprising current feature

Comments

@jbeker
Copy link

jbeker commented Mar 29, 2021

Problem

We are starting to need to use ARM based Linux (using Ubuntu) but we can't use Sorbet since there is not a binary version of Sorbet that will run. When performing a bundle install that includes sorbet we get the following error:

Unable to find a spec satisfying sorbet-static (= 0.5.5912) in the set. 
Perhaps the lockfile is corrupted? Found sorbet-static (0.5.5912-x86_64-linux), 
sorbet-static (0.5.5912-universal-darwin-19) that did not match the current platform.

This is running on Ubuntu 20 LTS

Linux local 5.4.0-70-generic #78-Ubuntu SMP Fri Mar 19 13:29:32 UTC 2021 aarch64 aarch64 aarch64 GNU/Linux

Proposed solution

Add a linux aarch64 pre-built sorbet-static.

@jbeker jbeker added enhancement New feature or surprising current feature unconfirmed This issue has not yet been confirmed by the Sorbet team labels Mar 29, 2021
@lox
Copy link

lox commented Jun 9, 2021

Are there any workarounds for this in the meantime?

@cguess
Copy link

cguess commented Oct 19, 2021

Has there been any updates on this? With the launch of even more M1 ARM-based Macs it's quickly becoming the soon-to-be-default architecture, and if you're running a VM there's no option except aarch64 for Linux (can't emulate x86).

@korbin
Copy link

korbin commented Oct 22, 2021

Has there been any updates on this? With the launch of even more M1 ARM-based Macs it's quickly becoming the soon-to-be-default architecture, and if you're running a VM there's no option except aarch64 for Linux (can't emulate x86).

You could use QEMU to run Sorbet, probably.


I was able to make ARM64 builds work for Linux aarch64 targets:

master...angellist:arm64

I am not familiar enough with Bazel to add all of the conditionals necessary to make this properly support cross-platform builds, however, my findings:


I also attempted to get Darwin ARM64 support working (and it probably will if these caveats are fixed), however:

  • The LLVM project does not publish Darwin ARM64 binaries. Homebrew clang or system clang will need to be used. (I am not familiar enough with Bazel yet to build this escape hatch cleanly.)

    • Consequently, all builds will always become x86_64 due to the use of emulated x86_64 clang.
  • jemalloc needs to be downloaded from the dev branch.


Hopefully this helps enable upstream ARM support!

@cguess
Copy link

cguess commented Nov 5, 2021

@korbin QEMU can emulate x64, but it is SLOW, pretty much unusable.

@klardotsh
Copy link

klardotsh commented Dec 2, 2021

this is a blocker to teams using sorbet in docker as well - let me know if there's anything I can do to help move this forward; as it stands I believe my workaround has to be forcing platform: linux/amd64 for our containers, which is unideal.

EDIT: nope, that doesn't work because of the lack of inotify in qemu and the unsuitability of the "Experimental Virtualization Backend" for our purposes. I'll be working to try to build arm64 native sorbet for my team.

@froydnj
Copy link
Contributor

froydnj commented Dec 3, 2021

let me know if there's anything I can do to help move this forward

Can you at least submit a PR for a7cdf0b ? I think the other commits would require some reworking (all the s/x86_64/aarch64/-style ones) or some testing (the blake2 changes), but the __builtin_debugtrap seems uncontroversial, assuming GCC supports it (i.e. we can build in Stripe's CI)

@froydnj
Copy link
Contributor

froydnj commented Dec 3, 2021

I think we'd take a PR for the bazel script changes too!

@klardotsh
Copy link

klardotsh commented Dec 3, 2021

A brief end of week update on my end: I haven't fully inspected the generated gems or run the test suite against them, but building on the work from AngelList above, I seem to have at least runnable aarch64 sorbet ELF binaries generated on an aarch64 host (read: not cross-compiled from amd64). The logic roughly being that usually I find on-host builds easier to reason about than cross-compiled, so I decided to head down the path I was most comfortable with in general (I've dealt with ARM Linux stuff for years, but almost never cross-compiled).

The commit logs are a little messy (especially on the bazel-toolchain side), there's decidedly some hackery going on that needs cleaned up because I don't particularly know Bazel well, and just broadly it'll need work before it'll be in a state to work with @korbin @froydnj and co. to upstream it, but it's progress and I'll likely continue poking at this Tuesday, if not over the weekend.

The below output is copied from an M1 Mac, but I was also able to use Docker BuildX to "cross-compile" (very, very, miserably slowly) from my AMD 3900X rig running Void Linux.

joshklar@twg-mba-klar sorbet % make release-linux-arm64                                                                                                                                                                                            
# this is PROBABLY dangerous in the event your system already has bin                                                                                                                                                                              
# handlers or something but whatever, those are *super* uncommon,                                                                                                                                                                                  
# especially on CI rigs                                                                                                                                                                                                                            
[ "$(uname -s) $(uname -m)" == "Linux x86_64" ] && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || true                                                                                                                  
docker buildx build --platform linux/arm64 .                                                                                                                                                                                                       
                                                                                                                                                                                                                                                   
[+] Building 516.1s (10/10) FINISHED                                                                                                                                                                                                               
 => [internal] load build definition from Dockerfile                                                                                                                                                                                          0.0s 
 => => transferring dockerfile: 573B                                                                                                                                                                                                          0.0s 
 => [internal] load .dockerignore                                                                                                                                                                                                             0.0s 
 => => transferring context: 2B                                                                                                                                                                                                               0.0s 
 => [internal] load metadata for docker.io/library/ubuntu:focal                                                                                                                                                                               1.1s 
 => [1/5] FROM docker.io/library/ubuntu:focal@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322                                                                                                                         0.0s 
 => [internal] load build context                                                                                                                                                                                                             5.6s 
 => => transferring context: 195.39MB                                                                                                                                                                                                         5.5s 
 => CACHED [2/5] RUN apt update && apt install -y build-essential curl perl unzip python autoconf                                                                                                                                             0.0s 
 => CACHED [3/5] RUN apt update && apt install -y libffi-dev libgmp-dev libtinfo5 libtinfo-dev python python3                                                                                                                                 0.0s 
 => [4/5] COPY . .                                                                                                                                                                                                                            0.8s 
 => [5/5] RUN ./bazel build //main:sorbet --config=release-linux                                                                                                                                                                            491.5s 
 => exporting to image                                                                                                                                                                                                                       17.1s 
 => => exporting layers                                                                                                                                                                                                                      17.1s 
 => => writing image sha256:aa08645ee8b33bba601a9140a4d33faeb23fe2a71cc592d60e2eb0f03af19624                                                                                                                                                  0.0s 

# ...

joshklar@twg-mba-klar sorbet % docker run --rm -it aa08645ee8b33bba601a9140a4d33faeb23fe2a71cc592d60e2eb0f03af19624                                                                                                                                
root@478d1ec030c9:/# file ./root/.cache/bazel/_bazel_root/6666cd76f96956469e7be39d750cc7d9/execroot/com_stripe_ruby_typer/bazel-out/aarch64-opt/bin/main/sorbet                                                                                    
./root/.cache/bazel/_bazel_root/6666cd76f96956469e7be39d750cc7d9/execroot/com_stripe_ruby_typer/bazel-out/aarch64-opt/bin/main/sorbet: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[md5/uuid]=121e6e884edc997ac510ce7630cc2037, with debug_info, not stripped
root@478d1ec030c9:/# ./root/.cache/bazel/_bazel_root/6666cd76f96956469e7be39d750cc7d9/execroot/com_stripe_ruby_typer/bazel-out/aarch64-opt/bin/main/sorbet                                                                                         
You must pass either `-e` or at least one folder or ruby file.                                                                                                                                                                                     
                                                                                                                                                                                                                                                   
Typechecker for Ruby                                                                                                                                                                                                                               
Usage:                                                                                                                                                                                                                                             
  sorbet [OPTION...] <path 1> <path 2> ...                                                                                                                                                                                                         
                                                                                                                                                                                                                                                   
  -e, string     Parse an inline ruby string (default: "")                                                                                                                                                                                         
  -q, --quiet    Silence all non-critical errors                                                                                                                                                                                                   
  -v, --verbose  Verbosity level [0-3]                                                                                                                                                                                                             
  -h,            Show short help                                                                                                                                                                                                                   
      --help     Show long help                                                                                                                                                                                                                    
      --version  Show version                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                   
root@478d1ec030c9:/# ./root/.cache/bazel/_bazel_root/6666cd76f96956469e7be39d750cc7d9/execroot/com_stripe_ruby_typer/bazel-out/aarch64-opt/bin/main/sorbet -e 'puts "yay"'                                                                         
No errors! Great job.                                                                                                                                                                                                                              

mwudka added a commit to mwudka/sorbet that referenced this issue Feb 1, 2022
Currently, Sorbet uses blake2 for wasm builds and libb2 for other builds.
Originally, this was because libb2 is heavily optimized but not portable. Since
that time, however, libb2 has been extended with optimized builds for common
architectures. That means that it's now possible to use the same library
everywhere. x86/arm platforms still benefit from optimized vectorized
implementations, and other platforms can still use the portable fallback. This
change simplifies and slightly speeds up the build, while removing one of the
blockers to Linux AArch64 support as described in
sorbet#4119.
@joaolrpaulo
Copy link

👋 Any news about this topic?

Will there be a new release of the sorbet-static for aarch64 anytime soon?

@vinistock
Copy link
Collaborator

Our team is working on support for the M1 macs tracked in this milestone. Based on the investigations posted here, I believe the changes needed for M1 support overlap with most of what is needed for Linux ARM64 as well - other than some configuration bits.

The changes in this experimental branch are enough to compile Sorbet to ARM64 on an M1 machine for both debug and release mode. However, we still need to figure out some build failures for the custom Ruby build and emscripten.

Additionally, that branch uses the bazel-toolchain version that has support for the ARM64 clang toolchains, which is still in a PR and not yet merged upstream.

After all of the code changes are merged and the configuration API is finalized on bazel-toolchain, we should be able to start releasing the new binaries.

@klardotsh
Copy link

please feel free to holler if there's anything we (Dockwa) can do to help, even if it's testing a quick thing. we've been using the linux/amd64 and linux/arm64 gems+docker images generated in https://github.com/dockwa/sorbet/commits/josh/arm64-more for a bit now and, short a PEBKAC issue I introduced with versioning at one point, haven't had issues (mind you, we fall back to upstream gems on Darwin-bare-metal because I never figured out cross-compilation, with Bazel or - experimentally at one point - with Zig's cross-compile-as-a-first-class-citizen toolchain)

excited to see this getting upstream traction!

@froydnj froydnj removed the unconfirmed This issue has not yet been confirmed by the Sorbet team label Feb 11, 2022
@froydnj
Copy link
Contributor

froydnj commented Feb 11, 2022

Note that getting all the necessary changes in to compile on arm64 is one step (and an important one!), but not the complete picture: we also need to cross-compile the appropriate bits on Buildkite (AFAICT, Buildkite does not seem to have native arm64 machines/containers available).

@klardotsh
Copy link

klardotsh commented Feb 11, 2022

Certainly native arm64 machines would be ideal, but if those fail, a (somewhat slow) option (that we're using in our fork) is to QEMU around the problem - Docker BuildX sets up a binfmt_misc handler to route cross-arch builds through QEMU wrappers, simulating a "native" arm64 build. From what I can tell, Rust's https://github.com/cross-rs/cross does this as well. Certainly not saying it's ideal (our arm64 images take about 5-10x longer than our amd64 images, building on an AMD 3900X with 24 threads), but it's a potential workaround if the cross-compile-directly story gets hairy. Happy to help there as well as time allows, if needed.

@klardotsh
Copy link

Chiming in here again, curious to see what the blockers here are, and what my org could do to help. At this point we're still running my fork from the winter, which means v0.5.9613 (the last version I could get to cleanly rebase), complete with all of our packaging layers to get there. Simplifying back to a simple "bundle install" would be great.

@louiscb
Copy link

louiscb commented Aug 17, 2022

@klardotsh can you publish your forked version that works with arm64?

@klardotsh
Copy link

@klardotsh can you publish your forked version that works with arm64?

Ah sorry, I realize I'd talked about the WIP above and never mentioned that all this work has been public all along... just without instructions available. Here goes!

master of https://github.com/dockwa/sorbet is at v0.5.9613 (this limits you to Tapioca 0.7.x if you use check-shims 1 2). This is a set of 12 commits over AngelList's fork above; essentially all are packaging and build system related.

In theory one should be able to apply this to bare-metal aarch64+glibc Linux; pulling the linux/arm64 OCI image (docker pull blahblah --platform linux/arm64 works I think maybe possibly, otherwise dig into the multiarch manifest) and dumping it to a tarball 3 should allow portability outside of containers.

To apply some duck-typing theory: this looks like a hack, walks like a hack, and quacks like a hack, so it's definitely a hack. With some caveats however (notably, that things like Tapioca RBI generation must be done in a consistent environment - for us that's linux/amd64 with RAILS_ENV=development - due to two Tapioca issues 4 5), it's been working for us at Dockwa since Dec/Jan ish.

Dockerfile
# https://github.com/dockwa/sorbet
FROM ghcr.io/dockwa/sorbet:0.5.9613 AS sorbet-gems

# the bins generated in the buster image are confirmed so far to be
# forward-compatible, so rather than rebuilding a bullseye image, we'll just
# mix and match this particular component
#
# https://github.com/dockwa/docker-watchman
FROM ghcr.io/dockwa/watchman:4.9.0-debian-buster AS watchman

FROM ruby:2.7.5-bullseye

# ...

# this version is/was required for arm64 support due to
# https://github.com/rubygems/rubygems/pull/5092
# (https://github.com/rubygems/rubygems/issues/5088)
RUN gem install bundler:2.2.33

# this (ab)uses awk's conditional print mechanics to find sorbet-static's
# x86_64 gem lock, duplicate it to a new line, and then find-replace over the
# duplicated line, described more in https://unix.stackexchange.com/a/675838
#
# without this, cryptic bundler errors occur in arm64 builds (only): not only
# is a dependency outright missing, but because it's a transient dependency,
# weird offshoots of https://github.com/rubygems/rubygems/pull/5092 (that are
# yet unfixed even in 2.2.33, it appears) pop up, all instances of the famous
# NilClass exception
RUN awk '1; gsub(/x86_64/,"aarch64")' Gemfile.lock > Gemfile.lock.new
RUN mv Gemfile.lock.new Gemfile.lock

# ... and since those issues stemmed from upstream not providing aarch64 bins
# in the first place, we'll provide our own *.gem for all things sorbet, and
# lean on bundler's implicit search path behaviors to avoid looking for this
# upstream (it won't exist)
COPY --from=sorbet-gems /sorbet*.gem ./vendor/cache/

RUN bundle install

# prep watchman (required for sorbet's LSP mode, which is sometimes called in
# this image via docker wrapper scripts hooked up to editors like neovim)
USER root
COPY --from=watchman /usr/local/bin/watchman* /usr/local/bin/
COPY --from=watchman /usr/local/share/doc/watchman-4.9.0 /usr/local/share/doc/watchman-4.9.0
COPY --from=watchman /usr/local/var/run/watchman /usr/local/var/run/watchman
RUN mkdir -p /usr/local/var/run/watchman
RUN touch /usr/local/var/run/watchman/.not-empty \
 && chown -R $(id -u app):$(id -g app) /usr/local/var/run/watchman
USER app
Makefile to wrangle BuildX
.POSIX:

REGISTRY_BASE ?= REDACTED
REGISTRY_BASE_IMAGE ?= $(shell git describe --always --abbrev)

ifeq ($(PUSH),1)
	BASE_PUSH_FLAG := --push
endif

ifeq ($(IS_TRUNK_CI_BUILD),1)
	BASE_LATEST_TAG := -t $(REGISTRY_BASE):latest
endif

.PHONY: multiarch-qemu-reset
multiarch-qemu-reset:
	# this is PROBABLY dangerous in the event your system already has bin
	# handlers or something but whatever, those are *super* uncommon normally
	#
	# DO NOT run this on GitHub Actions, use docker/setup-qemu-action@v1
	# instead!
	[ "$$(uname -s)" = "Linux" ] && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes || true

.PHONY: buildx-base-image
buildx-base-image:
	docker buildx build \
		--platform linux/amd64,linux/arm64 \
		-t $(REGISTRY_BASE):$(REGISTRY_BASE_IMAGE) \
		$(BASE_PUSH_FLAG) \
		$(BASE_LATEST_TAG) \
		.

Footnotes

  1. https://github.com/Shopify/tapioca/commit/03266889ca71a1114cd91a3cc9c3a0dd435c51d2

  2. I've tried rebasing this branch onto something newer and Tapioca 0.8.x compatible and while the diffs eventually apply cleanly, I get Bazel-induced build failures. Bazel is a monstrously complex beast I have thus far consistently failed to wrap my head around (especially debugging it), and thus I gave up for now - I have too many non-Sorbet responsibilities at work to dedicate the requisite time to this.

  3. docker docs, podman docs

  4. https://github.com/Shopify/tapioca/issues/658

  5. https://github.com/Shopify/tapioca/issues/657

@klardotsh
Copy link

klardotsh commented Sep 9, 2022

I should, however, explicitly note now: my org is removing Sorbet from our codebase in the near future; I will likely no longer be maintaining the above forks or Docker images any further, and in particular, will not be continuing the efforts to rebase onto newer Sorbet releases. I have no intentions quite yet of removing the repos, and of course the contributions are all under the same license as Sorbet upstream, so feel free to make your own forks or otherwise remix my work so far 1 :) Cheers y'all!

Footnotes

  1. I'll see what I can do about open-sourcing some of our internal scripts and helper tooling around this, perhaps in a GitHub Gist or something, but no promises.

@ethankhall
Copy link
Contributor

For those interested, I took @klardotsh's changes and made them compatible with main (as of Sep 26, 2022) and able to build a static sorbet for linux-arm. You can find the changes here https://gist.github.com/ethankhall/516ddcefd22297a6cb9f736648386292.

@technicalpickles
Copy link
Contributor

@bhuga this is the ARM64 issue I was telling you about

@Nealsoni00
Copy link

Nealsoni00 commented May 30, 2023

Is there any expectation that ARM Linux will be supported in the future?

The issue makes Sorbet inoperable for a small team like mine developing on ARM Macs with everything unified into docker 😞. Our CI is also running using ARM and has the same challenge. I would LOVE to add the benefit of sorbet's type system!

@v2kovac
Copy link

v2kovac commented Jun 4, 2023

Is there any expectation that ARM Linux will be supported in the future?

The issue makes Sorbet inoperable for a small team like mine developing on ARM Macs with everything unified into docker 😞. Our CI is also running using ARM and has the same challenge. I would LOVE to add the benefit of sorbet's type system!

@Nealsoni00 our team got around this by having a separate gemfile for your local machine and docker, you only need sorbet locally.
eg:

# local gemfile dont add stuff here
eval_gemfile './Gemfile.docker'
gem 'sorbet'
gem 'tapioca'

And then you can use the env variable BUNDLE_GEMFILE to specify which to use where. After this one time setup we've had no problems, been doing this since december.

@nalgenewaterbottle
Copy link

What can we do to help set up the ARM64 Buildkite agent?

@mlarraz
Copy link

mlarraz commented Oct 18, 2023

What can we do to help set up the ARM64 Buildkite agent?

I believe this has to be done by somebody at Stripe. FYI @jez

@tonybruess
Copy link
Contributor

tonybruess commented Oct 18, 2023

Two months ago the last comment on this subject was from @froydnj in Slack:

we don’t use sorbet-build-image for builds inside Stripe

Sorbet releases on linux-arm64 (and darwin-arm64) haven’t been a priority for us at the moment

Until this is prioritized internally at Stripe it feels like we shouldn't expect to see arm64 releases. We may want to consider setting up a community run agent and repo.

@froydnj
Copy link
Contributor

froydnj commented Oct 18, 2023

We (well, @jez) has been trying to set up a buildkite agent for arm64 builds, but the current status is that the build is getting peculiar errors while setting up the required Ubuntu PPA repos (it looks like it's trying to fetch from an entirely different PPA than the one specified in the Dockerfile). Things are moving, just maybe not as quickly as one might like.

@noizwaves
Copy link

Many thanks for this @froydnj & @jez !

it looks like it's trying to fetch from an entirely different PPA than the one specified in the Dockerfile

Do y'all have any build logs that you can share? Because of the work on sorbet/sorbet-build-image#8 I may be able to help.

@froydnj
Copy link
Contributor

froydnj commented Oct 18, 2023

This is the end of the log:

#8 53.15 Cannot add PPA: 'ppa:~ubuntu-toolchain-r/ubuntu/test'.
#8 53.15 The team named '~ubuntu-toolchain-r' has no PPA named 'ubuntu/test'
#8 53.15 Please choose from the following available PPAs:
#8 53.15  * 'aarch64':  AArch64
#8 53.15  * 'binutils':  binutils
#8 53.15  * 'dpkg-lto':  dpkg defaulting to LTO flags
#8 53.15  * 'glibc':  glibc test builds
#8 53.15  * 'golang-fips':  Go FIPS
#8 53.15  * 'lunar-o3':  lunar O3
#8 53.15  * 'lunar-o3-v3':  lunar O3 v3
#8 53.15  * 'lunar-v3':  lunar v3
#8 53.15  * 'p9':  POWER9
#8 53.15  * 'power8':  POWER8
#8 53.15  * 'ppa':  Toolchain builds
#8 53.15  * 'security':  Security Uploads
#8 53.15  * 'test':  Toolchain test builds
#8 53.15  * 'volatile':  Volatile Packages
#8 53.15  * 'x86-64-v2':  GCC x86-64-v2
#8 53.15  * 'x86-64-v3':  GCC x86-64-v3

@tonybruess
Copy link
Contributor

Thanks for prioritizing this @jez and @froydnj! We all greatly appreciate it.

That's a strange error. Where is the docker build being run?

@noizwaves
Copy link

Thanks for the extra info @froydnj & @jez. We really appreciate the effort here!

The latest code from GitHub builds for me on an M1 laptop with docker build --no-cache., so I suspect something environmental is contributing. I have a couple of theories/suggestions:

  1. It sounds like add-apt-repository may have trouble in some HTTP(S)_PROXY setups, and reports the error in a general way. Is the image being built on a machine where a proxy is being used? If so, try passing the proxy env var directly to the docker build command like this: docker build --build-arg HTTP_PROXY="$HTTP_PROXY" ..
  • If your environment uses an HTTPS_PROXY, use docker build --build-arg HTTP_PROXY="$HTTP_PROXY" . instead.
  • If you're not secure what proxies are present, env | grep _PROXY will show them.
  1. Replace the apt-add-repository command that achieve a similar (see patch below). Even if this doesn't work, it should yield a different error message 🤞 .
diff --git a/Dockerfile b/Dockerfile
index 1a79916..4de9908 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,7 +17,9 @@ RUN apt-get update && \
       echo "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" | tee /etc/apt/sources.list.d/llvm.list && \
       apt-get update && \
       apt-get install --no-install-recommends -y nodejs yarn clang-9 && \
-      add-apt-repository --yes ppa:ubuntu-toolchain-r/test && \
+      apt-key adv --no-tty --keyserver keyserver.ubuntu.com --recv-keys 1E9377A2BA9EF27F && \
+      echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main" | tee /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-bionic.list && \
+      echo "# deb-src http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu bionic main" | tee -a /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-bionic.list && \
       apt-get update && \
       apt-get install --yes --only-upgrade libstdc++6 && \
       cd bazel_loader && \

@eric-christian
Copy link

eric-christian commented Oct 26, 2023

Hello,

Will this solve the problems for people on OSX with M1 chip, too? I'm able to install sorbet locally with gem install sorbet but it fails within a rails project when using bundler. So i'm a little confused about (in)compatibility.

❯ uname -a
Darwin mymacbookpro 23.0.0 Darwin Kernel Version 23.0.0: Fri Sep 15 14:41:34 PDT 2023; root:xnu-10002.1.13~1/RELEASE_ARM64_T8103 arm64

❯ bundle -v
Bundler version 2.4.19

❯ rails -v
Rails 7.1.1

❯ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin22]

❯ bundle install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Resolving dependencies...
Could not find gem 'sorbet-static' with platforms 'aarch64-linux', 'ruby', 'x86_64-linux' in rubygems repository https://rubygems.org/ or installed locally.

@tonybruess
Copy link
Contributor

@eric-christian What does bundle config say? I've seen this issue if force_ruby_platform: true

@eric-christian
Copy link

@eric-christian What does bundle config say? I've seen this issue if force_ruby_platform: true

Yes, that was indeed on. Without, it works. Thank you!

Wonder why i had that on. Has probably something to do with a rails app i work on that requires all gems for all supported platforms to be packed within the vendor/cache. 🤔

@nalgenewaterbottle
Copy link

This sounds close! Thank you again to those that are working on this 😊

@noizwaves
Copy link

Hey @froydnj & @jez - hope you are both doing well. I just wanted to check in about this Docker image build issues you were experiencing, and if there were any new blockers?

I have some bandwidth to work on this at Gusto, and would love to help out where I can.

@froydnj
Copy link
Contributor

froydnj commented Dec 1, 2023

Hey @froydnj & @jez - hope you are both doing well. I just wanted to check in about this Docker image build issues you were experiencing, and if there were any new blockers?

I have some bandwidth to work on this at Gusto, and would love to help out where I can.

Thanks for checking in @noizwaves ! Whatever issue we were experiencing seemed to be transient; I couldn't reproduce and jez couldn't reproduce it a day or so later.

I think the part we got stuck on was tagging the resulting images on Docker Hub. Our current practice right now is tagging the x86-64 image as latest, but that...probably won't work to tag both the x86-64 and arm64 images as latest? So we have to have different tags for each one, or is there magic that ensures we can have multiple architectures tagged as latest? (None of us are Docker experts in this respect.)

@JamieMagee
Copy link
Contributor

JamieMagee commented Dec 1, 2023

You can make the latest tag into a manifest list. That allows Docker to pull the correct architecture for the platform it's on without you having to specify.

You'll need to create, tag, and push two architecture specific images, probably latest-amd64 and latest-arm64 but you can call them whatever you'd like. Then you can use the docker manifest command to create and push the manifest list. Something like:

docker manifest create sorbet:latest \
  --amend sorbet:latest-amd64 \
  --amend sorbet:latest-arm64
docker manifest push sorbet:latest

@simoleone
Copy link
Contributor

There's a way to use the same tag for both architectures and many images out there do, but it's a bit of a pain to set up and troubleshoot to put it mildly.

A few random tips having dealt with this recently:

  • docker push/pull almost never do what you want when building/tagging/managing multi-platform images. They'll only deal with the platform they happen to be running on, and worse, do it silently. They are fine for running the images, of course, in which case they do what you want.
  • docker buildx --platform .... --push can take a comma-separated list of platforms. When you do this it will join them together into a single manifest list automatically and push them straight away. On the other hand, buildx can be horrendously slow to cross-build.
  • skopeo is a useful tool if you need to multi-platform "promote" images once they're already pushed, or push them around between repos, etc.

@noizwaves
Copy link

I'd second @JamieMagee 's approach. Failing that, it's also possible to skip the multi-platform tag and just use the platform specific tags. This does require some parametrization of the build pipeline, but that can be easier to get working.

@noizwaves
Copy link

The docs on docker manifest create include a very relevant example too.

@nalgenewaterbottle
Copy link

I would love to help as needed too! 😄 What are the relevant roadblocks?

@noizwaves
Copy link

I built and released an aarch64-linux and arm64-darwin-22 version if anyone wants to take it for a test run.

Hey @tonybruess 👋 , do you have the build process you used for the arm64-darwin-22 gem build anywhere? I have a little bandwidth and would like to build some linux arm64 gems for the community, and would love to expand this to darwin too.

@tonybruess
Copy link
Contributor

@noizwaves Unfortunately I didn't save the exact steps anywhere. The only note I left for myself is:

Change /usr/local/var/bazelcache to /Users/name/.cache/bazel in .bazelrc.local

My org just decided to remove Sorbet entirely so unfortunately I don't have any bandwidth to support further. :(

@noizwaves
Copy link

Oh no, that sucks @tonybruess! Thank you for all the help so far on this issue ❤️

@noizwaves
Copy link

I have a little bandwidth and would like to build some linux arm64 gems for the community, and would love to expand this to darwin too.

Ok folks, I was able to get some time this weekend and have set up https://github.com/sorbet-multiarch. It builds the linux/arm64 Sorbet gem on CircleCI and publishes it to Gemfury. It automatically runs nightly, and should provide up to date linux/arm64 gems moving forward.

Currently version 0.5.11150 and 0.5.10993 are available. If you need another prior version, just create an issue over here and I'll build it for you.

@nalgenewaterbottle
Copy link

I'm curious if this is going to get official traction. Even with community solutions published and showing a near complete path for implementation, it just doesn't seem like there's room for it. Should we expect to use @noizwaves's implementation ? Which is great, and thank you for putting it forward.

@Dandush03
Copy link

I have a little bandwidth and would like to build some linux arm64 gems for the community, and would love to expand this to darwin too.

Ok folks, I was able to get some time this weekend and have set up https://github.com/sorbet-multiarch. It builds the linux/arm64 Sorbet gem on CircleCI and publishes it to Gemfury. It automatically runs nightly, and should provide up to date linux/arm64 gems moving forward.

Currently version 0.5.11150 and 0.5.10993 are available. If you need another prior version, just create an issue over here and I'll build it for you.

GREAT WORK!

@X-sam
Copy link

X-sam commented Feb 16, 2024

does the announcement of new m1 runners for open source projects make this an easier ask?

@nalgenewaterbottle
Copy link

I don't think so @X-sam - I think the solutions provided above (from @noizwaves) actually accomplish the asks. It would seem it's more so on the time @jez / @froydnj and team have to maintain and implement it. Something that doesn't seem to be prioritized. But who knows! Maybe that was really the blocker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or surprising current feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.