[MacPorts] #34524: qt4 +framework activate failure

MacPorts noreply at macports.org
Sun May 20 00:41:31 PDT 2012


#34524: qt4 +framework activate failure
-------------------------------+--------------------------------------------
 Reporter:  mackyle@…          |       Owner:  macports-tickets@…                   
     Type:  defect             |      Status:  new                                  
 Priority:  Low                |   Milestone:                                       
Component:  ports              |     Version:  2.1.1                                
 Keywords:  activate           |        Port:  qt4-mac                              
-------------------------------+--------------------------------------------
 == Overview ==

 The symptom of the problem when building {{{port install qt4-mac
 +framework}}}:

 {{{
 --->  Fetching qt4-mac
 --->  Verifying checksum(s) for qt4-mac
 --->  Extracting qt4-mac
 --->  Applying patches to qt4-mac
 --->  Configuring qt4-mac
 --->  Building qt4-mac
 --->  Staging qt4-mac into destroot
 --->  Installing qt4-mac @4.7.4_1+framework+quartz
 --->  Activating qt4-mac @4.7.4_1+framework+quartz
 Error: Target org.macports.activate returned: Image error: Source file
 /private/var/tmp/build/macports_i386/
 var/macports/software/qt4-mac/mpextract4roAV6L7/private/var/tmp/build/macports_i386/
 lib/QtMultimedia.framework/Versions/4/4 does not appear to exist (cannot
 lstat it).
 Unable to activate port qt4-mac.
 Log for qt4-mac is at:
 /private/var/tmp/build/macports_i386/var/macports/logs/
 _private_var_tmp_build_ports_aqua_qt4-mac/qt4-mac/main.log
 Error: Status 1 encountered during processing.
 }}}

 The above failure is only the culmination of a long chain of cascading
 problems.

 The fix described in ticket #34518 also makes this issue go away unless
 the {{{+debug}}} variant is then used.

 == Analysis ==

 The precise cause of the activation failure is that the {{{+CONTENTS}}}
 file in the archive created during the archiving (aka installing) phase
 mentions a {{{.../QtMultimedia.framework/Versions/4/4}}} symbolic link
 that is not actually present in the archive.

 It's not in the archive because during the archiving (aka installing)
 step, the following error occurred:

 {{{
 a
 ./private/var/tmp/build/macports_i386/lib/QtMultimedia.framework/Versions/4/4:
  Couldn't read symbolic link: Permission denied
 }}}

 However, that error did not cause the archiving step to fail, nor was it
 displayed since the {{{-v}}} option was not used.  It does prevent the
 symbolic link from being added to the archive though.

 It turns out that the symbolic link in question has these permissions:

 {{{
 l---------  1 macports  macports  1 May 19 18:35:00 2012 4@
 }}}

 Which is why it failed to be added to the archive.  However, the code in
 portinstall.tcl (portinstall::create_archive) goes ahead and adds it to
 the {{{+CONTENTS}}} file since no attempt is actually made to verify that
 it's readable when adding it to the {{{+CONTENTS}}} file.

 So how did it come to have those bizarre permissions?  Turns out that only
 10.6.x and 10.7.x are susceptible to this particular bug.

 The qt4-mac build itself sometimes produces this situation deep inside the
 build directory when building the +framework variant:

 {{{
 lrwxr-xr-x  1 macports  macports  1 May 19 18:34:50 2012 4@ -> 4
 }}}

 The problem is that during the destroot stage (aka staging) that self-
 referencing symlink ends up getting copied into the DESTDIR using {{{cp -f
 -R}}} which it turns out has problems on 10.6.x and 10.7.x (but not on
 10.4.x or 10.5.x).

 You can see this for yourself with the following:

 {{{
 cd /tmp
 mkdir -p this/my/foo
 cd this/my/foo
 ln -s 4 4
 cd /tmp
 cp -f -R this that
 ls -lR that
 # that/my/foo/4 will have an error in the listing (and bad permissions) if
 the problem is present
 }}}

 The copied hierarchy in {{{that}}} will have bizarre permissions on the
 copied symbolic link {{{that/my/foo/4}}} when running the test on 10.6 or
 later.

 This explains why it failed to get added to the archive.

 But why did a "4 -> 4" symbolic link get created by the build in the first
 place?

 It would seem to have limited utility and I'm a bit surprised it doesn't
 actually cause more problems than it does.

 The next part of the bug has to do with building qt4-mac in {{{-debug-and-
 release}}} mode on a machine with more than one cpu core.

 Because of the situation described in ticket #34518, all qt4-mac builds
 actually end up building a {{{-debug-and-release}}} build regardless
 of selected or default variants.

 On a two-core machine, the qt4-mac make command will be invoked using
 {{{-j2}}}.  When in {{{-debug-and-release}}} mode (or explicitly building
 the {{{all}}} target -- see #34518),
 make ends up kicking off simultaneous sub-makes of {{{Makefile.Release}}}
 and {{{Makefile.Debug}}}.

 They both contain commands for the target framework that look like this:

 {{{
 DEL_FILE      = rm -f

 [...]
         -$(DEL_FILE) ../../lib/QtMultimedia.framework/Versions/Current
         -ln -s 4 ../../lib/QtMultimedia.framework/Versions/Current
 }}}

 And both of the makefiles have the same working directory, so it's the
 same link being created.

 So what is the chance that the two parallel sub-makes will run each of
 their {{{rm -f}}} commands to completion before either one runs the {{{ln
 -s}}} command?

 Quite something actually.

 This is the race condition and far from being unlikely, when building the
 src/multimedia directory on a multi-core cpu it seems to happen quite
 easily.

 Unfortunately executing the same {{{ln -s}}} command twice in a row in
 this case (without the immediately preceding {{{rm -f}}}) produces the
 bizarre "4 -> 4" symbolic link.

 If, however, the machine is being used for other things during the build,
 the race condition can be disturbed just enough to avoid creating the
 poisonous symbolic link which ultimately allows the activation step to
 succeed.

 == Patch ==

 Adding the following to the existing {{{post-patch}}} section of the
 [http://svn.macports.org/repository/macports/trunk/dports/aqua/qt4-mac/Portfile
 qt4-mac Portfile] eliminates the problem:

 {{{
     reinplace "s/ln -s/ln -fns/"
 ${worksrcpath}/qmake/generators/unix/unixmake2.cpp
 }}}

 With this patch, even if the race condition occurs, the second {{{ln
 -fns}}} command will end up replacing the first symbolic link (with the
 same link) rather than creating the deadly "4 -> 4" symbolic link.

 == Summary ==

 Due to a rather nasty and unlikely combination of failures (enforced
 -debug-and-release build, parallel make race condition, missing -fn
 options on ln -s, operating system bug in cp -R, MacPorts bug allowing
 +CONTENTS to differ from the actual archive contents/continuing despite
 the archiving permissions error), installing the qt4-mac +framework port
 can sometimes fail unpredictably at times during the activation step.

 The fix in ticket #34518 will prevent this problem for qt4-mac in the
 default case (the {{{+debug}}} variant would then have to be added to
 cause it), but the patch is simple and will allow the full {{{-debug-and-
 release}}} aka {{{+debug}}} variant to install reliably.

 All the detail has been provided in case it's helpful resolving similar
 issues in other ports.

-- 
Ticket URL: <https://trac.macports.org/ticket/34524>
MacPorts <http://www.macports.org/>
Ports system for Mac OS


More information about the macports-tickets mailing list