diff options
Diffstat (limited to 'tqtinterface/qt4/qmake/generators/mac')
-rw-r--r-- | tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.cpp | 822 | ||||
-rw-r--r-- | tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.h | 71 | ||||
-rw-r--r-- | tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.cpp | 1428 | ||||
-rw-r--r-- | tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.h | 75 |
4 files changed, 2396 insertions, 0 deletions
diff --git a/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.cpp b/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.cpp new file mode 100644 index 0000000..8e3ec21 --- /dev/null +++ b/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.cpp @@ -0,0 +1,822 @@ +/**************************************************************************** +** +** Implementation of MetrowerksMakefileGenerator class. +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of qmake. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "metrowerks_xml.h" +#include "option.h" +#include <tqdir.h> +#include <tqdict.h> +#include <tqregexp.h> +#include <stdlib.h> +#include <time.h> +#if !defined(TQWS) && defined(TQ_OS_MAC) +#include <Carbon/Carbon.h> +#include <sys/types.h> +#include <sys/stat.h> +#endif + +MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(TQMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) +{ + +} + +bool +MetrowerksMakefileGenerator::writeMakefile(TQTextStream &t) +{ + if(!project->variables()["TQMAKE_FAILED_RETQUIREMENTS"].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("TQMAKE_FAILED_RETQUIREMENTS").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(TQTextStream &t) +{ + //..grrr.. libs! + TQStringList extra_objs; + bool do_libs = TRUE; + if(project->first("TEMPLATE") == "app") + extra_objs += project->variables()["TQMAKE_CRT_OBJECTS"]; + else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) + do_libs = FALSE; + if(do_libs) + extra_objs += project->variables()["TQMAKE_LIBS"]; + for(TQStringList::Iterator val_it = extra_objs.begin(); + val_it != extra_objs.end(); ++val_it) { + if((*val_it).startsWith("-L")) { + TQString dir((*val_it).right((*val_it).length() - 2)); + fixEnvVariables(dir); + if(project->variables()["DEPENDPATH"].tqfindIndex(dir) == -1 && + project->variables()["INCLUDEPATH"].tqfindIndex(dir) == -1) + project->variables()["INCLUDEPATH"].append(dir); + } else if((*val_it).startsWith("-l")) { + TQString lib("lib" + (*val_it).right((*val_it).length() - 2) + "." + + project->first("TQMAKE_EXTENSION_SHLIB")); + if(project->variables()["LIBRARIES"].tqfindIndex(lib) == -1) + project->variables()["LIBRARIES"].append(lib); + } else + if((*val_it) == "-framework") { + ++val_it; + if(val_it == extra_objs.end()) + break; + TQString frmwrk = (*val_it) + ".framework"; + if(project->variables()["FRAMEWORKS"].tqfindIndex(frmwrk) == -1) + project->variables()["FRAMEWORKS"].append(frmwrk); + } else if((*val_it).left(1) != "-") { + TQString lib=(*val_it); + int s = lib.tqfindRev('/'); + if(s != -1) { + TQString dir = lib.left(s); + lib = lib.right(lib.length() - s - 1); + fixEnvVariables(dir); + if(project->variables()["DEPENDPATH"].tqfindIndex(dir) == -1 && + project->variables()["INCLUDEPATH"].tqfindIndex(dir) == -1) + project->variables()["INCLUDEPATH"].append(dir); + } + project->variables()["LIBRARIES"].append(lib); + } + } + //let metrowerks tqfind the files & set the files to the type I expect + TQDict<void> seen(293); + TQString paths[] = { TQString("SRCTQMOC"), TQString("FORMS"), TQString("UICDECLS"), + TQString("UICIMPLS"), TQString("SOURCES"),TQString("HEADERS"), + TQString::null }; + for(int y = 0; paths[y] != TQString::null; y++) { + TQStringList &l = project->variables()[paths[y]]; + for(TQStringList::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 + TQStringList &d = tqfindDependencies((*val_it)); //depends + for(TQStringList::Iterator dep_it = d.begin(); dep_it != d.end(); ++dep_it) { + if(!seen.tqfind((*dep_it))) { + seen.insert((*dep_it), (void *)1); + createFork((*dep_it)); + } + } + //now chop it + int s = (*val_it).tqfindRev('/'); + if(s != -1) { + TQString dir = (*val_it).left(s); + (*val_it) = (*val_it).right((*val_it).length() - s - 1); + TQString tmpd=dir, tmpv; + if(fixifyToMacPath(tmpd, tmpv)) { + bool add_in = TRUE; + TQString deps[] = { TQString("DEPENDPATH"), + TQString("INCLUDEPATH"), TQString::null }, + dd, dv; + for(int yy = 0; deps[yy] != TQString::null; yy++) { + TQStringList &l2 = project->variables()[deps[yy]]; + for(TQStringList::Iterator val_it2 = l2.begin(); + val_it2 != l2.end(); ++val_it2) { + TQString 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")) { + TQString 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"); + } + + TQString xmlfile = tqfindTemplate(project->first("TQMAKE_XML_TEMPLATE")); + TQFile file(xmlfile); + if(!file.open(IO_ReadOnly )) { + fprintf(stderr, "Cannot open XML file: %s\n", + project->first("TQMAKE_XML_TEMPLATE").latin1()); + return FALSE; + } + TQTextStream xml( TQT_TQIODEVICE(&file) ); + createFork(Option::output.name()); + + int rep; + TQString line; + while ( !xml.eof() ) { + line = xml.readLine(); + while((rep = line.tqfind(TQRegExp("\\$\\$[!a-zA-Z0-9_-]*"))) != -1) { + TQString torep = line.mid(rep, line.tqfind(TQRegExp("[^\\$!a-zA-Z0-9_-]"), rep) - rep); + TQString 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_TQPREPROCESS" || + variable == "CODEWARRIOR_TQPREPROCESSOUT") { + TQString outcmd=variable.right(variable.length() - variable.tqfindRev('_') - 1); + TQStringList args; + if(outcmd == "TQPREPROCESS") + args << "UICS" << "TQMOCS"; + else if(outcmd == "TQPREPROCESSOUT") + args << "SRCTQMOC" << "UICIMPLS" << "UICDELCS"; + else + args << outcmd; + for(TQStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { + TQString arg = (*arit); + TQString kind = "Text"; + if(arg == "LIBRARIES") + kind = "Library"; + if(!project->variables()[arg].isEmpty()) { + TQStringList &list = project->variables()[arg]; + for(TQStringList::Iterator it = list.begin(); it != list.end(); ++it) { + TQString flag; + if(project->isActiveConfig("debug")) { + bool debug = TRUE; + if(outcmd == "TQPREPROCESS") { + debug = FALSE; + } else { + for(TQStringList::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_TQPREPROCESS_LINKORDER" || + variable == "CODEWARRIOR_TQPREPROCESSOUT_LINKORDER") { + TQString outcmd=variable.mid(variable.tqfind('_')+1, + variable.tqfindRev('_')-(variable.tqfind('_')+1)); + TQStringList args; + if(outcmd == "TQPREPROCESS") + args << "UICS" << "TQMOCS"; + else if(outcmd == "TQPREPROCESSOUT") + args << "SRCTQMOC" << "UICIMPLS" << "UICDELCS"; + else + args << outcmd; + for(TQStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { + TQString arg = (*arit); + if(!project->variables()[arg].isEmpty()) { + TQStringList &list = project->variables()[arg]; + for(TQStringList::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_TQPREPROCESS_GROUP" || + variable == "CODEWARRIOR_TQPREPROCESSOUT_GROUP") { + TQString outcmd = variable.mid(variable.tqfind('_')+1, + variable.tqfindRev('_')-(variable.tqfind('_')+1)); + TQStringList args; + if(outcmd == "TQPREPROCESS") + args << "UICS" << "TQMOCS"; + else if(outcmd == "TQPREPROCESSOUT") + args << "SRCTQMOC" << "UICIMPLS" << "UICDELCS"; + else + args << outcmd; + for(TQStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) { + TQString arg = (*arit); + if(!project->variables()[arg].isEmpty()) { + TQStringList &list = project->variables()[arg]; + for(TQStringList::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")) { + TQStringList &list = project->variables()["FRAMEWORKS"]; + for(TQStringList::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") { + TQString arg=variable.right(variable.length()-variable.tqfind('_')-1); + TQStringList list; + if(arg == "INCLUDEPATH") { + list = project->variables()[arg]; + list << Option::mkfile::qmakespec; + list << TQDir::current().currentDirPath(); + + TQStringList &l = project->variables()["TQMAKE_LIBS_PATH"]; + for(TQStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { + TQString 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") { + TQStringList &l = project->variables()[arg]; + for(TQStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) + { + //apparently tmake used colon separation... + TQStringList damn = TQStringList::split(':', (*val_it)); + if(!damn.isEmpty()) + list += damn; + else + list.append((*val_it)); + } + } else { + list = project->variables()[arg]; + } + for(TQStringList::Iterator it = list.begin(); it != list.end(); ++it) { + TQString 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") { + TQString 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")) { + TQString 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_TQTDIR") { + t << getenv("TQTDIR"); + } else if(variable == "CODEWARRIOR_CACHEMODDATES") { + t << "true"; + } else { + t << var(variable); + } + } + t << line << endl; + } + t << endl; + file.close(); + + if(tqmocAware()) { + TQString tqmocs = project->first("TQMOCS"); + TQFile tqmocfile(tqmocs); + if(!tqmocfile.open(IO_WriteOnly)) { + fprintf(stderr, "Cannot open TQMOCS file: %s\n", tqmocs.latin1()); + } else { + createFork(tqmocs); + TQTextStream tqmocs( TQT_TQIODEVICE(&tqmocfile) ); + TQStringList &list = project->variables()["SRCTQMOC"]; + for(TQStringList::Iterator it = list.begin(); it != list.end(); ++it) { + TQString src = tqfindMocSource((*it)); + if(src.tqfindRev('/') != -1) + src = src.right(src.length() - src.tqfindRev('/') - 1); + tqmocs << src << endl; + } + tqmocfile.close(); + } + } + + if(!project->isEmpty("FORMS")) { + TQString uics = project->first("UICS"); + TQFile uicfile(uics); + if(!uicfile.open(IO_WriteOnly)) { + fprintf(stderr, "Cannot open UICS file: %s\n", uics.latin1()); + } else { + createFork(uics); + TQTextStream uics( TQT_TQIODEVICE(&uicfile) ); + TQStringList &list = project->variables()["FORMS"]; + for(TQStringList::Iterator it = list.begin(); it != list.end(); ++it) { + TQString ui = (*it); + if(ui.tqfindRev('/') != -1) + ui = ui.right(ui.length() - ui.tqfindRev('/') - 1); + uics << ui << endl; + } + uicfile.close(); + } + } + + if(!project->isEmpty("CODEWARRIOR_PREFIX_HEADER")) { + TQFile 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")); + TQTextStream prefix( TQT_TQIODEVICE(&prefixfile) ); + TQStringList &list = project->variables()["DEFINES"]; + for(TQStringList::Iterator it = list.begin(); it != list.end(); ++it) { + if((*it).tqfind('=') != -1) { + int x = (*it).tqfind('='); + 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("TQMAKE_XML_TEMPLATE") ) + project->variables()["TQMAKE_XML_TEMPLATE"].append("mwerkstmpl.xml"); + + TQStringList &configs = project->variables()["CONFIG"]; + if(project->isActiveConfig("qt")) { + if(configs.tqfindIndex("tqmoc")) configs.append("tqmoc"); + if ( !( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") || + (project->first("TARGET") == "qt-mt") ) ) + project->variables()["TQMAKE_LIBS"] += project->variables()["TQMAKE_LIBS_QT"]; + if(configs.tqfindIndex("tqmoc")) + configs.append("tqmoc"); + if ( !project->isActiveConfig("debug") ) + project->variables()["DEFINES"].append("TQT_NO_DEBUG"); + } + + //version handling + if(project->variables()["VERSION"].isEmpty()) + project->variables()["VERSION"].append("1.0." + + (project->isEmpty("VER_PAT") ? TQString("0") : + project->first("VER_PAT")) ); + TQStringList ver = TQStringList::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()["TQMAKE_LIBS"] += project->variables()["LIBS"]; + if( project->variables()["TQMAKE_EXTENSION_SHLIB"].isEmpty() ) + project->variables()["TQMAKE_EXTENSION_SHLIB"].append( "dylib" ); + + if ( project->isActiveConfig("tqmoc") ) { + TQString tqmocfile = project->first("TARGET"); + if(project->first("TEMPLATE") == "lib") + tqmocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared"; + project->variables()["TQMOCS"].append(tqmocfile + ".tqmocs"); + setMocAware(TRUE); + } + if(!project->isEmpty("FORMS")) { + TQString 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(TQDir::currentDirPath()); + MakefileGenerator::init(); + + if ( project->isActiveConfig("opengl") ) { + project->variables()["INCLUDEPATH"] += project->variables()["TQMAKE_INCDIR_OPENGL"]; + if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") || + (project->first("TARGET") == "qt-mt") ) + project->variables()["TQMAKE_LIBS"] += project->variables()["TQMAKE_LIBS_OPENGL_QT"]; + else + project->variables()["TQMAKE_LIBS"] += project->variables()["TQMAKE_LIBS_OPENGL"]; + } + + if(project->isActiveConfig("qt")) + project->variables()["INCLUDEPATH"] += project->variables()["TQMAKE_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("TQMAKE_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("TQMAKE_ENTRYPOINT")) + project->variables()["TQMAKE_ENTRYPOINT"].append("start"); + project->variables()["CODEWARRIOR_ENTRYPOINT"].append( + project->first("TQMAKE_ENTRYPOINT")); + } +} + + +TQString +MetrowerksMakefileGenerator::tqfindTemplate(const TQString &file) +{ + TQString ret; + if(!TQFile::exists(ret = file) && + !TQFile::exists((ret = Option::mkfile::qmakespec + TQDir::separator() + file)) && + !TQFile::exists((ret = TQString(getenv("TQTDIR")) + "/mkspecs/mac-mwerks/" + file)) && + !TQFile::exists((ret = (TQString(getenv("HOME")) + "/.tmake/" + file)))) + return ""; + return ret; +} + +bool +MetrowerksMakefileGenerator::createFork(const TQString &f) +{ +#if !defined(TQWS) && defined(TQ_OS_MACX) + FSRef fref; + FSSpec fileSpec; + if(TQFile::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 + TQ_UNUSED(f) +#endif + return TRUE; +} + +bool +MetrowerksMakefileGenerator::fixifyToMacPath(TQString &p, TQString &v, bool ) +{ + v = "Absolute"; + if(p.tqfind(':') != -1) //guess its macish already + return TRUE; + + static TQString st_volume; + if(st_volume.isEmpty()) { + st_volume = var("TQMAKE_VOLUMENAME"); +#if !defined(TQWS) && defined(TQ_OS_MACX) + 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 + } + TQString 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(TQDir::isRelativePath(p)) { + if(p.startsWith("{")) { + int eoc = p.tqfind('}'); + if(eoc == -1) + return FALSE; + volume = p.mid(1, eoc - 1); + p = p.right(p.length() - eoc - 1); + } else { + TQFileInfo fi(p); + if(fi.convertToAbs()) //strange + return FALSE; + p = fi.filePath(); + } + } + p = TQDir::cleanDirPath(p); + if(!volume.isEmpty()) + v = volume; + p.tqreplace("/", ":"); + if(p.right(1) != ":") + p += ':'; + return TRUE; +} + +void +MetrowerksMakefileGenerator::processPrlFiles() +{ + TQPtrList<MakefileDependDir> libdirs; + libdirs.setAutoDelete(TRUE); + const TQString lflags[] = { "TQMAKE_LIBS", TQString::null }; + for(int i = 0; !lflags[i].isNull(); i++) { + for(bool ret = FALSE; TRUE; ret = FALSE) { + TQStringList l_out; + TQStringList &l = project->variables()[lflags[i]]; + for(TQStringList::Iterator it = l.begin(); it != l.end(); ++it) { + TQString opt = (*it); + if(opt.startsWith("-")) { + if(opt.startsWith("-L")) { + TQString r = opt.right(opt.length() - 2), l = r; + fixEnvVariables(l); + libdirs.append(new MakefileDependDir(r.tqreplace( "\"", ""), + l.tqreplace( "\"", ""))); + } else if(opt.left(2) == "-l") { + TQString 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; + if(processPrlFile(prl)) { + if(prl.startsWith(mdd->local_dir)) + prl.tqreplace(0, mdd->local_dir.length(), mdd->real_dir); + TQRegExp reg("^.*lib(" + lib + "[^.]*)\\." + + project->first("TQMAKE_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); + TQString prl = "/System/Library/Frameworks/" + opt + + ".framework/" + opt; + 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 TQString &var, const TQStringList &l) +{ + if(var == "TQMAKE_PRL_LIBS") { + TQStringList &out = project->variables()["TQMAKE_LIBS"]; + for(TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { + bool append = TRUE; + if((*it).startsWith("-")) { + if((*it).startsWith("-l") || (*it).startsWith("-L")) { + append = out.tqfindIndex((*it)) == -1; + } else if((*it).startsWith("-framework")) { + ++it; + for(TQStringList::ConstIterator outit = out.begin(); + outit != out.end(); ++it) { + if((*outit) == "-framework") { + ++outit; + if((*outit) == (*it)) { + append = FALSE; + break; + } + } + } + } + } else if(TQFile::exists((*it))) { + append = out.tqfindIndex((*it)); + } + if(append) + out.append((*it)); + } + } else { + MakefileGenerator::processPrlVariable(var, l); + } +} + + +bool +MetrowerksMakefileGenerator::openOutput(TQFile &file) const +{ + TQString outdir; + if(!file.name().isEmpty()) { + TQFileInfo fi(file); + if(fi.isDir()) + outdir = file.name() + TQDir::separator(); + } + if(!outdir.isEmpty() || file.name().isEmpty()) + file.setName(outdir + project->first("TARGET") + ".xml"); + return MakefileGenerator::openOutput(file); +} diff --git a/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.h b/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.h new file mode 100644 index 0000000..bd28500 --- /dev/null +++ b/tqtinterface/qt4/qmake/generators/mac/metrowerks_xml.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Definition of MetrowerksMakefileGenerator class. +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of qmake. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef __METROWERKS_XML_H__ +#define __METROWERKS_XML_H__ + +#include "makefile.h" + +class MetrowerksMakefileGenerator : public MakefileGenerator +{ + bool createFork(const TQString &f); + bool fixifyToMacPath(TQString &c, TQString &v, bool exists=TRUE); + + bool init_flag; + + bool writeMakeParts(TQTextStream &); + bool writeSubDirs(TQTextStream &); + + bool writeMakefile(TQTextStream &); + TQString tqfindTemplate(const TQString &file); + void init(); +public: + MetrowerksMakefileGenerator(TQMakeProject *p); + ~MetrowerksMakefileGenerator(); + + bool openOutput(TQFile &file) const; +protected: + virtual void processPrlFiles(); + virtual void processPrlVariable(const TQString &var, const TQStringList &l); + virtual bool doDepends() const { return FALSE; } //never necesary +}; + +inline MetrowerksMakefileGenerator::~MetrowerksMakefileGenerator() +{ } + +#endif /* __METROWERKS_XML_H__ */ diff --git a/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.cpp b/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.cpp new file mode 100644 index 0000000..7e072e2 --- /dev/null +++ b/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.cpp @@ -0,0 +1,1428 @@ +/**************************************************************************** +** +** Implementation of ProjectBuilderMakefileGenerator class. +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of qmake. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "pbuilder_pbx.h" +#include "option.h" +#include "meta.h" +#include <tqdir.h> +#include <tqdict.h> +#include <tqregexp.h> +#include <stdlib.h> +#include <time.h> +#include "tqtmd5.h" +#ifdef TQ_OS_UNIX +# include <sys/types.h> +# include <sys/stat.h> +#endif + +// Note: this is fairly hacky, but it does the job... + +ProjectBuilderMakefileGenerator::ProjectBuilderMakefileGenerator(TQMakeProject *p) : UnixMakefileGenerator(p) +{ + +} + +bool +ProjectBuilderMakefileGenerator::writeMakefile(TQTextStream &t) +{ + if(!project->variables()["TQMAKE_FAILED_RETQUIREMENTS"].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("TQMAKE_FAILED_RETQUIREMENTS").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") + return writeSubdirs(t, FALSE); + return FALSE; +} + +bool +ProjectBuilderMakefileGenerator::writeSubdirs(TQTextStream &t, bool direct) +{ + TQString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + TQDir::currentDirPath()); + TQFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + TQTextStream mkwrapt( TQT_TQIODEVICE(&mkwrapf) ); + UnixMakefileGenerator::writeSubdirs(mkwrapt, direct); + } + + //HEADER + const int pbVersion = pbuilderVersion(); + t << "// !$*UTF8*$!" << "\n" + << "{" << "\n" + << "\t" << "archiveVersion = 1;" << "\n" + << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" + << "\t" << "objectVersion = " << pbVersion << ";" << "\n" + << "\t" << "objects = {" << endl; + + //SUBDIRS + TQStringList subdirs = project->variables()["SUBDIRS"]; + TQString oldpwd = TQDir::currentDirPath(); + TQMap<TQString, TQStringList> groups; + for(TQStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { + TQFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); + if(fi.exists()) { + if(fi.isDir()) { + TQString profile = (*it); + if(!profile.endsWith(Option::dir_sep)) + profile += Option::dir_sep; + profile += fi.baseName() + ".pro"; + subdirs.append(profile); + } else { + TQMakeProject tmp_proj; + TQString dir = fi.dirPath(), fn = fi.fileName(); + if(!dir.isEmpty()) { + if(!TQDir::setCurrent(dir)) + fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); + } + if(tmp_proj.read(fn, oldpwd)) { + if(Option::debug_level) { + TQMap<TQString, TQStringList> &vars = tmp_proj.variables(); + for(TQMap<TQString, TQStringList>::Iterator it = vars.begin(); + it != vars.end(); ++it) { + if(it.key().left(1) != "." && !it.data().isEmpty()) + debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), + it.data().join(" :: ").latin1()); + } + } + if(tmp_proj.first("TEMPLATE") == "subdirs") { + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); + } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") { + TQString pbxproj = TQDir::currentDirPath() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix(); + if(!TQFile::exists(pbxproj)) { + warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.latin1()); + goto nextfile; // # Dirty! + } + project->variables()["TQMAKE_PBX_SUBDIRS"] += pbxproj; + //PROJECTREF + { + bool in_root = TRUE; + TQString name = TQDir::currentDirPath(); + TQString project_key = keyFor(pbxproj + "_PROJECTREF"); + if(project->isActiveConfig("flat")) { + TQString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(flat_file.tqfind(Option::dir_sep) != -1) { + TQStringList dirs = TQStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + TQString flat_file = fileFixify(name, oldpwd, Option::output_dir, TRUE); + if(TQDir::isRelativePath(flat_file) && flat_file.tqfind(Option::dir_sep) != -1) { + TQString last_grp("TQMAKE_PBX_HEIR_GROUP"); + TQStringList dirs = TQStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + for(TQStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + TQString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!groups.tqcontains(new_grp)) + project->variables()["TQMAKE_PBX_GROUPS"].append(new_grp_key); + } else { + if(!groups[last_grp].tqcontains(new_grp_key)) + groups[last_grp] += new_grp_key; + } + last_grp = new_grp; + } + groups[last_grp] += project_key; + in_root = FALSE; + } + } + if(in_root) + project->variables()["TQMAKE_PBX_GROUPS"] += project_key; + t << "\t\t" << project_key << " = {" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "name = " << tmp_proj.first("TARGET") << ";" << "\n" + << "\t\t\t" << "path = " << pbxproj << ";" << "\n" + << "\t\t\t" << "refType = 0;" << "\n" + << "\t\t\t" << "sourceTree = \"<absolute>\";" << "\n" + << "\t\t" << "};" << "\n"; + //PRODUCTGROUP + t << "\t\t" << keyFor(pbxproj + "_PRODUCTGROUP") << " = {" << "\n" + << "\t\t\t" << "tqchildren = (" << "\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\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + } + } + } +nextfile: + TQDir::setCurrent(oldpwd); + } + } + } + for(TQMap<TQString, TQStringList>::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" << "tqchildren = (" << "\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"; + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER + //BUILDSTYLE + TQString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + TQMap<TQString, TQString> settings; + settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); + if(as_release) + settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); + TQString name; + if(pbVersion >= 42) + name = (as_release ? "Release" : "Debug"); + else + name = (as_release ? "Deployment" : "Development"); + + if(pbVersion >= 42) { + TQString key = keyFor("TQMAKE_SUBDIR_PBX_BUILDCONFIG_" + name); + project->variables()["TQMAKE_SUBDIR_PBX_BUILDCONFIGS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "isa = XCBuildConfiguration;" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n"; + for(TQMap<TQString, TQString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) + t << "\t\t\t\t" << set_it.key() << " = \"" << set_it.data() << "\";\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "name = " << name << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + + TQString key = keyFor("TQMAKE_SUBDIR_PBX_BUILDSTYLE_" + name); + if(project->isActiveConfig("debug") != (bool)as_release) { + project->variables()["TQMAKE_SUBDIR_PBX_BUILDSTYLES"].append(key); + active_buildstyle = name; + } else if(pbVersion >= 42) { + project->variables()["TQMAKE_SUBDIR_PBX_BUILDSTYLES"].append(key); + } + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n"; + for(TQMap<TQString, TQString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) + t << "\t\t\t\t" << set_it.key() << " = \"" << set_it.data() << "\";\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" + << "\t\t\t" << "name = " << name << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + if(pbVersion >= 42) { + t << "\t\t" << keyFor("TQMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << " = {" << "\n" + << "\t\t\t" << "isa = XCConfigurationList;" << "\n" + << "\t\t\t" << "buildConfigurations = (" << "\n" + << varGlue("TQMAKE_SUBDIR_PBX_BUILDCONFIGS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "defaultConfigurationIsVisible = 0;" << "\n" + << "\t\t\t" << "defaultConfigurationIsName = " << active_buildstyle << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + +#ifdef GENERATE_AGGREGRATE_SUBDIR + //target + t << "\t\t" << keyFor("TQMAKE_SUBDIR_PBX_AGGREGATE_TARGET") << " = {" << "\n" + << "\t\t\t" << "buidPhases = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t\t" << "PRODUCT_NAME = " << project->variables()["TARGET"].first() << ";" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "dependencies = (" << "\n"; + { + const TQStringList &qmake_subdirs = project->variables()["TQMAKE_PBX_SUBDIRS"]; + for(int i = 0; i < qmake_subdirs.count(); i++) + t << "\t\t\t\t" << keyFor(qmake_subdirs[i] + "_TARGETREF") << "," << "\n"; + } + t << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXAggregateTarget;" << "\n" + << "\t\t\t" << "name = " << project->variables()["TARGET"].first() << ";" << "\n" + << "\t\t\t" << "productName = " << project->variables()["TARGET"].first() << ";" << "\n" + << "\t\t" << "};" << "\n"; +#endif + + //ROOT_GROUP + t << "\t\t" << keyFor("TQMAKE_PBX_ROOT_GROUP") << " = {" << "\n" + << "\t\t\t" << "tqchildren = (" << "\n" + << varGlue("TQMAKE_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" << "refType = 4;" << "\n" + << "\t\t\t" << "sourceTree = \"<group>\";" << "\n" + << "\t\t" << "};" << "\n"; + + //ROOT + t << "\t\t" << keyFor("TQMAKE_PBX_ROOT") << " = {" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "buildStyles = (" << "\n" + << varGlue("TQMAKE_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("TQMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n"; + if(pbVersion >= 42) + t << "\t\t\t" << "buildConfigurationList = " << keyFor("TQMAKE_SUBDIR_PBX_BUILDCONFIG_LIST") << ";" << "\n"; + t << "\t\t\t" << "projectReferences = (" << "\n"; + { + TQStringList &libdirs = project->variables()["TQMAKE_PBX_SUBDIRS"]; + for(TQStringList::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) + t << "\t\t\t\t" << "{" << "\n" + << "\t\t\t\t\t" << "ProductGroup = " << keyFor((*it) + "_PRODUCTGROUP") << ";" << "\n" + << "\t\t\t\t\t" << "ProjectRef = " << keyFor((*it) + "_PROJECTREF") << ";" << "\n" + << "\t\t\t\t" << "}," << "\n"; + } + t << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "targets = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t" << "};" << "\n"; + + //FOOTER + t << "\t" << "};" << "\n" + << "\t" << "rootObject = " << keyFor("TQMAKE_PBX_ROOT") << ";" << "\n" + << "}" << endl; + + return TRUE; +} + +bool +ProjectBuilderMakefileGenerator::writeMakeParts(TQTextStream &t) +{ + int i; + TQStringList tmp; + bool did_preprocess = FALSE; + + //HEADER + const int pbVersion = pbuilderVersion(); + t << "// !$*UTF8*$!" << "\n" + << "{" << "\n" + << "\t" << "archiveVersion = 1;" << "\n" + << "\t" << "classes = {" << "\n" << "\t" << "};" << "\n" + << "\t" << "objectVersion = " << pbVersion << ";" << "\n" + << "\t" << "objects = {" << endl; + + //MAKE TQMAKE equivelant + if(!project->isActiveConfig("no_autoqmake") && project->projectFile() != "(stdin)") { + TQString mkfile = pbx_dir + Option::dir_sep + "qt_makeqmake.mak"; + TQFile mkf(mkfile); + if(mkf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); + TQTextStream mkt( TQT_TQIODEVICE(&mkf) ); + writeHeader(mkt); + mkt << "TQMAKE = " << + (project->isEmpty("TQMAKE_TQMAKE") ? TQString("$(TQTDIR)/bin/qmake") : + var("TQMAKE_TQMAKE")) << endl; + writeMakeQmake(mkt); + mkf.close(); + } + TQString phase_key = keyFor("TQMAKE_PBX_MAKETQMAKE_BUILDPHASE"); + mkfile = fileFixify(mkfile, TQDir::currentDirPath()); + project->variables()["TQMAKE_PBX_PRESCRIPT_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 = \"TQt Qmake\";" << "\n" + << "\t\t\t" << "neededFileNames = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "shellPath = /bin/sh;" << "\n" + << "\t\t\t" << "shellScript = \"make -C " << TQDir::currentDirPath() << + " -f " << mkfile << "\";" << "\n" + << "\t\t" << "};" << "\n"; + } + + //DUMP SOURCES + TQMap<TQString, TQStringList> groups; + TQString srcs[] = { "HEADERS", "SOURCES", "SRCTQMOC", "UICIMPLS", "TQMAKE_IMAGE_COLLECTION", + "FORMS", "TQMAKE_INTERNAL_INCLUDED_FILES", TQString::null }; + for(i = 0; !srcs[i].isNull(); i++) { + tmp = project->variables()[srcs[i]]; + if(srcs[i] == "TQMAKE_INTERNAL_INCLUDED_FILES") { + TQString pfile = project->projectFile(); + if(pfile != "(stdin)") + tmp.prepend(pfile); + } + TQStringList &src_list = project->variables()["TQMAKE_PBX_" + srcs[i]]; + TQStringList &root_group_list = project->variables()["TQMAKE_PBX_GROUPS"]; + + //hard coded groups.. + TQString src_group; + if(srcs[i] == "SOURCES") + src_group = "Sources"; + else if(srcs[i] == "HEADERS") + src_group = "Headers"; + else if(srcs[i] == "SRCTQMOC") + src_group = "Sources [tqmoc]"; + else if(srcs[i] == "UICIMPLS" || srcs[i] == "FORMS") + src_group = "Sources [uic]"; + else if(srcs[i] == "TQMAKE_IMAGE_COLLECTION") + src_group = "Sources [images]"; + else if(srcs[i] == "TQMAKE_INTERNAL_INCLUDED_FILES") + src_group = "Sources [qmake]"; + + for(TQStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { + TQStringList files = (*it); + bool buildable = TRUE; + if(srcs[i] == "FORMS") { + TQString form_dot_h = (*it) + Option::h_ext.first(); + if(TQFile::exists(form_dot_h)) + files += form_dot_h; + buildable = FALSE; + } else if(srcs[i] == "HEADERS" || srcs[i] == "TQMAKE_INTERNAL_INCLUDED_FILES") { + buildable = FALSE; + } + + files = fileFixify(files); + for(TQStringList::Iterator file_it = files.begin(); file_it != files.end(); ++file_it) { + TQString file = (*file_it); + if(file.length() >= 2 && (file[0] == '"' || file[0] == '\'') && file[(int) file.length()-1] == file[0]) + file = file.mid(1, file.length()-2); + if(file.endsWith(Option::cpp_tqmoc_ext) || file.endsWith(Option::prl_ext)) + continue; + bool in_root = TRUE; + TQString src_key = keyFor(file), name = file; + if(project->isActiveConfig("flat")) { + TQString flat_file = fileFixify(file, TQDir::currentDirPath(), Option::output_dir, TRUE); + if(flat_file.tqfind(Option::dir_sep) != -1) { + TQStringList dirs = TQStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + } + } else { + TQString flat_file = fileFixify(file, TQDir::currentDirPath(), Option::output_dir, TRUE); + if(TQDir::isRelativePath(flat_file) && flat_file.tqfind(Option::dir_sep) != -1) { + TQString last_grp("TQMAKE_PBX_" + src_group + "_HEIR_GROUP"); + TQStringList dirs = TQStringList::split(Option::dir_sep, flat_file); + name = dirs.back(); + dirs.pop_back(); //remove the file portion as it will be added via src_key + for(TQStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { + TQString new_grp(last_grp + Option::dir_sep + (*dir_it)), new_grp_key(keyFor(new_grp)); + if(dir_it == dirs.begin()) { + if(!src_list.tqcontains(new_grp_key)) + src_list.append(new_grp_key); + } else { + if(!groups[last_grp].tqcontains(new_grp_key)) + 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" << "name = \"" << name << "\";" << "\n" + << "\t\t\t" << "path = \"" << file << "\";" << "\n" + << "\t\t\t" << "refType = " << reftypeForFile(file) << ";" << "\n"; + if(pbVersion >= 38) { + TQString filetype; + for(TQStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { + if(file.endsWith((*cppit))) { + filetype = "sourcecode.cpp.cpp"; + break; + } + } + if(!filetype.isNull()) + t << "\t\t\t" << "lastKnownFileType = " << filetype << ";" << "\n"; + } + t << "\t\t" << "};" << "\n"; + if(buildable) { //build reference + TQString 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()["TQMAKE_PBX_OBJ"].append(obj_key); + } + } + } + if(!src_list.isEmpty()) { + if(srcs[i] == "SOURCES") { + if(project->first("TEMPLATE") == "app" && !project->isEmpty("RC_FILE")) { //Icon + TQString 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"; + } + } + + TQString src_group_key = keyFor(src_group); + if(root_group_list.tqfindIndex(src_group_key) == -1) + root_group_list += src_group_key; + + TQStringList &group = groups[src_group]; + for(TQStringList::Iterator src_it = src_list.begin(); src_it != src_list.end(); ++src_it) { + if(group.tqfindIndex((*src_it)) == -1) + group += (*src_it); + } + } + } + for(TQMap<TQString, TQStringList>::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" << "tqchildren = (" << "\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("SRCTQMOC") || !project->isEmpty("IMAGES") || + !project->isEmpty("YACCSOURCES") || !project->isEmpty("LEXSOURCES")) { + TQString mkfile = pbx_dir + Option::dir_sep + "qt_preprocess.mak"; + TQFile mkf(mkfile); + if(mkf.open(IO_WriteOnly | IO_Translate)) { + did_preprocess = TRUE; + debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); + TQTextStream mkt( TQT_TQIODEVICE(&mkf) ); + writeHeader(mkt); + mkt << "TQMOC = " << Option::fixPathToTargetOS(var("TQMAKE_TQMOC")) << endl; + mkt << "UIC = " << Option::fixPathToTargetOS(var("TQMAKE_UIC")) << endl; + mkt << "LEX = " << var("TQMAKE_LEX") << endl; + mkt << "LEXFLAGS = " << var("TQMAKE_LEXFLAGS") << endl; + mkt << "YACC = " << var("TQMAKE_YACC") << endl; + mkt << "YACCFLAGS = " << var("TQMAKE_YACCFLAGS") << endl; + mkt << "DEL_FILE = " << var("TQMAKE_DEL_FILE") << endl; + mkt << "MOVE = " << var("TQMAKE_MOVE") << endl << endl; + mkt << "FORMS = " << varList("UICIMPLS") << endl; + mkt << "IMAGES = " << varList("TQMAKE_IMAGE_COLLECTION") << endl; + mkt << "TQMOCS = " << varList("SRCTQMOC") << endl; + mkt << "PARSERS ="; + if(!project->isEmpty("YACCSOURCES")) { + TQStringList &yaccs = project->variables()["YACCSOURCES"]; + for(TQStringList::Iterator yit = yaccs.begin(); yit != yaccs.end(); ++yit) { + TQFileInfo fi((*yit)); + mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) + << Option::yacc_mod << Option::cpp_ext.first(); + } + } + if(!project->isEmpty("LEXSOURCES")) { + TQStringList &lexs = project->variables()["LEXSOURCES"]; + for(TQStringList::Iterator lit = lexs.begin(); lit != lexs.end(); ++lit) { + TQFileInfo fi((*lit)); + mkt << " " << fi.dirPath() << Option::dir_sep << fi.baseName(TRUE) + << Option::lex_mod << Option::cpp_ext.first(); + } + } + mkt << "\n"; + mkt << "preprocess: $(FORMS) $(TQMOCS) $(PARSERS) $(IMAGES)" << endl; + mkt << "clean preprocess_clean: tqmocclean uiclean parser_clean" << endl << endl; + mkt << "tqmocclean:" << "\n"; + if(!project->isEmpty("SRCTQMOC")) + mkt << "\t-rm -f $(TQMOCS)" << "\n"; + mkt << "uiclean:" << "\n"; + if(!project->isEmpty("UICIMPLS")) + mkt << "\t-rm -f $(FORMS)" << "\n"; + if(!project->isEmpty("TQMAKE_IMAGE_COLLECTION")) + mkt << "\t-rm -f $(IMAGES)" << "\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"); + writeImageSrc(mkt, "TQMAKE_IMAGE_COLLECTION"); + mkf.close(); + } + mkfile = fileFixify(mkfile, TQDir::currentDirPath()); + TQString phase_key = keyFor("TQMAKE_PBX_PREPROCESS_TARGET"); +// project->variables()["TQMAKE_PBX_BUILDPHASES"].append(phase_key); + project->variables()["TQMAKE_PBX_PRESCRIPT_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" + << varGlue("TQMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXShellScriptBuildPhase;" << "\n" + << "\t\t\t" << "name = \"TQt Preprocessors\";" << "\n" + << "\t\t\t" << "neededFileNames = (" << "\n" + << varGlue("TQMAKE_PBX_OBJ", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "shellPath = /bin/sh;" << "\n" + << "\t\t\t" << "shellScript = \"make -C " << TQDir::currentDirPath() << + " -f " << mkfile << "\";" << "\n" + << "\t\t" << "};" << "\n"; + } + + //SOURCE BUILDPHASE + if(!project->isEmpty("TQMAKE_PBX_OBJ")) { + TQString grp = "Build Sources", key = keyFor(grp); + project->variables()["TQMAKE_PBX_BUILDPHASES"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" + << "\t\t\t" << "files = (" << "\n" + << varGlue("TQMAKE_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 + TQStringList &libdirs = project->variables()["TQMAKE_PBX_LIBPATHS"]; + TQString libs[] = { "TQMAKE_LFLAGS", "TQMAKE_LIBDIR_FLAGS", "TQMAKE_LIBS", TQString::null }; + for(i = 0; !libs[i].isNull(); i++) { + tmp = project->variables()[libs[i]]; + for(TQStringList::Iterator it = tmp.begin(); it != tmp.end();) { + bool remove = FALSE; + TQString library, name, opt = (*it).stripWhiteSpace(); + if(opt.length() >= 2 && (opt[0] == '"' || opt[0] == '\'') && opt[(int) opt.length()-1] == opt[0]) + opt = opt.mid(1, opt.length()-2); + if(opt.startsWith("-L")) { + TQString r = opt.right(opt.length() - 2); + fixEnvVariables(r); + libdirs.append(r); + } else if(opt == "-prebind") { + project->variables()["TQMAKE_DO_PREBINDING"].append("TRUE"); + remove = TRUE; + } else if(opt.startsWith("-l")) { + name = opt.right(opt.length() - 2); + TQString lib("lib" + name); + for(TQStringList::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 + */ + TQString lib_file = (*lit) + Option::dir_sep + lib; + if(TQMakeMetaInfo::libExists(lib_file)) { + TQMakeMetaInfo libinfo; + if(libinfo.readLib(lib_file)) { + if(!libinfo.isEmpty("TQMAKE_PRL_TARGET")) { + library = (*lit) + Option::dir_sep + libinfo.first("TQMAKE_PRL_TARGET"); + debug_msg(1, "pbuilder: Found library (%s) via PRL %s (%s)", + opt.latin1(), lib_file.latin1(), library.latin1()); + remove = TRUE; + } + } + } + } + if(!remove) { + TQString extns[] = { ".dylib", ".so", ".a", TQString::null }; + for(int n = 0; !remove && !extns[n].isNull(); n++) { + TQString tmp = (*lit) + Option::dir_sep + lib + extns[n]; + if(TQFile::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; + TQStringList &fdirs = project->variables()["TQMAKE_FRAMEWORKDIR"]; + if(fdirs.isEmpty()) + fdirs.append("/System/Library/Frameworks/"); + for(TQStringList::Iterator fit = fdirs.begin(); fit != fdirs.end(); ++fit) { + if(TQFile::exists((*fit) + TQDir::separator() + (*it) + ".framework")) { + --it; + it = tmp.remove(it); + remove = TRUE; + library = (*fit) + Option::dir_sep + (*it) + ".framework"; + break; + } + } + } else if(opt.left(1) != "-") { + if(TQFile::exists(opt)) { + remove = TRUE; + library = opt; + } + } + if(!library.isEmpty()) { + if(name.isEmpty()) { + int slsh = library.tqfindRev(Option::dir_sep); + if(slsh != -1) + name = library.right(library.length() - slsh - 1); + } + library = fileFixify(library); + TQString 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()["TQMAKE_PBX_LIBRARIES"].append(key); + TQString 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()["TQMAKE_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")) { + TQString mkfile = pbx_dir + Option::dir_sep + "qt_sublibs.mak"; + TQFile mkf(mkfile); + if(mkf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkfile.latin1()); + TQTextStream mkt(&mkf); + writeHeader(mkt); + mkt << "SUBLIBS= "; + tmp = project->variables()["SUBLIBS"]; + TQStringList::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(TQString("MAKELIB") + (*it)) << endl << endl; + mkf.close(); + } + TQString phase_key = keyFor("TQMAKE_PBX_SUBLIBS_BUILDPHASE"); + mkfile = fileFixify(mkfile, TQDir::currentDirPath()); + project->variables()["TQMAKE_PBX_PRESCRIPT_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 = \"TQt Sublibs\";" << "\n" + << "\t\t\t" << "neededFileNames = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "shellPath = /bin/sh;" << "\n" + << "\t\t\t" << "shellScript = \"make -C " << TQDir::currentDirPath() << + " -f " << mkfile << "\";" << "\n" + << "\t\t" << "};" << "\n"; + } + //LIBRARY BUILDPHASE + if(!project->isEmpty("TQMAKE_PBX_LIBRARIES")) { + tmp = project->variables()["TQMAKE_PBX_LIBRARIES"]; + if(!tmp.isEmpty()) { + TQString grp("External Frameworks and Libraries"), key = keyFor(grp); + project->variables()["TQMAKE_PBX_GROUPS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "tqchildren = (" << "\n" + << varGlue("TQMAKE_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"; + } + } + { + TQString grp("Frameworks & Libraries"), key = keyFor(grp); + project->variables()["TQMAKE_PBX_BUILDPHASES"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildActionMask = 2147483647;" << "\n" + << "\t\t\t" << "files = (" << "\n" + << varGlue("TQMAKE_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("console") && project->first("TEMPLATE") == "app") { //BUNDLE RESOURCES + TQString grp("Bundle Resources"), key = keyFor(grp); + project->variables()["TQMAKE_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") : TQString("")) + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXResourcesBuildPhase;" << "\n" + << "\t\t\t" << "name = \"" << grp << "\";" << "\n" + << "\t\t" << "};" << "\n"; + } + { //INSTALL BUILDPHASE (sh script) + TQString phase_key = keyFor("TQMAKE_PBX_TARGET_COPY_PHASE"); + TQString destDir = Option::output_dir; + if (!project->isEmpty("TQMAKE_ORIG_DESTDIR")) + destDir = project->first("TQMAKE_ORIG_DESTDIR"); + fixEnvs(destDir); + destDir = TQFileInfo(Option::fixPathToLocalOS(destDir)).absFilePath(); + project->variables()["TQMAKE_PBX_PRESCRIPT_BUILDPHASES"].append(phase_key); + t << "\t\t" << phase_key << " = {\n" + << "\t\t\tbuildActionMask = 2147483647;\n" + << "\t\t\tdstPath = " << destDir << ";\n" + << "\t\t\tdstSubfolderSpec = 0;\n" + << "\t\t\tfiles = (\n" + << "\t\t\t" << keyFor("TQMAKE_PBX_TARGET_COPY_FILE") << ",\n" + << "\t\t\t);\n" + << "\t\t\tisa = PBXCopyFilesBuildPhase;\n" + << "\t\t\trunOnlyForDeploymentPostprocessing = 0;\n" + << "\t\t};\n" + << "\t\t" << keyFor("TQMAKE_PBX_TARGET_COPY_FILE") << " = {\n" + << "\t\t\tfileRef = " << keyFor(pbx_dir + "TQMAKE_PBX_REFERENCE") << ";\n" + << "\t\t\tisa = PBXBuildFile;\n" + << "\t\t\tsettings = {\n" + << "\t\t\t};\n" + << "\t\t};\n"; + } + if(/*ideType() == MAC_XCODE &&*/ !project->isEmpty("TQMAKE_PBX_PRESCRIPT_BUILDPHASES") && 0) { + // build reference + t << "\t\t" << keyFor("TQMAKE_PBX_PRESCRIPT_BUILDREFERENCE") << " = {" << "\n" + << "\t\t\t" << "includeInIndex = 0;" << "\n" + << "\t\t\t" << "isa = PBXFileReference;" << "\n" + << "\t\t\t" << "path = preprocessor.out;" << "\n" + << "\t\t\t" << "refType = 3;" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR;" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["TQMAKE_PBX_PRODUCTS"].append(keyFor("TQMAKE_PBX_PRESCRIPTS_BUILDREFERENCE")); + //build phase + TQString prescript_key = keyFor("TQMAKE_PBX_PRESCRIPTS_BUILDPHASE"); + project->variables()["TQMAKE_PBX_TARGETS"].append(prescript_key); + t << "\t\t" << prescript_key << " = {" << "\n" + << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("TQMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "dependencies = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "isa = PBXNativeTarget;" << "\n" + << "\t\t\t" << "name = \"TQt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productName = \"TQt Preprocessor Steps\";" << "\n" + << "\t\t\t" << "productReference = " << keyFor("TQMAKE_PBX_PRESCRIPTS_BUILDREFERENCE") << ";" << "\n" + << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n" + << "\t\t" << "};" << "\n"; + //dependency + t << "\t\t" << keyFor("TQMAKE_PBX_PRESCRIPTS_DEPENDENCY") << " = {" << "\n" + << "\t\t\t" << "isa = PBXTargetDependency;" << "\n" + << "\t\t\t" << "target = " << keyFor("TQMAKE_PBX_PRESCRIPTS_BUILDPHASE") << ";" << "\n" + << "\t\t" << "};" << "\n"; + project->variables()["TQMAKE_PBX_TARGET_DEPENDS"].append(keyFor("TQMAKE_PBX_PRESCRIPTS_DEPENDENCY")); + project->variables()["TQMAKE_PBX_PRESCRIPT_BUILDPHASES"].clear(); //these are already consumed above + } + + //DUMP EVERYTHING THAT TIES THE ABOVE TOGETHER + //ROOT_GROUP + t << "\t\t" << keyFor("TQMAKE_PBX_ROOT_GROUP") << " = {" << "\n" + << "\t\t\t" << "tqchildren = (" << "\n" + << varGlue("TQMAKE_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("TQMAKE_ORIG_TARGET") << ";" << "\n" + << "\t\t\t" << "path = \"\";" << "\n" + << "\t\t\t" << "refType = 4;" << "\n" + << "\t\t" << "};" << "\n"; + //REFERENCE + project->variables()["TQMAKE_PBX_PRODUCTS"].append(keyFor(pbx_dir + "TQMAKE_PBX_REFERENCE")); + t << "\t\t" << keyFor(pbx_dir + "TQMAKE_PBX_REFERENCE") << " = {" << "\n" + << "\t\t\t" << "fallbackIsa = PBXFileReference;" << "\n"; + if(project->first("TEMPLATE") == "app") { + TQString targ = project->first("TQMAKE_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"; + } + TQString app = (!project->isEmpty("DESTDIR") ? project->first("DESTDIR") + project->first("TQMAKE_ORIG_TARGET") : + TQDir::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 { + TQString lib = project->first("TQMAKE_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.tqfindRev(Option::dir_sep); + if(slsh != -1) + lib = lib.right(lib.length() - slsh - 1); + t << "\t\t\t" << "isa = PBXLibraryReference;" << "\n" + << "\t\t\t" << "expectedFileType = \"compiled.mach-o.dylib\";" << "\n" + << "\t\t\t" << "path = " << lib << ";\n" + << "\t\t\t" << "refType = " << 3/*reftypeForFile(lib)*/ << ";" << "\n" + << "\t\t\t" << "sourceTree = BUILT_PRODUCTS_DIR" << ";" << "\n"; + } + t << "\t\t" << "};" << "\n"; + { //Products group + TQString grp("Products"), key = keyFor(grp); + project->variables()["TQMAKE_PBX_GROUPS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "tqchildren = (" << "\n" + << varGlue("TQMAKE_PBX_PRODUCTS", "\t\t\t\t", ",\n\t\t\t\t", "\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"; + } + //TARGET + TQString target_key = keyFor("TQMAKE_PBX_TARGET"); + project->variables()["TQMAKE_PBX_TARGETS"].append(target_key); + t << "\t\t" << target_key << " = {" << "\n" + << "\t\t\t" << "buildPhases = (" << "\n" + << varGlue("TQMAKE_PBX_PRESCRIPT_BUILDPHASES", "\t\t\t\t", ",\n\t\t\t\t", ",\n") + << varGlue("TQMAKE_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" << "CC = \"" << fixEnvsList("TQMAKE_CC") << "\";" << "\n" + << "\t\t\t\t" << "CPLUSPLUS = \"" << fixEnvsList("TQMAKE_CXX") << "\";" << "\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("TQMAKE_PBX_LIBPATHS") << "\";" << "\n" + << "\t\t\t\t" << "OPTIMIZATION_CFLAGS = \"\";" << "\n" + << "\t\t\t\t" << "GCC_GENERATE_DEBUGGING_SYMBOLS = " << + (project->isActiveConfig("debug") ? "YES" : "NO") << ";" << "\n" + << "\t\t\t\t" << "OTHER_CFLAGS = \"" << + fixEnvsList("TQMAKE_CFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(varGlue("DEFINES"," -D"," -D","")) << "\";" << "\n" + << "\t\t\t\t" << "LEXFLAGS = \"" << var("TQMAKE_LEXFLAGS") << "\";" << "\n" + << "\t\t\t\t" << "YACCFLAGS = \"" << var("TQMAKE_YACCFLAGS") << "\";" << "\n" + << "\t\t\t\t" << "OTHER_CPLUSPLUSFLAGS = \"" << + fixEnvsList("TQMAKE_CXXFLAGS") << fixQuotes(varGlue("PRL_EXPORT_DEFINES"," -D"," -D","")) << + fixQuotes(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" + << "\t\t\t\t" << "PREBINDING = " << (project->isEmpty("TQMAKE_DO_PREBINDING") ? "NO" : "YES") << ";" << "\n"; + if(project->isActiveConfig("debug")) + t << "\t\t\t\t" << "GCC_OPTIMIZATION_LEVEL = 0" << ";" << "\n"; + if(!project->isEmpty("PRECOMPILED_HEADER")) { + if(pbVersion >= 38) { + t << "\t\t\t\t" << "GCC_PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "GCC_PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } else { + t << "\t\t\t\t" << "PRECOMPILE_PREFIX_HEADER = \"YES\";" << "\n" + << "\t\t\t\t" << "PREFIX_HEADER = \"" << project->first("PRECOMPILED_HEADER") << "\";" << "\n"; + } + } + if(project->first("TEMPLATE") == "app") { + TQString plist = fileFixify(project->first("TQMAKE_INFO_PLIST")); + if(plist.isEmpty()) + plist = specdir() + TQDir::separator() + "Info.plist." + project->first("TEMPLATE"); + if(TQFile::exists(plist)) { + TQFile plist_in_file(plist); + if(plist_in_file.open(IO_ReadOnly)) { + TQTextStream plist_in(&plist_in_file); + TQString plist_in_text = plist_in.read(); + plist_in_text = plist_in_text.tqreplace("@ICON@", (project->isEmpty("RC_FILE") ? TQString("") : project->first("RC_FILE").section(Option::dir_sep, -1))); + plist_in_text = plist_in_text.tqreplace("@EXECUTABLE@", project->first("TQMAKE_ORIG_TARGET")); + TQFile plist_out_file("Info.plist"); + if(plist_out_file.open(IO_WriteOnly | IO_Translate)) { + TQTextStream plist_out(&plist_out_file); + plist_out << plist_in_text; + t << "\t\t\t\t" << "INFOPLIST_FILE = \"Info.plist\";" << "\n"; + } + } + } + } +#if 1 + t << "\t\t\t\t" << "BUILD_ROOT = \"" << TQDir::currentDirPath() << "\";" << "\n"; +#endif + if(!project->isActiveConfig("staticlib")) + t << "\t\t\t\t" << "OTHER_LDFLAGS = \"" << fixEnvsList("SUBLIBS") << " " << + fixEnvsList("TQMAKE_LFLAGS") << " " << fixEnvsList("TQMAKE_LIBDIR_FLAGS") << + " " << fixEnvsList("TQMAKE_LIBS") << "\";" << "\n"; + if(!project->isEmpty("DESTDIR")) { + TQString dir = project->first("DESTDIR"); + if (TQDir::isRelativePath(dir)) + dir.prepend(TQDir::currentDirPath() + Option::dir_sep); + t << "\t\t\t\t" << "INSTALL_DIR = \"" << dir << "\";" << "\n"; + } + if ( project->first("TEMPLATE") == "lib") { + t << "\t\t\t\t" << "INSTALL_PATH = \"" << "\";" << "\n"; + } + if(!project->isEmpty("VERSION") && project->first("VERSION") != "0.0.0") { + t << "\t\t\t\t" << "DYLIB_CURRENT_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "." << project->first("VER_PAT") << "\";" << "\n"; + if(project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("VER_MAJ") << "." + << project->first("VER_MIN") << "\";" << "\n"; + } + if(!project->isEmpty("COMPAT_VERSION")) + t << "\t\t\t\t" << "DYLIB_COMPATIBILITY_VERSION = \"" << project->first("COMPAT_VERSION") << "\";" << "\n"; + if(!project->isEmpty("TQMAKE_MACOSX_DEPLOYMENT_TARGET")) + t << "\t\t\t\t" << "MACOSX_DEPLOYMENT_TARGET = \"" + << project->first("TQMAKE_MACOSX_DEPLOYMENT_TARGET") << "\";" << "\n"; + if(pbVersion >= 38) { + if(!project->isEmpty("OBJECTS_DIR")) + t << "\t\t\t\t" << "OBJROOT = \"" << project->first("OBJECTS_DIR") << "\";" << "\n"; + } +#if 0 + if(!project->isEmpty("DESTDIR")) + t << "\t\t\t\t" << "SYMROOT = \"" << project->first("DESTDIR") << "\";" << "\n"; + else + t << "\t\t\t\t" << "SYMROOT = \"" << TQDir::currentDirPath() << "\";" << "\n"; +#endif + if(project->first("TEMPLATE") == "app") { + if(pbVersion < 38 && !project->isActiveConfig("console")) + t << "\t\t\t\t" << "WRAPPER_SUFFIX = app;" << "\n"; + t << "\t\t\t\t" << "PRODUCT_NAME = " << project->first("TQMAKE_ORIG_TARGET") << ";" << "\n"; + } else { + if(!project->isActiveConfig("plugin") && project->isActiveConfig("staticlib")) { + t << "\t\t\t\t" << "LIBRARY_STYLE = STATIC;" << "\n"; + } else { + t << "\t\t\t\t" << "LIBRARY_STYLE = DYNAMIC;" << "\n"; + } + TQString lib = project->first("TQMAKE_ORIG_TARGET"); + if (!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) + lib.prepend("lib"); + t << "\t\t\t\t" << "PRODUCT_NAME = " << lib << ";" << "\n"; + } + tmp = project->variables()["TQMAKE_PBX_VARS"]; + for(TQStringList::Iterator it = tmp.begin(); it != tmp.end(); ++it) { + TQString var = (*it), val = getenv(var); + if(!val && var == "TB") + val = "/usr/bin/"; + t << "\t\t\t\t" << var << " = \"" << val << "\";" << "\n"; + } + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "conditionalBuildSettings = {" << "\n" + << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "dependencies = (" << "\n" + << varGlue("TQMAKE_PBX_TARGET_DEPENDS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "productReference = " << keyFor(pbx_dir + "TQMAKE_PBX_REFERENCE") << ";" << "\n" + << "\t\t\t" << "shouldUseHeadermap = 1;" << "\n"; + if(pbVersion >= 38) + t << "\t\t\t" << "isa = PBXNativeTarget;" << "\n"; + if(project->first("TEMPLATE") == "app") { + if(project->isActiveConfig("console")) { + if(pbVersion >= 38) + t << "\t\t\t" << "productType = \"com.apple.product-type.tool\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXToolTarget;" << "\n"; + } else { + if(pbVersion >= 38) + t << "\t\t\t" << "productType = \"com.apple.product-type.application\";" << "\n"; + else + t << "\t\t\t" << "isa = PBXApplicationTarget;" << "\n"; + t << "\t\t\t" << "productSettingsXML = \""; + bool read_plist = false; + if(TQFile::exists("Info.plist")) { + TQFile plist("Info.plist"); + if(plist.open(IO_ReadOnly)) { + read_plist = true; + TQTextStream stream(&plist); + while(!stream.eof()) + t << stream.readLine().tqreplace('"', "\\\"") << endl; + } + } + if(!read_plist) { + t << "<?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("TQMAKE_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" + //Although the output below looks strange it is to avoid the trigraph ??< + << "\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>"; + } + } + t << "\";" << "\n"; + t << "\t\t\t" << "name = \"" << project->first("TQMAKE_ORIG_TARGET") << "\";" << "\n" + << "\t\t\t" << "productName = " << project->first("TQMAKE_ORIG_TARGET") << ";" << "\n"; + } else { + TQString lib = project->first("TQMAKE_ORIG_TARGET"); + if(!project->isActiveConfig("frameworklib") && !project->isActiveConfig("staticlib")) + lib.prepend("lib"); + t << "\t\t\t" << "name = \"" << lib << "\";" << "\n" + << "\t\t\t" << "productName = " << lib << ";" << "\n"; + if(pbVersion >= 38) { + if(project->isActiveConfig("staticlib")) + t << "\t\t\t" << "productType = \"com.apple.product-type.library.static\";" << "\n"; + else + t << "\t\t\t" << "productType = \"com.apple.product-type.library.dynamic\";" << "\n"; + } else { + t << "\t\t\t" << "isa = PBXLibraryTarget;" << "\n"; + } + } + t << "\t\t\t" << "startupPath = \"<<ProjectDirectory>>\";" << "\n"; + if(!project->isEmpty("DESTDIR")) + t << "\t\t\t" << "productInstallPath = \"" << project->first("DESTDIR") << "\";" << "\n"; + t << "\t\t" << "};" << "\n"; + //DEBUG/RELEASE + TQString active_buildstyle; +#if 0 + for(int as_release = 0; as_release < 2; as_release++) +#else + bool as_release = !project->isActiveConfig("debug"); +#endif + { + TQMap<TQString, TQString> settings; + settings.insert("COPY_PHASE_STRIP", (as_release ? "YES" : "NO")); + if(as_release) + settings.insert("GCC_GENERATE_DEBUGGING_SYMBOLS", "NO"); + TQString name; + if(pbVersion >= 42) + name = (as_release ? "Release" : "Debug"); + else + name = (as_release ? "Deployment" : "Development"); + + if(pbVersion >= 42) { + TQString key = keyFor("TQMAKE_PBX_BUILDCONFIG_" + name); + project->variables()["TQMAKE_PBX_BUILDCONFIGS"].append(key); + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "isa = XCBuildConfiguration;" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n"; + for(TQMap<TQString, TQString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) + t << "\t\t\t\t" << set_it.key() << " = \"" << set_it.data() << "\";\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "name = " << name << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + + TQString key = keyFor("TQMAKE_PBX_BUILDSTYLE_" + name); + if(project->isActiveConfig("debug") != (bool)as_release) { + project->variables()["TQMAKE_PBX_BUILDSTYLES"].append(key); + active_buildstyle = name; + } else if(pbVersion >= 42) { + project->variables()["TQMAKE_PBX_BUILDSTYLES"].append(key); + } + t << "\t\t" << key << " = {" << "\n" + << "\t\t\t" << "buildRules = (" << "\n" + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "buildSettings = {" << "\n"; + for(TQMap<TQString, TQString>::Iterator set_it = settings.begin(); set_it != settings.end(); ++set_it) + t << "\t\t\t\t" << set_it.key() << " = \"" << set_it.data() << "\";\n"; + t << "\t\t\t" << "};" << "\n" + << "\t\t\t" << "isa = PBXBuildStyle;" << "\n" + << "\t\t\t" << "name = " << name << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + if(pbVersion >= 42) { + t << "\t\t" << keyFor("TQMAKE_PBX_BUILDCONFIG_LIST") << " = {" << "\n" + << "\t\t\t" << "isa = XCConfigurationList;" << "\n" + << "\t\t\t" << "buildConfigurations = (" << "\n" + << varGlue("TQMAKE_PBX_BUILDCONFIGS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "defaultConfigurationIsVisible = 0;" << "\n" + << "\t\t\t" << "defaultConfigurationIsName = " << active_buildstyle << ";" << "\n" + << "\t\t" << "};" << "\n"; + } + //ROOT + t << "\t\t" << keyFor("TQMAKE_PBX_ROOT") << " = {" << "\n" + << "\t\t\t" << "buildStyles = (" << "\n" + << varGlue("TQMAKE_PBX_BUILDSTYLES", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t\t" << "hasScannedForEncodings = 1;" << "\n" + << "\t\t\t" << "isa = PBXProject;" << "\n" + << "\t\t\t" << "mainGroup = " << keyFor("TQMAKE_PBX_ROOT_GROUP") << ";" << "\n" + << "\t\t\t" << "projectDirPath = \"\";" << "\n" + << "\t\t\t" << "targets = (" << "\n" + << varGlue("TQMAKE_PBX_TARGETS", "\t\t\t\t", ",\n\t\t\t\t", "\n") + << "\t\t\t" << ");" << "\n" + << "\t\t" << "};" << "\n"; + + //FOOTER + t << "\t" << "};" << "\n" + << "\t" << "rootObject = " << keyFor("TQMAKE_PBX_ROOT") << ";" << "\n" + << "}" << endl; + + if(project->isActiveConfig("generate_pbxbuild_makefile")) { + TQString mkwrap = fileFixify(pbx_dir + Option::dir_sep + ".." + Option::dir_sep + project->first("MAKEFILE"), + TQDir::currentDirPath()); + TQFile mkwrapf(mkwrap); + if(mkwrapf.open(IO_WriteOnly | IO_Translate)) { + debug_msg(1, "pbuilder: Creating file: %s", mkwrap.latin1()); + TQTextStream mkwrapt(&mkwrapf); + writeHeader(mkwrapt); + const char *cleans = "uiclean tqmocclean preprocess_clean "; + mkwrapt << "#This is a makefile wrapper for PROJECT BUILDER\n" + << "all:" << "\n\t" + << "cd " << project->first("TQMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << "\n" + << "install: all" << "\n\t" + << "cd " << project->first("TQMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << pbxbuild() << " install\n" + << "distclean clean: preprocess_clean" << "\n\t" + << "cd " << project->first("TQMAKE_ORIG_TARGET") << projectSuffix() << "/ && " << 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; +} + +TQString +ProjectBuilderMakefileGenerator::fixQuotes(const TQString &val) +{ + TQString ret(val); + ret = ret.tqreplace(TQRegExp("('|\\\\|\")"), "\\\\1"); + return ret; +} + +TQString +ProjectBuilderMakefileGenerator::fixEnvs(const TQString &file) +{ + TQRegExp reg_var("\\$\\((.*)\\)"); + for(int rep = 0; (rep = reg_var.search(file, rep)) != -1; ) { + if(project->variables()["TQMAKE_PBX_VARS"].tqfindIndex(reg_var.cap(1)) == -1) + project->variables()["TQMAKE_PBX_VARS"].append(reg_var.cap(1)); + rep += reg_var.matchedLength(); + } + return file; +} + +TQString +ProjectBuilderMakefileGenerator::fixEnvsList(const TQString &where) +{ + TQString ret; + const TQStringList &l = project->variables()[where]; + for(TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { + fixEnvs((*it)); + if(!ret.isEmpty()) + ret += " "; + ret += fixQuotes((*it)); + } + return ret; +} + +TQString +ProjectBuilderMakefileGenerator::keyFor(const TQString &block) +{ +#if 1 //This make this code much easier to debug.. + if(project->isActiveConfig("no_pb_munge_key")) + return block; +#endif + TQString ret; + if(!keys.tqcontains(block)) { + ret = TQT_TQSTRING(qtMD5(block.utf8()).left(24)).upper(); + keys.insert(block, ret); + } else { + ret = keys[block]; + } + return ret; +} + +bool +ProjectBuilderMakefileGenerator::openOutput(TQFile &file) const +{ + if(TQDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run + TQFileInfo fi(file); + if(fi.extension() != "pbxproj" || file.name().isEmpty()) { + TQString output = file.name(); + if(fi.isDir()) + output += TQDir::separator(); + if(!output.endsWith(projectSuffix())) { + if(file.name().isEmpty() || fi.isDir()) + output += project->first("TARGET"); + output += projectSuffix() + TQDir::separator(); + } else if(output[(int)output.length() - 1] != TQDir::separator()) { + output += TQDir::separator(); + } + output += TQString("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; +} + +/* 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 +{ + TQString ret; + if(project->isEmpty("TQMAKE_PBUILDER_VERSION")) { + TQString version, version_plist = project->first("TQMAKE_PBUILDER_VERSION_PLIST"); + if(version_plist.isEmpty()) { + if(TQFile::exists("/Developer/Applications/Xcode.app/Contents/version.plist")) + version_plist = "/Developer/Applications/Xcode.app/Contents/version.plist"; + else + version_plist = "/Developer/Applications/Project Builder.app/Contents/version.plist"; + } else { + version_plist = version_plist.tqreplace(TQRegExp("\""), ""); + } + TQFile version_file(version_plist); + if (version_file.open(IO_ReadOnly)) { + debug_msg(1, "pbuilder: version.plist: Reading file: %s", version_plist.latin1()); + TQTextStream plist(&version_file); + + bool in_dict = false; + TQString current_key; + TQRegExp keyreg("^<key>(.*)</key>$"), stringreg("^<string>(.*)</string>$"); + while(!plist.atEnd()) { + TQString 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.isEmpty() && version_plist.tqcontains("Xcode")) { + ret = "39"; + } else { + if(version.startsWith("2.")) + ret = "42"; + else if(version == "1.5") + ret = "39"; + else if(version == "1.1") + ret = "34"; + } + } else { + ret = project->first("TQMAKE_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 +} + +int +ProjectBuilderMakefileGenerator::reftypeForFile(const TQString &where) +{ + int ret = 0; //absolute is the default.. + if(TQDir::isRelativePath(where)) + ret = 4; //relative + return ret; +} + +TQString +ProjectBuilderMakefileGenerator::projectSuffix() const +{ + const int pbVersion = pbuilderVersion(); + if(pbVersion >= 42) + return ".xcodeproj"; + else if(pbVersion >= 38) + return ".xcode"; + return ".pbproj"; +} + +TQString +ProjectBuilderMakefileGenerator::pbxbuild() +{ + if(TQFile::exists("/usr/bin/pbbuild")) + return "pbbuild"; + if(TQFile::exists("/usr/bin/xcodebuild")) + return "xcodebuild"; + return (pbuilderVersion() >= 38 ? "xcodebuild" : "pbxbuild"); +} + diff --git a/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.h b/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.h new file mode 100644 index 0000000..91cadfa --- /dev/null +++ b/tqtinterface/qt4/qmake/generators/mac/pbuilder_pbx.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Definition of ProjectBuilderMakefileGenerator class. +** +** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA. +** +** This file is part of qmake. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free TQt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.TQPL +** included in the packaging of this file. Licensees holding valid TQt +** Commercial licenses may use this file in accordance with the TQt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef __PBUILDER_PBX_H__ +#define __PBUILDER_PBX_H__ + +#include "unixmake.h" + +class ProjectBuilderMakefileGenerator : public UnixMakefileGenerator +{ + TQString pbx_dir; + int pbuilderVersion() const; + bool writeSubdirs(TQTextStream &, bool); + bool writeMakeParts(TQTextStream &); + bool writeMakefile(TQTextStream &); + + TQString pbxbuild(); + TQMap<TQString, TQString> keys; + TQString keyFor(const TQString &file); + TQString fixQuotes(const TQString &val); + TQString fixEnvs(const TQString &file); + TQString fixEnvsList(const TQString &where); + int reftypeForFile(const TQString &where); + TQString projectSuffix() const; + +public: + ProjectBuilderMakefileGenerator(TQMakeProject *p); + ~ProjectBuilderMakefileGenerator(); + + virtual bool openOutput(TQFile &) const; +protected: + bool doPrecompiledHeaders() const { return FALSE; } + virtual bool doDepends() const { return FALSE; } //never necesary +}; + +inline ProjectBuilderMakefileGenerator::~ProjectBuilderMakefileGenerator() +{ } + + +#endif /* __PBUILDER_PBX_H__ */ |