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

unixmake2.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 **
00004 ** Implementation of UnixMakefileGenerator 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 "unixmake.h"
00037 #include "option.h"
00038 #include "meta.h"
00039 #include <qregexp.h>
00040 #include <qfile.h>
00041 #include <qdir.h>
00042 #include <time.h>
00043 
00044 QString mkdir_p_asstring(const QString &dir);
00045 
00046 UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE)
00047 {
00048 
00049 }
00050 
00051 void
00052 UnixMakefileGenerator::writePrlFile(QTextStream &t)
00053 {
00054     MakefileGenerator::writePrlFile(t);
00055     // libtool support
00056     if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la
00057         if(project->isActiveConfig("compile_libtool"))
00058             warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n"
00059                      "formats, create_libtool has been disabled\n");
00060         else
00061             writeLibtoolFile();
00062     }
00063     // pkg-config support
00064     if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib")
00065         writePkgConfigFile();
00066 }
00067 
00068 bool
00069 UnixMakefileGenerator::writeMakefile(QTextStream &t)
00070 {
00071 
00072     writeHeader(t);
00073     if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
00074         t << "QMAKE    = "      << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
00075         { //write the extra unix targets..
00076             QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
00077             for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
00078                 t << *it << " ";
00079         }
00080         t << "all clean install distclean mocables uninstall uicables:" << "\n\t"
00081           << "@echo \"Some of the required modules ("
00082           << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
00083           << "@echo \"Skipped.\"" << endl << endl;
00084         writeMakeQmake(t);
00085         return TRUE;
00086     }
00087 
00088     if (project->variables()["TEMPLATE"].first() == "app" ||
00089         project->variables()["TEMPLATE"].first() == "lib") {
00090         writeMakeParts(t);
00091         return MakefileGenerator::writeMakefile(t);
00092     } else if(project->variables()["TEMPLATE"].first() == "subdirs") {
00093         writeSubdirs(t);
00094         return TRUE;
00095     }
00096     return FALSE;
00097 }
00098 
00099 void
00100 UnixMakefileGenerator::writeExtraVariables(QTextStream &t)
00101 {
00102     bool first = TRUE;
00103     QMap<QString, QStringList> &vars = project->variables();
00104     QStringList &exports = project->variables()["QMAKE_EXTRA_UNIX_VARIABLES"];
00105     for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) {
00106         for(QStringList::Iterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) {
00107             QRegExp rx((*exp_it), FALSE, TRUE);
00108             if(rx.exactMatch(it.key())) {
00109                 if(first) {
00110                     t << "\n####### Custom Variables" << endl;
00111                     first = FALSE;
00112                 }
00113                 t << "EXPORT_" << it.key() << " = " << it.data().join(" ") << endl;
00114             }
00115         }
00116     }
00117     if(!first)
00118         t << endl;
00119 }
00120 
00121 void
00122 UnixMakefileGenerator::writeMakeParts(QTextStream &t)
00123 {
00124     QString deps = fileFixify(Option::output.name()), target_deps, prl;
00125     bool do_incremental = (project->isActiveConfig("incremental") &&
00126                            !project->variables()["QMAKE_INCREMENTAL"].isEmpty() &&
00127                            (!project->variables()["QMAKE_APP_FLAG"].isEmpty() ||
00128                             !project->isActiveConfig("staticlib"))),
00129          src_incremental=FALSE, moc_incremental=FALSE;
00130 
00131     t << "####### Compiler, tools and options" << endl << endl;
00132     t << "CC       = ";
00133     if (project->isActiveConfig("thread") &&
00134         ! project->variables()["QMAKE_CC_THREAD"].isEmpty())
00135         t << var("QMAKE_CC_THREAD") << endl;
00136     else
00137         t << var("QMAKE_CC") << endl;
00138 
00139     t << "CXX      = ";
00140     if (project->isActiveConfig("thread") &&
00141         ! project->variables()["QMAKE_CXX_THREAD"].isEmpty())
00142         t << var("QMAKE_CXX_THREAD") << endl;
00143     else
00144         t << var("QMAKE_CXX") << endl;
00145 
00146     t << "LEX      = " << var("QMAKE_LEX") << endl;
00147     t << "YACC     = " << var("QMAKE_YACC") << endl;
00148     t << "CFLAGS   = " << var("QMAKE_CFLAGS") << " "
00149       << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
00150       << varGlue("DEFINES","-D"," -D","") << endl;
00151     t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
00152       << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
00153       << varGlue("DEFINES","-D"," -D","") << endl;
00154     t << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
00155     t << "YACCFLAGS= " << var("QMAKE_YACCFLAGS") << endl;
00156     t << "INCPATH  = " << "-I" << specdir();
00157     if(!project->isActiveConfig("no_include_pwd")) {
00158         QString pwd = fileFixify(QDir::currentDirPath());
00159         if(pwd.isEmpty())
00160             pwd = ".";
00161         t << " -I" << pwd;
00162     }
00163     t << varGlue("INCLUDEPATH"," -I", " -I", "") << endl;
00164 
00165     if(!project->isActiveConfig("staticlib")) {
00166         t << "LINK     = ";
00167         if (project->isActiveConfig("thread") &&
00168             ! project->variables()["QMAKE_LINK_THREAD"].isEmpty())
00169             t << var("QMAKE_LINK_THREAD") << endl;
00170         else
00171             t << var("QMAKE_LINK") << endl;
00172 
00173         t << "LFLAGS   = " << var("QMAKE_LFLAGS") << endl;
00174         t << "LIBS     = " << "$(SUBLIBS) " << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << endl;
00175     }
00176 
00177     t << "AR       = " << var("QMAKE_AR") << endl;
00178     t << "RANLIB   = " << var("QMAKE_RANLIB") << endl;
00179     t << "MOC      = " << var("QMAKE_MOC") << endl;
00180     t << "UIC      = "  << var("QMAKE_UIC") << endl;
00181     t << "QMAKE    = "  << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
00182     t << "TAR      = "  << var("QMAKE_TAR") << endl;
00183     t << "GZIP     = " << var("QMAKE_GZIP") << endl;
00184     if(project->isActiveConfig("compile_libtool"))
00185         t << "LIBTOOL   = " << var("QMAKE_LIBTOOL") << endl;
00186     t << "COPY     = " << var("QMAKE_COPY") << endl;
00187     t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl;
00188     t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl;
00189     t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl;
00190     t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
00191 
00192     t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
00193     t << "SYMLINK  = " << var("QMAKE_SYMBOLIC_LINK") << endl;
00194     t << "DEL_DIR  = " << var("QMAKE_DEL_DIR") << endl;
00195     t << "MOVE     = " << var("QMAKE_MOVE") << endl;
00196     t << "PRO      = " << fileFixify(project->projectFile()  )<< endl;
00197     t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
00198     t << "MKDIR    = " << var("QMAKE_MKDIR") << endl;
00199     t << endl;
00200 
00201     t << "####### Output directory" << endl << endl;
00202     if (! project->variables()["OBJECTS_DIR"].isEmpty())
00203         t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl;
00204     else
00205         t << "OBJECTS_DIR = ./" << endl;
00206     t << endl;
00207 
00208     /* files */
00209     t << "####### Files" << endl << endl;
00210     t << "HEADERS = " << varList("HEADERS") << endl;
00211     t << "SOURCES = " << varList("SOURCES") << endl;
00212     if(do_incremental) {
00213         QStringList &objs = project->variables()["OBJECTS"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
00214         t << "OBJECTS = ";
00215         for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
00216             bool increment = FALSE;
00217             for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
00218                 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
00219                     increment = TRUE;
00220                     incrs_out.append((*objit));
00221                     break;
00222                 }
00223             }
00224             if(!increment)
00225                 t << "\\\n\t\t" << (*objit);
00226         }
00227         if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
00228             t << incrs_out.join(" \\\n\t\t") << endl;
00229         } else if(!incrs_out.count()) {
00230             t << endl;
00231         } else {
00232             src_incremental = TRUE;
00233             t << endl;
00234             t << "INCREMENTAL_OBJECTS = " << incrs_out.join(" \\\n\t\t") << endl;
00235         }
00236     } else {
00237         t << "OBJECTS = " << varList("OBJECTS") << endl;
00238     }
00239     t << "FORMS = " << varList("FORMS") << endl;
00240     t << "UICDECLS = " << varList("UICDECLS") << endl;
00241     t << "UICIMPLS = " << varList("UICIMPLS") << endl;
00242     QString srcMoc = varList("SRCMOC"), objMoc = varList("OBJMOC");
00243     t << "SRCMOC   = " << srcMoc << endl;
00244     if(do_incremental) {
00245         QStringList &objs = project->variables()["OBJMOC"],
00246                    &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
00247         t << "OBJMOC = ";
00248         for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
00249             bool increment = FALSE;
00250             for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
00251                 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
00252                     increment = TRUE;
00253                     incrs_out.append((*objit));
00254                     break;
00255                 }
00256             }
00257             if(!increment)
00258                 t << "\\\n\t\t" << (*objit);
00259         }
00260         if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
00261             t << incrs_out.join(" \\\n\t\t") << endl;
00262         } else if(!incrs_out.count()) {
00263             t << endl;
00264         } else {
00265             moc_incremental = TRUE;
00266             t << endl;
00267             t << "INCREMENTAL_OBJMOC = " << incrs_out.join(" \\\n\t\t") << endl;
00268         }
00269     } else {
00270         t << "OBJMOC = " << objMoc << endl;
00271     }
00272     if(do_incremental && !moc_incremental && !src_incremental)
00273         do_incremental = FALSE;
00274     if(!project->isEmpty("QMAKE_EXTRA_UNIX_COMPILERS")) {
00275         t << "OBJCOMP = " << varList("OBJCOMP") << endl;
00276         target_deps += " $(OBJCOMP)";
00277 
00278         QStringList &comps = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
00279         for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) {
00280             QStringList &vars = project->variables()[(*compit) + ".variables"];
00281             for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) {
00282                 QStringList vals = project->variables()[(*varit)];
00283                 if(!vals.isEmpty())
00284                     t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl;
00285             }
00286         }
00287     }
00288     t << "DIST     = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl;
00289     t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
00290     t << "DESTDIR  = " << var("DESTDIR") << endl;
00291     if(project->isActiveConfig("compile_libtool"))
00292         t << "TARGETL   = " << var("TARGET_la") << endl;
00293     t << "TARGET   = " << var("TARGET") << endl;
00294     if(project->isActiveConfig("plugin") ) {
00295         t << "TARGETD   = " << var("TARGET") << endl;
00296     } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
00297         t << "TARGETA   = " << var("TARGETA") << endl;
00298         if (project->isEmpty("QMAKE_HPUX_SHLIB")) {
00299             t << "TARGETD       = " << var("TARGET_x.y.z") << endl;
00300             t << "TARGET0       = " << var("TARGET_") << endl;
00301             t << "TARGET1       = " << var("TARGET_x") << endl;
00302             t << "TARGET2       = " << var("TARGET_x.y") << endl;
00303         } else {
00304             t << "TARGETD       = " << var("TARGET_x") << endl;
00305             t << "TARGET0       = " << var("TARGET_") << endl;
00306         }
00307     }
00308     writeExtraVariables(t);
00309     t << endl;
00310 
00311     // blasted includes
00312     QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"];
00313     QStringList::Iterator it;
00314     for( it = qeui.begin(); it != qeui.end(); ++it)
00315         t << "include " << (*it) << endl;
00316 
00317     /* rules */
00318     t << "first: all" << endl;
00319     t << "####### Implicit rules" << endl << endl;
00320     t << ".SUFFIXES: .c " << Option::obj_ext;
00321     QStringList::Iterator cppit;
00322     for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
00323         t << " " << (*cppit);
00324     t << endl << endl;
00325     for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
00326         t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
00327     t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
00328 
00329     if(include_deps) {
00330         QString cmd=var("QMAKE_CFLAGS_DEPS") + " ";
00331         cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D","");
00332         if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
00333             cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " ";
00334         cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", "");
00335         QString odir;
00336         if(!project->variables()["OBJECTS_DIR"].isEmpty())
00337             odir = project->first("OBJECTS_DIR");
00338         t << "###### Dependencies" << endl << endl;
00339         t << odir << ".deps/%.d: %.cpp\n\t"
00340           << "@echo Creating depend for $<" << "\n\t"
00341           << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
00342           << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
00343 
00344         t << odir << ".deps/%.d: %.c\n\t"
00345           << "@echo Creating depend for $<" << "\n\t"
00346           << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
00347           << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
00348 
00349         QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null };
00350         for(int x = 0; !src[x].isNull(); x++) {
00351             QStringList &l = project->variables()[src[x]];
00352             for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00353                 if(!(*it).isEmpty()) {
00354                     QString d_file;
00355                     if((*it).endsWith(".c")) {
00356                         d_file = (*it).left((*it).length() - 2);
00357                     } else {
00358                         for(QStringList::Iterator cppit = Option::cpp_ext.begin();
00359                             cppit != Option::cpp_ext.end(); ++cppit) {
00360                             if((*it).endsWith((*cppit))) {
00361                                 d_file = (*it).left((*it).length() - (*cppit).length());
00362                                 break;
00363                             }
00364                         }
00365                     }
00366                     if(!d_file.isEmpty()) {
00367                         d_file = odir + ".deps/" + d_file + ".d";
00368                         QStringList deps = findDependencies((*it)).grep(QRegExp(Option::cpp_moc_ext + "$"));
00369                         if(!deps.isEmpty())
00370                             t << d_file << ": " << deps.join(" ") << endl;
00371                         t << var("QMAKE_CFLAGS_USE_PRECOMPILE") << " " << d_file << endl;
00372                     }
00373                 }
00374             }
00375         }
00376     }
00377 
00378     t << "####### Build rules" << endl << endl;
00379     if(!project->variables()["SUBLIBS"].isEmpty()) {
00380         QString libdir = "tmp/";
00381         if(!project->isEmpty("SUBLIBS_DIR"))
00382             libdir = project->first("SUBLIBS_DIR");
00383         t << "SUBLIBS= ";
00384         QStringList &l = project->variables()["SUBLIBS"];
00385         for(QStringList::Iterator it = l.begin(); it != l.end(); ++it)
00386             t << libdir << "lib" << (*it) << ".a ";
00387         t << endl << endl;
00388     }
00389     if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) {
00390         QStringList &l = project->variables()["QMAKE_PRL_INTERNAL_FILES"];
00391         QStringList::Iterator it;
00392         for(it = l.begin(); it != l.end(); ++it) {
00393             QMakeMetaInfo libinfo;
00394             if(libinfo.readLib((*it)) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) {
00395                 QString dir;
00396                 int slsh = (*it).findRev(Option::dir_sep);
00397                 if(slsh != -1)
00398                     dir = (*it).left(slsh + 1);
00399                 QString targ = dir + libinfo.first("QMAKE_PRL_TARGET");
00400                 deps += " " + targ;
00401                 t << targ << ":" << "\n\t"
00402                   << "@echo \"Creating '" << targ << "'\"" << "\n\t"
00403                   << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";"
00404                   << "$(MAKE) )" << endl;
00405             }
00406         }
00407     }
00408     if(!project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
00409         QString destdir = project->first("DESTDIR");
00410         if(do_incremental) {
00411             //incremental target
00412             QString incr_target = var("TARGET") + "_incremental";
00413             if(incr_target.find(Option::dir_sep) != -1)
00414                 incr_target = incr_target.right(incr_target.length() -
00415                                                 (incr_target.findRev(Option::dir_sep) + 1));
00416             QString incr_deps, incr_objs;
00417             if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
00418                 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
00419                 //actual target
00420                 t << incr_target_dir << ": $(OBJECTS)" << "\n\t"
00421                   << "ld -r  -o "<< incr_target_dir << " $(OBJECTS)" << endl;
00422                 //communicated below
00423                 deps.prepend(incr_target_dir + " ");
00424                 incr_deps = "$(UICDECLS) $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC) $(OBJMOC)";
00425                 if(!incr_objs.isEmpty())
00426                     incr_objs += " ";
00427                 incr_objs += incr_target_dir;
00428             } else {
00429                 //actual target
00430                 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." +
00431                                           project->variables()["QMAKE_EXTENSION_SHLIB"].first();
00432                 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
00433                 if(project->isActiveConfig("debug"))
00434                     incr_lflags += var("QMAKE_LFLAGS_DEBUG");
00435                 else
00436                     incr_lflags += var("QMAKE_LFLAGS_RELEASE");
00437                 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
00438                 if(!destdir.isEmpty())
00439                     t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00440                 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
00441                     " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
00442                 //communicated below
00443                 if(!destdir.isEmpty()) {
00444                     if(!incr_objs.isEmpty())
00445                         incr_objs += " ";
00446                     incr_objs += "-L" + destdir;
00447                 } else {
00448                     if(!incr_objs.isEmpty())
00449                         incr_objs += " ";
00450                     incr_objs += "-L" + QDir::currentDirPath();
00451                 }
00452                 if(!incr_objs.isEmpty())
00453                     incr_objs += " ";
00454                 incr_objs += " -l" + incr_target;
00455                 deps.prepend(incr_target_dir + " ");
00456                 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
00457             }
00458             t << "all: " << deps <<  " " << varGlue("ALL_DEPS",""," "," ") <<  "$(TARGET)"
00459               << endl << endl;
00460 
00461             //real target
00462             t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps
00463               << " " << var("POST_TARGETDEPS") << "\n\t";
00464             if(!destdir.isEmpty())
00465                 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00466             if(!project->isEmpty("QMAKE_PRE_LINK"))
00467                 t << var("QMAKE_PRE_LINK") << "\n\t";
00468             t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)";
00469             if(!project->isEmpty("QMAKE_POST_LINK"))
00470                 t << "\n\t" << var("QMAKE_POST_LINK");
00471             t << endl << endl;
00472         } else {
00473             t << "all: " << deps <<  " " << varGlue("ALL_DEPS",""," "," ") <<  "$(TARGET)"
00474               << endl << endl;
00475 
00476             t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
00477               << target_deps << " " << var("POST_TARGETDEPS") << "\n\t";
00478             if(!destdir.isEmpty())
00479                 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00480             if(!project->isEmpty("QMAKE_PRE_LINK"))
00481                 t << var("QMAKE_PRE_LINK") << "\n\t";
00482             t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS)";
00483             if(!project->isEmpty("QMAKE_POST_LINK"))
00484                 t << "\n\t" << var("QMAKE_POST_LINK");
00485             t << endl << endl;
00486         }
00487     } else if(!project->isActiveConfig("staticlib")) {
00488         QString destdir = project->first("DESTDIR"), incr_deps;
00489         if(do_incremental) {
00490             QString s_ext = project->variables()["QMAKE_EXTENSION_SHLIB"].first();
00491             QString incr_target = var("QMAKE_ORIG_TARGET").replace(
00492                 QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental";
00493             if(incr_target.find(Option::dir_sep) != -1)
00494                 incr_target = incr_target.right(incr_target.length() -
00495                                                 (incr_target.findRev(Option::dir_sep) + 1));
00496 
00497             if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
00498                 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
00499                 //actual target
00500                 const QString link_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
00501                 t << incr_target_dir << ": " << link_deps << "\n\t"
00502                   << "ld -r  -o " << incr_target_dir << " " << link_deps << endl;
00503                 //communicated below
00504                 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
00505                 cmd.first().replace("$(OBJECTS) $(OBJMOC)",
00506                                     "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"); //ick
00507                 cmd.append(incr_target_dir);
00508                 deps.prepend(incr_target_dir + " ");
00509                 incr_deps = "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
00510             } else {
00511                 //actual target
00512                 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + s_ext;
00513                 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
00514                 if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL"))
00515                     incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " ";
00516                 if(project->isActiveConfig("debug"))
00517                     incr_lflags += var("QMAKE_LFLAGS_DEBUG");
00518                 else
00519                     incr_lflags += var("QMAKE_LFLAGS_RELEASE");
00520                 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
00521                 if(!destdir.isEmpty())
00522                     t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00523                 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
00524                     " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
00525                 //communicated below
00526                 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
00527                 if(!destdir.isEmpty())
00528                     cmd.append(" -L" + destdir);
00529                 cmd.append(" -l" + incr_target);
00530                 deps.prepend(incr_target_dir + " ");
00531                 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
00532             }
00533 
00534             t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","")
00535               << " " <<  var("DESTDIR_TARGET") << endl << endl;
00536 
00537             //real target
00538             t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " "
00539               << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS");
00540         } else {
00541             t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " <<
00542                 var("DESTDIR_TARGET") << endl << endl;
00543             t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS")
00544               << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) $(OBJCOMP) " << target_deps
00545               << " " << var("POST_TARGETDEPS");
00546         }
00547         if(!destdir.isEmpty())
00548             t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir;
00549         if(!project->isEmpty("QMAKE_PRE_LINK"))
00550             t << "\n\t" << var("QMAKE_PRE_LINK");
00551 
00552         if(project->isActiveConfig("compile_libtool")) {
00553             t << "\n\t"
00554               << var("QMAKE_LINK_SHLIB_CMD");
00555         } else if(project->isActiveConfig("plugin")) {
00556             t << "\n\t"
00557               << "-$(DEL_FILE) $(TARGET)" << "\n\t"
00558               << var("QMAKE_LINK_SHLIB_CMD");
00559             if(!destdir.isEmpty())
00560                 t << "\n\t"
00561                   << "-$(MOVE) $(TARGET) " << var("DESTDIR");
00562             if(!project->isEmpty("QMAKE_POST_LINK"))
00563                 t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t";
00564             t << endl << endl;
00565         } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
00566             t << "\n\t"
00567               << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t"
00568               << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
00569             t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)")  << "\n\t"
00570               << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t"
00571               << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)");
00572             if(!destdir.isEmpty())
00573                 t << "\n\t"
00574                   << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
00575                   << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
00576                   << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t"
00577                   << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t"
00578                   << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR");
00579             if(!project->isEmpty("QMAKE_POST_LINK"))
00580                 t << "\n\t" << var("QMAKE_POST_LINK");
00581             t << endl << endl;
00582         } else {
00583             t << "\n\t"
00584               << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t"
00585               << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
00586             t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)");
00587             if(!destdir.isEmpty())
00588                 t  << "\n\t"
00589                    << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
00590                    << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
00591                    << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR");
00592             if(!project->isEmpty("QMAKE_POST_LINK"))
00593                 t << "\n\t" << var("QMAKE_POST_LINK");
00594             t << endl << endl;
00595         }
00596         t << endl << endl;
00597 
00598         if (! project->isActiveConfig("plugin")) {
00599             t << "staticlib: $(TARGETA)" << endl << endl;
00600             t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP)";
00601             if(do_incremental)
00602                 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
00603             t << var("POST_TARGETDEPS") << "\n\t"
00604               << "-$(DEL_FILE) $(TARGETA) " << "\n\t"
00605               << var("QMAKE_AR_CMD");
00606             if(do_incremental)
00607                 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
00608             if(!project->isEmpty("QMAKE_RANLIB"))
00609                 t << "\n\t" << "$(RANLIB) $(TARGETA)";
00610             t << endl << endl;
00611         }
00612     } else {
00613         t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) "
00614           << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n"
00615           << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n";
00616         if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
00617             t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS")
00618               << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t";
00619             if(!project->isEmpty("DESTDIR")) {
00620                 QString destdir = project->first("DESTDIR");
00621                 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00622             }
00623             t << "-$(DEL_FILE) $(TARGET)" << "\n\t"
00624               << var("QMAKE_AR_CMD") << "\n";
00625             if(!project->isEmpty("QMAKE_POST_LINK"))
00626                 t << "\t" << var("QMAKE_POST_LINK") << "\n";
00627             if(!project->isEmpty("QMAKE_RANLIB"))
00628                 t << "\t" << "$(RANLIB) $(TARGET)" << "\n";
00629             if(!project->isEmpty("DESTDIR"))
00630                 t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n"
00631                   << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n";
00632         } else {
00633             int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt();
00634             QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"] +
00635                                project->variables()["OBJCOMP"],
00636                         libs = project->variables()["QMAKE_AR_SUBLIBS"];
00637             libs.prepend("$(TARGET)");
00638             for(QStringList::Iterator libit = libs.begin(), objit = objs.begin();
00639                 libit != libs.end(); ++libit) {
00640                 QStringList build;
00641                 for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++)
00642                     build << (*objit);
00643                 QString ar;
00644                 if((*libit) == "$(TARGET)") {
00645                     t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS")
00646                       << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t";
00647                     ar = project->variables()["QMAKE_AR_CMD"].first();
00648                     ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)",
00649                                                              build.join(" "));
00650                 } else {
00651                     t << (*libit) << ": " << valList(build) << "\n\t";
00652                     ar = "$(AR) " + (*libit) + " " + build.join(" ");
00653                 }
00654                 if(!project->isEmpty("DESTDIR")) {
00655                     QString destdir = project->first("DESTDIR");
00656                     t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00657                 }
00658                 t << "-$(DEL_FILE) " << (*libit) << "\n\t"
00659                   << ar << "\n";
00660                 if(!project->isEmpty("QMAKE_POST_LINK"))
00661                     t << "\t" << var("QMAKE_POST_LINK") << "\n";
00662                 if(!project->isEmpty("QMAKE_RANLIB"))
00663                     t << "\t" << "$(RANLIB) " << (*libit) << "\n";
00664                 if(!project->isEmpty("DESTDIR"))
00665                     t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n"
00666                       << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n";
00667             }
00668         }
00669         t << endl << endl;
00670     }
00671 
00672     t << "mocables: $(SRCMOC)" << endl
00673       << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl;
00674 
00675     if(!project->isActiveConfig("no_mocdepend")) {
00676         //this is an implicity depend on moc, so it will be built if necesary, however
00677         //moc itself shouldn't have this dependency - this is a little kludgy but it is
00678         //better than the alternative for now.
00679         QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"),
00680             moc_dir = "$(QTDIR)/src/moc";
00681         if(!project->isEmpty("QMAKE_MOC_SRC"))
00682             moc_dir = project->first("QMAKE_MOC_SRC");
00683         fixEnvVariables(target);
00684         fixEnvVariables(moc);
00685         if(target != moc)
00686             t << "$(MOC): \n\t"
00687               << "( cd " << moc_dir << " && $(MAKE) )"  << endl << endl;
00688     }
00689 
00690     writeMakeQmake(t);
00691     if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) {
00692         QString meta_files;
00693         if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" &&
00694            !project->isActiveConfig("compile_libtool")) { //libtool
00695             if(!meta_files.isEmpty())
00696                 meta_files += " ";
00697             meta_files += libtoolFileName();
00698         }
00699         if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config
00700             if(!meta_files.isEmpty())
00701                 meta_files += " ";
00702             meta_files += pkgConfigFileName();
00703         }
00704         if(!meta_files.isEmpty()) {
00705             QStringList files = fileFixify(Option::mkfile::project_files);
00706             t << meta_files << ": " << "\n\t"
00707               << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl;
00708         }
00709     }
00710 
00711     if(!project->first("QMAKE_PKGINFO").isEmpty()) {
00712         QString pkginfo = project->first("QMAKE_PKGINFO");
00713         QString destdir = project->first("DESTDIR");
00714         t << pkginfo << ": " << "\n\t";
00715         if(!destdir.isEmpty())
00716             t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00717         t << "@$(DEL_FILE) " << pkginfo << "\n\t"
00718           << "@echo \"APPL????\" >" << pkginfo << endl;
00719     }
00720     if(!project->first("QMAKE_INFO_PLIST").isEmpty()) {
00721         QString info_plist = project->first("QMAKE_INFO_PLIST"),
00722             info_plist_out = project->first("QMAKE_INFO_PLIST_OUT");
00723         QString destdir = project->first("DESTDIR");
00724         t << info_plist_out << ": " << "\n\t";
00725         if(!destdir.isEmpty())
00726             t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
00727         t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
00728           << "@sed -e \"s,@ICON@,application.icns,g\" -e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET")
00729           << ",g\" \"" << info_plist << "\" >\"" << info_plist_out << "\"" << endl;
00730         if(!project->first("RC_FILE").isEmpty()) {
00731             QString dir = destdir + "../Resources/";
00732             t << dir << "application.icns: " << var("RC_FILE") << "\n\t"
00733               << "@test -d " << dir << " || mkdir -p " << dir << "\n\t"
00734               << "@$(DEL_FILE) " << dir << "application.icns" << "\n\t"
00735               << "@$(COPY_FILE) " << var("RC_FILE") << " " << dir << "application.icns" << endl;
00736         }
00737     }
00738 
00739     QString ddir = project->isEmpty("QMAKE_DISTDIR") ? project->first("QMAKE_ORIG_TARGET") :
00740                    project->first("QMAKE_DISTDIR");
00741     QString ddir_c = fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") :
00742                                  project->first("OBJECTS_DIR")) + ddir);
00743     t << "dist: " << "\n\t"
00744       << "@mkdir -p " << ddir_c << " && "
00745       << "$(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) " << ddir_c << Option::dir_sep << " && ";
00746     if(!project->isEmpty("TRANSLATIONS"))
00747         t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && ";
00748     if(!project->isEmpty("IMAGES"))
00749         t << "$(COPY_FILE) --parents " << var("IMAGES") << " " << ddir_c << Option::dir_sep << " && ";
00750     if(!project->isEmpty("FORMS")) {
00751         QStringList &forms = project->variables()["FORMS"], ui_headers;
00752         for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) {
00753             QString ui_h = fileFixify((*formit) + Option::h_ext.first());
00754             if(QFile::exists(ui_h) )
00755                ui_headers << ui_h;
00756         }
00757         if(!ui_headers.isEmpty())
00758             t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && ";
00759     }
00760     t << "( cd `dirname " << ddir_c << "` && "
00761       << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && "
00762       << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && "
00763       << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && "
00764       << "$(DEL_FILE) -r " << ddir_c
00765       << endl << endl;
00766 
00767     QString clean_targets;
00768     t << "mocclean:" << "\n";
00769     if(mocAware()) {
00770         if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) {
00771             if(!objMoc.isEmpty())
00772                 t << "\t-$(DEL_FILE) $(OBJMOC)" << '\n';
00773             if(!srcMoc.isEmpty())
00774                 t << "\t-$(DEL_FILE) $(SRCMOC)" << '\n';
00775             if(moc_incremental)
00776                 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
00777             clean_targets += " mocclean";
00778         }
00779         t << endl;
00780     }
00781     t << "uiclean:" << "\n";
00782     if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) {
00783         t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n";
00784         clean_targets += " uiclean";
00785     }
00786     t << endl;
00787 
00788     t << "yaccclean:" << "\n";
00789     if(!var("YACCSOURCES").isEmpty()) {
00790         QStringList clean, &l = project->variables()["YACCSOURCES"];
00791         for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00792             QFileInfo fi((*it));
00793             QString dir;
00794             if(fi.dirPath() != ".")
00795                 dir = fi.dirPath() + Option::dir_sep;
00796             dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
00797             if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
00798                 dir += Option::dir_sep;
00799             clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first() );
00800             clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first() );
00801         }
00802         if(!clean.isEmpty()) {
00803             t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n";
00804             clean_targets += " yaccclean";
00805         }
00806     }
00807 
00808     t << "lexclean:" << "\n";
00809     if(!var("LEXSOURCES").isEmpty()) {
00810         QStringList clean, &l = project->variables()["LEXSOURCES"];
00811         for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00812             QFileInfo fi((*it));
00813             QString dir;
00814             if(fi.dirPath() != ".")
00815                 dir = fi.dirPath() + Option::dir_sep;
00816             dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
00817             if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
00818                 dir += Option::dir_sep;
00819             clean << ( dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first() );
00820         }
00821         if(!clean.isEmpty()) {
00822             t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n";
00823             clean_targets += " lexclean";
00824         }
00825     }
00826 
00827     if(do_incremental) {
00828         t << "incrclean:" << "\n";
00829         if(src_incremental)
00830             t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n";
00831         if(moc_incremental)
00832             t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
00833         t << endl;
00834     }
00835 
00836     t << "clean:" << clean_targets << "\n\t";
00837     if(!project->isEmpty("OBJECTS")) {
00838         if(project->isActiveConfig("compile_libtool"))
00839             t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)" << "\n\t";
00840         else
00841             t << "-$(DEL_FILE) $(OBJECTS)" << "\n\t";
00842     }
00843     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
00844         QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
00845         QString precomph_out_dir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep;
00846         t << "-$(DEL_FILE) " << precomph_out_dir << header_prefix + "c "
00847           << precomph_out_dir << header_prefix << "c++" << "\n\t";
00848     }
00849     if(!project->isEmpty("IMAGES"))
00850         t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t";
00851     if(src_incremental)
00852         t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t";
00853     t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
00854       << "-$(DEL_FILE) *~ core *.core" << "\n"
00855       << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl;
00856     t << "####### Sub-libraries" << endl << endl;
00857     if ( !project->variables()["SUBLIBS"].isEmpty() ) {
00858         QString libdir = "tmp/";
00859         if(!project->isEmpty("SUBLIBS_DIR"))
00860             libdir = project->first("SUBLIBS_DIR");
00861         QStringList &l = project->variables()["SUBLIBS"];
00862         for(it = l.begin(); it != l.end(); ++it)
00863             t << libdir << "lib" << (*it) << ".a" << ":\n\t"
00864               << var(QString("MAKELIB") + (*it)) << endl << endl;
00865     }
00866 
00867     QString destdir = project->first("DESTDIR");
00868     if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
00869         destdir += Option::dir_sep;
00870     t << "distclean: " << "clean\n";
00871     if(project->first("TEMPLATE") == "app" &&
00872        project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
00873         t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n";
00874     else if(project->isActiveConfig("compile_libtool"))
00875         t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << "\n";
00876     else
00877         t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n";
00878     if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() &&
00879        !project->isActiveConfig("plugin") && !project->isActiveConfig("compile_libtool"))
00880         t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
00881           << destdir << "$(TARGET2) $(TARGETA)" << "\n";
00882     t << endl << endl;
00883 
00884     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") ) {
00885         QString precomph = fileFixify(project->first("PRECOMPILED_HEADER"));
00886         t << "###### Prefix headers" << endl;
00887         QString comps[] = { "C", "CXX", QString::null };
00888         for(int i = 0; !comps[i].isNull(); i++) {
00889             QString flags = var("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE");
00890             flags += " $(" + comps[i] + "FLAGS)";
00891 
00892             QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
00893             QString outdir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep, outfile = outdir;
00894             QString compiler;
00895             if(comps[i] == "C") {
00896                 outfile += header_prefix + "c";
00897                 compiler = "$(CC) ";
00898             } else {
00899                 outfile += header_prefix + "c++";
00900                 compiler = "$(CXX) ";
00901             }
00902             t << outfile << ": " << precomph << " " << findDependencies(precomph).join(" \\\n\t\t")
00903               << "\n\t" << "test -d " << outdir << " || mkdir -p " << outdir
00904               << "\n\t" << compiler << flags << " $(INCPATH) " << precomph << " -o " << outfile << endl << endl;
00905         }
00906     }
00907     if(!project->isEmpty("ALLMOC_HEADER")) {
00908         QString outdir = project->first("MOC_DIR");
00909         QString precomph = fileFixify(project->first("ALLMOC_HEADER"));
00910         t << "###### Combined headers" << endl << endl
00911           << outdir << "allmoc.cpp: " << precomph << " "
00912           << varList("HEADERS_ORIG") << "\n\t"
00913           << "echo '#include \"" << precomph << "\"' >" << outdir << "allmoc.cpp" << "\n\t"
00914           << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h "
00915           << outdir << "allmoc.cpp" << "\n\t"
00916           << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t"
00917           << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \""
00918           << precomph << "\"}' " << outdir << "allmoc.cpp" << "\n\t"
00919           << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl;
00920     }
00921 
00922     // user defined targets
00923     QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
00924     for(it = qut.begin(); it != qut.end(); ++it) {
00925         QString targ = var((*it) + ".target"),
00926                  cmd = var((*it) + ".commands"), deps;
00927         if(targ.isEmpty())
00928             targ = (*it);
00929         QStringList &deplist = project->variables()[(*it) + ".depends"];
00930         for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
00931             QString dep = var((*dep_it) + ".target");
00932             if(dep.isEmpty())
00933                 dep = (*dep_it);
00934             deps += " " + dep;
00935         }
00936         if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1)
00937             deps += QString(" ") + "FORCE";
00938         t << targ << ":" << deps << "\n\t"
00939           << cmd << endl << endl;
00940     }
00941     // user defined compilers
00942     QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
00943     for(it = quc.begin(); it != quc.end(); ++it) {
00944         QString tmp_out = project->variables()[(*it) + ".output"].first();
00945         QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" ");
00946         QString tmp_dep = project->variables()[(*it) + ".depends"].join(" ");
00947         QStringList &vars = project->variables()[(*it) + ".variables"];
00948         if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
00949             continue;
00950         QStringList &tmp = project->variables()[(*it) + ".input"];
00951         for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
00952             QStringList &inputs = project->variables()[(*it2)];
00953             for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
00954                 QFileInfo fi(Option::fixPathToLocalOS((*input)));
00955                 QString in = Option::fixPathToTargetOS((*input), FALSE),
00956                        out = tmp_out, cmd = tmp_cmd, deps;
00957                 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
00958                 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
00959                 cmd.replace("${QMAKE_FILE_BASE}", fi.baseName());
00960                 cmd.replace("${QMAKE_FILE_OUT}", out);
00961                 cmd.replace("${QMAKE_FILE_NAME}", fi.fileName());
00962                 for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3)
00963                     cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")");
00964                 if(!tmp_dep.isEmpty()) {
00965                     char buff[256];
00966                     QString dep_cmd = tmp_dep;
00967                     dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName());
00968                     if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) {
00969                         while(!feof(proc)) {
00970                             int read_in = int(fread(buff, 1, 255, proc));
00971                             if(!read_in)
00972                                 break;
00973                             int l = 0;
00974                             for(int i = 0; i < read_in; i++) {
00975                                 if(buff[i] == '\n' || buff[i] == ' ') {
00976                                     deps += " " + QCString(buff+l, (i - l) + 1);
00977                                     l = i;
00978                                 }
00979                             }
00980                         }
00981                         fclose(proc);
00982                     }
00983                 }
00984                 t << out << ": " << in << deps << "\n\t"
00985                   << cmd << endl << endl;
00986             }
00987         }
00988     }
00989     t <<"FORCE:" << endl << endl;
00990 }
00991 
00992 struct SubDir
00993 {
00994     QString directory, profile, target, makefile;
00995 };
00996 
00997 void
00998 UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct)
00999 {
01000     // blasted includes
01001     QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"];
01002     for(QStringList::Iterator qeui_it = qeui.begin(); qeui_it != qeui.end(); ++qeui_it)
01003         t << "include " << (*qeui_it) << endl;
01004     writeExtraVariables(t);
01005 
01006     QPtrList<SubDir> subdirs;
01007     {
01008         QStringList subdirs_in = project->variables()["SUBDIRS"];
01009         for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) {
01010             QString file = (*it);
01011             fileFixify(file);
01012             SubDir *sd = new SubDir;
01013             subdirs.append(sd);
01014             sd->makefile = "$(MAKEFILE)";
01015             if((*it).right(4) == ".pro") {
01016                 int slsh = file.findRev(Option::dir_sep);
01017                 if(slsh != -1) {
01018                     sd->directory = file.left(slsh+1);
01019                     sd->profile = file.mid(slsh+1);
01020                 } else {
01021                     sd->profile = file;
01022                 }
01023             } else {
01024                 if(!file.isEmpty())
01025                     sd->profile = file.section(Option::dir_sep, -1) + ".pro";
01026                 sd->directory = file;
01027             }
01028             while(sd->directory.right(1) == Option::dir_sep)
01029                 sd->directory = sd->directory.left(sd->directory.length() - 1);
01030             if(!sd->profile.isEmpty()) {
01031                 QString basename = sd->directory;
01032                 int new_slsh = basename.findRev(Option::dir_sep);
01033                 if(new_slsh != -1)
01034                     basename = basename.mid(new_slsh+1);
01035                 if(sd->profile != basename + ".pro")
01036                     sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro
01037             }
01038             sd->target = "sub-" + (*it);
01039             sd->target.replace('/', '-');
01040             sd->target.replace('.', '_');
01041         }
01042     }
01043     QPtrListIterator<SubDir> it(subdirs);
01044 
01045     QString ofile = Option::output.name();
01046     if(ofile.findRev(Option::dir_sep) != -1)
01047         ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1);
01048     t << "MAKEFILE =    " << var("MAKEFILE") << endl;
01049     t << "QMAKE    =    " << var("QMAKE") << endl;
01050     t << "DEL_FILE =    " << var("QMAKE_DEL_FILE") << endl;
01051     t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
01052     t << "MKDIR    = " << var("QMAKE_MKDIR") << endl;
01053     t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl;
01054     t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
01055     t << "SUBTARGETS =  ";     // subdirectory targets are sub-directory
01056     for( it.toFirst(); it.current(); ++it)
01057         t << " \\\n\t\t" << it.current()->target;
01058     t << endl << endl;
01059     t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl;
01060 
01061     // generate target rules
01062     for( it.toFirst(); it.current(); ++it) {
01063         bool have_dir = !(*it)->directory.isEmpty();
01064         QString mkfile = (*it)->makefile, out;
01065         if(have_dir)
01066             mkfile.prepend((*it)->directory + Option::dir_sep);
01067         if(direct || (*it)->makefile != "$(MAKEFILE)")
01068             out = " -o " + (*it)->makefile;
01069         //qmake it
01070         t << mkfile << ": " << "\n\t";
01071         if(have_dir)
01072             t << mkdir_p_asstring((*it)->directory) << "\n\t"
01073               << "cd " << (*it)->directory << " && ";
01074         QString profile = fileFixify((*it)->profile, (*it)->directory, (*it)->directory);
01075         t << "$(QMAKE) " << profile << buildArgs() << out << endl;
01076         //actually compile
01077         t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t";
01078         if(have_dir)
01079             t << "cd " << (*it)->directory << " && ";
01080         t << "$(MAKE) -f " << (*it)->makefile << endl << endl;
01081     }
01082 
01083     if (project->isActiveConfig("ordered")) {   // generate dependencies
01084         for( it.toFirst(); it.current(); ) {
01085             QString tar = it.current()->target;
01086             ++it;
01087             if (it.current())
01088                 t << it.current()->target << ": " << tar << endl;
01089         }
01090         t << endl;
01091     }
01092 
01093     writeMakeQmake(t);
01094 
01095     if(project->isEmpty("SUBDIRS")) {
01096         t << "all qmake_all distclean uicables mocables install_subdirs uninstall_subdirs"
01097           << " uiclean mocclean lexclean yaccclean clean " << var("SUBDIR_TARGETS") << ": FORCE" << endl;
01098     } else {
01099         t << "all: $(SUBTARGETS)" << endl;
01100         t << "qmake_all:";
01101         for( it.toFirst(); it.current(); ++it) {
01102             t << " ";
01103             if(!(*it)->directory.isEmpty())
01104                 t << (*it)->directory << Option::dir_sep;
01105             t << (*it)->makefile;
01106         }
01107         for( it.toFirst(); it.current(); ++it) {
01108             t << "\n\t ( ";
01109             if(!(*it)->directory.isEmpty())
01110                 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
01111             t << "grep \"^qmake_all:\" " << (*it)->makefile
01112               << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true";
01113         }
01114         t << endl;
01115         t << "clean uicables mocables uiclean mocclean lexclean yaccclean "
01116           << var("SUBDIR_TARGETS") << ": qmake_all FORCE";
01117         for( it.toFirst(); it.current(); ++it) {
01118             t << "\n\t ( ";
01119             if(!(*it)->directory.isEmpty())
01120                 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
01121             t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true";
01122         }
01123         t << endl;
01124         t << "uninstall_subdirs: qmake_all FORCE";
01125         for( it.toFirst(); it.current(); ++it) {
01126             t << "\n\t ( ";
01127             if(!(*it)->directory.isEmpty())
01128                 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
01129             t << "$(MAKE) -f " << (*it)->makefile << " uninstall" << "; ) || true";
01130         }
01131         t << endl;
01132         t << "install_subdirs: qmake_all FORCE";
01133         for( it.toFirst(); it.current(); ++it) {
01134             t << "\n\t ( ";
01135             if(!(*it)->directory.isEmpty())
01136                 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
01137             t << "$(MAKE) -f " << (*it)->makefile << " install" << "; ) || true";
01138         }
01139         t << endl;
01140         t << "distclean: qmake_all FORCE";
01141         for( it.toFirst(); it.current(); ++it) {
01142             t << "\n\t ( ";
01143             if(!(*it)->directory.isEmpty())
01144                 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
01145             t << "$(MAKE) -f " << (*it)->makefile << " $@; $(DEL_FILE) " << (*it)->makefile << "; ) || true";
01146         }
01147         t << endl << endl;
01148     }
01149 
01150     //installations
01151     project->variables()["INSTALLDEPS"]   += "install_subdirs";
01152     project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs";
01153     writeInstalls(t, "INSTALLS");
01154 
01155     // user defined targets
01156     QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
01157     for(QStringList::Iterator qut_it = qut.begin(); qut_it != qut.end(); ++qut_it) {
01158         QString targ = var((*qut_it) + ".target"),
01159                  cmd = var((*qut_it) + ".commands"), deps;
01160         if(targ.isEmpty())
01161             targ = (*qut_it);
01162         QStringList &deplist = project->variables()[(*qut_it) + ".depends"];
01163         for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
01164             QString dep = var((*dep_it) + ".target");
01165             if(dep.isEmpty())
01166                 dep = (*dep_it);
01167             deps += " " + dep;
01168         }
01169         if(project->variables()[(*qut_it) + ".CONFIG"].findIndex("phony") != -1)
01170             deps += QString(" ") + "FORCE";
01171         t << targ << ":" << deps << "\n\t"
01172           << cmd << endl << endl;
01173     }
01174     t <<"FORCE:" << endl << endl;
01175 }
01176 
01177 void UnixMakefileGenerator::init2()
01178 {
01179     //version handling
01180     if(project->variables()["VERSION"].isEmpty())
01181         project->variables()["VERSION"].append("1.0." +
01182                                                (project->isEmpty("VER_PAT") ? QString("0") :
01183                                                 project->first("VER_PAT")) );
01184     QStringList l = QStringList::split('.', project->first("VERSION"));
01185     l << "0" << "0"; //make sure there are three
01186     project->variables()["VER_MAJ"].append(l[0]);
01187     project->variables()["VER_MIN"].append(l[1]);
01188     project->variables()["VER_PAT"].append(l[2]);
01189 
01190     if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
01191 #if 0
01192         if ( project->isActiveConfig("dll") ) {
01193             project->variables()["TARGET"] += project->variables()["TARGET.so"];
01194             if(project->variables()["QMAKE_LFLAGS_SHAPP"].isEmpty())
01195                 project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
01196             if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty())
01197                 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET");
01198         }
01199 #endif
01200         project->variables()["TARGET"].first().prepend(project->first("DESTDIR"));
01201        if ( !project->variables()["QMAKE_CYGWIN_EXE"].isEmpty() )
01202             project->variables()["TARGET_EXT"].append(".exe");
01203     } else if ( project->isActiveConfig("staticlib") ) {
01204         project->variables()["TARGET"].first().prepend("lib");
01205         project->variables()["TARGET"].first() += ".a";
01206         if(project->variables()["QMAKE_AR_CMD"].isEmpty())
01207             project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)");
01208     } else {
01209         project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a");
01210         if( project->isActiveConfig("compile_libtool") )
01211             project->variables()["TARGET_la"] = project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext;
01212 
01213         if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() )
01214             project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)");
01215         else
01216             project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)");
01217         if( project->isActiveConfig("compile_libtool") ) {
01218             project->variables()["TARGET"] = project->variables()["TARGET_la"];
01219         } else if( project->isActiveConfig("plugin") ) {
01220             project->variables()["TARGET_x.y.z"].append("lib" +
01221                                                         project->first("TARGET") + "." +
01222                                                         project->first("QMAKE_EXTENSION_PLUGIN"));
01223             if(project->isActiveConfig("lib_version_first"))
01224                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01225                                                         project->first("VER_MAJ") + "." +
01226                                                         project->first("QMAKE_EXTENSION_PLUGIN"));
01227             else
01228                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01229                                                         project->first("QMAKE_EXTENSION_PLUGIN") +
01230                                                         "." + project->first("VER_MAJ"));
01231 
01232             project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
01233             if(project->isActiveConfig("qt"))
01234                 project->variables()["DEFINES"].append("QT_PLUGIN");
01235         } else if ( !project->isEmpty("QMAKE_HPUX_SHLIB") ) {
01236             project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl");
01237             if(project->isActiveConfig("lib_version_first"))
01238                 project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." +
01239                                                         project->first("TARGET"));
01240             else
01241                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01242                                                         project->first("VER_MAJ"));
01243             project->variables()["TARGET"] = project->variables()["TARGET_x"];
01244         } else if ( !project->isEmpty("QMAKE_AIX_SHLIB") ) {
01245             project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a");
01246             if(project->isActiveConfig("lib_version_first")) {
01247                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01248                                                         project->first("VER_MAJ") + "." +
01249                                                         project->first("QMAKE_EXTENSION_SHLIB"));
01250                 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
01251                                                           project->first("VER_MAJ") +
01252                                                           "." + project->first("VER_MIN") + "." +
01253                                                           project->first("QMAKE_EXTENSION_SHLIB"));
01254                 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
01255                                                             project->first("VER_MAJ") + "." +
01256                                                             project->first("VER_MIN") + "." +
01257                                                             project->first("VER_PAT") + "." +
01258                                                             project->first("QMAKE_EXTENSION_SHLIB"));
01259             } else {
01260                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01261                                                         project->first("QMAKE_EXTENSION_SHLIB") +
01262                                                         "." + project->first("VER_MAJ"));
01263                 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
01264                                                           project->first("QMAKE_EXTENSION_SHLIB") +
01265                                                           "." + project->first("VER_MAJ") +
01266                                                           "." + project->first("VER_MIN"));
01267                 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
01268                                                             project->first("QMAKE_EXTENSION_SHLIB") + "." +
01269                                                             project->first("VER_MAJ") + "." +
01270                                                             project->first("VER_MIN") + "." +
01271                                                             project->first("VER_PAT"));
01272             }
01273             project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
01274         } else {
01275             project->variables()["TARGET_"].append("lib" + project->first("TARGET") + "." +
01276                                                    project->first("QMAKE_EXTENSION_SHLIB"));
01277             if(project->isActiveConfig("lib_version_first")) {
01278                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01279                                                         project->first("VER_MAJ") + "." +
01280                                                         project->first("QMAKE_EXTENSION_SHLIB"));
01281                 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
01282                                                           project->first("VER_MAJ") +
01283                                                           "." + project->first("VER_MIN") + "." +
01284                                                           project->first("QMAKE_EXTENSION_SHLIB"));
01285                 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
01286                                                             project->first("VER_MAJ") + "." +
01287                                                             project->first("VER_MIN") +  "." +
01288                                                             project->first("VER_PAT") + "." +
01289                                                             project->variables()["QMAKE_EXTENSION_SHLIB"].first());
01290             } else {
01291                 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
01292                                                         project->first("QMAKE_EXTENSION_SHLIB") +
01293                                                         "." + project->first("VER_MAJ"));
01294                 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
01295                                                       project->first("QMAKE_EXTENSION_SHLIB")
01296                                                       + "." + project->first("VER_MAJ") +
01297                                                       "." + project->first("VER_MIN"));
01298                 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") +
01299                                                             "." +
01300                                                             project->variables()[
01301                                                                 "QMAKE_EXTENSION_SHLIB"].first() + "." +
01302                                                             project->first("VER_MAJ") + "." +
01303                                                             project->first("VER_MIN") +  "." +
01304                                                             project->first("VER_PAT"));
01305             }
01306             project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
01307         }
01308         if(project->isEmpty("QMAKE_LN_SHLIB"))
01309             project->variables()["QMAKE_LN_SHLIB"].append("ln -s");
01310         project->variables()["DESTDIR_TARGET"].append("$(TARGET)");
01311         if ( !project->variables()["DESTDIR"].isEmpty() )
01312             project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR"));
01313         if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) {
01314             if(project->isActiveConfig("plugin")) {
01315                 if(!project->variables()["TARGET"].isEmpty() )
01316                     project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET");
01317             } else {
01318                 if(!project->variables()["TARGET_x"].isEmpty() )
01319                     project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x");
01320             }
01321         }
01322         if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() )
01323             project->variables()["QMAKE_LINK_SHLIB_CMD"].append(
01324                 "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)");
01325     }
01326     if(project->isEmpty("QMAKE_SYMBOLIC_LINK"))
01327         project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf");
01328     if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
01329         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_APP"];
01330         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_APP"];
01331         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_APP"];
01332     } else if ( project->isActiveConfig("dll") ) {
01333         if( !project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) {
01334             project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"];
01335             project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"];
01336         }
01337         if ( project->isActiveConfig("plugin") ) {
01338             project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_PLUGIN"];
01339             project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_PLUGIN"];
01340             project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"];
01341             if( project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool"))
01342                 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
01343         } else {
01344             project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
01345             if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) {
01346                 if(project->isEmpty("COMPAT_VERSION"))
01347                     project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
01348                                                                     project->first("VER_MAJ") + "." +
01349                                                                     project->first("VER_MIN"));
01350                 else
01351                     project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
01352                                                                     project->first("COMPATIBILITY_VERSION"));
01353             }
01354             if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) {
01355                 project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_VERSION") +
01356                                                                 project->first("VER_MAJ") + "." +
01357                                                                 project->first("VER_MIN") + "." +
01358                                                                 project->first("VER_PAT"));
01359             }
01360             if(!project->isActiveConfig("compile_libtool"))
01361                 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
01362         }
01363         QString destdir = project->first("DESTDIR");
01364         if ( !destdir.isEmpty() && !project->variables()["QMAKE_RPATH"].isEmpty() ) {
01365             QString rpath_destdir = destdir;
01366             if(QDir::isRelativePath(rpath_destdir)) {
01367                 QFileInfo fi(Option::fixPathToLocalOS(rpath_destdir));
01368                 if(fi.convertToAbs())  //strange, shouldn't really happen
01369                     rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
01370                 else
01371                     rpath_destdir = fi.filePath();
01372             } else {
01373                 rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
01374             }
01375             project->variables()["QMAKE_LFLAGS"] += project->first("QMAKE_RPATH") + rpath_destdir;
01376         }
01377     }
01378     QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
01379     for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) {
01380         QString tmp_out = project->variables()[(*it) + ".output"].first();
01381         if(tmp_out.isEmpty())
01382             continue;
01383         QStringList &tmp = project->variables()[(*it) + ".input"];
01384         for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
01385             QStringList &inputs = project->variables()[(*it2)];
01386             for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
01387                 QFileInfo fi(Option::fixPathToLocalOS((*input)));
01388                 QString in = Option::fixPathToTargetOS((*input), FALSE),
01389                        out = tmp_out;
01390                 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
01391                 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
01392                 if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1)
01393                     project->variables()["OBJCOMP"] += out;
01394             }
01395         }
01396     }
01397 }
01398 
01399 QString
01400 UnixMakefileGenerator::libtoolFileName()
01401 {
01402     QString ret = var("TARGET");
01403     int slsh = ret.findRev(Option::dir_sep);
01404     if(slsh != -1)
01405         ret = ret.right(ret.length() - slsh);
01406     int dot = ret.find('.');
01407     if(dot != -1)
01408         ret = ret.left(dot);
01409     ret += Option::libtool_ext;
01410     if(!project->isEmpty("DESTDIR"))
01411         ret.prepend(var("DESTDIR"));
01412     return ret;
01413 }
01414 
01415 void
01416 UnixMakefileGenerator::writeLibtoolFile()
01417 {
01418     QString fname = libtoolFileName(), lname = fname;
01419     int slsh = lname.findRev(Option::dir_sep);
01420     if(slsh != -1)
01421         lname = lname.right(lname.length() - slsh - 1);
01422     QFile ft(fname);
01423     if(!ft.open(IO_WriteOnly))
01424         return;
01425     project->variables()["ALL_DEPS"].append(fname);
01426 
01427     QTextStream t(&ft);
01428     t << "# " << lname << " - a libtool library file\n";
01429     time_t now = time(NULL);
01430     t << "# Generated by qmake/libtool (" << qmake_version() << ") (Qt "
01431       << QT_VERSION_STR << ") on: " << ctime(&now) << "\n";
01432 
01433     t << "# The name that we can dlopen(3).\n"
01434       << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x")
01435       << "'\n\n";
01436 
01437     t << "# Names of this library.\n";
01438     t << "library_names='";
01439     if(project->isActiveConfig("plugin")) {
01440         t << var("TARGET");
01441     } else {
01442         if (project->isEmpty("QMAKE_HPUX_SHLIB"))
01443             t << var("TARGET_x.y.z") << " ";
01444         t << var("TARGET_x") << " " << var("TARGET_");
01445     }
01446     t << "'\n\n";
01447 
01448     t << "# The name of the static archive.\n"
01449       << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n";
01450 
01451     t << "# Libraries that this one depends upon.\n";
01452     QStringList libs;
01453     if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
01454         libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"];
01455     else
01456         libs << "QMAKE_LIBS"; //obvious one
01457     t << "dependency_libs='";
01458     for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
01459         t << project->variables()[(*it)].join(" ") << " ";
01460     t << "'\n\n";
01461 
01462     t << "# Version information for " << lname << "\n";
01463     int maj = project->first("VER_MAJ").toInt();
01464     int min = project->first("VER_MIN").toInt();
01465     int pat = project->first("VER_PAT").toInt();
01466     t << "current=" << (10*maj + min) << "\n" // best I can think of
01467       << "age=0\n"
01468       << "revision=" << pat << "\n\n";
01469 
01470     t << "# Is this an already installed library.\n"
01471         "installed=yes\n\n"; // ###
01472 
01473     t << "# Files to dlopen/dlpreopen.\n"
01474         "dlopen=''\n"
01475         "dlpreopen=''\n\n";
01476 
01477     QString install_dir = project->first("target.path");
01478     if(install_dir.isEmpty())
01479         install_dir = project->first("DESTDIR");
01480     t << "# Directory that this library needs to be installed in:\n"
01481         "libdir='" << Option::fixPathToTargetOS(install_dir, FALSE) << "'\n";
01482 }
01483 
01484 QString
01485 UnixMakefileGenerator::pkgConfigFileName()
01486 {
01487     QString ret = var("TARGET");
01488     int slsh = ret.findRev(Option::dir_sep);
01489     if(slsh != -1)
01490         ret = ret.right(ret.length() - slsh);
01491     if(ret.startsWith("lib"))
01492         ret = ret.mid(3);
01493     int dot = ret.find('.');
01494     if(dot != -1)
01495         ret = ret.left(dot);
01496     ret += Option::pkgcfg_ext;
01497     if(!project->isEmpty("DESTDIR")) {
01498         ret.prepend(var("DESTDIR"));
01499         ret = Option::fixPathToLocalOS(fileFixify(ret,QDir::currentDirPath(), Option::output_dir));
01500     }
01501     return ret;
01502 }
01503 
01504 QString
01505 UnixMakefileGenerator::pkgConfigPrefix() const
01506 {
01507     if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX"))
01508         return project->first("QMAKE_PKGCONFIG_PREFIX");
01509     return qInstallPath();
01510 }
01511 
01512 QString
01513 UnixMakefileGenerator::pkgConfigFixPath(QString path) const
01514 {
01515     QString prefix = pkgConfigPrefix();
01516     if(path.startsWith(prefix))
01517         path = path.replace(prefix, "${prefix}");
01518     return path;
01519 }
01520 
01521 void
01522 UnixMakefileGenerator::writePkgConfigFile()     // ### does make sense only for libqt so far
01523 {
01524     QString fname = pkgConfigFileName(), lname = fname;
01525     int slsh = lname.findRev(Option::dir_sep);
01526     if(slsh != -1)
01527         lname = lname.right(lname.length() - slsh - 1);
01528     QFile ft(fname);
01529     if(!ft.open(IO_WriteOnly))
01530         return;
01531     project->variables()["ALL_DEPS"].append(fname);
01532     QTextStream t(&ft);
01533 
01534     QString prefix = pkgConfigPrefix();
01535     QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR");
01536     if(libDir.isEmpty())
01537         libDir = prefix + "/lib";
01538     QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR");
01539     if(includeDir.isEmpty())
01540         includeDir = prefix + "/include";
01541 
01542     t << "prefix=" << prefix << endl;
01543     t << "exec_prefix=${prefix}\n"
01544       << "libdir=" << pkgConfigFixPath(libDir) << "\n"
01545       << "includedir=" << pkgConfigFixPath(includeDir) << endl;
01546     // non-standard entry. Provides useful info normally only
01547     // contained in the internal .qmake.cache file
01548     t << varGlue("CONFIG", "qt_config=", " ", "") << endl << endl;
01549 
01550     t << "Name: Qt" << endl;
01551     QString desc = project->first("QMAKE_PKGCONFIG_DESCRIPTION");
01552     if(desc.isEmpty()) {
01553         desc = project->first("TARGET").lower();
01554         desc.replace(0, 1, desc[0].upper());
01555         if(project->first("TEMPLATE") == "lib") {
01556             if(project->isActiveConfig("plugin"))
01557                desc += " Plugin";
01558             else
01559                desc += " Library";
01560         } else if(project->first("TEMPLATE") == "app") {
01561             desc += " Application";
01562         }
01563     }
01564     t << "Description: " << desc << endl;
01565     t << "Version: " << project->first("VERSION") << endl;
01566 
01567     // libs
01568     QStringList libs;
01569     if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
01570         libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"];
01571     else
01572         libs << "QMAKE_LIBS"; //obvious one
01573     if(project->isActiveConfig("thread"))
01574         libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread?
01575     t << "Libs: -L${libdir} -l" << lname.left(lname.length()-Option::libtool_ext.length()) << " ";
01576     for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
01577         t << project->variables()[(*it)].join(" ") << " ";
01578     t << endl;
01579 
01580     // flags
01581     // ### too many
01582     t << "Cflags: "
01583         // << var("QMAKE_CXXFLAGS") << " "
01584       << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
01585       << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ")
01586         //      << varGlue("DEFINES","-D"," -D"," ")
01587       << " -I${includedir}";
01588 }

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