EV fails to install on OS X 10.7

Alexey Borzenkov snaury at gmail.com
Thu Feb 2 07:01:26 CET 2012


On Thu, Feb 2, 2012 at 7:26 AM, Marc Lehmann <schmorp at schmorp.de> wrote:
>> I just did and there are two issues. First, it seems llvm is
>> deliberately excluded from ecb.h, but after this patch:
>
> Ahh, that makes more sense - the trouble with __llvm__ is that it's
> defined by a lot of compilers - is there a more specific way to check for
> apple's compiler, or is this guaranteed to work with all compilers that
> define __llvm__?

As far as I understand this specific place is for adding inline
assembly for different *architectures*, this shouldn't be about
compilers too much, as long as compiler supports __asm__. If __llvm__
is defined by other compilers (non gcc-compatible?) besides llvm-gcc,
maybe we could change the guard to `|| (defined(__GNUC__) &&
defined(__llvm__)) ||' so it selects llvm-gcc specifically?

I think allowing inline assembly is relatively safe (unless compiler
has bugs related to inline assembly, but even old gcc versions
sometimes have those). Now down below if fence wasn't defined with
assembly it tries to use intrinsics, I'm not propossing enabling it
for llvm-gcc there. If we're talking about Apple's llvm-gcc it's only
supposed to be used for ppc (now discontinued), i386, amd64 and maybe
arm32 (for iPhone/iPad sometimes).

> Because we always need to refer to the outside symbol, and using extern
> does that, even for static variables only tentatively defined.
[...]
> libev supports having its symbols external as well as static, which
> requires this maybe surprising but valid construct to work portably.

Hmm, you're right, although I'm not sure about portability (even
though I code in C I never actually read the standard, so I don't
really know what's supposed to happen here). Although when I
previously saw such a trick the symbol in libraries was always
declared extern, and there was a separate .c file that only defined
this global variable. It seems the idea usually is for users to be
able to override the symbol by simply using link order (if symbol is
in .o it won't be pulled from the library).

However, I'm not sure why you really need this. If user embeds libev,
then this variable would be static wherever user includes ev.c and
libev should use that. If user compiles libev separately, then ev
definitions wouldn't be compiled, and when user includes ev.h symbols
will be declared extern, so the inline function will refer to extern
symbol define elsewhere. I'm confused what is this elaborate construct
for?

> However, I am a bit confused - which compiler is used on apple, clang or
> llvm-gcc (or even dragonfly by now?), or yet another one?

Both. There's no plain gcc anymore, and XCode uses clang by default
(although you can still override). However most of system software
(Perl, Python, etc.) are compiled with llvm-gcc, so their build
systems compile extensions with llvm-gcc too. To add more to the
confusion MacPorts now compiles everything with clang by default (and
surprisingly almost everything builds well, I only had several cases
where package didn't compile because clang didn't like something about
some /usr/include headers (go figure!) and I had to use
configure.compiler=llvm-gcc-4.2, but the most interesting part is that
recently I reinstalled and now those packages build out of the box).

The future seems to be for clang to become the only compiler on Apple,
with current llvm-gcc left only for transition (or maybe Apple can't
build their whole system with clang yet :D). I looked at llvm-gcc
source code and it seems to be mostly gcc, with bits and pieces
tweaked in several files so that it emits llvm assembly (which
supports inline machine assembly) instead of machine assembly
directly. The most frustrating part is that llvm in llvm-gcc seems to
be a private copy and older (LLVM build 2336.1.00 whatever that is)
than the one used by clang is newer (LLVM 3.0svn). Some bugs seem to
come from this old/buggy llvm version, I have an interesting case
where I push compiler to its limits with inline __asm__ with lots of
constraints and I look at resulting llvm assembly and it looks
correct, but the final machine assembly messes up registers and that
seems to be llvm fault. :( Even funnier is that llvm in llvm-gcc seems
to be counting registers wrong (e.g. it thinks it ran out of registers
even when it still has at least esi and edi), when llvm in clang
doesn't have that problem. Overall, if Apple upgraded llvm-gcc to a
newer llvm version, maybe some bugs would disappear, but I haven't
tried it yet.

Unfortunately there's no dragonegg, and opinions on the internet when
I searched were that it wasn't coming, as maybe one reason that Apple
jumped on clang bandwagon was to avoid GPLv3+ that gcc >= 4.2.2 use
(and Apple is frozen in 4.2.1 land).

So the bottom line is that llvm-gcc is crap even when it works, but
it's default right now (and we have to deal with it) simply because
chunks of the OS are compiled with it, however clang is pushing to
become the default in the future and it's good to support both (at
least I try to test both).

Best regards,
Alexey.



More information about the libev mailing list