Jekyll Installation on Macs w/ARM64 w/o Package Manager

I am finding it impossible to get jekyll up and running on a new Mac equipped with the M1 CPU (ARM64). I know that some have had success by relying on a package manager, despite the fact that the most popular one on the Mac (homebrew) only has very preliminary support for the M1.

So… is it still supposed to be possible to install jekyll on a vanilla Mac configuration? On an Intel Mac it takes a few seconds to get jekyll up and running.

I hope someone who sympathizes with the “simplest possible installation strategy”, and with more experience with ruby can help. Here are the steps I followed:

  • I have installed the latest version of Xcode (2.2 at the time of this writing) which includes development tools.

  • I have run: gem install --user-install bundler jekyll which has the side effect of installing gems under ~/.gem/ruby/2.6.0/gems and thus does not run against file permissions on the /Library/Ruby folder. Some posts mention SIP as the problem but I do not think that is correct… you can’t sudo past SIP. The fact that admins no longer have write permissions to that location is probably just Apple protecting the standard Ruby environment for unauthenticated modification.

  • Some (likely outdated) posts suggest that you have to edit your GEM_HOME and GEM_PATH environment variables to get gems installed under your home directory recognized and loaded, but: A) that didn’t make a difference for me B) it doesn’t seem necessary to mess around with environment variables because an invocation of gem env reveals that the version of gem running on macOS is already adding the user-specific gem directory to its GEM_PATHS:

    • GEM PATHS:
      • /Library/Ruby/Gems/2.6.0
      • /Users/me/.gem/ruby/2.6.0
      • /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0
  • gem update runs without problems.

  • I can cd to a directory containing my Jekyll site, and I can also run bundle update without problems

  • So what happens when I invoke the jekyll command? I get the following error:
    […]
    1: from /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require' /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in require’: dlopen(/Users/gds/.gem/ruby/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle, 0x0009): missing compatible arch in /Users/gds/.gem/ruby/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle - /Users/gds/.gem/ruby/2.6.0/gems/ffi-1.13.1/lib/ffi_c.bundle ( LoadError )

OK, so as an ignoramus on Ruby, I can deduct that FFI is a component required by jekyll/rubygems. My first thought is that this is compiled, and it lacks the arm64 binary. But when I cd to that directory and run lipo on that file…

lipo -info ffi_c.bundle
Architectures in the fat file: ffi_c.bundle are: x86_64 arm64e

…it clearly looks like both Intel and ARM binaries are present.

What gives?

ffi seems to be broken, there are multiple bug reports for various projects all over the place, but so far I haven’t seen a lot of progress to fix them. I spent some time this morning trying to figure out a solution, but at this point, all I can do is provide the same rosetta2 workaround I’ve seen elsewhere.

I use bundler, rather than a user install, so that my gems are packaged; in this case I recommend you do the same. You might already have a working Gemfile. Then use the arch command to force ruby to use rosetta2 as x86 and build/run the gems that way.

To be clear: this is a workaround, not a fix.

cd jekyll_install
arch -arch x86_64 bundle install --path vendor/bundle

then to run, eg jekyll serve
arch -arch x86_64 bundle exec jekyll serve

if you get errors about missing symbols, try
arch -arch x86_64 bundle pristine

and then try to run jekyll again.

1 Like

I’ve learned some more. The issue appears to be bigger than initially though. The OS ruby is build again the arm64e platform, as you have discovered. Because ruby spawns the compiler to compile the ffi gem system extension, the build arch for ffi is also arm64e.

But currently, only Apple binaries will run on arm64e. I tested this by creating a very basic C program. If built for arm64, it works. If built for arm64e, it won’t run and shows ‘killed’ as an exit status.

Most ruby developers immediately build their own ruby, which gets built as arm64 (no e), and if you build ffi 1.14 (released today) against a non-default ruby, it’ll likely work.

I’m just going to stick with rosetta emulation for now, but I suspect that once Apple releases the arm64e Application Binary Interface so that a wider group of applications can use it, it’ll get better.

[1] https://developer.apple.com/forums/thread/652340
[2] https://github.com/ffi/ffi/issues/860

Thank you for all your research and explanations. I’ll try to follow up on your recommendations ASAP. Knowing the exact nature of the problem is a good start. A few days ago I had come across this document:

…and I could scarcely believe that Apple would allow me to build a binary with arm64e but then disallow me from testing it (on the Mac, at least). I have no idea why arm64 and arm64e binaries aren’t able or allowed to interoperate, but I’m gonna assume there is a good reason for that.

Your help is super-appreciated. I’ll keep an eye on these forums for more news :slight_smile:

Holy shit!
I destroyed so much of my laptop, lost my databases because of brew uninstall (including spilling gum on my keyboard) and this bloody worked!
Thank you!