Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

metrowerks_xml.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** 
00003 **
00004 ** Implementation of MetrowerksMakefileGenerator class.
00005 **
00006 ** Copyright (C) 1992-2003 Trolltech AS.  All rights reserved.
00007 **
00008 ** This file is part of qmake.
00009 **
00010 ** This file may be distributed under the terms of the Q Public License
00011 ** as defined by Trolltech AS of Norway and appearing in the file
00012 ** LICENSE.QPL included in the packaging of this file.
00013 **
00014 ** This file may be distributed and/or modified under the terms of the
00015 ** GNU General Public License version 2 as published by the Free Software
00016 ** Foundation and appearing in the file LICENSE.GPL included in the
00017 ** packaging of this file.
00018 **
00019 ** Licensees holding valid Qt Enterprise Edition licenses may use this
00020 ** file in accordance with the Qt Commercial License Agreement provided
00021 ** with the Software.
00022 **
00023 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00024 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00025 **
00026 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00027 **   information about Qt Commercial License Agreements.
00028 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00029 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00030 **
00031 ** Contact info@trolltech.com if any conditions of this licensing are
00032 ** not clear to you.
00033 **
00034 **********************************************************************/
00035 
00036 #include "metrowerks_xml.h"
00037 #include "option.h"
00038 #include <qdir.h>
00039 #include <qdict.h>
00040 #include <qregexp.h>
00041 #include <stdlib.h>
00042 #include <time.h>
00043 #if !defined(QWS) && defined(Q_OS_MAC)
00044 #include <Carbon/Carbon.h>
00045 #include <sys/types.h>
00046 #include <sys/stat.h>
00047 #endif
00048 
00049 MetrowerksMakefileGenerator::MetrowerksMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE)
00050 {
00051 
00052 }
00053 
00054 bool
00055 MetrowerksMakefileGenerator::writeMakefile(QTextStream &t)
00056 {
00057     if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
00058         /* for now just dump, I need to generated an empty xml or something.. */
00059         fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
00060                 var("QMAKE_FAILED_REQUIREMENTS").latin1());
00061         return TRUE;
00062     }
00063 
00064     if(project->first("TEMPLATE") == "app" ||
00065        project->first("TEMPLATE") == "lib") {
00066         return writeMakeParts(t);
00067     }
00068     else if(project->first("TEMPLATE") == "subdirs") {
00069         writeHeader(t);
00070         qDebug("Not supported!");
00071         return TRUE;
00072     }
00073     return FALSE;
00074 }
00075 
00076 bool
00077 MetrowerksMakefileGenerator::writeMakeParts(QTextStream &t)
00078 {
00079     //..grrr.. libs!
00080     QStringList extra_objs;
00081     bool do_libs = TRUE;
00082     if(project->first("TEMPLATE") == "app") 
00083         extra_objs += project->variables()["QMAKE_CRT_OBJECTS"];
00084     else if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib"))
00085         do_libs = FALSE;
00086     if(do_libs)
00087         extra_objs += project->variables()["QMAKE_LIBS"];
00088     for(QStringList::Iterator val_it = extra_objs.begin(); 
00089         val_it != extra_objs.end(); ++val_it) {
00090         if((*val_it).startsWith("-L")) {
00091             QString dir((*val_it).right((*val_it).length() - 2));
00092             fixEnvVariables(dir);
00093             if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
00094                project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
00095                 project->variables()["INCLUDEPATH"].append(dir);
00096         } else if((*val_it).startsWith("-l")) {
00097             QString lib("lib" + (*val_it).right((*val_it).length() - 2)  + "." + 
00098                         project->first("QMAKE_EXTENSION_SHLIB"));
00099             if(project->variables()["LIBRARIES"].findIndex(lib) == -1)
00100                 project->variables()["LIBRARIES"].append(lib);
00101         } else 
00102             if((*val_it) == "-framework") {
00103             ++val_it;
00104             if(val_it == extra_objs.end())
00105                 break;
00106             QString frmwrk = (*val_it) + ".framework";
00107             if(project->variables()["FRAMEWORKS"].findIndex(frmwrk) == -1)
00108                 project->variables()["FRAMEWORKS"].append(frmwrk);
00109         } else if((*val_it).left(1) != "-") {
00110             QString lib=(*val_it);
00111             int s = lib.findRev('/');
00112             if(s != -1) {
00113                 QString dir = lib.left(s);
00114                 lib = lib.right(lib.length() - s - 1);
00115                 fixEnvVariables(dir);
00116                 if(project->variables()["DEPENDPATH"].findIndex(dir) == -1 &&
00117                    project->variables()["INCLUDEPATH"].findIndex(dir) == -1)
00118                     project->variables()["INCLUDEPATH"].append(dir);
00119             }
00120             project->variables()["LIBRARIES"].append(lib);
00121         }
00122     }
00123     //let metrowerks find the files & set the files to the type I expect
00124     QDict<void> seen(293);
00125     QString paths[] = { QString("SRCMOC"), QString("FORMS"), QString("UICDECLS"),
00126                         QString("UICIMPLS"), QString("SOURCES"),QString("HEADERS"),
00127                         QString::null };
00128     for(int y = 0; paths[y] != QString::null; y++) {
00129         QStringList &l = project->variables()[paths[y]];
00130         for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
00131             //establish file types
00132             seen.insert((*val_it), (void *)1);
00133             createFork((*val_it)); //the file itself
00134             QStringList &d = findDependencies((*val_it)); //depends
00135             for(QStringList::Iterator dep_it = d.begin(); dep_it != d.end(); ++dep_it) {
00136                 if(!seen.find((*dep_it))) {
00137                     seen.insert((*dep_it), (void *)1);
00138                     createFork((*dep_it));
00139                 }
00140             }
00141             //now chop it
00142             int s = (*val_it).findRev('/');
00143             if(s != -1) {
00144                 QString dir = (*val_it).left(s);
00145                 (*val_it) = (*val_it).right((*val_it).length() - s - 1);
00146                 QString tmpd=dir, tmpv;
00147                 if(fixifyToMacPath(tmpd, tmpv)) {
00148                     bool add_in = TRUE;
00149                     QString deps[] = { QString("DEPENDPATH"), 
00150                                      QString("INCLUDEPATH"), QString::null }, 
00151                                      dd, dv;
00152                     for(int yy = 0; deps[yy] != QString::null; yy++) {
00153                         QStringList &l2 = project->variables()[deps[yy]];
00154                         for(QStringList::Iterator val_it2 = l2.begin(); 
00155                             val_it2 != l2.end(); ++val_it2) {
00156                             QString dd= (*val_it2), dv;
00157                             if(!fixifyToMacPath(dd, dv)) 
00158                                 continue;
00159                             if(dd == tmpd && tmpv == dv) {
00160                                 add_in = FALSE;
00161                                 break;
00162                             }
00163                         }
00164                     }
00165                     if(add_in) 
00166                         project->variables()["INCLUDEPATH"].append(dir);
00167                 }
00168             }
00169         }
00170     }
00171     //need a defines file
00172     if(!project->isEmpty("DEFINES")) {
00173         QString pre_pref = project->first("TARGET_STEM");
00174         if(project->first("TEMPLATE") == "lib")
00175             pre_pref += project->isActiveConfig("staticlib") ? "_static" : "_shared";
00176         project->variables()["CODEWARRIOR_PREFIX_HEADER"].append(pre_pref + "_prefix.h");
00177     }
00178 
00179     QString xmlfile = findTemplate(project->first("QMAKE_XML_TEMPLATE"));
00180     QFile file(xmlfile);
00181     if(!file.open(IO_ReadOnly )) {
00182         fprintf(stderr, "Cannot open XML file: %s\n", 
00183                 project->first("QMAKE_XML_TEMPLATE").latin1());
00184         return FALSE;
00185     }
00186     QTextStream xml(&file);
00187     createFork(Option::output.name());
00188 
00189     int rep;
00190     QString line;
00191     while ( !xml.eof() ) {
00192         line = xml.readLine();
00193         while((rep = line.find(QRegExp("\\$\\$[!a-zA-Z0-9_-]*"))) != -1) {
00194             QString torep = line.mid(rep, line.find(QRegExp("[^\\$!a-zA-Z0-9_-]"), rep) - rep);
00195             QString variable = torep.right(torep.length()-2);
00196 
00197             t << line.left(rep); //output the left side
00198             line = line.right(line.length() - (rep + torep.length())); //now past the variable
00199             if(variable == "CODEWARRIOR_HEADERS" || variable == "CODEWARRIOR_SOURCES" || 
00200                variable == "CODEWARRIOR_LIBRARIES" || variable == "CODEWARRIOR_QPREPROCESS" ||
00201                 variable == "CODEWARRIOR_QPREPROCESSOUT") {
00202                 QString outcmd=variable.right(variable.length() - variable.findRev('_') - 1);
00203                 QStringList args;
00204                 if(outcmd == "QPREPROCESS")
00205                     args << "UICS" << "MOCS";
00206                 else if(outcmd == "QPREPROCESSOUT")
00207                     args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
00208                 else
00209                     args << outcmd;
00210                 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
00211                     QString arg = (*arit);
00212                     QString kind = "Text";
00213                     if(arg == "LIBRARIES")
00214                         kind = "Library";
00215                     if(!project->variables()[arg].isEmpty()) {
00216                         QStringList &list = project->variables()[arg];
00217                         for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00218                             QString flag;
00219                             if(project->isActiveConfig("debug")) {
00220                                 bool debug = TRUE;
00221                                 if(outcmd == "QPREPROCESS") {
00222                                     debug = FALSE;
00223                                 } else {
00224                                     for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) {
00225                                         if((*it).endsWith((*hit))) { 
00226                                             debug = FALSE;
00227                                             break;
00228                                         }
00229                                     }
00230                                 }
00231                                 if(debug)
00232                                     flag = "Debug";
00233                             }
00234                             t << "\t\t\t\t<FILE>" << endl
00235                               << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
00236                               << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
00237                               << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
00238                               << "\t\t\t\t\t<FILEKIND>" << kind << "</FILEKIND>" << endl
00239                               << "\t\t\t\t\t<FILEFLAGS>" << flag << "</FILEFLAGS>" << endl
00240                               << "\t\t\t\t</FILE>" << endl;
00241                         }
00242                     }
00243                 }
00244             } else if(variable == "CODEWARRIOR_SOURCES_LINKORDER" || 
00245                       variable == "CODEWARRIOR_HEADERS_LINKORDER" ||
00246                       variable == "CODEWARRIOR_LIBRARIES_LINKORDER" || 
00247                       variable == "CODEWARRIOR_QPREPROCESS_LINKORDER" ||
00248                       variable == "CODEWARRIOR_QPREPROCESSOUT_LINKORDER") {
00249                 QString outcmd=variable.mid(variable.find('_')+1, 
00250                                             variable.findRev('_')-(variable.find('_')+1));
00251                 QStringList args;
00252                 if(outcmd == "QPREPROCESS")
00253                     args << "UICS" << "MOCS";
00254                 else if(outcmd == "QPREPROCESSOUT")
00255                     args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
00256                 else
00257                     args << outcmd;
00258                 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
00259                     QString arg = (*arit);
00260                     if(!project->variables()[arg].isEmpty()) {
00261                         QStringList &list = project->variables()[arg];
00262                         for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00263                             t << "\t\t\t\t<FILEREF>" << endl
00264                               << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
00265                               << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
00266                               << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
00267                               << "\t\t\t\t</FILEREF>" << endl;
00268                         }
00269                     }
00270                 }
00271             } else if(variable == "CODEWARRIOR_HEADERS_GROUP" || 
00272                       variable == "CODEWARRIOR_SOURCES_GROUP" ||
00273                       variable == "CODEWARRIOR_LIBRARIES_GROUP" || 
00274                       variable == "CODEWARRIOR_QPREPROCESS_GROUP" ||
00275                       variable == "CODEWARRIOR_QPREPROCESSOUT_GROUP") {
00276                 QString outcmd = variable.mid(variable.find('_')+1, 
00277                                               variable.findRev('_')-(variable.find('_')+1));
00278                 QStringList args;
00279                 if(outcmd == "QPREPROCESS")
00280                     args << "UICS" << "MOCS";
00281                 else if(outcmd == "QPREPROCESSOUT")
00282                     args << "SRCMOC" << "UICIMPLS" << "UICDELCS";
00283                 else
00284                     args << outcmd;
00285                 for(QStringList::Iterator arit = args.begin(); arit != args.end(); ++arit) {
00286                     QString arg = (*arit);
00287                     if(!project->variables()[arg].isEmpty()) {
00288                         QStringList &list = project->variables()[arg];
00289                         for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00290                             t << "\t\t\t\t<FILEREF>" << endl
00291                               << "\t\t\t\t\t<TARGETNAME>" << var("TARGET_STEM") << "</TARGETNAME>" 
00292                               << endl
00293                               << "\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
00294                               << "\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
00295                               << "\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
00296                               << "\t\t\t\t</FILEREF>" << endl;
00297                         }
00298                     }
00299                 }
00300             } else if(variable == "CODEWARRIOR_FRAMEWORKS") {
00301                 if(!project->isEmpty("FRAMEWORKS")) {
00302                     QStringList &list = project->variables()["FRAMEWORKS"];
00303                     for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00304                         t << "\t\t\t\t<FRAMEWORK>" << endl
00305                           << "\t\t\t\t\t<FILEREF>" << endl
00306                           << "\t\t\t\t\t\t<PATHTYPE>Name</PATHTYPE>" << endl
00307                           << "\t\t\t\t\t\t<PATH>" << (*it) << "</PATH>" << endl
00308                           << "\t\t\t\t\t\t<PATHFORMAT>MacOS</PATHFORMAT>" << endl
00309                           << "\t\t\t\t\t</FILEREF>" << endl
00310                           << "\t\t\t\t</FRAMEWORK>" << endl;
00311                     }
00312                 }
00313             } else if(variable == "CODEWARRIOR_DEPENDPATH" || variable == "CODEWARRIOR_INCLUDEPATH" ||
00314                 variable == "CODEWARRIOR_FRAMEWORKPATH") {      
00315                 QString arg=variable.right(variable.length()-variable.find('_')-1);
00316                 QStringList list;
00317                 if(arg == "INCLUDEPATH") {
00318                     list = project->variables()[arg];
00319                     list << Option::mkfile::qmakespec;
00320                     list << QDir::current().currentDirPath();
00321 
00322                     QStringList &l = project->variables()["QMAKE_LIBS_PATH"];
00323                     for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
00324                         QString p = (*val_it), v;
00325                         if(!fixifyToMacPath(p, v))
00326                             continue;
00327 
00328                         t << "\t\t\t\t\t<SETTING>" << endl
00329                           << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
00330                           << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
00331                           << "<VALUE>" << p << "</VALUE></SETTING>" << endl
00332                           << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
00333                           << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>CodeWarrior</VALUE></SETTING>" << endl
00334                           << "\t\t\t\t\t\t</SETTING>" << endl
00335                           << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>true</VALUE></SETTING>" << endl
00336                           << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
00337                           << "\t\t\t\t\t</SETTING>" << endl;
00338                     }
00339                 } else if(variable == "DEPENDPATH") {
00340                     QStringList &l = project->variables()[arg];
00341                     for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it)
00342                     {
00343                         //apparently tmake used colon separation...
00344                         QStringList damn = QStringList::split(':', (*val_it));
00345                         if(!damn.isEmpty())
00346                             list += damn;
00347                         else
00348                             list.append((*val_it));
00349                     }
00350                 } else {
00351                     list = project->variables()[arg];
00352                 }
00353                 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00354                     QString p = (*it), v, recursive = "false", framework = "false";
00355                     if(p.startsWith("recursive--")) {
00356                         p = p.right(p.length() - 11);
00357                         recursive = "true";
00358                     } 
00359                     if(!fixifyToMacPath(p, v))
00360                         continue;
00361                     if(arg == "FRAMEWORKPATH")
00362                         framework = "true";
00363 
00364                     t << "\t\t\t\t\t<SETTING>" << endl
00365                       << "\t\t\t\t\t\t<SETTING><NAME>SearchPath</NAME>" << endl
00366                       << "\t\t\t\t\t\t\t<SETTING><NAME>Path</NAME>"
00367                       << "<VALUE>" << p << "</VALUE></SETTING>" << endl
00368                       << "\t\t\t\t\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
00369                       << "\t\t\t\t\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << v << "</VALUE></SETTING>" << endl
00370                       << "\t\t\t\t\t\t</SETTING>" << endl
00371                       << "\t\t\t\t\t\t<SETTING><NAME>Recursive</NAME><VALUE>" << recursive << "</VALUE></SETTING>" << endl
00372                     << "\t\t\t\t\t\t<SETTING><NAME>FrameworkPath</NAME><VALUE>" << framework << "</VALUE></SETTING>" << endl
00373                     << "\t\t\t\t\t\t<SETTING><NAME>HostFlags</NAME><VALUE>All</VALUE></SETTING>" << endl
00374                       << "\t\t\t\t\t</SETTING>" << endl;
00375                 }
00376             } else if(variable == "CODEWARRIOR_WARNING" || variable == "!CODEWARRIOR_WARNING") {
00377                 bool b = ((!project->isActiveConfig("warn_off")) && 
00378                           project->isActiveConfig("warn_on"));
00379                 if(variable.startsWith("!"))
00380                     b = !b;
00381                 t << (int)b;
00382             } else if(variable == "CODEWARRIOR_TEMPLATE") {
00383                 if(project->first("TEMPLATE") == "app" ) {
00384                     t << "Executable";
00385                 } else if(project->first("TEMPLATE") == "lib") {
00386                     if(project->isActiveConfig("staticlib"))
00387                        t << "Library";
00388                     else
00389                         t << "SharedLibrary";
00390                 }
00391             } else if(variable == "CODEWARRIOR_OUTPUT_DIR") {
00392                 QString outdir = "{Project}/", volume;
00393                 if(!project->isEmpty("DESTDIR"))
00394                     outdir = project->first("DESTDIR");
00395                 if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console"))
00396                     outdir += var("TARGET") + ".app/Contents/MacOS/";
00397                 if(fixifyToMacPath(outdir, volume, FALSE)) {
00398                     t << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir << "</VALUE></SETTING>" 
00399                       << endl
00400                       << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" << endl
00401                       << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume << "</VALUE></SETTING>" 
00402                       << endl;
00403                 }
00404             } else if(variable == "CODEWARRIOR_PACKAGER_PANEL") {
00405                 if(project->first("TEMPLATE") == "app" && !project->isActiveConfig("console")) {
00406                     QString outdir = "{Project}/", volume;
00407                     if(!project->isEmpty("DESTDIR"))
00408                         outdir = project->first("DESTDIR");
00409                     outdir += var("TARGET") + ".app";
00410                     if(fixifyToMacPath(outdir, volume, FALSE)) {
00411                         t << "\t\t<SETTING><NAME>MWMacOSPackager_UsePackager</NAME>"
00412                           << "<VALUE>1</VALUE></SETTING>" << "\n"
00413                           << "\t\t<SETTING><NAME>MWMacOSPackager_FolderToPackage</NAME>" << "\n"
00414                           << "\t\t\t<SETTING><NAME>Path</NAME><VALUE>" << outdir 
00415                           << "</VALUE></SETTING>" << "\n"
00416                           << "\t\t\t<SETTING><NAME>PathFormat</NAME><VALUE>MacOS</VALUE></SETTING>" 
00417                           << "\n"
00418                           << "\t\t\t<SETTING><NAME>PathRoot</NAME><VALUE>" << volume 
00419                           << "</VALUE></SETTING>" << "\n"
00420                           << "\t\t</SETTING>" << "\n"
00421                           << "\t\t<SETTING><NAME>MWMacOSPackager_CreateClassicAlias</NAME>"
00422                           << "<VALUE>0</VALUE></SETTING>" << "\n"
00423                           << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasMethod</NAME>"
00424                           << "<VALUE>UseTargetOutput</VALUE></SETTING>" << "\n"
00425                           << "\t\t<SETTING><NAME>MWMacOSPackager_ClassicAliasPath</NAME>"
00426                           << "<VALUE></VALUE></SETTING>" << "\n"
00427                           << "\t\t<SETTING><NAME>MWMacOSPackager_CreatePkgInfo</NAME>"
00428                           << "<VALUE>1</VALUE></SETTING>" << "\n"
00429                           << "\t\t<SETTING><NAME>MWMacOSPackager_PkgCreatorType</NAME>" 
00430                           << "<VALUE>CUTE</VALUE></SETTING>" << "\n"
00431                           << "\t\t<SETTING><NAME>MWMacOSPackager_PkgFileType</NAME>" 
00432                           << "<VALUE>APPL</VALUE></SETTING>" << endl;
00433                     }
00434                 }
00435             } else if(variable == "CODEWARRIOR_FILETYPE") {
00436                 if(project->first("TEMPLATE") == "lib")
00437                         t << "MYDL";
00438                 else
00439                         t << "MEXE";
00440             } else if(variable == "CODEWARRIOR_QTDIR") {
00441                 t << getenv("QTDIR");
00442             } else if(variable == "CODEWARRIOR_CACHEMODDATES") {
00443                 t << "true";
00444             } else {
00445                 t << var(variable);
00446             }
00447         }
00448         t << line << endl;
00449     }
00450     t << endl;
00451     file.close();
00452 
00453     if(mocAware()) { 
00454         QString mocs = project->first("MOCS");
00455         QFile mocfile(mocs);
00456         if(!mocfile.open(IO_WriteOnly)) {
00457             fprintf(stderr, "Cannot open MOCS file: %s\n", mocs.latin1());
00458         } else {
00459             createFork(mocs);
00460             QTextStream mocs(&mocfile);
00461             QStringList &list = project->variables()["SRCMOC"];
00462             for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00463                 QString src = findMocSource((*it));
00464                 if(src.findRev('/') != -1)
00465                     src = src.right(src.length() - src.findRev('/') - 1);
00466                 mocs << src << endl;
00467             }
00468             mocfile.close();
00469         }
00470     }
00471 
00472     if(!project->isEmpty("FORMS")) { 
00473         QString uics = project->first("UICS");
00474         QFile uicfile(uics);
00475         if(!uicfile.open(IO_WriteOnly)) {
00476             fprintf(stderr, "Cannot open UICS file: %s\n", uics.latin1());
00477         } else {
00478             createFork(uics);
00479             QTextStream uics(&uicfile);
00480             QStringList &list = project->variables()["FORMS"];
00481             for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00482                 QString ui = (*it);
00483                 if(ui.findRev('/') != -1)
00484                     ui = ui.right(ui.length() - ui.findRev('/') - 1);
00485                 uics << ui << endl;
00486             }
00487             uicfile.close();
00488         }
00489     }
00490 
00491     if(!project->isEmpty("CODEWARRIOR_PREFIX_HEADER")) {
00492         QFile prefixfile(project->first("CODEWARRIOR_PREFIX_HEADER"));
00493         if(!prefixfile.open(IO_WriteOnly)) {
00494             fprintf(stderr, "Cannot open PREFIX file: %s\n", prefixfile.name().latin1());
00495         } else {
00496             createFork(project->first("CODEWARRIOR_PREFIX_HEADER"));
00497             QTextStream prefix(&prefixfile);
00498             QStringList &list = project->variables()["DEFINES"];
00499             for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
00500                 if((*it).find('=') != -1) {
00501                     int x = (*it).find('=');
00502                     prefix << "#define " << (*it).left(x) << " " << (*it).right((*it).length() - x - 1) << endl;
00503                 } else {
00504                     prefix << "#define " << (*it) << endl;
00505                 }
00506             }
00507             prefixfile.close();
00508         }
00509     }
00510     return TRUE;
00511 }
00512 
00513 
00514 
00515 void
00516 MetrowerksMakefileGenerator::init()
00517 {
00518     if(init_flag)
00519         return;
00520     init_flag = TRUE;
00521 
00522     if ( project->isEmpty("QMAKE_XML_TEMPLATE") ) 
00523         project->variables()["QMAKE_XML_TEMPLATE"].append("mwerkstmpl.xml");
00524 
00525     QStringList &configs = project->variables()["CONFIG"];
00526     if(project->isActiveConfig("qt")) {
00527         if(configs.findIndex("moc")) configs.append("moc");
00528         if ( !( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
00529                 (project->first("TARGET") == "qt-mt") ) ) 
00530             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
00531         if(configs.findIndex("moc")) 
00532             configs.append("moc");
00533         if ( !project->isActiveConfig("debug") ) 
00534             project->variables()["DEFINES"].append("QT_NO_DEBUG");
00535     }
00536 
00537     //version handling
00538     if(project->variables()["VERSION"].isEmpty())
00539         project->variables()["VERSION"].append("1.0." + 
00540                                                (project->isEmpty("VER_PAT") ? QString("0") : 
00541                                                 project->first("VER_PAT")) );
00542     QStringList ver = QStringList::split('.', project->first("VERSION"));
00543     ver << "0" << "0"; //make sure there are three
00544     project->variables()["VER_MAJ"].append(ver[0]);
00545     project->variables()["VER_MIN"].append(ver[1]);
00546     project->variables()["VER_PAT"].append(ver[2]);
00547 
00548     if( !project->isEmpty("LIBS") )
00549         project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
00550     if( project->variables()["QMAKE_EXTENSION_SHLIB"].isEmpty() )
00551         project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dylib" );
00552 
00553     if ( project->isActiveConfig("moc") ) {
00554         QString mocfile = project->first("TARGET");
00555         if(project->first("TEMPLATE") == "lib")
00556             mocfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
00557         project->variables()["MOCS"].append(mocfile + ".mocs");
00558         setMocAware(TRUE);
00559     }
00560     if(!project->isEmpty("FORMS")) {
00561         QString uicfile = project->first("TARGET");
00562         if(project->first("TEMPLATE") == "lib")
00563             uicfile += project->isActiveConfig("staticlib") ? "_static" : "_shared";
00564         project->variables()["UICS"].append(uicfile + ".uics");
00565     }
00566     if(project->isEmpty("DESTDIR"))
00567         project->variables()["DESTDIR"].append(QDir::currentDirPath());
00568     MakefileGenerator::init();
00569 
00570     if ( project->isActiveConfig("opengl") ) {
00571         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
00572         if ( (project->first("TARGET") == "qt") || (project->first("TARGET") == "qte") ||
00573              (project->first("TARGET") == "qt-mt") )
00574             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
00575         else 
00576             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
00577     }
00578 
00579     if(project->isActiveConfig("qt"))
00580         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
00581     if(project->isEmpty("FRAMEWORKPATH"))
00582         project->variables()["FRAMEWORKPATH"].append("/System/Library/Frameworks/");
00583 
00584     //set the target up
00585     project->variables()["TARGET_STEM"] = project->variables()["TARGET"];
00586     if(project->first("TEMPLATE") == "lib") {
00587         if(project->isActiveConfig("staticlib"))
00588             project->variables()["TARGET"].first() =  "lib" + project->first("TARGET") + ".lib";
00589         else
00590             project->variables()["TARGET"].first() =  "lib" + project->first("TARGET") + "." +
00591                                                       project->first("QMAKE_EXTENSION_SHLIB");
00592 
00593         project->variables()["CODEWARRIOR_VERSION"].append(project->first("VER_MAJ") +
00594                                                           project->first("VER_MIN") +
00595                                                           project->first("VER_PAT"));
00596     } else {
00597         project->variables()["CODEWARRIOR_VERSION"].append("0");
00598         if(project->isEmpty("QMAKE_ENTRYPOINT"))
00599            project->variables()["QMAKE_ENTRYPOINT"].append("start");
00600         project->variables()["CODEWARRIOR_ENTRYPOINT"].append(
00601             project->first("QMAKE_ENTRYPOINT"));
00602     }
00603 }
00604 
00605 
00606 QString
00607 MetrowerksMakefileGenerator::findTemplate(const QString &file)
00608 {
00609     QString ret;
00610     if(!QFile::exists(ret = file) && 
00611        !QFile::exists((ret = Option::mkfile::qmakespec + QDir::separator() + file)) && 
00612        !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/mac-mwerks/" + file)) &&
00613        !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
00614         return "";
00615     return ret;
00616 }
00617 
00618 bool
00619 MetrowerksMakefileGenerator::createFork(const QString &f)
00620 {
00621 #if !defined(QWS) && defined(Q_OS_MACX)
00622     FSRef fref;
00623     FSSpec fileSpec;
00624     if(QFile::exists(f)) {
00625         mode_t perms = 0;
00626         {
00627             struct stat s;
00628             stat(f.latin1(), &s);
00629             if(!(s.st_mode & S_IWUSR)) {
00630                 perms = s.st_mode;
00631                 chmod(f.latin1(), perms | S_IWUSR);
00632             }
00633         }
00634         FILE *o = fopen(f.latin1(), "a");
00635         if(!o)
00636             return FALSE;
00637         if(FSPathMakeRef((const UInt8 *)f.latin1(), &fref, NULL) == noErr) {
00638             if(FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &fileSpec, NULL) == noErr) 
00639                 FSpCreateResFile(&fileSpec, 'CUTE', 'TEXT', smSystemScript);
00640             else 
00641                 qDebug("bogus %d", __LINE__);
00642         } else 
00643             qDebug("bogus %d", __LINE__);
00644         fclose(o);
00645         if(perms)
00646             chmod(f.latin1(), perms);
00647     }
00648 #else
00649     Q_UNUSED(f)
00650 #endif
00651     return TRUE;
00652 }
00653 
00654 bool
00655 MetrowerksMakefileGenerator::fixifyToMacPath(QString &p, QString &v, bool )
00656 {
00657     v = "Absolute";
00658     if(p.find(':') != -1) //guess its macish already
00659         return TRUE;
00660 
00661     static QString st_volume;
00662     if(st_volume.isEmpty()) {
00663         st_volume = var("QMAKE_VOLUMENAME");
00664 #if !defined(QWS) && defined(Q_OS_MACX)
00665         if(st_volume.isEmpty()) {
00666             uchar foo[512];
00667             HVolumeParam pb;
00668             memset(&pb, '\0', sizeof(pb));
00669             pb.ioVRefNum = 0;
00670             pb.ioNamePtr = foo;
00671             if(PBHGetVInfoSync((HParmBlkPtr)&pb) == noErr) {
00672                 int len = foo[0];
00673                 memcpy(foo,foo+1, len);
00674                 foo[len] = '\0';
00675                 st_volume = (char *)foo;
00676             }
00677         }
00678 #endif
00679     }
00680     QString volume = st_volume;
00681 
00682     fixEnvVariables(p);
00683     if(p.startsWith("\"") && p.endsWith("\""))
00684         p = p.mid(1, p.length() - 2);
00685     if(p.isEmpty()) 
00686         return FALSE;
00687     if(!p.endsWith("/"))
00688         p += "/";
00689     if(QDir::isRelativePath(p)) {
00690         if(p.startsWith("{")) {
00691             int eoc = p.find('}');
00692             if(eoc == -1)
00693                 return FALSE;
00694             volume = p.mid(1, eoc - 1);
00695             p = p.right(p.length() - eoc - 1);
00696         } else {
00697             QFileInfo fi(p);
00698             if(fi.convertToAbs()) //strange
00699                 return FALSE;
00700             p = fi.filePath();
00701         } 
00702     } 
00703     p = QDir::cleanDirPath(p);
00704     if(!volume.isEmpty()) 
00705         v = volume;
00706     p.replace("/", ":");
00707     if(p.right(1) != ":")
00708         p += ':';
00709     return TRUE;
00710 }
00711 
00712 void
00713 MetrowerksMakefileGenerator::processPrlFiles()
00714 {
00715     QPtrList<MakefileDependDir> libdirs;
00716     libdirs.setAutoDelete(TRUE);
00717     const QString lflags[] = { "QMAKE_LIBS", QString::null };
00718     for(int i = 0; !lflags[i].isNull(); i++) {
00719         for(bool ret = FALSE; TRUE; ret = FALSE) {
00720             QStringList l_out;
00721             QStringList &l = project->variables()[lflags[i]];
00722             for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00723                 QString opt = (*it);
00724                 if(opt.startsWith("-")) {
00725                     if(opt.startsWith("-L")) {
00726                         QString r = opt.right(opt.length() - 2), l = r;
00727                         fixEnvVariables(l);
00728                         libdirs.append(new MakefileDependDir(r.replace( "\"", ""),
00729                                                              l.replace( "\"", "")));
00730                     } else if(opt.left(2) == "-l") {
00731                         QString lib = opt.right(opt.length() - 2), prl;
00732                         for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
00733                             prl = mdd->local_dir + Option::dir_sep + "lib" + lib;
00734                             if(processPrlFile(prl)) {
00735                                 if(prl.startsWith(mdd->local_dir))
00736                                     prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
00737                                 QRegExp reg("^.*lib(" + lib + "[^.]*)\\." + 
00738                                             project->first("QMAKE_EXTENSION_SHLIB") + "$");
00739                                 if(reg.exactMatch(prl))
00740                                     prl = "-l" + reg.cap(1);
00741                                 opt = prl;
00742                                 ret = TRUE;
00743                                 break;
00744                             }
00745                         }
00746                     } else if(opt == "-framework") {
00747                         l_out.append(opt);
00748                         ++it;
00749                         opt = (*it);
00750                         QString prl = "/System/Library/Frameworks/" + opt +
00751                                       ".framework/" + opt;
00752                         if(processPrlFile(prl))
00753                             ret = TRUE;
00754                     }
00755                     if(!opt.isEmpty())
00756                         l_out.append(opt);
00757                 } else {
00758                     if(processPrlFile(opt))
00759                         ret = TRUE;
00760                     if(!opt.isEmpty())
00761                         l_out.append(opt);
00762                 }
00763             }
00764             if(ret)
00765                 l = l_out;
00766             else
00767                 break;
00768         }
00769     }
00770 }
00771 
00772 void
00773 MetrowerksMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
00774 {
00775     if(var == "QMAKE_PRL_LIBS") {
00776         QStringList &out = project->variables()["QMAKE_LIBS"];
00777         for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
00778             bool append = TRUE;
00779             if((*it).startsWith("-")) {
00780                 if((*it).startsWith("-l") || (*it).startsWith("-L")) {
00781                     append = out.findIndex((*it)) == -1;
00782                 } else if((*it).startsWith("-framework")) {
00783                     ++it;
00784                     for(QStringList::ConstIterator outit = out.begin(); 
00785                         outit != out.end(); ++it) {
00786                         if((*outit) == "-framework") {
00787                             ++outit;
00788                             if((*outit) == (*it)) {
00789                                 append = FALSE;
00790                                 break;
00791                             }
00792                         }
00793                     }
00794                 }
00795             } else if(QFile::exists((*it))) {
00796                 append = out.findIndex((*it));
00797             }
00798             if(append)
00799                 out.append((*it));
00800         }
00801     } else {
00802         MakefileGenerator::processPrlVariable(var, l);
00803     }
00804 }
00805 
00806 
00807 bool
00808 MetrowerksMakefileGenerator::openOutput(QFile &file) const
00809 {
00810     QString outdir;
00811     if(!file.name().isEmpty()) {
00812         QFileInfo fi(file);
00813         if(fi.isDir())
00814             outdir = file.name() + QDir::separator();
00815     }
00816     if(!outdir.isEmpty() || file.name().isEmpty()) 
00817         file.setName(outdir + project->first("TARGET") + ".xml");
00818     return MakefileGenerator::openOutput(file);
00819 }

Generated on Sat Nov 5 16:18:18 2005 for OPIE by  doxygen 1.4.2