/Users/ekr/dev/chromium/src/third_party/WebKit/Source/WebCore/WebCore.gyp ar: input.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it) ar: input.a: Inappropriate file type or format rm: /Users/ekr/dev/chromium/src/out/Debug/obj.target/\ webkit_system_interface/geni/adjust_visibility/self/cuDbUtils.o: No such file or directory make: *** [out/Debug/libWebKitSystemInterfaceLeopardPrivateExtern.a] Error 1 make: *** Waiting for unfinished jobs....
Luckily, I've run into this problem before so I know what the problem is.
The script third_party/WebKit/Source/WebCore/WebCore.gyp/mac/adjust_visibility.sh
,
which does some library mangling, uses file
to determine
what kind of library it's dealing with. Unfortunately, it invokes
file
with an unqualified name, and since MacPorts
wants to put itself at the beginning of PATH
this
means that you get the file implementation from MacPorts which
has a slightly different output than the system file. The result
is that adjust_visibility.sh
decides that you
have a thin version of libWebKit...a
and tries
to run ar
on it. When ar
fails, so does
the build.
The fix here is to move MacPorts below /usr/bin
in your
path. I'd already done this—or so I thought— but it
turned out that MacPorts had inserted itself twice in .cshrc
so I had to edit .cshrc
and then run source .cshrc
.
I did this, and after correcting a typo things looked good and I
and went to rerun the build, only to be greeted with:
CXX(target) out/Debug/obj.target/base/base/sync_socket_posix.o In file included from base/sync_socket_posix.cc:18: ./base/file_util.h:416:56: error: no type named 'set' in namespace 'std' const std::set& group_gids); ~~~~~^ ./base/file_util.h:416:59: error: expected ')' const std::set & group_gids); ^ ./base/file_util.h:413:44: note: to match this '(' BASE_EXPORT bool VerifyPathControlledByUser(const FilePath& base, ^ 2 errors generated. make: *** [out/Debug/obj.target/base/base/sync_socket_posix.o]
I know what you're thinking here—or at least what I thought—someone
forgot to #include <set>
and for some reason the automated
builds didn't catch it, perhaps due to some conditional compilation problem
getting triggered on Lion. But checking the source quite clearly showed
that set
was being included. Moreover, other STL containers
like vector
work fine. Changing from clang to GCC didn't
help here, so eventually I reverted to gcc -E
. For those of
you who don't know, this runs the preprocessor but not the compiler and
so is really useful for diagnosing this kind of include error. Here's
the relevant portion of the result:
# 18 "./base/file_util.h" 2 # 1 "./set" 1 # 24 "./base/file_util.h" 2
It's a little hard to read, but if you know what to look for, it's telling you
that instead of including set
from /Developer
, where
the system include files live, the compiler is getting it from the
local directory. Now, you might ask what the heck a file named
set
is doing in the local directory, especially as
when I looked it was totally empty. Naturally, it was
my fault, but it took a minute to realize what. Remember I said that
I had to correct a typo in .cshrc
but now what the typo
was. Well, the problem was that I had written:
>set OSVER=`uname -r`Instead of
set OSVER=`uname -r`
Of course, when I ran this it create a file called set
in
the current directory and since the compile flags included the
current directory in the include path, the compiler duly included
it instead of the system include file. And since the file was
empty, there wasn't any definition of std::set
and we got a compile error. Time wasted by this error: 11 minutes
(not including writing this up).