Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/macdeployqt/shared/shared.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5151
    5252bool runStripEnabled = true;
     53
    5354
    5455using std::cout;
     
    6263QDebug operator<<(QDebug debug, const FrameworkInfo &info)
    6364{
     65
    6466    debug << "Framework directory" << info.frameworkDirectory << "\n";
    65     debug << "Framework name" << info.frameworkName << "\n";
    6667    debug << "Framework path" << info.frameworkPath << "\n";
    6768    debug << "Binary directory" << info.binaryDirectory << "\n";
     
    7273    debug << "Deployed install name" << info.deployedInstallName << "\n";
    7374    debug << "Source file Path" << info.sourceFilePath << "\n";
    74     debug << "Deployed Directtory (relative to bundle)" << info.destinationDirectory << "\n";
    75    
     75    debug << "Deployed Directory (relative to bundle)" << info.destinationDirectory << "\n";
     76
    7677    return debug;
    7778}
     
    9091{
    9192    if (QFile::copy(from, to)) {
    92         qDebug() << "copied" << from << "to" << to;
     93        LogNormal() << " copied:" << from;
     94        LogNormal() << " to" << to;
    9395        return true;
    9496    } else {
    95         qDebug() << "ERROR: file copy failed from" << from << "to" << to;
     97        LogError() << "file copy failed from" << from;
     98        LogError() << " to" << to;
    9699        return false;
    97100    }
    98101}
    99102
    100 
    101 FrameworkInfo parseOtoolLibraryLine(const QString &line)
     103FrameworkInfo parseOtoolLibraryLine(const QString &line, bool useDebugLibs)
    102104{
    103105    FrameworkInfo info;
     
    106108    if (trimmed.isEmpty())
    107109        return info;
    108        
     110
    109111    // Don't deploy system libraries.
    110112    if (trimmed.startsWith("/System/Library/") ||
     
    112114        || trimmed.startsWith("@executable_path"))
    113115        return info;
    114        
     116
    115117    enum State {QtPath, FrameworkName, DylibName, Version, End};
    116118    State state = QtPath;
     
    118120    QString name;
    119121    QString qtPath;
     122
    120123
    121124    // Split the line into [Qt-path]/lib/qt[Module].framework/Versions/[Version]/
     
    123126    while (part < parts.count()) {
    124127        const QString currentPart = parts.at(part).simplified() ;
    125 //        qDebug() << "currentPart" << currentPart;
    126128        ++part;
    127129        if (currentPart == "")
     
    149151                    state = DylibName;
    150152                }
    151                
     153
    152154                --part;
    153155                continue;
    154156            }
    155157            qtPath += (currentPart + "/");
    156        
    157         } if (state == FrameworkName) { 
     158
     159        } if (state == FrameworkName) {
    158160            // remove ".framework"
    159161            name = currentPart;
     
    164166            continue;
    165167        } if (state == DylibName) {
    166             name =  currentPart.split(" (compatibility").at(0);
     168            name = currentPart.split(" (compatibility").at(0);
    167169            info.frameworkName = name;
    168             info.installName += info.frameworkName;
    169             info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName;
    170             info.binaryName = name;
    171             info.frameworkPath = info.frameworkDirectory + info.frameworkName;
     170            info.;
     171            info.ame;
     172            info.ame;
     173            info.frameworkPath = info.frameworkDirectory + info.Name;
    172174            info.sourceFilePath = info.frameworkPath;
    173175            info.destinationDirectory = bundleFrameworkDirectory + "/";
     176
     177
    174178            state = End;
    175179            ++part;
     
    177181        } else if (state == Version) {
    178182            info.version = currentPart;
    179             info.binaryDirectory = "Versions/" + info.version; 
    180             info.binaryName = name;
     183            info.binaryDirectory = "Versions/" + info.version;
     184            info.binaryName = name;
    181185            info.binaryPath = "/" + info.binaryDirectory + "/" + info.binaryName;
    182             info.installName += info.frameworkName + info.binaryPath;
     186            info.installName += info.frameworkName + ;
    183187            info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName + info.binaryPath;
    184188            info.frameworkPath = info.frameworkDirectory + info.frameworkName;
    185189            info.sourceFilePath = info.frameworkPath + info.binaryPath;
    186190            info.destinationDirectory = bundleFrameworkDirectory + "/" + info.frameworkName + "/" + info.binaryDirectory;
    187 
    188191            state = End;
    189192        } else if (state == End) {
     
    199202    QString appName = QFileInfo(appBundlePath).completeBaseName();
    200203    QString binaryPath = appBundlePath  + "/Contents/MacOS/" + appName;
    201    
     204
    202205    if (QFile::exists(binaryPath))
    203206        return binaryPath;
    204     qDebug() << "Error: Could not find bundle binary for" << appBundlePath;
     207    Could not find bundle binary for" << appBundlePath;
    205208    return QString();
    206209}
    207210
    208 QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines)
    209 {
    210     QList<FrameworkInfo> libraries; 
     211QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines)
     212{
     213    QList<FrameworkInfo> libraries;
    211214    foreach(const QString line, otoolLines) {
    212         FrameworkInfo info = parseOtoolLibraryLine(line);
     215        FrameworkInfo info = parseOtoolLibraryLine(line);
    213216        if (info.frameworkName.isEmpty() == false) {
     217
     218
    214219            libraries.append(info);
    215220        }
     
    218223}
    219224
    220 QList<FrameworkInfo> getQtFrameworks(const QString &path)
    221 {
     225QList<FrameworkInfo> getQtFrameworks(const QString &path, bool useDebugLibs)
     226{
     227    LogDebug() << "Using otool:";
     228    LogDebug() << " inspecting" << path;
    222229    QProcess otool;
    223230    otool.start("otool", QStringList() << "-L" << path);
    224231    otool.waitForFinished();
    225    
     232
    226233    if (otool.exitCode() != 0) {
    227         qDebug() << otool.readAllStandardError();
    228     }
    229    
     234        () << otool.readAllStandardError();
     235    }
     236
    230237    QString output = otool.readAllStandardOutput();
    231238    QStringList outputLines = output.split("\n");
     
    234241        outputLines.removeFirst(); // frameworks and dylibs lists themselves as a dependency.
    235242
    236     return getQtFrameworks(outputLines);
     243    return getQtFrameworks(outputLines);
    237244}
    238245
     
    257264QString copyFramework(const FrameworkInfo &framework, const QString path)
    258265{
    259     const QString from = framework.sourceFilePath;
    260     const QString toDir = path + "/" + framework.destinationDirectory;
    261     const QString to = toDir + "/" + framework.binaryName;
     266    QString from = framework.sourceFilePath;
     267    QString toDir = path + "/" + framework.destinationDirectory;
     268    QString to = toDir + "/" + framework.binaryName;
    262269
    263270    if (QFile::exists(from) == false) {
    264         qDebug() << "ERROR: no file at" << from;
     271        no file at" << from;
    265272        return QString();
    266273    }
     
    269276    QDir dir;
    270277    if (dir.mkpath(toDir) == false) {
    271         qDebug() << "ERROR: could not create destination directory" << to;
     278        could not create destination directory" << to;
    272279        return QString();
    273280    }
    274    
     281
    275282
    276283    if (QFile::exists(to)) {
    277 //        qDebug() << framework.frameworkName << "already deployed, skip";
    278284        return QString();
    279285    }
    280    
     286
    281287    copyFilePrintStatus(from, to);
    282288
    283     const QString resourcesSourcePath = framework.frameworkPath + "/Resources"; 
    284     const QString resourcesDestianationPath = path + "/Contents/Frameworks/" + framework.frameworkName + "/Resources"; 
     289    const QString resourcesSourcePath = framework.frameworkPath + "/Resources";
     290    const QString resourcesDestianationPath = path + "/Contents/Frameworks/" + framework.frameworkName + "/Resources";
    285291    recursiveCopy(resourcesSourcePath, resourcesDestianationPath);
    286292
     
    294300    installNametool.waitForFinished();
    295301    if (installNametool.exitCode() != 0) {
    296         qDebug() << installNametool.readAllStandardError();
    297         qDebug() << installNametool.readAllStandardOutput();
     302        () << installNametool.readAllStandardError();
     303        () << installNametool.readAllStandardOutput();
    298304    }
    299305}
     
    301307void changeIdentification(const QString &id, const QString &binaryPath)
    302308{
    303 //    qDebug() << "change identification on" << binaryPath << id;
     309    LogDebug() << "Using install_name_tool:";
     310    LogDebug() << " change identification in" << binaryPath;
     311    LogDebug() << " to" << id;
    304312    runInstallNameTool(QStringList() << "-id" << id << binaryPath);
    305313}
     
    307315void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath)
    308316{
    309 //    qDebug() << "change install name on" << binaryPath << oldName << newName;
     317    LogDebug() << "Using install_name_tool:";
     318    LogDebug() << " in" << binaryPath;
     319    LogDebug() << " change reference" << oldName;
     320    LogDebug() << " to" << newName;
    310321    runInstallNameTool(QStringList() << "-change" << oldName << newName << binaryPath);
    311322}
     
    316327        return;
    317328
     329
     330
    318331    QProcess strip;
    319332    strip.start("strip", QStringList() << "-x" << binaryPath);
    320333    strip.waitForFinished();
    321334    if (strip.exitCode() != 0) {
    322         qDebug() << strip.readAllStandardError();
    323         qDebug() << strip.readAllStandardOutput();
    324     } else {
    325         qDebug() << "stripped" << binaryPath;
     335        LogError() << strip.readAllStandardError();
     336        LogError() << strip.readAllStandardOutput();
    326337    }
    327338}
     
    334345    a list of actually deployed frameworks.
    335346*/
    336 DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString &bundlePath, const QString &binaryPath)
    337 {
     347DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
     348        const QString &bundlePath, const QString &binaryPath, bool useDebugLibs)
     349{
     350    LogNormal();
     351    LogNormal() << "Deploying Qt frameworks found inside:" << binaryPath;
    338352    QStringList copiedFrameworks;
    339353    DeploymentInfo deploymenInfo;
    340    
     354
    341355    while (frameworks.isEmpty() == false) {
    342356        const FrameworkInfo framework = frameworks.takeFirst();
    343357        copiedFrameworks.append(framework.frameworkName);
    344        
     358
    345359        // Get the qt path from one of the Qt frameworks;
    346         if (deploymenInfo.qtPath == QString() && framework.frameworkName.contains("Qt")
     360        if (deploymenInfo.qtPath() && framework.frameworkName.contains("Qt")
    347361            && framework.frameworkDirectory.contains("/lib"))
    348362        {
     
    351365        }
    352366
    353 //        qDebug() << "";
    354 //        qDebug() << "deploy" << framework.frameworkName;
    355 
    356367        if (framework.installName.startsWith("/@executable_path/")) {
    357             qDebug()  << framework.frameworkName << "already deployed, skipping.";
     368            ()  << framework.frameworkName << "already deployed, skipping.";
    358369            continue;
    359370        }
    360        
     371
    361372        // Install_name_tool the new id into the binary
    362373        changeInstallName(framework.installName, framework.deployedInstallName, binaryPath);
     
    365376        const QString deployedBinaryPath = copyFramework(framework, bundlePath);
    366377        // Skip the rest if already was deployed.
    367         if (deployedBinaryPath == QString())
     378        if (deployedBinaryPath())
    368379            continue;
    369        
     380
    370381        runStrip(deployedBinaryPath);
    371382
     
    373384        changeIdentification(framework.deployedInstallName, deployedBinaryPath);
    374385        // Check for framework dependencies
    375         QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath);
     386        QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath);
    376387
    377388        foreach (FrameworkInfo dependency, dependencies) {
    378 //            qDebug() << "dependent framework" << dependency.installName << deployedBinaryPath;
    379389            changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath);
    380            
     390
    381391            // Deploy framework if neccesary.
    382392            if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) {
     
    389399}
    390400
    391 DeploymentInfo deployQtFrameworks(const QString &appBundlePath)
     401DeploymentInfo deployQtFrameworks(const QString &appBundlePath)
    392402{
    393403   ApplicationBundleInfo applicationBundle;
    394404   applicationBundle.path = appBundlePath;
    395405   applicationBundle.binaryPath = findAppBinary(appBundlePath);
    396    return deployQtFrameworks(getQtFrameworks(applicationBundle.binaryPath), applicationBundle.path, applicationBundle.binaryPath);
    397 }
    398 
    399 void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath, const QString pluginDestinationPath, DeploymentInfo deploymentInfo)
    400 {
     406   QList<FrameworkInfo> frameworks = getQtFrameworks(applicationBundle.binaryPath, useDebugLibs);
     407   if (frameworks.isEmpty()) {
     408        LogWarning();
     409        LogWarning() << "Could not find any external Qt frameworks to deploy in" << appBundlePath;
     410        LogWarning() << "Perhaps macdeployqt was already used on" << appBundlePath << "?";
     411        LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again.";
     412        return DeploymentInfo();
     413   } else {
     414       return deployQtFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, useDebugLibs);
     415   }
     416}
     417
     418void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath,
     419        const QString pluginDestinationPath, DeploymentInfo deploymentInfo, bool useDebugLibs)
     420{
     421    LogNormal() << "Deploying plugins from" << pluginSourcePath;
    401422    QStringList plugins = QDir(pluginSourcePath).entryList(QStringList() << "*.dylib");
    402423
    403424    foreach (QString pluginName, plugins) {
    404        
    405         // Skip some Qt plugins based on what frameworks were deployed:
    406         //qDebug() << pluginSourcePath << deploymentInfo.pluginPath;
    407        
    408425        if (pluginSourcePath.contains(deploymentInfo.pluginPath)) {
    409426            QStringList deployedFrameworks = deploymentInfo.deployedFrameworks;
    410427
    411             // Skip the debug versions of the plugins
    412             if (pluginName.endsWith("_debug.dylib"))
     428            // Skip the debug versions of the plugins, unless specified otherwise.
     429            if (!useDebugLibs && pluginName.endsWith("_debug.dylib"))
     430                continue;
     431
     432            // Skip the release versions of the plugins, unless specified otherwise.
     433            if (useDebugLibs && !pluginName.endsWith("_debug.dylib"))
    413434                continue;
    414435
     
    421442            if (pluginName.contains("libqglgraphicssystem"))
    422443                continue;
    423 #endif           
     444#endif
    424445            // Deploy accessibility for Qt3Support only if the Qt3Support.framework is in use
    425446            if (deployedFrameworks.indexOf("Qt3Support.framework") == -1 && pluginName.contains("accessiblecompatwidgets"))
     
    449470        const QString destinationPath = pluginDestinationPath + "/" + pluginName;
    450471        if (copyFilePrintStatus(sourcePath, destinationPath)) {
    451        
    452         runStrip(destinationPath);
    453 
    454         // Special case for the phonon plugin: CoreVideo is not available as a separate framework
    455         // on panther, link against the QuartzCore framework instead. (QuartzCore contians CoreVideo.)
    456         if (pluginName.contains("libphonon_qt7")) {
    457             changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
    458                               "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
    459                                 destinationPath);
    460         }
    461 
    462 //        qDebug() << "deploy plugin depedencies:";
    463             QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath);
    464 //            qDebug() << frameworks;
    465             deployQtFrameworks(frameworks, appBundleInfo.path, destinationPath);
    466 //        qDebug() << "deploy plugin depedencies done";
     472
     473            runStrip(destinationPath);
     474
     475            // Special case for the phonon plugin: CoreVideo is not available as a separate framework
     476            // on panther, link against the QuartzCore framework instead. (QuartzCore contians CoreVideo.)
     477            if (pluginName.contains("libphonon_qt7")) {
     478                changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
     479                        "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
     480                        destinationPath);
     481            }
     482
     483            QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, useDebugLibs);
     484            deployQtFrameworks(frameworks, appBundleInfo.path, destinationPath, useDebugLibs);
    467485        }
    468486    } // foreach plugins
     
    470488    QStringList subdirs = QDir(pluginSourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
    471489    foreach (const QString &subdir, subdirs)
    472         deployPlugins(appBundleInfo, pluginSourcePath + "/" + subdir, pluginDestinationPath + "/" + subdir, deploymentInfo);
     490        deployPlugins(appBundleInfo, pluginSourcePath + "/" + subdir, pluginDestinationPath + "/" + subdir, deploymentInfo);
    473491}
    474492
     
    480498
    481499    QDir().mkpath(filePath);
    482    
     500
    483501    QFile qtconf(fileName);
    484502    if (qtconf.exists()) {
    485         qDebug() << "";
    486         qDebug() << "Warning:" << fileName << "already exists, will not overwrite.";
    487         qDebug() << "To make sure the plugins are loaded from the correct location,";
    488         qDebug() << "please make sure qt.conf contains the following lines:";
    489         qDebug() << contents;
    490         qDebug() << "";
     503        ;
     504        << fileName << "already exists, will not overwrite.";
     505        g() << "To make sure the plugins are loaded from the correct location,";
     506        g() << "please make sure qt.conf contains the following lines:";
     507        ;
     508        ";
    491509        return;
    492510    }
     
    494512    qtconf.open(QIODevice::WriteOnly);
    495513    if (qtconf.write(contents) != -1) {
    496         qDebug() << "";
    497         qDebug() << "Created configuration file:" << fileName;
    498         qDebug() << "This file sets the plugin search path to" << appBundlePath + "/Contents/PlugIns";
    499         qDebug() << "";
    500     }
    501 }
    502 
    503 void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo)
     514        LogNormal() << "Created configuration file:" << fileName;
     515        LogNormal() << "This file sets the plugin search path to" << appBundlePath + "/Contents/PlugIns";
     516    }
     517}
     518
     519void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs)
    504520{
    505521    ApplicationBundleInfo applicationBundle;
    506522    applicationBundle.path = appBundlePath;
    507523    applicationBundle.binaryPath = findAppBinary(appBundlePath);
    508    
     524
    509525    const QString pluginDestinationPath = appBundlePath + "/" + "Contents/PlugIns";
    510    
    511 //    qDebug() << "";
    512 //    qDebug() << "recursively copying plugins from" << deploymentInfo.pluginPath << "to" << pluginDestinationPath;
    513     deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo);
     526    deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo, useDebugLibs);
    514527}
    515528
     
    517530void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QString &appBinaryPath, const QString &absoluteQtPath)
    518531{
    519     qDebug() << "Changing" << appBinaryPath << "to link against Qt in" << absoluteQtPath;
     532    LogNormal() << "Changing" << appBinaryPath << "to link against";
     533    LogNormal() << "Qt in" << absoluteQtPath;
    520534    QString finalQtPath = absoluteQtPath;
    521535
    522     if (absoluteQtPath.startsWith("/Library/Frameworks") == false)
     536    if ()
    523537        finalQtPath += "/lib/";
    524538
     
    526540        const QString oldBinaryId = framework.installName;
    527541        const QString newBinaryId = finalQtPath + framework.frameworkName +  framework.binaryPath;
    528         qDebug() << "Changing" << oldBinaryId << "to" << newBinaryId;
    529542        changeInstallName(oldBinaryId, newBinaryId, appBinaryPath);
    530543    }
    531544}
    532545
    533 void changeQtFrameworks(const QString appPath, const QString &qtPath)
     546void changeQtFrameworks(const QString appPath, const QString &qtPath)
    534547{
    535548    const QString appBinaryPath = findAppBinary(appPath);
    536     const QList<FrameworkInfo> qtFrameworks = getQtFrameworks(appBinaryPath);
    537     const QString absoluteQtPath = QDir(qtPath).absolutePath();
    538     changeQtFrameworks(qtFrameworks, appBinaryPath, absoluteQtPath);
     549    const QList<FrameworkInfo> frameworks = getQtFrameworks(appBinaryPath, useDebugLibs);
     550    if (frameworks.isEmpty()) {
     551        LogWarning();
     552        LogWarning() << "Could not find any _external_ Qt frameworks to change in" << appPath;
     553        return;
     554    } else {
     555        const QString absoluteQtPath = QDir(qtPath).absolutePath();
     556        changeQtFrameworks(frameworks, appBinaryPath, absoluteQtPath);
     557    }
    539558}
    540559