We have a number of OSX users in the community (myself included) and some of you may have recently noticed issues extending Chef functionality by installing ruby gems like berkshelf, chefspec, and foodcritic which require building native extensions. Specifically, this issue crops up if you’re using omnibus or system Ruby along with newly released Xcode5.1 and its CLI tools.
You can check your version of Xcode with this command:
pkgutil --regexp --pkg-info=com.apple.pkg.XcodeMAS_iOSSDK*
If you see the output below, this bug may apply to you:
package-id: com.apple.pkg.XcodeMAS_iOSSDK_7_1 version: 18.104.22.168.1.1393561416
Let’s look at an example of the error caused by our bug. You’ll see this error when trying to install ruby gems that require native extensions:
clang: warning: argument unused during compilation: '-L/opt/chef/embedded/lib' linking shared-object hitimes/1.9/hitimes.bundle clang: error: unknown argument: '-R/opt/chef/embedded/lib' [-Wunused-command-line-argument-hard-error-in-future] clang: note: this will be a hard error (cannot be downgraded to a warning) in the future make: *** [hitimes.bundle] Error 1
The implementation of the GCC compatibility frontend in Xcode 5.1 (clang for LLVM) introduces a breaking change. In previous versions of Xcode, clang would accept unknown command line flags with a warning. As of Xcode 5.1, passing unknown flags causes rejection with an error. Clearly, rejecting unknown flags is sane behavior and Xcode is now arguably doing the right thing. This change highlights a bug that has been generating a mostly quiet failure for far too long.
Great. But how can you get back to a working state?
There are at least two known workarounds:
- Remove the Xcode 5.1 Application and downgrade to Xcode 5.0.2 (you don’t have to worry about downgrading the CLI tools add-on)
- Continue to use Xcode 5.1 and alter the ldflags being passed to clang by setting them prior to building your gem:
CONFIGURE_ARGS="--with-ldflags='-Wno-error=unused-command-line-argument-hard-error-in-future'" sudo -E /opt/chef/embedded/bin/gem install [gem name]
CONFIGURE_ARGS="--with-ldflags='-Wno-error=unused-command-line-argument-hard-error-in-future'" sudo -E /opt/chef/embedded/bin/gem install berkshelf
A patch for this bug has been merged into upstream source and if you build Ruby from recent source on 1.9.3, you can bypass the issue entirely. However, there is not an official Ruby release containing this patch available yet.
Which ruby to use?
As a Consultant for Chef, customers often ask me if they should manage a separate Ruby environment or use the omnibus ruby packaged with Chef for their development needs. The advice I typically give is to start by using omnibus ruby until your needs outgrow it. This tends to be sufficient for many Chef users, especially newer ones. You don’t really need Ruby to get started with Chef out of the box. When you find yourself wanting to color outside the lines, having a bit of Ruby really helps.
If you’ve used Chef’s embedded omnibus ruby, you know that upgrading your omnibus installation of Chef will blow away any of your customizations. If your ruby needs have expanded enough, it may be more appealing to manage that environment outside of Chef. Once Chef users become familiar with their ruby development needs, I then recommend looking at one of the many ways to manage them (such as chruby or rbenv). For those managing their own ruby environments, patch your ruby distributions before upgrading to Xcode 5.1.
For those using omnibus ruby, the best advice is to use one of the two workarounds listed above until we resolve that issue in a chef client release. We’ll be making changes to the way Chef Client omnibus packages are built for OSX to incorporate fixes to this issue. Our plan around addressing this in omnibus ruby can be referenced in this gist from Serdar Sutay.