summaryrefslogtreecommitdiff
path: root/qmake/generators/mac
Side-by-side diff
Diffstat (limited to 'qmake/generators/mac') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/generators/mac/metrowerks_xml.cpp822
-rw-r--r--qmake/generators/mac/metrowerks_xml.h69
-rw-r--r--qmake/generators/mac/pbuilder_pbx.cpp983
-rw-r--r--qmake/generators/mac/pbuilder_pbx.h68
4 files changed, 1942 insertions, 0 deletions
diff --git a/qmake/generators/mac/metrowerks_xml.cpp b/qmake/generators/mac/metrowerks_xml.cpp
new file mode 100644
index 0000000..125749d
--- a/dev/null
+++ b/qmake/generators/mac/metrowerks_xml.cpp
@@ -0,0 +1,822 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Created : 970521
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "metrowerks_xml.h"
+#include "option.h"
+#include <qdir.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef Q_OS_MAC
+#include <Carbon/Carbon.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+
+MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE)
+{
+
+}
+
+bool
+MetrowerksMakefileGenerator::writeMakefile(QTextStream &t)
+{
+ if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
+ /* for now just dump, I need to generated an empty xml or something.. */
+ fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
+ var("QMAKE_FAILED_REQUIREMENTS").latin1());
+ return TRUE;
+ }
+
+ if(project->first("TEMPLATE") == "app" ||
+ project->first("TEMPLATE") == "lib") {
+ return writeMakeParts(t);
+ }
+ else if(project->first("TEMPLATE") == "subdirs") {
+ writeHeader(t);
+ qDebug("Not supported!");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool
+MetrowerksMakefileGenerator::writeMakeParts(QTextStream &t)
+{
+ //..grrr.. libs!
+ QStringList extra_objs;
+ bool do_libs = TRUE;
+ if(project->first("TEMPLATE") == "app")
+ extra_objs += project->variables()["QMAKE_CRT_OBJECTS"];
+ else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib"))
+ do_libs = FALSE;
+ if(do_libs)
+ extra_objs += project->variables()["QMAKE_LIBS"];
+ for(QStringList::Iterator val_it = extra_objs.begin();
+ val_it != extra_objs.end(); ++val_it) {
+ if((*val_it).startsWith("-L")) {
+ QString dir((*val_it).right((*val_it).length() - 2));
+ fixEnvVariables(dir);
+ if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
+ project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
+ project->variables()["INCLUDEPATH"].append(dir);
+ } else if((*val_it).startsWith("-l")) {
+ QString lib("lib" + (*val_it).right((*val_it).length() - 2) + "." +
+ project->first("QMAKE_EXTENSION_SHLIB"));
+ if(project->variables()["LIBRARIES"].findIndex(lib) == -1)
+ project->variables()["LIBRARIES"].append(lib);
+ } else
+ if((*val_it) == "-framework") {
+ ++val_it;
+ if(val_it == extra_objs.end())
+ break;
+ QString frmwrk = (*val_it) + ".framework";
+ if(project->variables()["FRAMEWORKS"].findIndex(frmwrk) == -1)
+ project->variables()["FRAMEWORKS"].append(frmwrk);
+ } else if((*val_it).left(1) != "-") {
+ QString lib=(*val_it);
+ int s = lib.findRev('/');
+ if(s != -1) {
+ QString dir = lib.left(s);
+ lib = lib.right(lib.length() - s - 1);
+ fixEnvVariables(dir);
+ if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
+ project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
+ project->variables()["INCLUDEPATH"].append(dir);
+ }
+ project->variables()["LIBRARIES"].append(lib);
+ }
+ }
+ //let metrowerks find the files & set the files to the type I expect
+ QDict<void> seen(293);
+ QString paths[] = { QString("SRCMOC"), QString("FORMS"), QString("UICDECLS"),
+ QString("UICIMPLS"), QString("SOURCES"),QString("HEADERS"),
+ QString::null };
+ for(int y = 0; paths[y] != QString::null; y++) {
+ QStringList &l = project->variables()[paths[y]];
+ for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
+ //establish file types
+ seen.insert((*val_it), (void *)1);
+ createFork((*val_it)); //the file itself
+ QStringList &d = findDependencies((*val_it)); //depends
+ for(QStringList::Iterator dep_it = d.begin(); dep_it != d.end(); ++dep_it) {
+ if(!seen.find((*dep_it))) {
+ seen.insert((*dep_it), (void *)1);
+ createFork((*dep_it));
+ }
+ }
+ //now chop it
+ int s = (*val_it).findRev('/');
+ if(s != -1) {
+ QString dir = (*val_it).left(s);
+ (*val_it) = (*val_it).right((*val_it).length() - s - 1);
+ QString tmpd=dir, tmpv;
+ if(fixifyToMacPath(tmpd, tmpv)) {
+ bool add_in = TRUE;
+ QString deps[] = { QString("DEPENDPATH"),
+ QString("INCLUDEPATH"), QString::null },
+ dd, dv;
+ for(int yy = 0; deps[yy] != QString::null; yy++) {
+ QStringList &l2 = project->variables()[deps[yy]];
+ for(QStringList::Iterator val_it2 = l2.begin();
+ val_it2 != l2.end(); ++val_it2) {
+ QString dd= (*val_it2), dv;
+ if(!fixifyToMacPath(dd, dv))
+ continue;
+ if(dd == tmpd && tmpv == dv) {
+ add_in = FALSE;
+ break;
+ }
+ }
+ }
+ if(add_in)
+ project->variables()["INCLUDEPATH"].append(dir);
+ }
+ }
+ }
+ }
+ //need a defines file
+ if(!project->isEmpty("DEFINES")) {
+ QString pre_pref = project->first("TARGET_STEM");
+ if(project->first("TEMPLATE") == "lib")
+ pre_pref += project->isActiveConfig("staticlib") ? "_static" : "_shared";
+ project->variables()["CODEWARRIOR_PREFIX_HEADER"].append(pre_pref + "_prefix.h");
+ }
+
+ QString xmlfile = findTemplate(project->first("QMAKE_XML_TEMPLATE"));
+ QFile file(xmlfile);
+ if(!file.open(IO_ReadOnly )) {
+ fprintf(stderr, "Cannot open XML file: %s\n",
+ project->first("QMAKE_XML_TEMPLATE").latin1());
+ return FALSE;
+ }
+ QTextStream xml(&file);
+ createFork(Option::output.name());
+
+ int rep;
+ QString line;
+ while ( !xml.eof() ) {
+ line = xml.readLine();
+ while((rep = line.find(QRegExp("\\$\\$[!a-zA-Z0-9_-]*"))) != -1) {
+ QString torep = line.mid(rep, line.find(QRegExp("[^\\$!a-zA-Z0-9_-]"), rep) - rep);
+ QString variable = torep.right(torep.length()-2);
+
+ t << line.left(rep); //output the left side
+ line = line.right(line.length() - (rep + torep.length())); //now past the variable
+ if(variable == "CODEWARRIOR_HEADERS" || variable == "CODEWARRIOR_SOURCES" ||
+ variable == "CODEWARRIOR_LIBRARIES" || variable == "CODEWARRIOR_QPREPROCESS" ||
+ variable == "CODEWARRIOR_QPREPROCESSOUT") {
+ QString outcmd=variable.right(variable.length() - variable.findRev('_') - 1);
+ QStringList args;
+ if(outcmd == "QPREPROCESS")
+ args << "UICS" << "MOCS";
+ else if(outcmd == "QPREPROCESSOUT")
+ args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
+ else
+ args << outcmd;
+ for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
+ QString arg = (*arit);
+ QString kind = "Text";
+ if(arg == "LIBRARIES")
+ kind = "Library";
+ if(!project->variables()[arg].isEmpty()) {
+ QStringList &list = project->variables()[arg];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ QString flag;
+ if(project->isActiveConfig("debug")) {
+ bool debug = TRUE;
+ if(outcmd == "QPREPROCESS") {
+ debug = FALSE;
+ } else {
+ for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) {
+ if((*it).endsWith((*hit))) {
+ debug = FALSE;
+ break;
+ }
+ }
+ }
+ if(debug)
+ flag = "Debug";
+ }
+ t << "\t\t\t\t<FILE>" << endl
+ << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
+ << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
+ << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
+ << "\t\t\t\t\t<FILEKIND>" << kind << "</FILEKIND>" << endl
+ << "\t\t\t\t\t<FILEFLAGS>" << flag << "</FILEFLAGS>" << endl
+ << "\t\t\t\t</FILE>" << endl;
+ }
+ }
+ }
+ } else if(variable == "CODEWARRIOR_SOURCES_LINKORDER" ||
+ variable == "CODEWARRIOR_HEADERS_LINKORDER" ||
+ variable == "CODEWARRIOR_LIBRARIES_LINKORDER" ||
+ variable == "CODEWARRIOR_QPREPROCESS_LINKORDER" ||
+ variable == "CODEWARRIOR_QPREPROCESSOUT_LINKORDER") {
+ QString outcmd=variable.mid(variable.find('_')+1,
+ variable.findRev('_')-(variable.find('_')+1));
+ QStringList args;
+ if(outcmd == "QPREPROCESS")
+ args << "UICS" << "MOCS";
+ else if(outcmd == "QPREPROCESSOUT")
+ args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
+ else
+ args << outcmd;
+ for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
+ QString arg = (*arit);
+ if(!project->variables()[arg].isEmpty()) {
+ QStringList &list = project->variables()[arg];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ t << "\t\t\t\t<FILEREF>" << endl
+ << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
+ << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
+ << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
+ << "\t\t\t\t</FILEREF>" << endl;
+ }
+ }
+ }
+ } else if(variable == "CODEWARRIOR_HEADERS_GROUP" ||
+ variable == "CODEWARRIOR_SOURCES_GROUP" ||
+ variable == "CODEWARRIOR_LIBRARIES_GROUP" ||
+ variable == "CODEWARRIOR_QPREPROCESS_GROUP" ||
+ variable == "CODEWARRIOR_QPREPROCESSOUT_GROUP") {
+ QString outcmd = variable.mid(variable.find('_')+1,
+ variable.findRev('_')-(variable.find('_')+1));
+ QStringList args;
+ if(outcmd == "QPREPROCESS")
+ args << "UICS" << "MOCS";
+ else if(outcmd == "QPREPROCESSOUT")
+ args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
+ else
+ args << outcmd;
+ for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
+ QString arg = (*arit);
+ if(!project->variables()[arg].isEmpty()) {
+ QStringList &list = project->variables()[arg];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ t << "\t\t\t\t<FILEREF>" << endl
+ << "\t\t\t\t\t<TARGETNAME>" << var("TARGET_STEM") << "</TARGETNAME>"
+ << endl
+ << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
+ << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
+ << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
+ << "\t\t\t\t</FILEREF>" << endl;
+ }
+ }
+ }
+ } else if(variable == "CODEWARRIOR_FRAMEWORKS") {
+ if(!project->isEmpty("FRAMEWORKS")) {
+ QStringList &list = project->variables()["FRAMEWORKS"];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ t << "\t\t\t\t<FRAMEWORK>" << endl
+ << "\t\t\t\t\t<FILEREF>" << endl
+ << "\t\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
+ << "\t\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
+ << "\t\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
+ << "\t\t\t\t\t</FILEREF>" << endl
+ << "\t\t\t\t</FRAMEWORK>" << endl;
+ }
+ }
+ } else if(variable == "CODEWARRIOR_DEPENDPATH" || variable == "CODEWARRIOR_INCLUDEPATH" ||
+ variable == "CODEWARRIOR_FRAMEWORKPATH") {
+ QString arg=variable.right(variable.length()-variable.find('_')-1);
+ QStringList list;
+ if(arg == "INCLUDEPATH") {
+ list = project->variables()[arg];
+ list << Option::mkfile::qmakespec;
+ list << QDir::current().currentDirPath();
+
+ QStringList &l = project->variables()["QMAKE_LIBS_PATH"];
+ for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
+ QString p = (*val_it), v;
+ if(!fixifyToMacPath(p, v))
+ continue;
+
+ t << "\t\t\t\t\t<SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
+ << "<VALUE>" << p << "</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t</SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t</SETTING>" << endl;
+ }
+ } else if(variable == "DEPENDPATH") {
+ QStringList &l = project->variables()[arg];
+ for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it)
+ {
+ //apparently tmake used colon separation...
+ QStringList damn = QStringList::split(':', (*val_it));
+ if(!damn.isEmpty())
+ list += damn;
+ else
+ list.append((*val_it));
+ }
+ } else {
+ list = project->variables()[arg];
+ }
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ QString p = (*it), v, recursive = "false", framework = "false";
+ if(p.startsWith("recursive--")) {
+ p = p.right(p.length() - 11);
+ recursive = "true";
+ }
+ if(!fixifyToMacPath(p, v))
+ continue;
+ if(arg == "FRAMEWORKPATH")
+ framework = "true";
+
+ t << "\t\t\t\t\t<SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
+ << "<VALUE>" << p << "</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << v << "</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t</SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>" << recursive << "</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>FrameworkPath</NAME><VALUE>" << framework << "</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
+ << "\t\t\t\t\t</SETTING>" << endl;
+ }
+ } else if(variable == "CODEWARRIOR_WARNING" || variable == "!CODEWARRIOR_WARNING") {
+ bool b = ((!project->isActiveConfig("warn_off")) &&
+ project->isActiveConfig("warn_on"));
+ if(variable.startsWith("!"))
+ b = !b;
+ t << (int)b;
+ } else if(variable == "CODEWARRIOR_TEMPLATE") {
+ if(project->first("TEMPLATE") == "app" ) {
+ t << "Executable";
+ } else if(project->first("TEMPLATE") == "lib") {
+ if(project->isActiveConfig("staticlib"))
+ t << "Library";
+ else
+ t << "SharedLibrary";
+ }
+ } else if(variable == "CODEWARRIOR_OUTPUT_DIR") {
+ QString outdir = "{Project}/", volume;
+ if(!project->isEmpty("DESTDIR"))
+ outdir = project->first("DESTDIR");
+ if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console"))
+ outdir += var("TARGET") + ".app/Contents/MacOS/";
+ if(fixifyToMacPath(outdir, volume, FALSE)) {
+ t << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir << "</VALUE></SETTING>"
+ << endl
+ << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
+ << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume << "</VALUE></SETTING>"
+ << endl;
+ }
+ } else if(variable == "CODEWARRIOR_PACKAGER_PANEL") {
+ if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console")) {
+ QString outdir = "{Project}/", volume;
+ if(!project->isEmpty("DESTDIR"))
+ outdir = project->first("DESTDIR");
+ outdir += var("TARGET") + ".app";
+ if(fixifyToMacPath(outdir, volume, FALSE)) {
+ t << "\t\t<SETTING><NAME>MWMacOSPackager_UsePackager</NAME>"
+ << "<VALUE>1</VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_FolderToPackage</NAME>" << "\n"
+ << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir
+ << "</VALUE></SETTING>" << "\n"
+ << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>"
+ << "\n"
+ << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume
+ << "</VALUE></SETTING>" << "\n"
+ << "\t\t</SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_CreateClassicAlias</NAME>"
+ << "<VALUE>0</VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasMethod</NAME>"
+ << "<VALUE>UseTargetOutput</VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasPath</NAME>"
+ << "<VALUE></VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_CreatePkgInfo</NAME>"
+ << "<VALUE>1</VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_PkgCreatorType</NAME>"
+ << "<VALUE>CUTE</VALUE></SETTING>" << "\n"
+ << "\t\t<SETTING><NAME>MWMacOSPackager_PkgFileType</NAME>"
+ << "<VALUE>APPL</VALUE></SETTING>" << endl;
+ }
+ }
+ } else if(variable == "CODEWARRIOR_FILETYPE") {
+ if(project->first("TEMPLATE") == "lib")
+ t << "MYDL";
+ else
+ t << "MEXE";
+ } else if(variable == "CODEWARRIOR_QTDIR") {
+ t << getenv("QTDIR");
+ } else if(variable == "CODEWARRIOR_CACHEMODDATES") {
+ t << "true";
+ } else {
+ t << var(variable);
+ }
+ }
+ t << line << endl;
+ }
+ t << endl;
+ file.close();
+
+ if(mocAware()) {
+ QString mocs = project->first("MOCS");
+ QFile mocfile(mocs);
+ if(!mocfile.open(IO_WriteOnly)) {
+ fprintf(stderr, "Cannot open MOCS file: %s\n", mocs.latin1());
+ } else {
+ createFork(mocs);
+ QTextStream mocs(&mocfile);
+ QStringList &list = project->variables()["SRCMOC"];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ QString src = findMocSource((*it));
+ if(src.findRev('/') != -1)
+ src = src.right(src.length() - src.findRev('/') - 1);
+ mocs << src << endl;
+ }
+ mocfile.close();
+ }
+ }
+
+ if(!project->isEmpty("FORMS")) {
+ QString uics = project->first("UICS");
+ QFile uicfile(uics);
+ if(!uicfile.open(IO_WriteOnly)) {
+ fprintf(stderr, "Cannot open UICS file: %s\n", uics.latin1());
+ } else {
+ createFork(uics);
+ QTextStream uics(&uicfile);
+ QStringList &list = project->variables()["FORMS"];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ QString ui = (*it);
+ if(ui.findRev('/') != -1)
+ ui = ui.right(ui.length() - ui.findRev('/') - 1);
+ uics << ui << endl;
+ }
+ uicfile.close();
+ }
+ }
+
+ if(!project->isEmpty("CODEWARRIOR_PREFIX_HEADER")) {
+ QFile prefixfile(project->first("CODEWARRIOR_PREFIX_HEADER"));
+ if(!prefixfile.open(IO_WriteOnly)) {
+ fprintf(stderr, "Cannot open PREFIX file: %s\n", prefixfile.name().latin1());
+ } else {
+ createFork(project->first("CODEWARRIOR_PREFIX_HEADER"));
+ QTextStream prefix(&prefixfile);
+ QStringList &list = project->variables()["DEFINES"];
+ for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
+ if((*it).find('=') != -1) {
+ int x = (*it).find('=');
+ prefix << "#define " << (*it).left(x) << " " << (*it).right((*it).length() - x - 1) << endl;
+ } else {
+ prefix << "#define " << (*it) << endl;
+ }
+ }
+ prefixfile.close();
+ }
+ }
+ return TRUE;
+}
+
+
+
+void
+MetrowerksMakefileGenerator::init()
+{
+ if(init_flag)
+ return;
+ init_flag = TRUE;
+
+ if ( project->isEmpty("QMAKE_XML_TEMPLATE") )
+ project->variables()["QMAKE_XML_TEMPLATE"].append("mwerkstmpl.xml");
+
+ QStringList &configs = project->variables()["CONFIG"];
+ if(project->isActiveConfig("qt")) {
+ if(configs.findIndex("moc")) configs.append("moc");
+ if ( !( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
+ (project->first("TARGET") == "qt-mt") ) )
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
+ if(configs.findIndex("moc"))
+ configs.append("moc");
+ if ( !project->isActiveConfig("debug") )
+ project->variables()["DEFINES"].append("QT_NO_DEBUG");
+ }
+
+ //version handling
+ if(project->variables()["VERSION"].isEmpty())
+ project->variables()["VERSION"].append("1.0." +
+ (project->isEmpty("VER_PAT") ? QString("0") :
+ project->first("VER_PAT")) );
+ QStringList ver = QStringList::split('.', project->first("VERSION"));
+ ver << "0" << "0"; //make sure there are three
+ project->variables()["VER_MAJ"].append(ver[0]);
+ project->variables()["VER_MIN"].append(ver[1]);
+ project->variables()["VER_PAT"].append(ver[2]);
+
+ if( !project->isEmpty("LIBS") )
+ project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
+ if( project->variables()["QMAKE_EXTENSION_SHLIB"].isEmpty() )
+ project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dylib" );
+
+ if ( project->isActiveConfig("moc") ) {
+ QString mocfile = project->first("TARGET");
+ if(project->first("TEMPLATE") == "lib")
+ mocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
+ project->variables()["MOCS"].append(mocfile + ".mocs");
+ setMocAware(TRUE);
+ }
+ if(!project->isEmpty("FORMS")) {
+ QString uicfile = project->first("TARGET");
+ if(project->first("TEMPLATE") == "lib")
+ uicfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
+ project->variables()["UICS"].append(uicfile + ".uics");
+ }
+ if(project->isEmpty("DESTDIR"))
+ project->variables()["DESTDIR"].append(QDir::currentDirPath());
+ MakefileGenerator::init();
+
+ if ( project->isActiveConfig("opengl") ) {
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
+ if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
+ (project->first("TARGET") == "qt-mt") )
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
+ else
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
+ }
+
+ if(project->isActiveConfig("qt"))
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
+ if(project->isEmpty("FRAMEWORKPATH"))
+ project->variables()["FRAMEWORKPATH"].append("/System/Library/Frameworks/");
+
+ //set the target up
+ project->variables()["TARGET_STEM"] = project->variables()["TARGET"];
+ if(project->first("TEMPLATE") == "lib") {
+ if(project->isActiveConfig("staticlib"))
+ project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + ".lib";
+ else
+ project->variables()["TARGET"].first() = "lib" + project->first("TARGET") + "." +
+ project->first("QMAKE_EXTENSION_SHLIB");
+
+ project->variables()["CODEWARRIOR_VERSION"].append(project->first("VER_MAJ") +
+ project->first("VER_MIN") +
+ project->first("VER_PAT"));
+ } else {
+ project->variables()["CODEWARRIOR_VERSION"].append("0");
+ if(project->isEmpty("QMAKE_ENTRYPOINT"))
+ project->variables()["QMAKE_ENTRYPOINT"].append("start");
+ project->variables()["CODEWARRIOR_ENTRYPOINT"].append(
+ project->first("QMAKE_ENTRYPOINT"));
+ }
+}
+
+
+QString
+MetrowerksMakefileGenerator::findTemplate(QString file)
+{
+ QString ret;
+ if(!QFile::exists(ret = file) &&
+ !QFile::exists((ret = Option::mkfile::qmakespec + QDir::separator() + file)) &&
+ !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/mac-mwerks/" + file)) &&
+ !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
+ return "";
+ return ret;
+}
+
+bool
+MetrowerksMakefileGenerator::createFork(const QString &f)
+{
+#if defined(Q_OS_MACX)
+ FSRef fref;
+ FSSpec fileSpec;
+ if(QFile::exists(f)) {
+ mode_t perms = 0;
+ {
+ struct stat s;
+ stat(f.latin1(), &s);
+ if(!(s.st_mode & S_IWUSR)) {
+ perms = s.st_mode;
+ chmod(f.latin1(), perms | S_IWUSR);
+ }
+ }
+ FILE *o = fopen(f.latin1(), "a");
+ if(!o)
+ return FALSE;
+ if(FSPathMakeRef((const UInt8 *)f.latin1(), &fref, NULL) == noErr) {
+ if(FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL) == noErr)
+ FSpCreateResFile(&fileSpec, 'CUTE', 'TEXT', smSystemScript);
+ else
+ qDebug("bogus %d", __LINE__);
+ } else
+ qDebug("bogus %d", __LINE__);
+ fclose(o);
+ if(perms)
+ chmod(f.latin1(), perms);
+ }
+#else
+ Q_UNUSED(f)
+#endif
+ return TRUE;
+}
+
+bool
+MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool )
+{
+ v = "Absolute";
+ if(p.find(':') != -1) //guess its macish already
+ return TRUE;
+
+ static QString st_volume;
+ if(st_volume.isEmpty()) {
+ st_volume = var("QMAKE_VOLUMENAME");
+#ifdef Q_OS_MAC
+ if(st_volume.isEmpty()) {
+ uchar foo[512];
+ HVolumeParam pb;
+ memset(&pb, '\0', sizeof(pb));
+ pb.ioVRefNum = 0;
+ pb.ioNamePtr = foo;
+ if(PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr) {
+ int len = foo[0];
+ memcpy(foo,foo+1, len);
+ foo[len] = '\0';
+ st_volume = (char *)foo;
+ }
+ }
+#endif
+ }
+ QString volume = st_volume;
+
+ fixEnvVariables(p);
+ if(p.startsWith("\"") && p.endsWith("\""))
+ p = p.mid(1, p.length() - 2);
+ if(p.isEmpty())
+ return FALSE;
+ if(!p.endsWith("/"))
+ p += "/";
+ if(QDir::isRelativePath(p)) {
+ if(p.startsWith("{")) {
+ int eoc = p.find('}');
+ if(eoc == -1)
+ return FALSE;
+ volume = p.mid(1, eoc - 1);
+ p = p.right(p.length() - eoc - 1);
+ } else {
+ QFileInfo fi(p);
+ if(fi.convertToAbs()) //strange
+ return FALSE;
+ p = fi.filePath();
+ }
+ }
+ p = QDir::cleanDirPath(p);
+ if(!volume.isEmpty())
+ v = volume;
+ p.replace("/", ":");
+ if(p.right(1) != ":")
+ p += ':';
+ return TRUE;
+}
+
+void
+MetrowerksMakefileGenerator::processPrlFiles()
+{
+ QPtrList<MakefileDependDir> libdirs;
+ libdirs.setAutoDelete(TRUE);
+ const QString lflags[] = { "QMAKE_LIBS", QString::null };
+ for(int i = 0; !lflags[i].isNull(); i++) {
+ for(bool ret = FALSE; TRUE; ret = FALSE) {
+ QStringList l_out;
+ QStringList &l = project->variables()[lflags[i]];
+ for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
+ QString opt = (*it);
+ if(opt.startsWith("-")) {
+ if(opt.startsWith("-L")) {
+ QString r = opt.right(opt.length() - 2), l = r;
+ fixEnvVariables(l);
+ libdirs.append(new MakefileDependDir(r.replace( "\"", ""),
+ l.replace( "\"", "")));
+ } else if(opt.left(2) == "-l") {
+ QString lib = opt.right(opt.length() - 2), prl;
+ for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
+ prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext;
+ if(processPrlFile(prl)) {
+ if(prl.startsWith(mdd->local_dir))
+ prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
+ QRegExp reg("^.*lib(" + lib + "[^.]*)\\." +
+ project->first("QMAKE_EXTENSION_SHLIB") + "$");
+ if(reg.exactMatch(prl))
+ prl = "-l" + reg.cap(1);
+ opt = prl;
+ ret = TRUE;
+ break;
+ }
+ }
+ } else if(opt == "-framework") {
+ l_out.append(opt);
+ ++it;
+ opt = (*it);
+ QString prl = "/System/Library/Frameworks/" + opt +
+ ".framework/" + opt + Option::prl_ext;
+ if(processPrlFile(prl))
+ ret = TRUE;
+ }
+ if(!opt.isEmpty())
+ l_out.append(opt);
+ } else {
+ if(processPrlFile(opt))
+ ret = TRUE;
+ if(!opt.isEmpty())
+ l_out.append(opt);
+ }
+ }
+ if(ret)
+ l = l_out;
+ else
+ break;
+ }
+ }
+}
+
+void
+MetrowerksMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
+{
+ if(var == "QMAKE_PRL_LIBS") {
+ QStringList &out = project->variables()["QMAKE_LIBS"];
+ for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
+ bool append = TRUE;
+ if((*it).startsWith("-")) {
+ if((*it).startsWith("-l") || (*it).startsWith("-L")) {
+ append = out.findIndex((*it)) == -1;
+ } else if((*it).startsWith("-framework")) {
+ ++it;
+ for(QStringList::ConstIterator outit = out.begin();
+ outit != out.end(); ++it) {
+ if((*outit) == "-framework") {
+ ++outit;
+ if((*outit) == (*it)) {
+ append = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ } else if(QFile::exists((*it))) {
+ append = out.findIndex((*it));
+ }
+ if(append)
+ out.append((*it));
+ }
+ } else {
+ MakefileGenerator::processPrlVariable(var, l);
+ }
+}
+
+
+bool
+MetrowerksMakefileGenerator::openOutput(QFile &file) const
+{
+ QString outdir;
+ if(!file.name().isEmpty()) {
+ QFileInfo fi(file);
+ if(fi.isDir())
+ outdir = file.name() + QDir::separator();
+ }
+ if(!outdir.isEmpty() || file.name().isEmpty())
+ file.setName(outdir + project->first("TARGET") + ".xml");
+ return MakefileGenerator::openOutput(file);
+}
diff --git a/qmake/generators/mac/metrowerks_xml.h b/qmake/generators/mac/metrowerks_xml.h
new file mode 100644
index 0000000..ae3cfae
--- a/dev/null
+++ b/qmake/generators/mac/metrowerks_xml.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Created : 970521
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __METROWERKSMAKE_H__
+#define __METROWERKSMAKE_H__
+
+#include "makefile.h"
+
+class MetrowerksMakefileGenerator : public MakefileGenerator
+{
+ bool createFork(const QString &f);
+ bool fixifyToMacPath(QString &c, QString &v, bool exists=TRUE);
+
+ bool init_flag;
+
+ bool writeMakeParts(QTextStream &);
+ bool writeSubDirs(QTextStream &);
+
+ bool writeMakefile(QTextStream &);
+ QString findTemplate(QString file);
+ void init();
+public:
+ MetrowerksMakefileGenerator(QMakeProject *p);
+ ~MetrowerksMakefileGenerator();
+
+ bool openOutput(QFile &file) const;
+protected:
+ virtual void processPrlFiles();
+ virtual void processPrlVariable(const QString &var, const QStringList &l);
+ virtual bool doDepends() const { return FALSE; } //never necesary
+};
+
+inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator()
+{ }
+
+#endif /* __METROWERKSMAKE_H__ */
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp
new file mode 100644
index 0000000..8525058
--- a/dev/null
+++ b/qmake/generators/mac/pbuilder_pbx.cpp
@@ -0,0 +1,983 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Created : 970521
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "pbuilder_pbx.h"
+#include "option.h"
+#include <qdir.h>
+#include <qdict.h>
+#include <qregexp.h>
+#include <stdlib.h>
+#include <time.h>
+#ifdef Q_OS_UNIX
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+// Note: this is fairly hacky, but it does the job...
+
+
+ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(QMakeProject *p) : UnixMakefileGenerator(p)
+{
+
+}
+
+bool
+ProjectBuilderMakefileGenerator::writeMakefile(QTextStream &t)
+{
+ if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
+ /* for now just dump, I need to generated an empty xml or something.. */
+ fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
+ var("QMAKE_FAILED_REQUIREMENTS").latin1());
+ return TRUE;
+ }
+
+ project->variables()["MAKEFILE"].clear();
+ project->variables()["MAKEFILE"].append("Makefile");
+ if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") {
+ return writeMakeParts(t);
+ } else if(project->first("TEMPLATE") == "subdirs") {
+ writeSubdirs(t, FALSE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool
+ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
+{
+ int i;
+ QStringList tmp;
+ bool did_preprocess = FALSE;
+
+ //HEADER
+ t << "// !$*UTF8*$!" << "\n"
+ << "{" << "\n"
+ << "\t" << "archiveVersion = 1;" << "\n"
+ << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n"
+ << "\t" << "objectVersion = " << pbuilderVersion() << ";" << "\n"
+ << "\t" << "objects = {" << endl;
+
+ //MAKE QMAKE equivlant
+ if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") {
+ QString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak";
+ QFile mkf(mkfile);
+ if(mkf.open(IO_WriteOnly | IO_Translate)) {
+ debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
+ QTextStream mkt(&mkf);
+ writeHeader(mkt);
+ mkt << "QMAKE = " <<
+ (project->isEmpty("QMAKE_QMAKE") ? QString("$(QTDIR)/bin/qmake") :
+ var("QMAKE_QMAKE")) << endl;
+ writeMakeQmake(mkt);
+ mkf.close();
+ }
+ QString phase_key = keyFor("QMAKE_PBX_MAKEQMAKE_BUILDPHASE");
+ mkfile = fileFixify(mkfile, QDir::currentDirPath());
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
+ t << "\t\t" << phase_key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
+ << "\t\t\t" << "files = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "generatedFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"Qt Qmake\";" << "\n"
+ << "\t\t\t" << "neededFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
+ << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
+ " -f " << mkfile << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+
+ //DUMP SOURCES
+ QMap<QString, QStringList> groups;
+ QString srcs[] = { "SOURCES", "SRCMOC", "UICIMPLS", QString::null };
+ for(i = 0; !srcs[i].isNull(); i++) {
+ tmp = project->variables()[srcs[i]];
+ QStringList &src_list = project->variables()["QMAKE_PBX_" + srcs[i]];
+ for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) {
+ QString file = fileFixify((*it));
+ if(file.endsWith(Option::moc_ext))
+ continue;
+ bool in_root = TRUE;
+ QString src_key = keyFor(file);
+ if(!project->isActiveConfig("flat")) {
+ QString flat_file = fileFixify(file, QDir::currentDirPath(), Option::output_dir, TRUE);
+ if(QDir::isRelativePath(flat_file) && flat_file.find(Option::dir_sep) != -1) {
+ QString last_grp("QMAKE_PBX_" + srcs[i] + "_HEIR_GROUP");
+ QStringList dirs = QStringList::split(Option::dir_sep, flat_file);
+ dirs.pop_back(); //remove the file portion as it will be added via src_key
+ for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
+ QString new_grp(last_grp + Option::dir_sep + (*dir_it)),
+ new_grp_key(keyFor(new_grp)), last_grp_key(keyFor(last_grp));
+ if(dir_it == dirs.begin()) {
+ if(!groups.contains(new_grp))
+ project->variables()["QMAKE_PBX_" + srcs[i]].append(new_grp_key);
+ } else {
+ groups[last_grp] += new_grp_key;
+ }
+ last_grp = new_grp;
+ }
+ groups[last_grp] += src_key;
+ in_root = FALSE;
+ }
+ }
+ if(in_root)
+ src_list.append(src_key);
+ //source reference
+ t << "\t\t" << src_key << " = {" << "\n"
+ << "\t\t\t" << "isa = PBXFileReference;" << "\n"
+ << "\t\t\t" << "path = \"" << file << "\";" << "\n"
+ << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ //build reference
+ QString obj_key = file + ".o";
+ obj_key = keyFor(obj_key);
+ t << "\t\t" << obj_key << " = {" << "\n"
+ << "\t\t\t" << "fileRef = " << src_key << ";" << "\n"
+ << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
+ << "\t\t\t" << "settings = {" << "\n"
+ << "\t\t\t\t" << "ATTRIBUTES = (" << "\n"
+ << "\t\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "};" << "\n"
+ << "\t\t" << "};" << "\n";
+ project->variables()["QMAKE_PBX_OBJ"].append(obj_key);
+ }
+ if(!src_list.isEmpty()) {
+ QString grp;
+ if(srcs[i] == "SOURCES") {
+ if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon
+ QString icns_file = keyFor("ICNS_FILE");
+ src_list.append(icns_file);
+ t << "\t\t" << icns_file << " = {" << "\n"
+ << "\t\t\t" << "isa = PBXFileReference;" << "\n"
+ << "\t\t\t" << "path = \"" << project->first("RC_FILE") << "\";" << "\n"
+ << "\t\t\t" << "refType = " << reftypeForFile(project->first("RC_FILE")) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ t << "\t\t" << keyFor("ICNS_FILE_REFERENCE") << " = {" << "\n"
+ << "\t\t\t" << "fileRef = " << icns_file << ";" << "\n"
+ << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
+ << "\t\t\t" << "settings = {" << "\n"
+ << "\t\t\t" << "};" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ grp = "Sources";
+ } else if(srcs[i] == "SRCMOC") {
+ grp = "Mocables";
+ } else if(srcs[i] == "UICIMPLS") {
+ grp = "UICables";
+ }
+ QString grp_key = keyFor(grp);
+ project->variables()["QMAKE_PBX_GROUPS"].append(grp_key);
+ t << "\t\t" << grp_key << " = {" << "\n"
+ << "\t\t\t" << "children = (" << "\n"
+ << varGlue("QMAKE_PBX_" + srcs[i], "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXGroup;" << "\n"
+ << "\t\t\t" << "name = " << grp << ";" << "\n"
+ << "\t\t\t" << "refType = 4;" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ }
+ for(QMap<QString, QStringList>::Iterator grp_it = groups.begin();
+ grp_it != groups.end(); ++grp_it) {
+ t << "\t\t" << keyFor(grp_it.key()) << " = {" << "\n"
+ << "\t\t\t" << "isa = PBXGroup;" << "\n"
+ << "\t\t\t" << "children = (" << "\n"
+ << valGlue(grp_it.data(), "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "name = \"" << grp_it.key().section(Option::dir_sep, -1) << "\";" << "\n"
+ << "\t\t\t" << "refType = 4;" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+
+ //PREPROCESS BUILDPHASE (just a makefile)
+ if(!project->isEmpty("UICIMPLS") || !project->isEmpty("SRCMOC") ||
+ !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) {
+ QString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak";
+ QFile mkf(mkfile);
+ if(mkf.open(IO_WriteOnly | IO_Translate)) {
+ did_preprocess = TRUE;
+ debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
+ QTextStream mkt(&mkf);
+ writeHeader(mkt);
+ mkt << "MOC = " << var("QMAKE_MOC") << endl;
+ mkt << "UIC = " << var("QMAKE_UIC") << endl;
+ mkt << "LEX = " << var("QMAKE_LEX") << endl;
+ mkt << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
+ mkt << "YACC = " << var("QMAKE_YACC") << endl;
+ mkt << "YACCFLAGS = " << var("QMAKE_YACCFLAGS") << endl;
+ mkt << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
+ mkt << "MOVE = " << var("QMAKE_MOVE") << endl << endl;
+ mkt << "FORMS = " << varList("UICIMPLS") << endl;
+ mkt << "MOCS = " << varList("SRCMOC") << endl;
+ mkt << "PARSERS =";
+ if(!project->isEmpty("YACCSOURCES")) {
+ QStringList &yaccs = project->variables()["YACCSOURCES"];
+ for(QStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) {
+ QFileInfo fi((*yit));
+ mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
+ << Option::yacc_mod << Option::cpp_ext.first();
+ }
+ }
+ if(!project->isEmpty("LEXSOURCES")) {
+ QStringList &lexs = project->variables()["LEXSOURCES"];
+ for(QStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) {
+ QFileInfo fi((*lit));
+ mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE)
+ << Option::lex_mod << Option::cpp_ext.first();
+ }
+ }
+ mkt << "\n";
+ mkt << "preprocess: $(FORMS) $(MOCS) $(PARSERS)" << endl;
+ mkt << "preprocess_clean: mocclean uiclean parser_clean" << endl << endl;
+ mkt << "mocclean:" << "\n";
+ if(!project->isEmpty("SRCMOC"))
+ mkt << "\t-rm -f $(MOCS)" << "\n";
+ mkt << "uiclean:" << "\n";
+ if(!project->isEmpty("UICIMPLS"))
+ mkt << "\t-rm -f $(FORMS)" << "\n";
+ mkt << "parser_clean:" << "\n";
+ if(!project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES"))
+ mkt << "\t-rm -f $(PARSERS)" << "\n";
+ writeUicSrc(mkt, "FORMS");
+ writeMocSrc(mkt, "HEADERS");
+ writeMocSrc(mkt, "SOURCES");
+ writeMocSrc(mkt, "UICDECLS");
+ writeYaccSrc(mkt, "YACCSOURCES");
+ writeLexSrc(mkt, "LEXSOURCES");
+ mkf.close();
+ }
+ QString target_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET");
+ mkfile = fileFixify(mkfile, QDir::currentDirPath());
+ t << "\t\t" << target_key << " = {" << "\n"
+ << "\t\t\t" << "buildArgumentsString = \"-f " << mkfile << "\";" << "\n"
+ << "\t\t\t" << "buildPhases = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "buildSettings = {" << "\n"
+ << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << "buildToolPath = \"/usr/bin/gnumake\";"<< "\n"
+ << "\t\t\t" << "buildWorkingDirectory = \"" << QDir::currentDirPath() << "\";" << "\n"
+ << "\t\t\t" << "dependencies = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXLegacyTarget;" << "\n"
+ << "\t\t\t" << "name = QtPreprocessors;" << "\n"
+ << "\t\t\t" << "productName = QtPreprocessors;" << "\n"
+ << "\t\t\t" << "settingsToExpand = 6;" << "\n"
+ << "\t\t\t" << "settingsToPassInEnvironment = 287;" << "\n"
+ << "\t\t\t" << "settingsToPassOnCommandLine = 280;" << "\n"
+ << "\t\t\t" << "shouldsUseHeadermap = 0;" << "\n"
+ << "\t\t" << "};" << "\n";
+
+ QString target_depend_key = keyFor("QMAKE_PBX_PREPROCESS_TARGET_DEPEND");
+ project->variables()["QMAKE_PBX_TARGETDEPENDS"].append(target_depend_key);
+ t << "\t\t" << target_depend_key << " = {" << "\n"
+ << "\t\t\t" << "isa = PBXTargetDependency;" << "\n"
+ << "\t\t\t" << "target = " << target_key << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ //SOURCE BUILDPHASE
+ if(!project->isEmpty("QMAKE_PBX_OBJ")) {
+ QString grp = "Build Sources", key = keyFor(grp);
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
+ << "\t\t\t" << "files = (" << "\n"
+ << varGlue("QMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXSourcesBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+
+ if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
+ QStringList &libdirs = project->variables()["QMAKE_PBX_LIBPATHS"];
+ QString libs[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
+ for(i = 0; !libs[i].isNull(); i++) {
+ tmp = project->variables()[libs[i]];
+ for(QStringList::Iterator it = tmp.begin(); it != tmp.end();) {
+ bool remove = FALSE;
+ QString library, name, opt = (*it).stripWhiteSpace();
+ if(opt.startsWith("-L")) {
+ QString r = opt.right(opt.length() - 2);
+ fixEnvVariables(r);
+ libdirs.append(r);
+ } else if(opt.startsWith("-l")) {
+ name = opt.right(opt.length() - 2);
+ QString lib("lib" + name);
+ for(QStringList::Iterator lit = libdirs.begin(); lit != libdirs.end(); ++lit) {
+ if(project->isActiveConfig("link_prl")) {
+ /* This isn't real nice, but it is real usefull. This looks in a prl
+ for what the library will ultimately be called so we can stick it
+ in the ProjectFile. If the prl format ever changes (not likely) then
+ this will not really work. However, more concerning is that it will
+ encode the version number in the Project file which might be a bad
+ things in days to come? --Sam
+ */
+ QString prl_file = (*lit) + Option::dir_sep + lib + Option::prl_ext;
+ if(QFile::exists(prl_file)) {
+ QMakeProject proj;
+ if(proj.read(prl_file, QDir::currentDirPath())) {
+ if(!proj.isEmpty("QMAKE_PRL_TARGET")) {
+ library = (*lit) + Option::dir_sep + proj.first("QMAKE_PRL_TARGET");
+ debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)",
+ opt.latin1(), prl_file.latin1(), library.latin1());
+ remove = TRUE;
+ }
+ }
+
+ }
+ }
+ if(!remove) {
+ QString extns[] = { ".dylib", ".so", ".a", QString::null };
+ for(int n = 0; !remove && !extns[n].isNull(); n++) {
+ QString tmp = (*lit) + Option::dir_sep + lib + extns[n];
+ if(QFile::exists(tmp)) {
+ library = tmp;
+ debug_msg(1, "pbuilder: Found library (%s) via %s",
+ opt.latin1(), library.latin1());
+ remove = TRUE;
+ }
+ }
+ }
+ }
+ } else if(opt == "-framework") {
+ ++it;
+ if(it == tmp.end())
+ break;
+ QStringList &fdirs = project->variables()["QMAKE_FRAMEWORKDIR"];
+ if(fdirs.isEmpty())
+ fdirs.append("/System/Library/Frameworks/");
+ for(QStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) {
+ if(QFile::exists((*fit) + QDir::separator() + (*it) + ".framework")) {
+ --it;
+ it = tmp.remove(it);
+ remove = TRUE;
+ library = (*fit) + Option::dir_sep + (*it) + ".framework";
+ break;
+ }
+ }
+ } else if(opt.left(1) != "-") {
+ remove = TRUE;
+ library = opt;
+ }
+ if(!library.isEmpty()) {
+ if(name.isEmpty()) {
+ int slsh = library.findRev(Option::dir_sep);
+ if(slsh != -1)
+ name = library.right(library.length() - slsh - 1);
+ }
+ library = fileFixify(library);
+ QString key = keyFor(library);
+ bool is_frmwrk = (library.endsWith(".framework"));
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "isa = " << (is_frmwrk ? "PBXFrameworkReference" : "PBXFileReference") << ";" << "\n"
+ << "\t\t\t" << "name = \"" << name << "\";" << "\n"
+ << "\t\t\t" << "path = \"" << library << "\";" << "\n"
+ << "\t\t\t" << "refType = " << reftypeForFile(library) << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ project->variables()["QMAKE_PBX_LIBRARIES"].append(key);
+ QString obj_key = library + ".o";
+ obj_key = keyFor(obj_key);
+ t << "\t\t" << obj_key << " = {" << "\n"
+ << "\t\t\t" << "fileRef = " << key << ";" << "\n"
+ << "\t\t\t" << "isa = PBXBuildFile;" << "\n"
+ << "\t\t\t" << "settings = {" << "\n"
+ << "\t\t\t" << "};" << "\n"
+ << "\t\t" << "};" << "\n";
+ project->variables()["QMAKE_PBX_BUILD_LIBRARIES"].append(obj_key);
+ }
+ if(remove)
+ it = tmp.remove(it);
+ else
+ ++it;
+ }
+ project->variables()[libs[i]] = tmp;
+ }
+ }
+ //SUBLIBS BUILDPHASE (just another makefile)
+ if(!project->isEmpty("SUBLIBS")) {
+ QString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak";
+ QFile mkf(mkfile);
+ if(mkf.open(IO_WriteOnly | IO_Translate)) {
+ debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1());
+ QTextStream mkt(&mkf);
+ writeHeader(mkt);
+ mkt << "SUBLIBS= ";
+ tmp = project->variables()["SUBLIBS"];
+ QStringList::Iterator it;
+ for(it = tmp.begin(); it != tmp.end(); ++it)
+ t << "tmp/lib" << (*it) << ".a ";
+ t << endl << endl;
+ mkt << "sublibs: $(SUBLIBS)" << endl << endl;
+ tmp = project->variables()["SUBLIBS"];
+ for(it = tmp.begin(); it != tmp.end(); ++it)
+ t << "tmp/lib" << (*it) << ".a" << ":\n\t"
+ << var(QString("MAKELIB") + (*it)) << endl << endl;
+ mkf.close();
+ }
+ QString phase_key = keyFor("QMAKE_PBX_SUBLIBS_BUILDPHASE");
+ mkfile = fileFixify(mkfile, QDir::currentDirPath());
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
+ t << "\t\t" << phase_key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
+ << "\t\t\t" << "files = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "generatedFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"Qt Sublibs\";" << "\n"
+ << "\t\t\t" << "neededFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
+ << "\t\t\t" << "shellScript = \"make -C " << QDir::currentDirPath() <<
+ " -f " << mkfile << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ //LIBRARY BUILDPHASE
+ if(!project->isEmpty("QMAKE_PBX_LIBRARIES")) {
+ tmp = project->variables()["QMAKE_PBX_LIBRARIES"];
+ if(!tmp.isEmpty()) {
+ QString grp("External Frameworks and Libraries"), key = keyFor(grp);
+ project->variables()["QMAKE_PBX_GROUPS"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "children = (" << "\n"
+ << varGlue("QMAKE_PBX_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXGroup;" << "\n"
+ << "\t\t\t" << "name = \"" << grp << "\"" << ";" << "\n"
+ << "\t\t\t" << "path = \"\";" << "\n"
+ << "\t\t\t" << "refType = 4;" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ }
+ {
+ QString grp("Frameworks & Libraries"), key = keyFor(grp);
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
+ << "\t\t\t" << "files = (" << "\n"
+ << varGlue("QMAKE_PBX_BUILD_LIBRARIES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXFrameworksBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console") &&
+ project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES
+ QString grp("Bundle Resources"), key = keyFor(grp);
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 2147483647;" << "\n"
+ << "\t\t\t" << "files = (" << "\n"
+ << (!project->isEmpty("RC_FILE") ? keyFor("ICNS_FILE_REFERENCE") : QString(""))
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"" << grp << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+
+ //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER
+ //PRODUCTS
+ {
+ QString grp("Products"), key = keyFor(grp);
+ project->variables()["QMAKE_PBX_GROUPS"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "children = (" << "\n"
+ << "\t\t\t\t" << keyFor("QMAKE_PBX_REFERENCE") << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXGroup;" << "\n"
+ << "\t\t\t" << "name = Products;" << "\n"
+ << "\t\t\t" << "refType = 4;" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ { //INSTALL BUILDPHASE (sh script)
+ QString targ = project->first("TARGET");
+ if(project->first("TEMPLATE") == "app" ||
+ (project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") &&
+ project->isActiveConfig("frameworklib")))
+ targ = project->first("QMAKE_ORIG_TARGET");
+ int slsh = targ.findRev(Option::dir_sep);
+ if(slsh != -1)
+ targ = targ.right(targ.length() - slsh - 1);
+ fixEnvVariables(targ);
+ QStringList links;
+ if(project->first("TEMPLATE") == "app") {
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
+ targ += ".app";
+ } else if(!project->isActiveConfig("staticlib") &&
+ !project->isActiveConfig("frameworklib")) {
+ QString li[] = { "TARGET_", "TARGET_x", "TARGET_x.y", QString::null };
+ for(int n = 0; !li[n].isNull(); n++) {
+ QString t = project->first(li[n]);
+ slsh = t.findRev(Option::dir_sep);
+ if(slsh != -1)
+ t = t.right(t.length() - slsh);
+ fixEnvVariables(t);
+ links << t;
+ }
+ }
+ QString script = pbx_dir + Option::dir_sep + "qt_install.sh";
+ QFile shf(script);
+ if(shf.open(IO_WriteOnly | IO_Translate)) {
+ debug_msg(1, "pbuilder: Creating file: %s", script.latin1());
+ QString targ = project->first("QMAKE_ORIG_TARGET"), cpflags;
+ if(project->first("TEMPLATE") == "app") {
+ targ = project->first("TARGET");
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
+ targ += ".app";
+ cpflags += "-r ";
+ }
+ } else if(!project->isActiveConfig("frameworklib")) {
+ if(project->isActiveConfig("staticlib"))
+ targ = project->first("TARGET");
+ else
+ targ = project->first("TARGET_");
+ int slsh = targ.findRev(Option::dir_sep);
+ if(slsh != -1)
+ targ = targ.right(targ.length() - slsh - 1);
+ }
+ QTextStream sht(&shf);
+ QString dstdir = project->first("DESTDIR");
+ fixEnvVariables(dstdir);
+
+ sht << "#!/bin/sh" << endl;
+ //copy the actual target
+ sht << "OUT_TARG=\"" << targ << "\"\n"
+ << "[ -z \"$BUILD_ROOT\" ] || OUT_TARG=\"${BUILD_ROOT}/${OUT_TARG}\"" << endl;
+ sht << "[ \"$OUT_TARG\" = \""
+ << (dstdir.isEmpty() ? QDir::currentDirPath() + QDir::separator(): dstdir) << targ << "\" ] || "
+ << "[ \"$OUT_TARG\" = \"" << targ << "\" ] || "
+ << "cp -r \"$OUT_TARG\" " << "\"" << dstdir << targ << "\"" << endl;
+ //rename as a framework
+ if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("frameworklib"))
+ sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << targ << "\"" << endl;
+ //create all the version symlinks (just to be like unixmake)
+ for(QStringList::Iterator it = links.begin(); it != links.end(); ++it) {
+ if(targ != (*it))
+ sht << "ln -sf \"" << targ << "\" " << "\"" << dstdir << (*it) << "\"" << endl;
+ }
+ shf.close();
+#ifdef Q_OS_UNIX
+ chmod(script.latin1(), S_IRWXU | S_IRWXG);
+#endif
+ QString phase_key = keyFor("QMAKE_PBX_INSTALL_BUILDPHASE");
+ script = fileFixify(script, QDir::currentDirPath());
+ project->variables()["QMAKE_PBX_BUILDPHASES"].append(phase_key);
+ t << "\t\t" << phase_key << " = {" << "\n"
+ << "\t\t\t" << "buildActionMask = 8;" << "\n" //only on install!
+ << "\t\t\t" << "files = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "generatedFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n"
+ << "\t\t\t" << "name = \"Qt Install\";" << "\n"
+ << "\t\t\t" << "neededFileNames = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "shellPath = /bin/sh;" << "\n"
+ << "\t\t\t" << "shellScript = \"" << script << "\";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ }
+ //ROOT_GROUP
+ t << "\t\t" << keyFor("QMAKE_PBX_ROOT_GROUP") << " = {" << "\n"
+ << "\t\t\t" << "children = (" << "\n"
+ << varGlue("QMAKE_PBX_GROUPS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXGroup;" << "\n"
+ << "\t\t\t" << "name = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n"
+ << "\t\t\t" << "path = \"\";" << "\n"
+ << "\t\t\t" << "refType = 4;" << "\n"
+ << "\t\t" << "};" << "\n";
+ //REFERENCE
+ t << "\t\t" << keyFor("QMAKE_PBX_REFERENCE") << " = {" << "\n";
+ if(project->first("TEMPLATE") == "app") {
+ QString targ = project->first("QMAKE_ORIG_TARGET");
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
+ targ += ".app";
+ t << "\t\t\t" << "isa = PBXApplicationReference;" << "\n";
+ } else {
+ t << "\t\t\t" << "isa = PBXExecutableFileReference;" << "\n";
+ }
+ QString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("QMAKE_ORIG_TARGET") :
+ QDir::currentDirPath()) + Option::dir_sep + targ;
+ t << "\t\t\t" << "name = " << targ << ";" << "\n"
+ << "\t\t\t" << "path = \"" << targ << "\";" << "\n"
+ << "\t\t\t" << "refType = " << reftypeForFile(app) << ";" << "\n";
+ } else {
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if(project->isActiveConfig("staticlib")) {
+ lib = project->first("TARGET");
+ } else if(!project->isActiveConfig("frameworklib")) {
+ if(project->isActiveConfig("plugin"))
+ lib = project->first("TARGET");
+ else
+ lib = project->first("TARGET_");
+ }
+ int slsh = lib.findRev(Option::dir_sep);
+ if(slsh != -1)
+ lib = lib.right(lib.length() - slsh - 1);
+ t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n"
+ << "\t\t\t" << "path = " << lib << ";\n"
+ << "\t\t\t" << "refType = " << reftypeForFile(lib) << ";" << "\n";
+ }
+ t << "\t\t" << "};" << "\n";
+ //TARGET
+ t << "\t\t" << keyFor("QMAKE_PBX_TARGET") << " = {" << "\n"
+ << "\t\t\t" << "buildPhases = (" << "\n"
+ << varGlue("QMAKE_PBX_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "buildSettings = {" << "\n"
+ << "\t\t\t\t" << "FRAMEWORK_SEARCH_PATHS = \"\";" << "\n"
+ << "\t\t\t\t" << "HEADER_SEARCH_PATHS = \"" << fixEnvsList("INCLUDEPATH") << " " << fixEnvs(specdir()) << "\";" << "\n"
+ << "\t\t\t\t" << "LIBRARY_SEARCH_PATHS = \"" << var("QMAKE_PBX_LIBPATHS") << "\";" << "\n"
+ << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n"
+ << "\t\t\t\t" << "OTHER_CFLAGS = \"" <<
+ fixEnvsList("QMAKE_CFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
+ varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
+ << "\t\t\t\t" << "LEXFLAGS = \"" << var("QMAKE_LEXFLAGS") << "\";" << "\n"
+ << "\t\t\t\t" << "YACCFLAGS = \"" << var("QMAKE_YACCFLAGS") << "\";" << "\n"
+ << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" <<
+ fixEnvsList("QMAKE_CXXFLAGS") << varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") <<
+ varGlue("DEFINES"," -D"," -D","") << "\";" << "\n"
+ << "\t\t\t\t" << "OTHER_REZFLAGS = \"\";" << "\n"
+ << "\t\t\t\t" << "SECTORDER_FLAGS = \"\";" << "\n"
+ << "\t\t\t\t" << "WARNING_CFLAGS = \"\";" << "\n";
+#if 1
+ t << "\t\t\t\t" << "BUILD_ROOT = \"" << QDir::currentDirPath() << "\";" << "\n";
+#endif
+ if(!project->isActiveConfig("staticlib"))
+ t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " <<
+ fixEnvsList("QMAKE_LFLAGS") << " " << fixEnvsList("QMAKE_LIBDIR_FLAGS") <<
+ " " << fixEnvsList("QMAKE_LIBS") << "\";" << "\n";
+ if(!project->isEmpty("DESTDIR"))
+ t << "\t\t\t\t" << "INSTALL_PATH = \"" << project->first("DESTDIR") << "\";" << "\n";
+ if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0")
+ t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VERSION") << "\";" << "\n";
+ if(!project->isEmpty("OBJECTS_DIR"))
+ t << "\t\t\t\t" << "OBJECT_FILE_DIR = \"" << project->first("OBJECTS_DIR") << "\";" << "\n";
+ if(project->first("TEMPLATE") == "app") {
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
+ t << "\t\t\t\t" << "WRAPPER_EXTENSION = app;" << "\n";
+ t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
+ } else {
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) {
+ t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n";
+ lib = project->first("TARGET");
+ } else {
+ t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n";
+ if(!project->isActiveConfig("frameworklib")) {
+ if(project->isActiveConfig("plugin"))
+ lib = project->first("TARGET");
+ else
+ lib = project->first("TARGET_");
+ }
+ }
+ int slsh = lib.findRev(Option::dir_sep);
+ if(slsh != -1)
+ lib = lib.right(lib.length() - slsh - 1);
+ t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n";
+ }
+ tmp = project->variables()["QMAKE_PBX_VARS"];
+ for(QStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it)
+ t << "\t\t\t\t" << (*it) << " = \"" << getenv((*it)) << "\";" << "\n";
+ t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << "conditionalBuildSettings = {" << "\n"
+ << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << "dependencies = (" << "\n"
+ << varGlue("QMAKE_PBX_TARGETDEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "productReference = " << keyFor("QMAKE_PBX_REFERENCE") << ";" << "\n"
+ << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n";
+ if(project->first("TEMPLATE") == "app") {
+ if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
+ t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n"
+ << "\t\t\t" << "productSettingsXML = " << "\"" << "<?xml version="
+ << "\\\"1.0\\\" encoding=" << "\\\"UTF-8\\\"" << "?>" << "\n"
+ << "\t\t\t\t" << "<!DOCTYPE plist SYSTEM \\\"file://localhost/System/"
+ << "Library/DTDs/PropertyList.dtd\\\">" << "\n"
+ << "\t\t\t\t" << "<plist version=\\\"0.9\\\">" << "\n"
+ << "\t\t\t\t" << "<dict>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleDevelopmentRegion</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>English</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleExecutable</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>" << project->first("QMAKE_ORIG_TARGET") << "</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleIconFile</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>" << var("RC_FILE").section(Option::dir_sep, -1) << "</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleInfoDictionaryVersion</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>6.0</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundlePackageType</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>APPL</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleSignature</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>????</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CFBundleVersion</key>" << "\n"
+ << "\t\t\t\t\t" << "<string>0.1</string>" << "\n"
+ << "\t\t\t\t\t" << "<key>CSResourcesFileMapped</key>" << "\n"
+ << "\t\t\t\t\t" << "<true/>" << "\n"
+ << "\t\t\t\t" << "</dict>" << "\n"
+ << "\t\t\t\t" << "</plist>" << "\";" << "\n";
+ } else {
+ t << "\t\t\t" << "isa = PBXToolTarget;" << "\n";
+ }
+ t << "\t\t\t" << "name = \"" << project->first("QMAKE_ORIG_TARGET") << "\";" << "\n"
+ << "\t\t\t" << "productName = " << project->first("QMAKE_ORIG_TARGET") << ";" << "\n";
+ } else {
+ QString lib = project->first("QMAKE_ORIG_TARGET");
+ if(!project->isActiveConfig("frameworklib"))
+ lib.prepend("lib");
+ t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n"
+ << "\t\t\t" << "name = \"" << lib << "\";" << "\n"
+ << "\t\t\t" << "productName = " << lib << ";" << "\n";
+ }
+ if(!project->isEmpty("DESTDIR"))
+ t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n";
+ t << "\t\t" << "};" << "\n";
+ //DEBUG/RELEASE
+ for(i = 0; i < 2; i++) {
+ bool as_release = !i;
+ if(project->isActiveConfig("debug"))
+ as_release = i;
+ QString key = "QMAKE_PBX_" + QString(as_release ? "RELEASE" : "DEBUG");
+ key = keyFor(key);
+ project->variables()["QMAKE_PBX_BUILDSTYLES"].append(key);
+ t << "\t\t" << key << " = {" << "\n"
+ << "\t\t\t" << "buildRules = (" << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "buildSettings = {" << "\n"
+ << "\t\t\t\t" << "COPY_PHASE_STRIP = " << (as_release ? "YES" : "NO") << ";" << "\n";
+ if(as_release)
+ t << "\t\t\t\t" << "DEBUGGING_SYMBOLS = NO;" << "\n";
+ t << "\t\t\t" << "};" << "\n"
+ << "\t\t\t" << "isa = PBXBuildStyle;" << "\n"
+ << "\t\t\t" << "name = " << (as_release ? "Deployment" : "Development") << ";" << "\n"
+ << "\t\t" << "};" << "\n";
+ }
+ //ROOT
+ t << "\t\t" << keyFor("QMAKE_PBX_ROOT") << " = {" << "\n"
+ << "\t\t\t" << "buildStyles = (" << "\n"
+ << varGlue("QMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n")
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t\t" << "isa = PBXProject;" << "\n"
+ << "\t\t\t" << "mainGroup = " << keyFor("QMAKE_PBX_ROOT_GROUP") << ";" << "\n"
+ << "\t\t\t" << "targets = (" << "\n"
+ << "\t\t\t\t" << keyFor("QMAKE_PBX_TARGET") << "\n"
+ << "\t\t\t" << ");" << "\n"
+ << "\t\t" << "};" << "\n";
+
+ //FOOTER
+ t << "\t" << "};" << "\n"
+ << "\t" << "rootObject = " << keyFor("QMAKE_PBX_ROOT") << ";" << "\n"
+ << "}" << endl;
+
+ QString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"),
+ QDir::currentDirPath());
+ QFile mkwrapf(mkwrap);
+ if(mkwrapf.open(IO_WriteOnly | IO_Translate)) {
+ debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1());
+ QTextStream mkwrapt(&mkwrapf);
+ writeHeader(mkwrapt);
+ const char *cleans = "uiclean mocclean preprocess_clean ";
+ mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n"
+ << "all:" << "\n\t"
+ << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild") << "\n"
+ << "install: all" << "\n\t"
+ << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild install") << "\n"
+ << "distclean clean: preprocess_clean" << "\n\t"
+ << "cd " << (project->first("QMAKE_ORIG_TARGET") + ".pbproj/ && pbxbuild clean") << "\n"
+ << (!did_preprocess ? cleans : "") << ":" << "\n";
+ if(did_preprocess)
+ mkwrapt << cleans << ":" << "\n\t"
+ << "make -f "
+ << pbx_dir << Option::dir_sep << "qt_preprocess.mak $@" << endl;
+ }
+ return TRUE;
+}
+
+QString
+ProjectBuilderMakefileGenerator::fixEnvs(QString file)
+{
+ QRegExp reg_var("\\$\\((.*)\\)");
+ for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) {
+ if(project->variables()["QMAKE_PBX_VARS"].findIndex(reg_var.cap(1)) == -1)
+ project->variables()["QMAKE_PBX_VARS"].append(reg_var.cap(1));
+ rep += reg_var.matchedLength();
+ }
+ return file;
+}
+
+QString
+ProjectBuilderMakefileGenerator::fixEnvsList(QString where)
+{
+ QString ret;
+ const QStringList &l = project->variables()[where];
+ for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
+ fixEnvs((*it));
+ if(!ret.isEmpty())
+ ret += " ";
+ ret += (*it);
+ }
+ return ret;
+}
+
+QString
+ProjectBuilderMakefileGenerator::keyFor(QString block)
+{
+#if 0 //This make this code much easier to debug..
+ return block;
+#endif
+
+ QString ret;
+ if(!keys.contains(block)) {
+#if 0
+ static unsigned int r = 0;
+ ret.sprintf("%024x", ++r);
+#else //not really necesary, but makes it look more interesting..
+ static struct { unsigned int a1, a2, a3; } r = { 0, 0, 0 };
+ if(!r.a1 && !r.a2 && !r.a3) {
+ r.a1 = rand();
+ r.a2 = rand();
+ r.a3 = rand();
+ }
+ switch(rand() % 3) {
+ case 0: ++r.a1; break;
+ case 1: ++r.a2; break;
+ case 2: ++r.a3; break;
+ }
+ ret.sprintf("%08x%08x%08x", r.a1, r.a2, r.a3);
+#endif
+ ret = ret.upper();
+ keys.insert(block, ret);
+ } else {
+ ret = keys[block];
+ }
+ return ret;
+}
+
+bool
+ProjectBuilderMakefileGenerator::openOutput(QFile &file) const
+{
+ if(project->first("TEMPLATE") != "subdirs") {
+ QFileInfo fi(file);
+ if(fi.extension() != "pbxproj" || file.name().isEmpty()) {
+ QString output = file.name();
+ if(fi.isDir())
+ output += QDir::separator();
+ if(fi.extension() != "pbproj") {
+ if(file.name().isEmpty() || fi.isDir())
+ output += project->first("TARGET");
+ output += QString(".pbproj") + QDir::separator();
+ } else if(output[(int)output.length() - 1] != QDir::separator()) {
+ output += QDir::separator();
+ }
+ output += QString("project.pbxproj");
+ file.setName(output);
+ }
+ bool ret = UnixMakefileGenerator::openOutput(file);
+ ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1);
+ Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2);
+ return ret;
+ }
+ return UnixMakefileGenerator::openOutput(file);
+}
+
+/* This function is such a hack it is almost pointless, but it
+ eliminates the warning message from ProjectBuilder that the project
+ file is for an older version. I guess this could be used someday if
+ the format of the output is dependant upon the version of
+ ProjectBuilder as well.
+*/
+int
+ProjectBuilderMakefileGenerator::pbuilderVersion() const
+{
+ QString ret;
+ if(project->isEmpty("QMAKE_PBUILDER_VERSION")) {
+ QString version, version_plist = project->first("QMAKE_PBUILDER_VERSION_PLIST");
+ if(version_plist.isEmpty())
+ version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist";
+ else
+ version_plist = version_plist.replace(QRegExp("\""), "");
+ QFile version_file(version_plist);
+ if(version_file.open(IO_ReadOnly)) {
+ debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1());
+ QTextStream plist(&version_file);
+
+ bool in_dict = FALSE;
+ QString current_key;
+ QRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$");
+ while(!plist.eof()) {
+ QString line = plist.readLine().stripWhiteSpace();
+ if(line == "<dict>")
+ in_dict = TRUE;
+ else if(line == "</dict>")
+ in_dict = FALSE;
+ else if(in_dict) {
+ if(keyreg.exactMatch(line))
+ current_key = keyreg.cap(1);
+ else if(current_key == "CFBundleShortVersionString" && stringreg.exactMatch(line))
+ version = stringreg.cap(1);
+ }
+ }
+ version_file.close();
+ } else debug_msg(1, "pbuilder: version.plist: Failure to open %s", version_plist.latin1());
+ if(version.startsWith("2.0"))
+ ret = "38";
+ else if(version == "1.1")
+ ret = "34";
+ } else {
+ ret = project->first("QMAKE_PBUILDER_VERSION");
+ }
+ if(!ret.isEmpty()) {
+ bool ok;
+ int int_ret = ret.toInt(&ok);
+ if(ok) {
+ debug_msg(1, "pbuilder: version.plist: Got version: %d", int_ret);
+ return int_ret;
+ }
+ }
+ debug_msg(1, "pbuilder: version.plist: Fallback to default version");
+ return 34; //my fallback
+}
+
+QString
+ProjectBuilderMakefileGenerator::reftypeForFile(QString where)
+{
+ if(QDir::isRelativePath(where))
+ return "4"; //relative
+ return "0"; //absolute
+}
diff --git a/qmake/generators/mac/pbuilder_pbx.h b/qmake/generators/mac/pbuilder_pbx.h
new file mode 100644
index 0000000..ec2e1be
--- a/dev/null
+++ b/qmake/generators/mac/pbuilder_pbx.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Created : 970521
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __PBUILDERMAKE_H__
+#define __PBUILDERMAKE_H__
+
+#include "unixmake.h"
+
+class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator
+{
+ QString pbx_dir;
+ int pbuilderVersion() const;
+ bool writeMakeParts(QTextStream &);
+ bool writeMakefile(QTextStream &);
+
+ QMap<QString, QString> keys;
+ QString keyFor(QString file);
+ QString fixEnvs(QString file);
+ QString fixEnvsList(QString where);
+ QString reftypeForFile(QString file);
+
+public:
+ ProjectBuilderMakefileGenerator(QMakeProject *p);
+ ~ProjectBuilderMakefileGenerator();
+
+ virtual bool openOutput(QFile &) const;
+protected:
+ virtual bool doDepends() const { return FALSE; } //never necesary
+};
+
+inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator()
+{ }
+
+
+#endif /* __PBUILDERMAKE_H__ */