[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