Opened 12 years ago

Closed 12 years ago

#34524 closed defect (fixed)

qt4-mac +framework activate failure

Reported by: mackyle@… Owned by: michaelld (Michael Dickens)
Priority: Low Milestone:
Component: ports Version: 2.1.1
Keywords: activate Cc:
Port: qt4-mac

Description (last modified by ryandesign (Ryan Carsten Schmidt))

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 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.

Change History (2)

comment:1 Changed 12 years ago by ryandesign (Ryan Carsten Schmidt)

Cc: michaelld@… removed
Description: modified (diff)
Owner: changed from macports-tickets@… to michaelld@…
Summary: qt4 +framework activate failureqt4-mac +framework activate failure

comment:2 Changed 12 years ago by michaelld (Michael Dickens)

Resolution: fixed
Status: newclosed

FIxed in r94241. Please do the following

sudo port clean qt4-mac
sudo port selfupdate

and then try to install or upgrade qt4-mac again. I'm closing this ticket, since it now refers to an old version of qt4-mac. Please open a new ticket if this issue persists with the new qt4-mac.

Note: See TracTickets for help on using tickets.