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

unixmake.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 <qregexp.h>
00039 #include <qfile.h>
00040 #include <qdict.h>
00041 #include <qdir.h>
00042 #include <time.h>
00043 
00044 
00045 void
00046 UnixMakefileGenerator::init()
00047 {
00048     if(init_flag)
00049         return;
00050     init_flag = TRUE;
00051 
00052     if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */
00053         return;
00054 
00055     QStringList &configs = project->variables()["CONFIG"];
00056     /* this should probably not be here, but I'm using it to wrap the .t files */
00057     if(project->first("TEMPLATE") == "app")
00058         project->variables()["QMAKE_APP_FLAG"].append("1");
00059     else if(project->first("TEMPLATE") == "lib")
00060         project->variables()["QMAKE_LIB_FLAG"].append("1");
00061     else if(project->first("TEMPLATE") == "subdirs") {
00062         MakefileGenerator::init();
00063         if(project->isEmpty("MAKEFILE"))
00064             project->variables()["MAKEFILE"].append("Makefile");
00065         if(project->isEmpty("QMAKE"))
00066             project->variables()["QMAKE"].append("qmake");
00067         if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1)
00068             project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
00069         return; /* subdirs is done */
00070     }
00071 
00072     if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) {
00073         if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) {
00074             project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" );
00075         } else {
00076             project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" );
00077         }
00078     }
00079     if( project->isEmpty("QMAKE_CFLAGS_PRECOMPILE"))
00080         project->variables()["QMAKE_CFLAGS_PRECOMPILE"].append("-x c-header -c");
00081     if( project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE"))
00082         project->variables()["QMAKE_CXXFLAGS_PRECOMPILE"].append("-x c++-header -c");
00083     if( project->isEmpty("QMAKE_CFLAGS_USE_PRECOMPILE"))
00084         project->variables()["QMAKE_CFLAGS_USE_PRECOMPILE"].append("-include");
00085     if( project->isEmpty("QMAKE_EXTENSION_PLUGIN") )
00086         project->variables()["QMAKE_EXTENSION_PLUGIN"].append(project->first("QMAKE_EXTENSION_SHLIB"));
00087     if( project->isEmpty("QMAKE_COPY_FILE") )
00088         project->variables()["QMAKE_COPY_FILE"].append( "$(COPY)" );
00089     if( project->isEmpty("QMAKE_COPY_DIR") )
00090         project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -R" );
00091     if( project->isEmpty("QMAKE_INSTALL_FILE") )
00092         project->variables()["QMAKE_INSTALL_FILE"].append( "$(COPY_FILE)" );
00093     if( project->isEmpty("QMAKE_INSTALL_DIR") )
00094         project->variables()["QMAKE_INSTALL_DIR"].append( "$(COPY_DIR)" );
00095     if( project->isEmpty("QMAKE_LIBTOOL") )
00096         project->variables()["QMAKE_LIBTOOL"].append( "libtool --silent" );
00097     //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
00098     if(!project->isEmpty("TARGET")) {
00099         QString targ = project->first("TARGET");
00100         int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep));
00101         if(slsh != -1) {
00102             if(project->isEmpty("DESTDIR"))
00103                 project->values("DESTDIR").append("");
00104             else if(project->first("DESTDIR").right(1) != Option::dir_sep)
00105                 project->variables()["DESTDIR"] = project->first("DESTDIR") + Option::dir_sep;
00106             project->variables()["DESTDIR"] = project->first("DESTDIR") + targ.left(slsh+1);
00107             project->variables()["TARGET"] = targ.mid(slsh+1);
00108         }
00109     }
00110 
00111     project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
00112 
00113     bool is_qt = (project->first("TARGET") == "qt" || project->first("TARGET") == "qte" ||
00114                   project->first("TARGET") == "qt-mt" || project->first("TARGET") == "qte-mt");
00115     bool extern_libs = !project->isEmpty("QMAKE_APP_FLAG") ||
00116                        (!project->isEmpty("QMAKE_LIB_FLAG") &&
00117                         project->isActiveConfig("dll")) || is_qt;
00118     project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
00119     if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) ||
00120          (project->isActiveConfig("qt") &&  project->isActiveConfig( "plugin" ) )) {
00121         if(configs.findIndex("dll") == -1) configs.append("dll");
00122     } else if ( !project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll") ) {
00123         configs.remove("staticlib");
00124     }
00125     if ( project->isActiveConfig("warn_off") ) {
00126         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
00127         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
00128     } else if ( project->isActiveConfig("warn_on") ) {
00129         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
00130         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
00131     }
00132     if ( project->isActiveConfig("debug") ) {
00133         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
00134         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
00135         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
00136     } else {
00137         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
00138         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
00139         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
00140     }
00141     if(!project->isEmpty("QMAKE_INCREMENTAL"))
00142         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"];
00143     else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") &&
00144             !project->variables()["QMAKE_LIB_FLAG"].isEmpty() &&
00145             project->isActiveConfig("dll"))
00146         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"];
00147     if(!project->isEmpty("QMAKE_INCDIR"))
00148         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
00149     if(!project->isEmpty("QMAKE_LIBDIR")) {
00150         if ( !project->isEmpty("QMAKE_RPATH") )
00151             project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"),
00152                                                             " " + var("QMAKE_RPATH"), "");
00153         project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" );
00154     }
00155     if ( project->isActiveConfig("qtopia") ) {
00156         if(configs.findIndex("qtopialib") == -1)
00157             configs.append("qtopialib");
00158         if(configs.findIndex("qtopiainc") == -1)
00159             configs.append("qtopiainc");
00160     }
00161     if ( project->isActiveConfig("qtopiainc") )
00162         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"];
00163     if ( project->isActiveConfig("qtopialib") ) {
00164         if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA"))
00165             project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QTOPIA", "-L", " -L", "");
00166         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"];
00167     }
00168     if ( project->isActiveConfig("qt") ) {
00169         if ( project->isActiveConfig("accessibility" ) )
00170             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
00171         if ( project->isActiveConfig("tablet") )
00172             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
00173         if(configs.findIndex("moc")) configs.append("moc");
00174         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
00175         if ( !project->isActiveConfig("debug") )
00176             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
00177         if ( !is_qt ) {
00178             if ( !project->isEmpty("QMAKE_RPATH") ) {
00179                 if ( !project->isEmpty("QMAKE_RTLDIR_QT") )
00180                     project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_RTLDIR_QT", " " + var("QMAKE_RPATH"),
00181                                                                     " " + var("QMAKE_RPATH"), "");
00182                 else if ( !project->isEmpty("QMAKE_LIBDIR_QT") )
00183                     project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"),
00184                                                                     " " + var("QMAKE_RPATH"), "");
00185             }
00186             if ( !project->isEmpty("QMAKE_LIBDIR_QT") )
00187                 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", "");
00188             if ( project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD") )
00189                 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
00190             else
00191                 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
00192         }
00193     }
00194     if ( project->isActiveConfig("opengl") && !project->isActiveConfig("dlopen_opengl")) {
00195         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
00196         if(!project->isEmpty("QMAKE_LIBDIR_OPENGL"))
00197             project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", "");
00198         if ( is_qt )
00199             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
00200         else
00201             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
00202     }
00203     if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) {
00204         if(configs.findIndex("x11lib") == -1)
00205             configs.append("x11lib");
00206         if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 )
00207             configs.append("x11inc");
00208     }
00209     if ( project->isActiveConfig("x11") ) {
00210         if(configs.findIndex("x11lib") == -1)
00211             configs.append("x11lib");
00212         if(configs.findIndex("x11inc") == -1)
00213             configs.append("x11inc");
00214     }
00215     if ( project->isActiveConfig("x11inc") )
00216         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"];
00217     if ( project->isActiveConfig("x11lib") ) {
00218         if(!project->isEmpty("QMAKE_LIBDIR_X11"))
00219             project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", "");
00220         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"];
00221     }
00222     if ( project->isActiveConfig("x11sm") )
00223         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"];
00224     if ( project->isActiveConfig("dylib") )
00225         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"];
00226     if ( project->isActiveConfig("thread") ) {
00227         if(project->isActiveConfig("qt"))
00228             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
00229         if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) {
00230             project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"];
00231             project->variables()["PRL_EXPORT_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"];
00232         }
00233         if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) {
00234             project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"];
00235             project->variables()["PRL_EXPORT_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"];
00236         }
00237         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"];
00238         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"];
00239         if(!project->isEmpty("QMAKE_LFLAGS_THREAD"))
00240             project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"];
00241     }
00242     if ( project->isActiveConfig("moc") )
00243         setMocAware(TRUE);
00244     QString compile_flag = var("QMAKE_COMPILE_FLAG");
00245     if(compile_flag.isEmpty())
00246         compile_flag = "-c";
00247     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
00248         QString prefix_flags = project->first("QMAKE_CFLAGS_PREFIX_INCLUDE");
00249         if(prefix_flags.isEmpty())
00250             prefix_flags = "-include";
00251         compile_flag += " " + prefix_flags + " " + project->first("QMAKE_ORIG_TARGET");
00252     }
00253     if(!project->isEmpty("ALLMOC_HEADER")) {
00254         initOutPaths();         // Need to fix outdirs since we do this before init() (because we could add to SOURCES et al)
00255         QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir);
00256         project->variables()["SOURCES"].prepend(allmoc);
00257         project->variables()["HEADERS_ORIG"] = project->variables()["HEADERS"];
00258         project->variables()["HEADERS"].clear();
00259     }
00260     if ( project->isEmpty("QMAKE_RUN_CC") )
00261         project->variables()["QMAKE_RUN_CC"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $obj $src");
00262     if ( project->isEmpty("QMAKE_RUN_CC_IMP") )
00263         project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $@ $<");
00264     if ( project->isEmpty("QMAKE_RUN_CXX") )
00265         project->variables()["QMAKE_RUN_CXX"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $obj $src");
00266     if ( project->isEmpty("QMAKE_RUN_CXX_IMP") )
00267         project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $@ $<");
00268     project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " ");
00269     if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS"))
00270         include_deps = TRUE; //do not generate deps
00271     if(project->isActiveConfig("compile_libtool"))
00272         Option::obj_ext = ".lo"; //override the .o
00273 
00274     MakefileGenerator::init();
00275     if ( project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
00276         if(!project->isEmpty("QMAKE_APP_FLAG")) {
00277             if(project->isEmpty("DESTDIR"))
00278                 project->values("DESTDIR").append("");
00279             project->variables()["DESTDIR"].first() += project->variables()["TARGET"].first() +
00280                                                        ".app/Contents/MacOS/";
00281             project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + "../PkgInfo");
00282             project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO");
00283 
00284             QString plist = fileFixify(project->first("QMAKE_INFO_PLIST"));
00285             if(plist.isEmpty())
00286                 plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
00287             if(QFile::exists(Option::fixPathToLocalOS(plist))) {
00288                 if(project->isEmpty("QMAKE_INFO_PLIST"))
00289                     project->variables()["QMAKE_INFO_PLIST"].append(plist);
00290                 project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") +
00291                                                                     "../Info.plist");
00292                 project->variables()["ALL_DEPS"] += project->first("QMAKE_INFO_PLIST_OUT");
00293                 if(!project->isEmpty("RC_FILE"))
00294                     project->variables()["ALL_DEPS"] += project->first("DESTDIR") +
00295                                                         "../Resources/application.icns";
00296             }
00297         }
00298     }
00299 
00300     if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES"))
00301         project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"];
00302     project->variables()["DISTFILES"] += Option::mkfile::project_files;
00303 
00304     init2();
00305     project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS";
00306     if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
00307         bool ok;
00308         int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok);
00309         QStringList ar_sublibs, objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"];
00310         if(ok && max_files > 5 && max_files < (int)objs.count()) {
00311             int obj_cnt = 0, lib_cnt = 0;
00312             QString lib;
00313             for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
00314                 if((++obj_cnt) >= max_files) {
00315                     if(lib_cnt) {
00316                         lib.sprintf("lib%s-tmp%d.a", project->first("QMAKE_ORIG_TARGET").latin1(), lib_cnt);
00317                         ar_sublibs << lib;
00318                         obj_cnt = 0;
00319                     }
00320                     lib_cnt++;
00321                 }
00322             }
00323         }
00324         if(!ar_sublibs.isEmpty()) {
00325             project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs;
00326             project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS";
00327         }
00328     }
00329 
00330     if(project->isActiveConfig("compile_libtool")) {
00331         const QString libtoolify[] = { "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP",
00332                                        "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP",
00333                                        "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD",
00334                                        QString::null };
00335         for(int i = 0; !libtoolify[i].isNull(); i++) {
00336             QStringList &l = project->variables()[libtoolify[i]];
00337             if(!l.isEmpty()) {
00338                 QString libtool_flags, comp_flags;
00339                 if(libtoolify[i].startsWith("QMAKE_LINK") || libtoolify[i] == "QMAKE_AR_CMD") {
00340                     libtool_flags += " --mode=link";
00341                     if(project->isActiveConfig("staticlib")) {
00342                         libtool_flags += " -static";
00343                     } else {
00344                         if(!project->isEmpty("QMAKE_LIB_FLAG")) {
00345                             int maj = project->first("VER_MAJ").toInt();
00346                             int min = project->first("VER_MIN").toInt();
00347                             int pat = project->first("VER_PAT").toInt();
00348                             comp_flags += " -version-info " + QString::number(10*maj + min) +
00349                                           ":" + QString::number(pat) + ":0";
00350                             if(libtoolify[i] != "QMAKE_AR_CMD") {
00351                                 QString rpath = Option::output_dir;
00352                                 if(!project->isEmpty("DESTDIR")) {
00353                                     rpath = project->first("DESTDIR");
00354                                     if(QDir::isRelativePath(rpath))
00355                                         rpath.prepend(Option::output_dir + Option::dir_sep);
00356                                 }
00357                                 comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, FALSE);
00358                             }
00359                         }
00360                     }
00361                     if(project->isActiveConfig("plugin"))
00362                         libtool_flags += " -module";
00363                 } else {
00364                     libtool_flags += " --mode=compile";
00365                 }
00366                 l.first().prepend("$(LIBTOOL)" + libtool_flags + " ");
00367                 if(!comp_flags.isEmpty())
00368                     l.first() += comp_flags;
00369             }
00370         }
00371     }
00372 }
00373 
00374 QStringList
00375 UnixMakefileGenerator::combineSetLFlags(const QStringList &list1, const QStringList &list2)
00376 {
00377     if(project->isActiveConfig("no_smart_library_merge"))
00378         return list1 + list2;
00379 
00380     QStringList ret;
00381     for(int i = 0; i < 2; i++) {
00382         const QStringList *lst = i ? &list2 : &list1;
00383         for(QStringList::ConstIterator it = lst->begin(); it != lst->end(); ++it) {
00384             if((*it).startsWith("-")) {
00385                 if((*it).startsWith("-L")) {
00386                     if(ret.findIndex((*it)) == -1)
00387                         ret.append((*it));
00388                 } else if((*it).startsWith("-l")) {
00389                     while(1) {
00390                         QStringList::Iterator idx = ret.find((*it));
00391                         if(idx == ret.end())
00392                             break;
00393                         ret.remove(idx);
00394                     }
00395                     ret.append((*it));
00396                 } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) {
00397                     int as_one = TRUE;
00398                     QString framework_in;
00399                     if((*it).length() > 11) {
00400                         framework_in = (*it).mid(11);
00401                     } else {
00402                         if(it != lst->end()) {
00403                             ++it;
00404                             as_one = FALSE;
00405                             framework_in = (*it);
00406                         }
00407                     }
00408                     if(!framework_in.isEmpty()) {
00409                         for(QStringList::Iterator outit = ret.begin(); outit != ret.end(); ++outit) {
00410                             if((*outit).startsWith("-framework")) {
00411                                 int found = 0;
00412                                 if((*outit).length() > 11) {
00413                                     if(framework_in == (*outit).mid(11))
00414                                         found = 1;
00415                                 } else {
00416                                     if(it != lst->end()) {
00417                                         ++outit;
00418                                         if(framework_in == (*outit)) {
00419                                             --outit;
00420                                             found = 2;
00421                                         }
00422                                     }
00423                                 }
00424                                 for(int i = 0; i < found; i++)
00425                                     outit = ret.remove(outit);
00426                             }
00427                         }
00428                         if(as_one) {
00429                             ret.append("-framework " + framework_in);
00430                         } else {
00431                             ret.append("-framework");
00432                             ret.append(framework_in);
00433                         }
00434                     }
00435                 } else {
00436 #if 1
00437                     while(1) {
00438                         QStringList::Iterator idx = ret.find((*it));
00439                         if(idx == ret.end())
00440                             break;
00441                         ret.remove(idx);
00442                     }
00443 #endif
00444                     ret.append((*it));
00445                 }
00446             } else /*if(QFile::exists((*it)))*/ {
00447                 while(1) {
00448                     QStringList::Iterator idx = ret.find((*it));
00449                     if(idx == ret.end())
00450                         break;
00451                     ret.remove(idx);
00452                 }
00453                 ret.append((*it));
00454             }
00455         }
00456     }
00457     return ret;
00458 }
00459 
00460 void
00461 UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
00462 {
00463     if(var == "QMAKE_PRL_LIBS")
00464         project->variables()["QMAKE_CURRENT_PRL_LIBS"] = combineSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"] +
00465                                                                           project->variables()["QMAKE_LIBS"], l);
00466     else
00467         MakefileGenerator::processPrlVariable(var, l);
00468 }
00469 
00470 QString
00471 UnixMakefileGenerator::findDependency(const QString &dep)
00472 {
00473     QStringList::Iterator it;
00474     {
00475         QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
00476         for(it = qut.begin(); it != qut.end(); ++it) {
00477             QString targ = var((*it) + ".target");
00478             if(targ.isEmpty())
00479                 targ = (*it);
00480             if(targ.endsWith(dep))
00481                 return targ;
00482         }
00483     }
00484     {
00485         QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
00486         for(it = quc.begin(); it != quc.end(); ++it) {
00487             QString tmp_out = project->variables()[(*it) + ".output"].first();
00488             QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" ");
00489             if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
00490                 continue;
00491             QStringList &tmp = project->variables()[(*it) + ".input"];
00492             for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
00493                 QStringList &inputs = project->variables()[(*it2)];
00494                 for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
00495                     QString out = tmp_out;
00496                     QFileInfo fi(Option::fixPathToLocalOS((*input)));
00497                     out.replace("${QMAKE_FILE_BASE}", fi.baseName());
00498                     out.replace("${QMAKE_FILE_NAME}", fi.fileName());
00499                     if(out.endsWith(dep))
00500                         return out;
00501                 }
00502             }
00503         }
00504     }
00505     return MakefileGenerator::findDependency(dep);
00506 }
00507 
00508 QStringList
00509 &UnixMakefileGenerator::findDependencies(const QString &file)
00510 {
00511     QStringList &ret = MakefileGenerator::findDependencies(file);
00512     // Note: The QMAKE_IMAGE_COLLECTION file have all images
00513     // as dependency, so don't add precompiled header then
00514     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")
00515        && file != project->first("QMAKE_IMAGE_COLLECTION")) {
00516         QString header_prefix = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep;
00517         header_prefix += project->first("QMAKE_PRECOMP_PREFIX");
00518         if(file.endsWith(".c")) {
00519             QString precomp_h = header_prefix + "c";
00520             if(!ret.contains(precomp_h))
00521                 ret += precomp_h;
00522         } else {
00523             for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) {
00524                 if(file.endsWith(*it)) {
00525                     QString precomp_h = header_prefix + "c++";
00526                     if(!ret.contains(precomp_h))
00527                         ret += precomp_h;
00528                     break;
00529                 }
00530             }
00531         }
00532     }
00533     return ret;
00534 }
00535 
00536 bool
00537 UnixMakefileGenerator::findLibraries()
00538 {
00539     QPtrList<MakefileDependDir> libdirs;
00540     libdirs.setAutoDelete(TRUE);
00541     const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
00542     for(int i = 0; !lflags[i].isNull(); i++) {
00543         QStringList &l = project->variables()[lflags[i]];
00544         for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00545             QString stub, dir, extn, opt = (*it).stripWhiteSpace();
00546             if(opt.startsWith("-")) {
00547                 if(opt.startsWith("-L")) {
00548                     QString r = opt.right(opt.length() - 2), l = r;
00549                     fixEnvVariables(l);
00550                     libdirs.append(new MakefileDependDir(r.replace("\"",""),
00551                                                          l.replace("\"","")));
00552                 } else if(opt.startsWith("-l")) {
00553                     stub = opt.mid(2);
00554                 } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) {
00555                     if(opt.length() > 11) {
00556                         opt = opt.mid(11);
00557                     } else {
00558                         ++it;
00559                         opt = (*it);
00560                     }
00561                     extn = "";
00562                     dir = "/System/Library/Frameworks/" + opt + ".framework/";
00563                     stub = opt;
00564                 }
00565             } else {
00566                 extn = dir = "";
00567                 stub = opt;
00568                 int slsh = opt.findRev(Option::dir_sep);
00569                 if(slsh != -1) {
00570                     dir = opt.left(slsh);
00571                     stub = opt.mid(slsh+1);
00572                 }
00573                 QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$");
00574                 if(stub_reg.exactMatch(stub)) {
00575                     stub = stub_reg.cap(1);
00576                     extn = stub_reg.cap(2);
00577                 }
00578             }
00579             if(!stub.isEmpty()) {
00580                 const QString modifs[] = { "", "-mt", QString::null };
00581                 for(int modif = 0; !modifs[modif].isNull(); modif++) {
00582                     bool found = FALSE;
00583                     QStringList extens;
00584                     if(!extn.isNull())
00585                         extens << extn;
00586                     else
00587                         extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a";
00588                     for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) {
00589                         if(dir.isNull()) {
00590                             QString lib_stub;
00591                             for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
00592                                 if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub +
00593                                                  modifs[modif] + "." + (*extit))) {
00594                                     lib_stub = stub + modifs[modif];
00595                                     break;
00596                                 }
00597                             }
00598                             if(!lib_stub.isNull()) {
00599                                 (*it) = "-l" + lib_stub;
00600                                 found = TRUE;
00601                                 break;
00602                             }
00603                         } else {
00604                             if(QFile::exists("lib" + stub + modifs[modif] + "." + (*extit))) {
00605                                 (*it) = "lib" + stub + modifs[modif] + "." + (*extit);
00606                                 found = TRUE;
00607                                 break;
00608                             }
00609                         }
00610                     }
00611                     if(!found && project->isActiveConfig("compile_libtool")) {
00612                         for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
00613                             if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext)) {
00614                                 (*it) = mdd->real_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext;
00615                                 found = TRUE;
00616                                 break;
00617                             }
00618                         }
00619                     }
00620                     if(found)
00621                         break;
00622 
00623                 }
00624             }
00625         }
00626     }
00627     return FALSE;
00628 }
00629 
00630 QString linkLib(const QString &file, const QString &libName) {
00631   QString ret;
00632   QRegExp reg("^.*lib(" + libName + "[^./=]*).*$");
00633   if(reg.exactMatch(file))
00634     ret = "-l" + reg.cap(1);
00635   return ret;
00636 }
00637 
00638 void
00639 UnixMakefileGenerator::processPrlFiles()
00640 {
00641     QDict<void> processed;
00642     QPtrList<MakefileDependDir> libdirs;
00643     libdirs.setAutoDelete(TRUE);
00644     const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
00645     for(int i = 0; !lflags[i].isNull(); i++) {
00646         for(bool ret = FALSE; TRUE; ret = FALSE) {
00647             QStringList l_out;
00648             QStringList &l = project->variables()[lflags[i]];
00649             for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00650                 project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear();
00651                 QString opt = (*it).stripWhiteSpace();
00652                 if(opt.startsWith("-")) {
00653                     if(opt.startsWith("-L")) {
00654                         QString r = opt.right(opt.length() - 2), l = r;
00655                         fixEnvVariables(l);
00656                         libdirs.append(new MakefileDependDir(r.replace("\"",""),
00657                                                              l.replace("\"","")));
00658                     } else if(opt.startsWith("-l") && !processed[opt]) {
00659                         QString lib = opt.right(opt.length() - 2);
00660                         for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
00661                             if(!project->isActiveConfig("compile_libtool")) { //give them the .libs..
00662                                 QString la = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::libtool_ext;
00663                                 if(QFile::exists(la) && QFile::exists(mdd->local_dir + Option::dir_sep + ".libs")) {
00664                                     l_out.append("-L" + mdd->real_dir + Option::dir_sep + ".libs");
00665                                     libdirs.append(new MakefileDependDir(mdd->real_dir +  Option::dir_sep + ".libs",
00666                                                                          mdd->local_dir + Option::dir_sep + ".libs"));
00667                                 }
00668                             }
00669 
00670                             QString prl = mdd->local_dir + Option::dir_sep + "lib" + lib;
00671                             if(processPrlFile(prl)) {
00672                                 if(prl.startsWith(mdd->local_dir))
00673                                     prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
00674                                 opt = linkLib(prl, lib);
00675                                 processed.insert(opt, (void*)1);
00676                                 ret = TRUE;
00677                                 break;
00678                             }
00679                         }
00680                     } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) {
00681                         if(opt.length() > 11) {
00682                             opt = opt.mid(11);
00683                         } else {
00684                             ++it;
00685                             opt = (*it);
00686                         }
00687                         QString prl = "/System/Library/Frameworks/" + opt +
00688                                       ".framework/" + opt;
00689                         if(processPrlFile(prl))
00690                             ret = TRUE;
00691                         l_out.append("-framework");
00692                     }
00693                     if(!opt.isEmpty())
00694                         l_out.append(opt);
00695                     l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]);
00696                 } else {
00697                     QString lib = opt;
00698                     if(!processed[lib] && processPrlFile(lib)) {
00699                       processed.insert(lib, (void*)1);
00700                       ret = TRUE;
00701                     }
00702 #if 0
00703                     if(ret)
00704                       opt = linkLib(lib, "");
00705 #endif
00706                     if(!opt.isEmpty())
00707                       l_out.append(opt);
00708                     l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]);
00709                 }
00710             }
00711             if(ret && l != l_out)
00712                 l = l_out;
00713             else
00714                 break;
00715         }
00716     }
00717 }
00718 
00719 QString
00720 UnixMakefileGenerator::defaultInstall(const QString &t)
00721 {
00722     if(t != "target" || project->first("TEMPLATE") == "subdirs")
00723         return QString();
00724 
00725     bool resource = FALSE;
00726     const QString root = "$(INSTALL_ROOT)";
00727     QStringList &uninst = project->variables()[t + ".uninstall"];
00728     QString ret, destdir=project->first("DESTDIR");
00729     QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE);
00730     if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
00731         destdir += Option::dir_sep;
00732     targetdir = fileFixify(targetdir);
00733     if(targetdir.right(1) != Option::dir_sep)
00734         targetdir += Option::dir_sep;
00735 
00736     QStringList links;
00737     QString target="$(TARGET)";
00738     if(project->first("TEMPLATE") == "app") {
00739         target = "$(QMAKE_TARGET)";
00740         if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
00741             destdir += "../../../";
00742             target += ".app";
00743             resource = TRUE;
00744         }
00745     } else if(project->first("TEMPLATE") == "lib") {
00746         if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") &&
00747            !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
00748             QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE");
00749             int slsh = dst_prl.findRev('/');
00750             if(slsh != -1)
00751                 dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
00752             dst_prl = root + targetdir + dst_prl;
00753             ret += "-$(INSTALL_FILE) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\"";
00754             if(!uninst.isEmpty())
00755                 uninst.append("\n\t");
00756             uninst.append("-$(DEL_FILE) \"" + dst_prl + "\"");
00757         }
00758         if(project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) {
00759             QString src_lt = var("QMAKE_ORIG_TARGET");
00760             int slsh = src_lt.findRev(Option::dir_sep);
00761             if(slsh != -1)
00762                 src_lt = src_lt.right(src_lt.length() - slsh);
00763             int dot = src_lt.find('.');
00764             if(dot != -1)
00765                 src_lt = src_lt.left(dot);
00766             src_lt += Option::libtool_ext;
00767             src_lt.prepend("lib");
00768             QString dst_lt = root + targetdir + src_lt;
00769             if(!project->isEmpty("DESTDIR")) {
00770                 src_lt.prepend(var("DESTDIR"));
00771                 src_lt = Option::fixPathToLocalOS(fileFixify(src_lt,
00772                                                              QDir::currentDirPath(), Option::output_dir));
00773             }
00774             if(!ret.isEmpty())
00775                 ret += "\n\t";
00776             ret += "-$(INSTALL_FILE) \"" + src_lt + "\" \"" + dst_lt + "\"";
00777             if(!uninst.isEmpty())
00778                 uninst.append("\n\t");
00779             uninst.append("-$(DEL_FILE) \"" + dst_lt + "\"");
00780         }
00781         if(project->isActiveConfig("create_pc")) {
00782             QString src_pc = var("QMAKE_ORIG_TARGET");
00783             int slsh = src_pc.findRev(Option::dir_sep);
00784             if(slsh != -1)
00785                 src_pc = src_pc.right(src_pc.length() - slsh);
00786             int dot = src_pc.find('.');
00787             if(dot != -1)
00788                 src_pc = src_pc.left(dot);
00789             src_pc += ".pc";
00790             QString d = root + targetdir + "pkgconfig" + Option::dir_sep;
00791             QString dst_pc = d + src_pc;
00792             if(!project->isEmpty("DESTDIR")) {
00793                 src_pc.prepend(var("DESTDIR"));
00794                 src_pc = Option::fixPathToLocalOS(fileFixify(src_pc,
00795                                                              QDir::currentDirPath(), Option::output_dir));
00796             }
00797             if(!ret.isEmpty())
00798                 ret += "\n\t";
00799             ret += mkdir_p_asstring(d) + "\n\t";
00800             ret += "-$(INSTALL_FILE) \"" + src_pc + "\" \"" + dst_pc + "\"";
00801             if(!uninst.isEmpty())
00802                 uninst.append("\n\t");
00803             uninst.append("-$(DEL_FILE) \"" + dst_pc + "\"");
00804         }
00805         if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) {
00806             if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) {
00807                 if ( project->isEmpty("QMAKE_HPUX_SHLIB") ) {
00808                     links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)";
00809                 } else {
00810                     links << "$(TARGET0)";
00811                 }
00812             }
00813         }
00814     }
00815 
00816     if(!resource && project->isActiveConfig("compile_libtool")) {
00817         QString src_targ = target;
00818         if(src_targ == "$(TARGET)")
00819             src_targ = "$(TARGETL)";
00820         QString dst_dir = fileFixify(targetdir);
00821         if(QDir::isRelativePath(dst_dir))
00822             dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir);
00823         ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + root + dst_dir + "\"";
00824         uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\"");
00825     } else {
00826         QString src_targ = target;
00827         if(!destdir.isEmpty())
00828             src_targ = Option::fixPathToTargetOS(destdir + target, FALSE);
00829         QString dst_targ = root + fileFixify(targetdir + target, 
00830                                              QDir::currentDirPath(), Option::output_dir);
00831         if(!ret.isEmpty())
00832             ret += "\n\t";
00833         if(resource)
00834             ret += "$(DEL_FILE) -r \"" + dst_targ + "\"" + "\n\t";
00835         if(!ret.isEmpty())
00836             ret += "\n\t";
00837         ret += QString(resource ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" +
00838                src_targ + "\" \"" + dst_targ + "\"";
00839         if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP") &&
00840            (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("staticlib"))) {
00841             ret += "\n\t-" + var("QMAKE_STRIP");
00842             if(project->first("TEMPLATE") == "lib" && !project->isEmpty("QMAKE_STRIPFLAGS_LIB"))
00843                 ret += " " + var("QMAKE_STRIPFLAGS_LIB");
00844             else if(project->first("TEMPLATE") == "app" && !project->isEmpty("QMAKE_STRIPFLAGS_APP"))
00845                 ret += " " + var("QMAKE_STRIPFLAGS_APP");
00846             if(resource)
00847                 ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\"";
00848             else
00849                 ret += " \"" + dst_targ + "\"";
00850         }
00851         if(!uninst.isEmpty())
00852             uninst.append("\n\t");
00853         if(resource)
00854             uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\"");
00855         else
00856             uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"");
00857         if(!links.isEmpty()) {
00858             for(QStringList::Iterator it = links.begin(); it != links.end(); it++) {
00859                 if(Option::target_mode == Option::TARG_WIN_MODE ||
00860                    Option::target_mode == Option::TARG_MAC9_MODE) {
00861                 } else if(Option::target_mode == Option::TARG_UNIX_MODE ||
00862                           Option::target_mode == Option::TARG_MACX_MODE) {
00863                     QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE);
00864                     int lslash = link.findRev(Option::dir_sep);
00865                     if(lslash != -1)
00866                         link = link.right(link.length() - (lslash + 1));
00867                     QString dst_link = root + targetdir + link;
00868                     ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\"";
00869                     if(!uninst.isEmpty())
00870                         uninst.append("\n\t");
00871                     uninst.append("-$(DEL_FILE) \"" + dst_link + "\"");
00872                 }
00873             }
00874         }
00875     }
00876     return ret;
00877 }

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