"-Xclang -fobjc-nonfragile-abi2" is single flag with one argument

@jeff_lamarche is asking over twitter early today:

Anyone know which build setting generates a -c flag? LLVM doesn’t support -c, trying to figure out what needs to change.

And turns out the order of flags in $OTHER_CFLAGS was wrong, and causing the error during compiling.

Actually, there’s only one flag

If you wan to enable Objective-C 2.0 ABI in modern runtime (so that you can use synthesized by default feature), you need to add following flag in your $OTHER_CFLAGS:

-Xclang -fobjc-nonfragile-abi2

And people who saw this might think they are two different arguments, so add into your Xcode project like this:

It works, no error. But if you add them in reversed order, like this:

And oops, the Xcode chocked once you clicked the build button:

It will tell you the compiler can’t handle the -c argument, just like @jeff_lamarche said at the beginning. But, why?

Why

From clang man page:

% man 1 clang
...
Driver Options
-Xclang arg
    Pass arg to the clang compiler.

The -Xclang flag is a LLVM driver option for “Pass argument to the clang compiler,” and the the argument here is -fobjc-nonfragile-abi2.

So, if you put them in reversed order, the compiler will use -fobjc-nonfragile-abi2 as cflag, which isn’t, and get you the error in return.

I don’t want Xcode to treat them as two flags

In Xcode project setting description,

Space-separated list of additional flags to pass to the compiler for C and Objective-C files. Be sure to backslash-escape any arguments that contain spaces or special characters (e.g. path names that may contain spaces). Use this setting if Xcode does not already provide UI for a particular C or Objective-C compiler flag. [OTHER_CFLAGS]

The Backslash-escape can’t be used in here, since there’s no space in our argument -fobjc-nonfragile-abi2. (e.g. -L/path\ with\ space is fine.)

If you try to add in this way: “-Xclang\ -fobjc-nonfragile-abi2”, backslash-escape the space between the flag and argument, sorry, won’t work.

And in the Xcode Build Setting Reference,

option specification String that may contain the characters an identifier may contain as well as spaces. When an option specification contains spaces, it must be surrounded by single quotation marks (‘) or double quotation marks (“).

It sounds like we can use quotation marks, but sorry, still won’t work. Though the Xcode treats them as one flag, the Objective-C 2.0 ABI is not enabled, you will see lot of warnings saying the property requires accessors to be defined.

So, in current Xcode (version 3.2.3), add them as -Xclang -fobjc-nonfragile-abi2 in $OTHER_CFLAGS, and let Xcode treat them as two arguments.

Reference

  1. digdog posted this