00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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"))
00053 return;
00054
00055 QStringList &configs = project->variables()["CONFIG"];
00056
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;
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
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();
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;
00271 if(project->isActiveConfig("compile_libtool"))
00272 Option::obj_ext = ".lo";
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 {
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
00513
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")) {
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 }