Xcode 11 GM Seed 2 Released

OK, I’ve had some more time to dig into the Ruby issues, and I think I have a good handle on it now. The issue is that Apple have changed the path where ruby is installed to with Xcode 11. This means that after installing Xcode 11, the system Ruby is in some sense “corrupt”.

To explain a little more, if you try to install a gem with native extensions, you can see that it’s trying to search in /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/include for ruby.h:

$ sudo gem install json
<snip>
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/include/ruby.h

You can see this same search path here:

$ ruby -e 'puts $:'
<snip>
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/x86_64-darwin18
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/universal-darwin18

After installing Xcode 11, the ruby headers are located in a different location on disk, in /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/:

$ xcrun --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk

So the act of installing Xcode 11 has moved the headers required for native Ruby extensions with the system Ruby to a location that is not searched.

Luckily, we install 2 other version of Ruby in the Xcode 11 image: 2.5 and 2.6. To swap to use one of these version of Ruby is straightforward - there are 2 steps:

  1. In your job in .circleci/config.yml, change the shell parameter to /bin/bash --login -eo pipefail to make the steps run in a login shell (by default CircleCI runs steps in a non-interactive, non-login shell, in which case neither .bashrc nor .bash_profile are loaded).
  2. Add a step to set the version of Ruby that you require: echo "ruby-2.6" > ~/.ruby-version.

A sample configuration file looks like this:

version: 2.1
jobs:
  build:
    macos:
      xcode: 11.0.0
    steps:
      - checkout
      - run:
          name: Set Ruby Version
          command:  echo "ruby-2.6" > ~/.ruby-version

This should unblock you and allow you build with Xcode 11.

In the meantime, we are going to ship a change to make the default shell on macOS be a login shell, and we are going to change the default Ruby to be 2.6 in the Xcode 11 image. I hope to be able to ship this change tomorrow.

In related news, I’ve also got an Xcode 11.1 GM Seed image that is built, and all going well, it will be distributed tomorrow.

2 Likes

Thanks for the update.
Could you specify which ruby version for 2.6 is installed?
We had a .ruby-version file already on our project directory, I tried setting that to 2.6.4
(the last one) but I receive an error

#!/bin/bash --login -eo pipefail echo “ruby-2.6” > ~/.ruby-version
^D^Dchruby: unknown Ruby: 2.6.4 Exited with code 1

remove that file from our project seems to make it work on the CI, but I would still want to keep it in order to make sure locally we use the same version.

Hi Alex,

That’s an interesting one - since chruby is now enabled in the image, it is detecting the .ruby-version in your checkout and trying to select it. If you change the .ruby-version in your repo to 2.6 you should be OK. We have 2.6.3 installed in the image, so you could change to that either.

The Xcode 11.1 GM image has Ruby 2.6.4: Xcode 11.1 Image released

Marc

OK, I’ve pushed a big change live:

  • The default shell for all images is now a login shell, and .bash_profile will be executed on every step. This will also enable chruby automatically, which will pick up any .ruby-version files and activate the requested version of Ruby

  • The default Ruby for Xcode 11 and 11.1 is now 2.6: I’ve also added a new file at ~/.ruby-version for Xcode 11 and 11.1 images. This file contains the string ruby-2.6, which has the effect of setting the default Ruby to be 2.6.

These are breaking changes that might affect some of your builds, but it was the only way to fix the Ruby issues with Xcode 11 given our current setup.

Thanks,

Marc

As a headsup. Is posible that this affected old (before Xcode11) images? I have some jobs that use old Xcode images failing with

^D^Dchruby: unknown Ruby: 2.3.3
Exited with code 1

In any case is not a big deal, I will update those old jobs anyway. Just wanted to clarify it.


Changed our .ruby_version to that and it works fine now :wink: We use rvm and I think that only saying 2.6 is not enough. Anyway, we’re fine with .3.

Thanks!

Yeah, because of reasons we can’t change the shell for each image, only for each OS. I had to change to for all macOS jobs.

I’ve been back and forth in my head about whether it’s best to use chruby's auto system or not in out images Or even chruby at all. Should we just brew install ruby and use the latest stable Ruby in the next image (and stop offering different versions?)

We brew install Java, Python 2 and 3, and no-one ever has complains about those not working*. It’s only ruby that causes all the problems.

* Except for Xcode 10.2 when we accidentally installed a JRE instead of the JDK :man_facepalming:

Okey that makes sense, don’t worry. It was a quick fix on our side :slight_smile:

We personally use rvm to make sure the entire team uses the same ruby version, so I guess it will always be hard to please everybody.