The problem
Let's begin with a common example. You want to build EDCommon & EDInternet as these are frameworks which are needed for MulleNewz.dock or XMLRPC for example. Let's assume you've checked out the latest versions from CVS to make sure you get the best snapshots that hopefully have all remaining bugs fixed.
You start by compiling EDCommon as this is the prerequisite for building EDInternet. You type:
% cd ed/EDCommon
% pbxbuild install -buildstyle Development INSTALL_ROOT=/
=== BUILDING TARGET EDCommon (Framework) OF TYPE Framework ===
/usr/bin/jam -d0 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- install
ACTION=install "TARGETNAME=EDCommon (Framework)" NATIVE_ARCH=ppc BUILD_STYLE=Development
"CPP_HEADERMAP_FILE=/Local/BuildArea/EDCommon (Framework).build/Headermaps/EDCommon.hmap"
DSTROOT=/tmp/EDCommon.dst INSTALL_ROOT=/ OBJROOT=/Local/BuildArea
SRCROOT=/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon SYMROOT=/Local/BuildArea
warning: <EDCommon>EDCommon.framework depends on itself
Completed phase <CopyHeaders> for EDCommon.framework
Completed phase <CopyResources> for EDCommon.framework
Completed phase <DeriveAndCompileSources> for EDCommon.framework
Completed phase <LinkWithFrameworksAndLibraries> for EDCommon.framework
Completed phase <RezResourceManagerFiles> for EDCommon.framework
** BUILD SUCCEEDED **
This went fairly smooth, so you continue building EDInternet. You type:
% cd ../EDInternet
% pbxbuild install -buildstyle Development INSTALL_ROOT=/
=== BUILDING TARGET EDInternet (Framework) OF TYPE Framework ===
/usr/bin/jam -d0 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- install
ACTION=install "TARGETNAME=EDInternet (Framework)" NATIVE_ARCH=ppc BUILD_STYLE=Development
"CPP_HEADERMAP_FILE=/Local/BuildArea/EDInternet (Framework).build/Headermaps/EDInternet.hmap"
DSTROOT=/tmp/EDInternet.dst INSTALL_ROOT=/ OBJROOT=/Local/BuildArea
SRCROOT=/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDInternet SYMROOT=/Local/BuildArea
warning: <EDInternet>EDInternet.framework depends on itself
Completed phase <CopyHeaders> for EDInternet.framework
Completed phase <CopyResources> for EDInternet.framework
/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon/EDCommon.h:25: header file
'NSArray+Extensions.h' not found
...
/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon/EDCommon.h:74: header file 'EDSwapView.h' not
found
cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode
** BUILD FAILED **
What happened? Understanding the problem
If you switch to Build Log
detail level: Detailed Logs mode you'll see that both the resulting products and the intermediary
build files are being put in/Local/BuildArea . Most probably your directory will be named differently but that's how some people at Mulle kybernetiK name it (since early Object Factory days). If we take a look in that directory we can see a directory called ProjectHeaders in there. In that directory, PBX places intermediary versions of the projects' header files which are simply stubs. These stubs contain references to the real header files by simply containing a (sample taken from my copy of EDCommon's NSArray+Extensions.h) #include "/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon/FoundationExtensions.subproj/NSArray+Extensions.h"
reference.
Now let's compile again and have a
look at the detailed logs (for simplicity's sake I'm only including the relevant parts in the
output):
% pbxbuild install -buildstyle Development INSTALL_ROOT=/ === BUILDING TARGET EDInternet (Framework) OF TYPE Framework === /usr/bin/jam -d2 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- install ACTION=install "TARGETNAME=EDInternet (Framework)" NATIVE_ARCH=ppc BUILD_STYLE=Development "CPP_HEADERMAP_FILE=/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Headermaps/EDInternet.hmap" DSTROOT=/tmp/EDInternet.dst INSTALL_ROOT=/ OBJROOT=/Local/BuildArea/EDInternet.build SRCROOT=/automount/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDInternet SYMROOT=/Local/BuildArea
warning: <EDInternet>EDInternet.framework depends on itself ...updating 27 target(s)... BuildPhase EDInternet.framework [...] CompileC /Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Objects/ppc/NSHost+Extensions.o
/usr/bin/cc -c "-F/Local/BuildArea/ProjectHeaders" "-F/Local/BuildArea" "-F/Library/Frameworks" "-I/Local/BuildArea/ProjectHeaders/EDInternet" "-I/Local/BuildArea/include" "-IFoundationExtensions.subproj" "-arch" "ppc" "-fno-common" "-fpascal-strings" "-O3" "-Wmost" "-Wno-four-char-constants" "-Wno-unknown-pragmas" "-pipe" "-g" "-precomp-trustfile" "/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/TrustedPrecomps.txt" "-Wp,-header-mapfile,/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Headermaps/EDInternet.hmap" "-I/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/DerivedSources" "FoundationExtensions.subproj/NSHost+Extensions.m" -o "/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Objects/ppc/NSHost+Extensions.o"
/automount/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon/EDCommon.h:25: header file 'NSArray+Extensions.h' not found /automount/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDCommon/EDCommon.h:26: header file 'NSAttributedString+Extensions.h' not found [...] cpp-precomp: warning: errors during smart preprocessing, retrying in basic mode ...failed CompileC /Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Objects/ppc/NSHost+Extensions.o ... ** BUILD FAILED **
For some reasons /Local/BuildArea/ProjectHeaders is the first framework include path as we can see in the output above. This shouldn't be a problem but it turns out that there is a bug in the compiler that prevents the stub's (see above) referenced files from being found when there are multiple references to identical "sounding" headers in a framework include path. [Note: this sounds a bit flaky - and it is - but it's rather complicated to go into the compiler's internals. All testcases that I could think of provided me with this result, however.] If one would change the order in the include path and put /Local/BuildArea frontmost everything would be ok. Solution
We cannot simply change the framework include order because the Jamfile is generated automatically on the fly. But another workaround is pretty easy: Remove the EDCommon.framework directory from
/Local/BuildArea/ProjectHeaders before you build EDInternet. Here is what happens then:
% pbxbuild install -buildstyle Development INSTALL_ROOT=/ === BUILDING TARGET EDInternet (Framework) OF TYPE Framework === /usr/bin/jam -d0 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- install ACTION=install "TARGETNAME=EDInternet (Framework)" NATIVE_ARCH=ppc BUILD_STYLE=Development "CPP_HEADERMAP_FILE=/Local/BuildArea/EDInternet.build/EDInternet (Framework).build/Headermaps/EDInternet.hmap" DSTROOT=/tmp/EDInternet.dst INSTALL_ROOT=/ OBJROOT=/Local/BuildArea/EDInternet.build SRCROOT=/automount/Network/Users/znek/Projects/mulle-anon-cvs/ed/EDInternet SYMROOT=/Local/BuildArea
warning: <EDInternet>EDInternet.framework depends on itself Completed phase <CopyHeaders> for EDInternet.framework Completed phase <CopyResources> for EDInternet.framework FoundationExtensions.subproj/NSString+MessageUtils.m:142: warning: ** workaround for broken implementation of -invertedSet in 5G64 Socket.subproj/EDStream.m:95: warning: * auto close (cf EDSMTPStream) Message.subproj/ContentCoder.subproj/EDPlainTextContentCoder.m:52: warning: * maybe we should allow text/enriched or even text/html and dump the formatting... Mail.subproj/EDMailAgent.m:128: warning: * maybe check for root if not debug build Completed phase <DeriveAndCompileSources> for EDInternet.framework Completed phase <LinkWithFrameworksAndLibraries> for EDInternet.framework Completed phase <RezResourceManagerFiles> for EDInternet.framework ** BUILD SUCCEEDED **
Usually I do remove the whole /Local/BuildArea/ProjectHeaders directory before building anything. This imposes a small time penalty on larger builds - but your builds won't fail for the above reasons, probably saving more time and nerves.
Copyright (C) 2001 Mulle kybernetiK written by ZNeK <znek@mulle-kybernetik.com>
|