-rw-r--r-- | qmake/generators/makefile.cpp | 384 | ||||
-rw-r--r-- | qmake/generators/makefile.h | 10 | ||||
-rw-r--r-- | qmake/generators/projectgenerator.cpp | 64 | ||||
-rw-r--r-- | qmake/generators/unix/unixmake.cpp | 154 | ||||
-rw-r--r-- | qmake/generators/unix/unixmake.h | 1 | ||||
-rw-r--r-- | qmake/generators/unix/unixmake2.cpp | 149 | ||||
-rw-r--r-- | qmake/generators/win32/borland_bmake.cpp | 56 | ||||
-rw-r--r-- | qmake/generators/win32/borland_bmake.h | 9 | ||||
-rw-r--r-- | qmake/generators/win32/mingw_make.cpp | 524 | ||||
-rw-r--r-- | qmake/generators/win32/mingw_make.h | 58 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_dsp.cpp | 163 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_dsp.h | 14 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 98 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.h | 8 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.cpp | 155 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.h | 50 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 316 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.h | 30 | ||||
-rw-r--r-- | qmake/generators/win32/winmakefile.cpp | 126 |
19 files changed, 1833 insertions, 536 deletions
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index f490313..c12375d 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1,2085 +1,2263 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "makefile.h" #include "option.h" #include <qdir.h> #include <qfile.h> #include <qtextstream.h> #include <qregexp.h> #include <qdict.h> #if defined(Q_OS_UNIX) #include <unistd.h> #else #include <io.h> #endif #include <stdio.h> #include <stdlib.h> #include <time.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> // Well, Windows doesn't have this, so here's the macro #ifndef S_ISDIR #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif +static QString mkdir_p_asstring(const QString &dir) +{ + QString ret = "@$(CHK_DIR_EXISTS) \"" + dir + "\" "; + if(Option::target_mode == Option::TARG_WIN_MODE) + ret += "$(MKDIR)"; + else + ret += "|| $(MKDIR)"; + ret += " \"" + dir + "\""; + return ret; +} + static bool createDir(const QString& fullPath) { + if(QFile::exists(fullPath)) + return FALSE; + QDir dirTmp; bool ret = TRUE; QString pathComponent, tmpPath; QStringList hierarchy = QStringList::split(QString(Option::dir_sep), fullPath, TRUE); for(QStringList::Iterator it = hierarchy.begin(); it != hierarchy.end(); ++it) { pathComponent = *it + QDir::separator(); tmpPath += pathComponent; if(!dirTmp.mkdir(tmpPath)) { ret = FALSE; // break; } } return ret; } MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE), init_already(FALSE), moc_aware(FALSE), no_io(FALSE), project(p) { } static char *gimme_buffer(off_t s) { static char *big_buffer = NULL; static int big_buffer_size = 0; if(!big_buffer || big_buffer_size < s) big_buffer = (char *)realloc(big_buffer, s); return big_buffer; } bool -MakefileGenerator::generateMocList(QString fn_target) +MakefileGenerator::generateMocList(const QString &fn_target) { if(!findMocDestination(fn_target).isEmpty()) return TRUE; QString fn_local = Option::fixPathToLocalOS(fileFixify(fn_target, QDir::currentDirPath(), Option::output_dir)); int file = open(fn_local.latin1(), O_RDONLY); if(file == -1) return FALSE; struct stat fst; if(fstat(file, &fst) || S_ISDIR(fst.st_mode)) return FALSE; //shouldn't happen char *big_buffer = gimme_buffer(fst.st_size); int total_size_read; for(int have_read = total_size_read = 0; (have_read = read(file, big_buffer + total_size_read, fst.st_size - total_size_read)); total_size_read += have_read); close(file); bool ignore_qobject = FALSE; int line_count = 1; /* qmake ignore Q_OBJECT */ #define COMP_LEN 8 //strlen("Q_OBJECT") #define OBJ_LEN 8 //strlen("Q_OBJECT") #define DIS_LEN 10 //strlen("Q_DISPATCH") int x; for(x = 0; x < (total_size_read-COMP_LEN); x++) { if(*(big_buffer + x) == '/') { x++; if(total_size_read >= x) { if(*(big_buffer + x) == '/') { //c++ style comment for( ;x < total_size_read && *(big_buffer + x) != '\n'; x++); line_count++; } else if(*(big_buffer + x) == '*') { //c style comment for( ;x < total_size_read; x++) { if(*(big_buffer + x) == 't' || *(big_buffer + x) == 'q') { //ignore if(total_size_read >= (x + 20)) { if(!strncmp(big_buffer + x + 1, "make ignore Q_OBJECT", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"", fn_target.latin1(), line_count); x += 20; ignore_qobject = TRUE; } } } else if(*(big_buffer + x) == '*') { if(total_size_read >= (x+1) && *(big_buffer + (x+1)) == '/') { x += 2; break; } } else if(*(big_buffer + x) == '\n') { line_count++; } } } } } #define SYMBOL_CHAR(x) ((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z') || \ (x <= '0' && x >= '9') || x == '_') bool interesting = *(big_buffer+x) == 'Q' && (!strncmp(big_buffer+x, "Q_OBJECT", OBJ_LEN) || !strncmp(big_buffer+x, "Q_DISPATCH", DIS_LEN)); if(interesting) { int len = 0; if(!strncmp(big_buffer+x, "Q_OBJECT", OBJ_LEN)) { if(ignore_qobject) { debug_msg(2, "Mocgen: %s:%d Ignoring Q_OBJECT", fn_target.latin1(), line_count); interesting = FALSE; } len=OBJ_LEN; } else if(!strncmp(big_buffer+x, "Q_DISPATCH", DIS_LEN)) { len=DIS_LEN; } if(SYMBOL_CHAR(*(big_buffer+x+len))) interesting = FALSE; if(interesting) { *(big_buffer+x+len) = '\0'; - debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), line_count, big_buffer+x); + debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), + line_count, big_buffer+x); int ext_pos = fn_target.findRev('.'); int ext_len = fn_target.length() - ext_pos; int dir_pos = fn_target.findRev(Option::dir_sep, ext_pos); QString mocFile; if(!project->isEmpty("MOC_DIR")) mocFile = project->first("MOC_DIR"); else if(dir_pos != -1) mocFile = fn_target.left(dir_pos+1); bool cpp_ext = FALSE; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { + for(QStringList::Iterator cppit = Option::cpp_ext.begin(); + cppit != Option::cpp_ext.end(); ++cppit) { if((cpp_ext = (fn_target.right(ext_len) == (*cppit)))) break; } if(cpp_ext) { mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext; - findDependencies(fn_target).append(mocFile); project->variables()["_SRCMOC"].append(mocFile); } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) { - for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { + for(QStringList::Iterator hit = Option::h_ext.begin(); + hit != Option::h_ext.end(); ++hit) { if((fn_target.right(ext_len) == (*hit))) { mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::cpp_ext.first(); logicWarn(mocFile, "SOURCES"); project->variables()["_HDRMOC"].append(mocFile); break; } } } if(!mocFile.isEmpty()) { mocFile = Option::fixPathToTargetOS(mocFile); mocablesToMOC[cleanFilePath(fn_target)] = mocFile; mocablesFromMOC[cleanFilePath(mocFile)] = fn_target; } break; } } while(x < total_size_read && SYMBOL_CHAR(*(big_buffer+x))) x++; if(*(big_buffer+x) == '\n') line_count++; } #undef OBJ_LEN #undef DIS_LEN return TRUE; } bool -MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QString fn, bool recurse) +MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &f, bool recurse) { - fn = fileFixify(fn); - QStringList &fndeps = findDependencies(fn); + QStringList &fndeps = findDependencies(f); if(!fndeps.isEmpty()) return TRUE; - + QString fn = fileFixify(f, QDir::currentDirPath(), Option::output_dir); fn = Option::fixPathToLocalOS(fn, FALSE); QString fix_env_fn = Option::fixPathToLocalOS(fn); int file = open(fix_env_fn.latin1(), O_RDONLY); if(file == -1) return FALSE; struct stat fst; if(fstat(file, &fst) || S_ISDIR(fst.st_mode)) return FALSE; //shouldn't happen QString fndir, fix_env_fndir; int dl = fn.findRev(Option::dir_sep); if(dl != -1) fndir = fn.left(dl+1); dl = fix_env_fn.findRev(Option::dir_sep); if(dl != -1) fix_env_fndir = fix_env_fn.left(dl + 1); int line_count = 1; char *big_buffer = gimme_buffer(fst.st_size); int total_size_read; for(int have_read = total_size_read = 0; (have_read = read(file, big_buffer + total_size_read, fst.st_size - total_size_read)); total_size_read += have_read); close(file); bool ui_file = fn.endsWith(Option::ui_ext); for(int x = 0; x < total_size_read; x++) { QStringList *outdeps=&fndeps; QString inc; if(!ui_file) { if(*(big_buffer + x) == '/') { x++; if(total_size_read >= x) { if(*(big_buffer + x) == '/') { //c++ style comment for( ; x < total_size_read && *(big_buffer + x) != '\n'; x++); } else if(*(big_buffer + x) == '*') { //c style comment for( ; x < total_size_read; x++) { if(*(big_buffer + x) == '*') { if(total_size_read >= (x+1) && *(big_buffer + (x+1)) == '/') { x += 2; break; } } else if(*(big_buffer + x) == '\n') { line_count++; } } } } } if(*(big_buffer + x) == '#') { x++; while(x < total_size_read && //Skip spaces after hash (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; - if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include ", 8)) { - for(x+=8; //skip spaces after keyword + if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && + (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '\t' || + *(big_buffer + x + 7) == '<' || *(big_buffer + x + 7) == '"')) { + for(x+=7; //skip spaces after keyword x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); char term = *(big_buffer + x); if(term == '"'); else if(term == '<') term = '>'; else continue; //wtf? x++; int inc_len; for(inc_len = 0; *(big_buffer + x + inc_len) != term; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; } else if(total_size_read >= x + 14 && !strncmp(big_buffer + x, "qmake_warning ", 14)) { for(x+=14; //skip spaces after keyword x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); x++); char term = '\n'; if(*(big_buffer + x) == '"') term = '"'; if(*(big_buffer + x) == '\'') term = '\''; if(term != '\n') x++; int msg_len; for(msg_len = 0; *(big_buffer + x + msg_len) != term; msg_len++); *(big_buffer + x + msg_len) = '\0'; QString msg = big_buffer + x; debug_msg(0, "%s:%d qmake_warning -- %s", fix_env_fn.latin1(), line_count, msg.latin1()); *(big_buffer + x + msg_len) = term; //put it back } } } else if(ui_file) { // skip whitespaces while(x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) x++; if(*(big_buffer + x) == '<') { x++; if(total_size_read >= x + 12 && !strncmp(big_buffer + x, "includehint", 11) && (*(big_buffer + x + 11) == ' ' || *(big_buffer + x + 11) == '>')) { for(x += 12; *(big_buffer + x) != '>'; x++); int inc_len = 0; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) { for(x += 8; *(big_buffer + x) != '>'; x++) { if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' && !strncmp(big_buffer + x, "impldecl", 8)) { for(x += 8; *(big_buffer + x) != '='; x++); if(*(big_buffer + x) != '=') continue; for(x++; *(big_buffer+x) == '\t' || *(big_buffer+x) == ' '; x++); char quote = 0; if(*(big_buffer+x) == '\'' || *(big_buffer+x) == '"') { quote = *(big_buffer + x); x++; } int val_len; for(val_len = 0; TRUE; val_len++) { if(quote) { if(*(big_buffer+x+val_len) == quote) break; } else if(*(big_buffer + x + val_len) == '>' || *(big_buffer + x + val_len) == ' ') { break; } } char saved = *(big_buffer + x + val_len); *(big_buffer + x + val_len) = '\0'; QString where = big_buffer + x; *(big_buffer + x + val_len) = saved; if(where == "in implementation") { QString cpp = fn.left(fn.length() - Option::ui_ext.length()) + Option::cpp_ext.first(); outdeps = &findDependencies(cpp); } } } int inc_len = 0; for(x += 1 ; *(big_buffer + x + inc_len) != '<'; inc_len++); *(big_buffer + x + inc_len) = '\0'; inc = big_buffer + x; } } } if(!inc.isEmpty()) { + bool from_source_dir = TRUE; debug_msg(5, "%s:%d Found dependency to %s", fix_env_fn.latin1(), line_count, inc.latin1()); if(!project->isEmpty("SKIP_DEPENDS")) { bool found = FALSE; QStringList &nodeplist = project->values("SKIP_DEPENDS"); for(QStringList::Iterator it = nodeplist.begin(); it != nodeplist.end(); ++it) { QRegExp regx((*it)); if(regx.search(inc) != -1) { found = TRUE; break; } } if(found) continue; } QString fqn; if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && !stat(fix_env_fndir + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = fndir + inc; + goto handle_fqn; } else { if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) || (Option::target_mode == Option::TARG_WIN_MODE && inc[1] != ':') || ((Option::target_mode == Option::TARG_UNIX_MODE || Option::target_mode == Option::TARG_QNX6_MODE || Option::target_mode == Option::TARG_MACX_MODE) && inc[0] != '/')) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { if(!stat(mdd->local_dir + QDir::separator() + inc, &fst) && !S_ISDIR(fst.st_mode)) { fqn = mdd->real_dir + QDir::separator() + inc; - break; + goto handle_fqn; } } } } - if(fqn.isEmpty()) { + if(fqn.isEmpty() && Option::mkfile::do_dep_heuristics) { //these are some hacky heuristics it will try to do on an include //however these can be turned off at runtime, I'm not sure how //reliable these will be, most likely when problems arise turn it off //and see if they go away.. - if(Option::mkfile::do_dep_heuristics && depHeuristics.contains(inc)) { + if(depHeuristics.contains(inc)) { fqn = depHeuristics[inc]; } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. //is it a file from a .ui? QString inc_file = inc.section(Option::dir_sep, -1); int extn = inc_file.findRev('.'); if(extn != -1 && (inc_file.right(inc_file.length()-extn) == Option::cpp_ext.first() || inc_file.right(inc_file.length()-extn) == Option::h_ext.first())) { QString uip = inc_file.left(extn) + Option::ui_ext; QStringList uil = project->variables()["FORMS"]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); ++it) { if((*it).section(Option::dir_sep, -1) == uip) { if(!project->isEmpty("UI_DIR")) fqn = project->first("UI_DIR"); else if(!project->isEmpty("UI_HEADERS_DIR")) fqn = project->first("UI_HEADERS_DIR"); else fqn = (*it).section(Option::dir_sep, 0, -2); if(!fqn.isEmpty() && !fqn.endsWith(Option::dir_sep)) fqn += Option::dir_sep; fqn += inc_file; - break; + from_source_dir = FALSE; //uics go in the output_dir (so don't fix them) + fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir); + goto handle_fqn; + } + } + } + if(project->isActiveConfig("lex_included")) { //is this the lex file? + QString rhs = Option::lex_mod + Option::cpp_ext.first(); + if(inc.endsWith(rhs)) { + QString lhs = inc.left(inc.length() - rhs.length()) + Option::lex_ext; + QStringList ll = project->variables()["LEXSOURCES"]; + for(QStringList::Iterator it = ll.begin(); it != ll.end(); ++it) { + QString s = (*it), d; + int slsh = s.findRev(Option::dir_sep); + if(slsh != -1) { + d = s.left(slsh + 1); + s = s.right(s.length() - slsh - 1); + } + if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) + d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); + if(s == lhs) { + fqn = d + inc; + goto handle_fqn; + } } } } - if(fqn.isEmpty()) { //is it from a .y? + { //is it from a .y? QString rhs = Option::yacc_mod + Option::h_ext.first(); if(inc.endsWith(rhs)) { QString lhs = inc.left(inc.length() - rhs.length()) + Option::yacc_ext; QStringList yl = project->variables()["YACCSOURCES"]; for(QStringList::Iterator it = yl.begin(); it != yl.end(); ++it) { QString s = (*it), d; int slsh = s.findRev(Option::dir_sep); if(slsh != -1) { d = s.left(slsh + 1); s = s.right(s.length() - slsh - 1); } if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); if(s == lhs) { fqn = d + inc; - break; + goto handle_fqn; + } + } + } + } + if(mocAware() && //is it a moc file? + (inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::moc_ext))) { + QString mocs[] = { QString("_HDRMOC"), QString("_SRCMOC"), QString::null }; + for(int moc = 0; !mocs[moc].isNull(); moc++) { + QStringList &l = project->variables()[mocs[moc]]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString file = Option::fixPathToTargetOS((*it)); + if(file.section(Option::dir_sep, -(inc.contains('/')+1)) == inc) { + fqn = (*it); + if(mocs[moc] == "_HDRMOC") { + //Since it is include, no need to link it in as well + project->variables()["_SRCMOC"].append((*it)); + l.remove(it); + } else if(!findMocSource(fqn).endsWith(fn)) { + /* Not really a very good test, but this will at least avoid + confusion if it really does happen (since tmake/qmake + previously didn't even allow this the test is mostly accurate) */ + warn_msg(WarnLogic, + "Found potential multiple MOC include %s (%s) in '%s'", + inc.latin1(), fqn.latin1(), fix_env_fn.latin1()); + } + from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them) + goto handle_fqn; } } } } depHeuristics.insert(inc, fqn); } - if(!Option::mkfile::do_dep_heuristics || fqn.isEmpty()) //I give up - continue; } - - fqn = fileFixify(Option::fixPathToTargetOS(fqn, FALSE)); - debug_msg(4, "Resolved dependancy of %s to %s", inc.latin1(), fqn.latin1()); + handle_fqn: + if(fqn.isEmpty()) //I give up + continue; + fqn = Option::fixPathToTargetOS(fqn, FALSE); + if(from_source_dir) + fqn = fileFixify(fqn); + debug_msg(4, "Resolved dependency of %s to %s", inc.latin1(), fqn.latin1()); if(outdeps && outdeps->findIndex(fqn) == -1) outdeps->append(fqn); } //read past new line now.. for( ; x < total_size_read && (*(big_buffer + x) != '\n'); x++); line_count++; } if(recurse) { for(QStringList::Iterator fnit = fndeps.begin(); fnit != fndeps.end(); ++fnit) { generateDependencies(dirs, (*fnit), recurse); QStringList &deplist = findDependencies((*fnit)); for(QStringList::Iterator it = deplist.begin(); it != deplist.end(); ++it) if(fndeps.findIndex((*it)) == -1) fndeps.append((*it)); } } - debug_msg(2, "Dependancies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); + debug_msg(2, "Dependencies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); return TRUE; } void MakefileGenerator::initOutPaths() { if(init_opath_already) return; init_opath_already = TRUE; QMap<QString, QStringList> &v = project->variables(); if(!v.contains("QMAKE_ABSOLUTE_SOURCE_PATH")) { if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty() && v.contains("QMAKE_ABSOLUTE_SOURCE_ROOT")) { QString root = v["QMAKE_ABSOLUTE_SOURCE_ROOT"].first(); root = Option::fixPathToTargetOS( root ); if(!root.isEmpty()) { QFileInfo fi(Option::mkfile::cachefile); if(!fi.convertToAbs()) { QString cache_r = fi.dirPath(), pwd = Option::output_dir; if ( pwd.startsWith(cache_r) && !pwd.startsWith(root) ) { pwd = Option::fixPathToTargetOS(root + pwd.mid(cache_r.length())); if(QFile::exists(pwd)) v.insert("QMAKE_ABSOLUTE_SOURCE_PATH", pwd); } } } } } if(!v["QMAKE_ABSOLUTE_SOURCE_PATH"].isEmpty()) { QString &asp = v["QMAKE_ABSOLUTE_SOURCE_PATH"].first(); asp = Option::fixPathToTargetOS( asp ); if(asp.isEmpty() || asp == Option::output_dir) //if they're the same, why bother? v["QMAKE_ABSOLUTE_SOURCE_PATH"].clear(); } QString currentDir = QDir::currentDirPath(); QString dirs[] = { QString("OBJECTS_DIR"), QString("MOC_DIR"), QString("UI_HEADERS_DIR"), QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString("DESTDIR"), QString("SUBLIBS_DIR"), QString::null }; for(int x = 0; dirs[x] != QString::null; x++) { if ( !v[dirs[x]].isEmpty() ) { QString orig_path = v[dirs[x]].first(); { QString &path = v[dirs[x]].first(); path = fileFixify(path, Option::output_dir, Option::output_dir); if(path.right(Option::dir_sep.length()) != Option::dir_sep) path += Option::dir_sep; } if(noIO()) continue; QString path = project->first(dirs[x]); //not to be changed any further path = Option::fixPathToTargetOS(fileFixify(path, QDir::currentDirPath(), Option::output_dir)); debug_msg(3, "Fixed output_dir %s (%s) into %s (%s)", dirs[x].latin1(), orig_path.latin1(), v[dirs[x]].join("::").latin1(), path.latin1()); QDir d; if(path.startsWith(Option::dir_sep)) { d.cd(Option::dir_sep); path = path.right(path.length() - 1); } #ifdef Q_WS_WIN bool driveExists = TRUE; if ( !QDir::isRelativePath( path ) ) { if ( QFile::exists( path.left( 3 ) ) ) { d.cd( path.left( 3 ) ); path = path.right( path.length() - 3 ); } else { warn_msg(WarnLogic, "%s: Cannot access drive '%s' (%s)", dirs[x].latin1(), path.left( 3 ).latin1(), path.latin1() ); driveExists = FALSE; } } if ( driveExists ) { #endif QStringList subs = QStringList::split(Option::dir_sep, path); for(QStringList::Iterator subit = subs.begin(); subit != subs.end(); ++subit) { if(!d.cd(*subit)) { d.mkdir((*subit)); if ( d.exists( (*subit) ) ) d.cd((*subit)); else { warn_msg(WarnLogic, "%s: Cannot access directory '%s' (%s)", dirs[x].latin1(), (*subit).latin1(), path.latin1() ); break; } } } #ifdef Q_WS_WIN } #endif } } QDir::current().cd( currentDir ); } void MakefileGenerator::init() { initOutPaths(); if(init_already) return; init_already = TRUE; QMap<QString, QStringList> &v = project->variables(); QString paths[] = { QString("SOURCES"), QString("FORMS"), QString("YACCSOURCES"), QString("INCLUDEPATH"), QString("HEADERS"), QString("HEADERS_ORIG"), QString("LEXSOURCES"), QString("QMAKE_INTERNAL_INCLUDED_FILES"), QString::null }; for(int y = 0; paths[y] != QString::null; y++) { QStringList &l = v[paths[y]]; if(!l.isEmpty()) l = fileFixify(l); } /* get deps and mocables */ QDict<void> cache_found_files; - QString cache_file(Option::output_dir + QDir::separator() + ".qmake.internal.cache"); + QString cache_file(".qmake.internal.cache"); + if(!project->isEmpty("QMAKE_INTERNAL_CACHE_FILE")) + cache_file = Option::fixPathToLocalOS(project->first("QMAKE_INTERNAL_CACHE_FILE")); + if(cache_file.find(QDir::separator()) == -1) //guess they know what they are doing.. + cache_file.prepend(Option::output_dir + QDir::separator()); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps || Option::mkfile::do_mocs) && !noIO()) { QPtrList<MakefileDependDir> deplist; deplist.setAutoDelete(TRUE); if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_deps) && doDepends()) { QStringList incDirs = v["DEPENDPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"]; if(project->isActiveConfig("depend_includepath")) incDirs += v["INCLUDEPATH"]; for(QStringList::Iterator it = incDirs.begin(); it != incDirs.end(); ++it) { QString r = (*it), l = Option::fixPathToLocalOS((*it)); deplist.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } - debug_msg(1, "Dependancy Directories: %s", incDirs.join(" :: ").latin1()); + debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").latin1()); if(Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) { QFile cachef(cache_file); if(cachef.open(IO_ReadOnly | IO_Translate)) { QFileInfo cachefi(cache_file); debug_msg(2, "Trying internal cache information: %s", cache_file.latin1()); QTextStream cachet(&cachef); QString line, file; enum { CacheInfo, CacheDepend, CacheMoc } state = CacheInfo; while (!cachet.eof()) { line = cachet.readLine().stripWhiteSpace(); int sep = line.find('='); if(line == "[depend]") { state = CacheDepend; } else if(line == "[mocable]") { state = CacheMoc; } else if(line == "[check]") { state = CacheInfo; } else if(!line.isEmpty() && sep != -1) { file = line.left(sep).stripWhiteSpace(); line = line.right(line.length() - sep - 1).stripWhiteSpace(); if(state == CacheInfo) { if(file == "QMAKE_CACHE_VERSION") { if(line != qmake_version()) break; } else { const QStringList &l = project->variables()[file]; if(!l.isEmpty() && !line.isEmpty() && l.join(" ") != line) break; } } else if(state == CacheDepend) { bool found = (bool)cache_found_files[file]; QStringList files = QStringList::split(" ", line); if(!found) { QFileInfo fi(fileFixify(file, QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert(file, (void *)1); found = TRUE; } } if(found) { for(QStringList::Iterator dep_it = files.begin(); dep_it != files.end(); ++dep_it) { if(!cache_found_files[(*dep_it)]) { QFileInfo fi(fileFixify((*dep_it), QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert((*dep_it), (void *)1); } else { found = FALSE; break; } } } if(found) { - debug_msg(2, "Dependancies (cached): %s -> %s", file.latin1(), + debug_msg(2, "Dependencies (cached): %s -> %s", file.latin1(), files.join(" :: ").latin1()); findDependencies(file) = files; } } } else { void *found = cache_found_files[file]; if(found != (void *)2) { if(found) { cache_found_files.replace(file, (void *)2); } else { QFileInfo fi(fileFixify(file, QDir::currentDirPath(), Option::output_dir)); if(fi.exists() && fi.lastModified() < cachefi.lastModified()) { cache_found_files.insert(file, (void *)2); found = (void*)1; } } } if(found && line != "*qmake_ignore*") { int ext_len = file.length() - file.findRev('.'); bool cpp_ext = FALSE; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((cpp_ext = (file.right(ext_len) == (*cppit)))) break; } if(cpp_ext) { project->variables()["_SRCMOC"].append(line); } else if(project->variables()["HEADERS"].findIndex(file) != -1) { for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if((file.right(ext_len) == (*hit))) { project->variables()["_HDRMOC"].append(line); break; } } } debug_msg(2, "Mocgen (cached): %s -> %s", file.latin1(), line.latin1()); mocablesToMOC[file] = line; mocablesFromMOC[line] = file; } } } } cachef.close(); } } } if(!noIO()) { QString sources[] = { QString("OBJECTS"), QString("LEXSOURCES"), QString("YACCSOURCES"), QString("HEADERS"), QString("SOURCES"), QString("FORMS"), QString::null }; depHeuristics.clear(); bool write_cache = FALSE, read_cache = QFile::exists(cache_file); for(int x = 0; sources[x] != QString::null; x++) { QStringList vpath, &l = v[sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) { QString file = Option::fixPathToLocalOS((*val_it)); + QStringList file_list(file); if(!QFile::exists(file)) { bool found = FALSE; if(QDir::isRelativePath(file)) { if(vpath.isEmpty()) vpath = v["VPATH_" + sources[x]] + v["VPATH"] + v["QMAKE_ABSOLUTE_SOURCE_PATH"] + v["DEPENDPATH"]; for(QStringList::Iterator vpath_it = vpath.begin(); vpath_it != vpath.end(); ++vpath_it) { QString real_dir = Option::fixPathToLocalOS((*vpath_it)); if(QFile::exists(real_dir + QDir::separator() + (*val_it))) { QString dir = (*vpath_it); if(dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; (*val_it) = fileFixify(dir + (*val_it)); found = TRUE; debug_msg(1, "Found file through vpath %s -> %s", file.latin1(), (*val_it).latin1()); break; } } } if(!found) { QString dir, regex = (*val_it), real_dir; if(regex.findRev(Option::dir_sep) != -1) { dir = regex.left(regex.findRev(Option::dir_sep) + 1); real_dir = fileFixify(Option::fixPathToLocalOS(dir), QDir::currentDirPath(), Option::output_dir); regex = regex.right(regex.length() - dir.length()); } if(real_dir.isEmpty() || QFile::exists(real_dir)) { QDir d(real_dir, regex); if(!d.count()) { debug_msg(1, "%s:%d Failure to find %s in vpath (%s)", __FILE__, __LINE__, (*val_it).latin1(), vpath.join("::").latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); continue; } else { - (*val_it) = dir + d[0]; - for(int i = 1; i < (int)d.count(); i++) + file_list.clear(); + for(int i = 0; i < (int)d.count(); i++) { + file_list.append(dir + d[i]); + if(i == (int)d.count() - 1) + (*val_it) = dir + d[i]; + else l.insert(val_it, dir + d[i]); } + } } else { debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.", __FILE__, __LINE__, real_dir.latin1(), QDir::separator(), regex.latin1(), real_dir.latin1()); warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); } } } - - QString val_file = fileFixify((*val_it)); + for(QStringList::Iterator file_it = file_list.begin(); + file_it != file_list.end(); ++file_it) { + QString file_list_file = fileFixify((*file_it)); bool found_cache_moc = FALSE, found_cache_dep = FALSE; if(read_cache && Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) { - if(!findDependencies(val_file).isEmpty()) + if(!findDependencies(file_list_file).isEmpty()) found_cache_dep = TRUE; - if(cache_found_files[(*val_it)] == (void *)2) + if(cache_found_files[(*file_it)] == (void *)2) found_cache_moc = TRUE; if(!found_cache_moc || !found_cache_dep) write_cache = TRUE; } - if(!found_cache_dep && sources[x] != "OBJECTS") { - debug_msg(5, "Looking for dependancies for %s", (*val_it).latin1()); - generateDependencies(deplist, (*val_it), doDepends()); - } + /* Do moc before dependency checking since some includes can come from + moc_*.cpp files */ if(found_cache_moc) { - QString moc = findMocDestination(val_file); + QString moc = findMocDestination(file_list_file); if(!moc.isEmpty()) { for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { - if(val_file.endsWith((*cppit))) { - QStringList &deps = findDependencies(val_file); + if(file_list_file.endsWith((*cppit))) { + QStringList &deps = findDependencies(file_list_file); if(!deps.contains(moc)) deps.append(moc); break; } } } } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") && (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || Option::mkfile::do_mocs)) { - generateMocList((*val_it)); + generateMocList((*file_it)); + } + if(!found_cache_dep && sources[x] != "OBJECTS") { + debug_msg(5, "Looking for dependencies for %s", (*file_it).latin1()); + generateDependencies(deplist, (*file_it), doDepends()); + } } } } } if(project->isActiveConfig("qmake_cache") && (write_cache || !read_cache)) { QFile cachef(cache_file); if(cachef.open(IO_WriteOnly | IO_Translate)) { debug_msg(2, "Writing internal cache information: %s", cache_file.latin1()); QTextStream cachet(&cachef); cachet << "[check]" << "\n" << "QMAKE_CACHE_VERSION = " << qmake_version() << "\n" << "QMAKE_ABSOLUTE_SOURCE_PATH = " << var("QMAKE_ABSOLUTE_SOURCE_PATH") << "\n" << "MOC_DIR = " << var("MOC_DIR") << "\n" << "UI_DIR = " << var("UI_DIR") << "\n" << "UI_HEADERS_DIR = " << var("UI_HEADERS_DIR") << "\n" << "UI_SOURCES_DIR = " << var("UI_SOURCES_DIR") << "\n"; cachet << "[depend]" << endl; for(QMap<QString, QStringList>::Iterator it = depends.begin(); it != depends.end(); ++it) cachet << depKeyMap[it.key()] << " = " << it.data().join(" ") << endl; cachet << "[mocable]" << endl; QString mc, moc_sources[] = { QString("HEADERS"), QString("SOURCES"), QString::null }; for(int x = 0; moc_sources[x] != QString::null; x++) { QStringList &l = v[moc_sources[x]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { - if(!(*val_it).isEmpty()) { - mc = mocablesToMOC[(*val_it)]; + QString f = fileFixify((*val_it)); + if(!f.isEmpty()) { + mc = mocablesToMOC[f]; if(mc.isEmpty()) mc = "*qmake_ignore*"; - cachet << (*val_it) << " = " << mc << endl; + cachet << f << " = " << mc << endl; } } } cachef.close(); } } } } v["OBJECTS"] = createObjectList("SOURCES") + v["OBJECTS"]; // init variables //lex files { QStringList &impls = v["LEXIMPLS"]; QStringList &l = v["LEXSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString dir; QFileInfo fi((*it)); if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); logicWarn(impl, "SOURCES"); logicWarn(impl, "SOURCES"); impls.append(impl); if( ! project->isActiveConfig("lex_included")) { v["SOURCES"].append(impl); // attribute deps of lex file to impl file QStringList &lexdeps = findDependencies((*it)); QStringList &impldeps = findDependencies(impl); for(QStringList::ConstIterator d = lexdeps.begin(); d != lexdeps.end(); ++d) { if(!impldeps.contains(*d)) impldeps.append(*d); } lexdeps.clear(); } } if( ! project->isActiveConfig("lex_included")) v["OBJECTS"] += (v["LEXOBJECTS"] = createObjectList("LEXIMPLS")); } //yacc files { QStringList &decls = v["YACCCDECLS"], &impls = v["YACCIMPLS"]; QStringList &l = v["YACCSOURCES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString dir; QFileInfo fi((*it)); if(fi.dirPath() != ".") dir = fi.dirPath() + Option::dir_sep; dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); logicWarn(impl, "SOURCES"); QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); logicWarn(decl, "HEADERS"); decls.append(decl); impls.append(impl); v["SOURCES"].append(impl); QStringList &impldeps = findDependencies(impl); impldeps.append(decl); // attribute deps of yacc file to impl file QStringList &yaccdeps = findDependencies((*it)); for(QStringList::ConstIterator d = yaccdeps.begin(); d != yaccdeps.end(); ++d) { if(!impldeps.contains(*d)) impldeps.append(*d); } if( project->isActiveConfig("lex_included")) { // is there a matching lex file ? Transfer its dependencies. QString lexsrc = fi.baseName(TRUE) + Option::lex_ext; if(fi.dirPath() != ".") lexsrc.prepend(fi.dirPath() + Option::dir_sep); if(v["LEXSOURCES"].findIndex(lexsrc) != -1) { QString trg = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); impldeps.append(trg); impldeps += findDependencies(lexsrc); depends[lexsrc].clear(); } } yaccdeps.clear(); } v["OBJECTS"] += (v["YACCOBJECTS"] = createObjectList("YACCIMPLS")); } //UI files { + QStringList &includepath = project->variables()["INCLUDEPATH"]; if(!project->isEmpty("UI_DIR")) - project->variables()["INCLUDEPATH"].append(project->first("UI_DIR")); + includepath.append(project->first("UI_DIR")); else if(!project->isEmpty("UI_HEADERS_DIR")) - project->variables()["INCLUDEPATH"].append(project->first("UI_HEADERS_DIR")); + includepath.append(project->first("UI_HEADERS_DIR")); QStringList &decls = v["UICDECLS"], &impls = v["UICIMPLS"]; QStringList &l = v["FORMS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString impl, decl; QFileInfo fi(Option::fixPathToLocalOS((*it))); if ( !project->isEmpty("UI_DIR") ) { impl = decl = project->first("UI_DIR"); QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); - d = fileFixify(d); - if( !project->variables()["INCLUDEPATH"].contains(d)) - project->variables()["INCLUDEPATH"].append(d); + d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); + if(!includepath.contains(d)) + includepath.append(d); } else { if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR")) decl = project->first("UI_HEADERS_DIR"); - if ( !decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && !project->isEmpty("UI_SOURCES_DIR")) ) { + if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && + !project->isEmpty("UI_SOURCES_DIR")) ) { QString d = fi.dirPath(); if( d == ".") d = QDir::currentDirPath(); - d = fileFixify(d); - if( !project->variables()["INCLUDEPATH"].contains(d)) - project->variables()["INCLUDEPATH"].append(d); + d = fileFixify(d, QDir::currentDirPath(), Option::output_dir); + if(includepath.contains(d)) + includepath.append(d); } if(impl.isEmpty() && !project->isEmpty("UI_SOURCES_DIR")) impl = project->first("UI_SOURCES_DIR"); if(fi.dirPath() != ".") { if(impl.isEmpty()) impl = fi.dirPath() + Option::dir_sep; if(decl.isEmpty()) decl = fi.dirPath() + Option::dir_sep; } } - impl += fi.baseName(TRUE) + Option::cpp_ext.first(), + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + if(!impl.isEmpty()) + impl += Option::dir_sep; + impl += fi.baseName(TRUE) + Option::cpp_ext.first(); + if(Option::output_dir != QDir::currentDirPath() && + project->isEmpty("UI_DIR") && project->isEmpty("UI_HEADERS_DIR")) { + QString decl_fixed = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(!includepath.contains(decl_fixed)) + includepath.append(decl_fixed); + if(!includepath.contains(decl)) + project->variables()["INCLUDEPATH"].append(decl); + } + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + if(!decl.isEmpty()) + decl += Option::dir_sep; decl += fi.baseName(TRUE) + Option::h_ext.first(); logicWarn(impl, "SOURCES"); logicWarn(decl, "HEADERS"); decls.append(decl); impls.append(impl); findDependencies(impl).append(decl); QString mocable = Option::moc_mod + fi.baseName(TRUE) + Option::cpp_ext.first(); if(!v["MOC_DIR"].isEmpty()) mocable.prepend(v["MOC_DIR"].first()); else if(fi.dirPath() != ".") mocable.prepend(fi.dirPath() + Option::dir_sep); logicWarn(mocable, "SOURCES"); mocablesToMOC[cleanFilePath(decl)] = mocable; mocablesFromMOC[cleanFilePath(mocable)] = decl; v["_UIMOC"].append(mocable); } v["OBJECTS"] += (v["UICOBJECTS"] = createObjectList("UICDECLS")); } //Image files if(!project->isEmpty("IMAGES")) { if(project->isEmpty("QMAKE_IMAGE_COLLECTION")) v["QMAKE_IMAGE_COLLECTION"].append("qmake_image_collection" + Option::cpp_ext.first()); QString imgfile = project->first("QMAKE_IMAGE_COLLECTION"); Option::fixPathToTargetOS(imgfile); if(!project->isEmpty("UI_DIR") || !project->isEmpty("UI_SOURCES_DIR")) { if(imgfile.find(Option::dir_sep) != -1) imgfile = imgfile.right(imgfile.findRev(Option::dir_sep) + 1); imgfile.prepend( (project->isEmpty("UI_DIR") ? project->first("UI_SOURCES_DIR") : project->first("UI_DIR")) ); v["QMAKE_IMAGE_COLLECTION"] = QStringList(imgfile); } logicWarn(imgfile, "SOURCES"); if(!noIO()) { QStringList &l = v["IMAGES"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if(!QFile::exists((*it))) { warn_msg(WarnLogic, "Failure to open: %s", (*it).latin1()); continue; } findDependencies(imgfile).append(fileFixify((*it))); } } v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION")); } - - if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) - project->variables()["INCLUDEPATH"].append(Option::output_dir); + if(Option::output_dir != QDir::currentDirPath()) + project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir, + Option::output_dir)); //moc files if ( mocAware() ) { if(!project->isEmpty("MOC_DIR")) project->variables()["INCLUDEPATH"].append(project->first("MOC_DIR")); v["OBJMOC"] = createObjectList("_HDRMOC") + createObjectList("_UIMOC"); QStringList &l = v["SRCMOC"]; l = v["_HDRMOC"] + v["_UIMOC"] + v["_SRCMOC"]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(!(*val_it).isEmpty()) (*val_it) = Option::fixPathToTargetOS((*val_it), FALSE); } } } bool MakefileGenerator::processPrlFile(QString &file) { bool ret = FALSE, try_replace_file=FALSE; QString prl_file; if(file.endsWith(Option::prl_ext)) { try_replace_file = TRUE; prl_file = file; file = ""; } else { QString tmp = file; int ext = tmp.findRev('.'); if(ext != -1) tmp = tmp.left(ext); prl_file = tmp + Option::prl_ext; } prl_file = fileFixify(prl_file); if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && project->isActiveConfig("qt")) { QString stem = prl_file, dir, extn; int slsh = stem.findRev('/'), hadlib = 0; if(slsh != -1) { dir = stem.left(slsh + 1); stem = stem.right(stem.length() - slsh - 1); } if(stem.startsWith("lib")) { hadlib = 1; stem = stem.right(stem.length() - 3); } int dot = stem.find('.'); if(dot != -1) { extn = stem.right(stem.length() - dot); stem = stem.left(dot); } if(stem == "qt" || stem == "qte" || stem == "qte-mt" || stem == "qt-mt") { if(stem.endsWith("-mt")) stem = stem.left(stem.length() - 3); //lose the -mt else stem += "-mt"; //try the thread case prl_file = dir; if(hadlib) prl_file += "lib"; prl_file += stem + extn; try_replace_file = TRUE; } } QString real_prl_file = Option::fixPathToLocalOS(prl_file); if(project->variables()["QMAKE_PRL_INTERNAL_FILES"].findIndex(prl_file) != -1) { ret = TRUE; } else if(!real_prl_file.isEmpty() && QFile::exists(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir))) { project->variables()["QMAKE_PRL_INTERNAL_FILES"].append(prl_file); QMakeProject proj; debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1()); if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir), - QDir::currentDirPath())) { + QDir::currentDirPath(), TRUE)) { fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1()); } else { ret = TRUE; QMap<QString, QStringList> &vars = proj.variables(); for( QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) processPrlVariable(it.key(), it.data()); if(try_replace_file && !proj.isEmpty("QMAKE_PRL_TARGET")) { QString dir; int slsh = real_prl_file.findRev(Option::dir_sep); if(slsh != -1) dir = real_prl_file.left(slsh+1); file = dir + proj.first("QMAKE_PRL_TARGET"); } } if(ret) project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].append(prl_file); } return ret; } void MakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_LIBS") { QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &out = project->variables()[where]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if( out.findIndex((*it)) == -1) out.append((*it)); } } else if(var == "QMAKE_PRL_DEFINES") { QStringList &out = project->variables()["DEFINES"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(out.findIndex((*it)) == -1 && project->variables()["PRL_EXPORT_DEFINES"].findIndex((*it)) == -1) out.append((*it)); } } } void MakefileGenerator::processPrlFiles() { QDict<void> processed; for(bool ret = FALSE; TRUE; ret = FALSE) { //read in any prl files included.. QStringList l_out; QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &l = project->variables()[where]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString file = (*it); if(!processed[file] && processPrlFile(file)) { processed.insert(file, (void*)1); ret = TRUE; } if(!file.isEmpty()) l_out.append(file); } if(ret) l = l_out; else break; } } void MakefileGenerator::writePrlFile(QTextStream &t) { QString target = project->first("TARGET"); int slsh = target.findRev(Option::dir_sep); if(slsh != -1) target = target.right(target.length() - slsh - 1); QString bdir = Option::output_dir; if(bdir.isEmpty()) bdir = QDir::currentDirPath(); t << "QMAKE_PRL_BUILD_DIR = " << bdir << endl; if(!project->projectFile().isEmpty() && project->projectFile() != "-") t << "QMAKE_PRO_INPUT = " << project->projectFile().section('/', -1) << endl; if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) t << "QMAKE_PRL_SOURCE_DIR = " << project->first("QMAKE_ABSOLUTE_SOURCE_PATH") << endl; t << "QMAKE_PRL_TARGET = " << target << endl; if(!project->isEmpty("PRL_EXPORT_DEFINES")) t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl; if(!project->isEmpty("CONFIG")) t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl; + if(!project->isEmpty("VERSION")) + t << "QMAKE_PRL_VERSION = " << project->first("VERSION") << endl; if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) { QStringList libs; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"]; else libs << "QMAKE_LIBS"; //obvious one t << "QMAKE_PRL_LIBS = "; for(QStringList::Iterator it = libs.begin(); it != libs.end(); ++it) t << project->variables()[(*it)].join(" ") << " "; t << endl; } } bool MakefileGenerator::write() { init(); findLibraries(); if((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || //write prl Option::qmake_mode == Option::QMAKE_GENERATE_PRL) && project->isActiveConfig("create_prl") && project->first("TEMPLATE") == "lib" && !project->isActiveConfig("plugin")) { QString prl = var("TARGET"); int slsh = prl.findRev(Option::dir_sep); if(slsh != -1) prl = prl.right(prl.length() - slsh); int dot = prl.find('.'); if(dot != -1) prl = prl.left(dot); prl += Option::prl_ext; if(!project->isEmpty("DESTDIR")) prl.prepend(var("DESTDIR")); - QString local_prl = fileFixify(prl, QDir::currentDirPath(), Option::output_dir); - fixEnvVariables(local_prl); + QString local_prl = Option::fixPathToLocalOS(fileFixify(prl, QDir::currentDirPath(), Option::output_dir)); QFile ft(local_prl); if(ft.open(IO_WriteOnly)) { project->variables()["ALL_DEPS"].append(prl); project->variables()["QMAKE_INTERNAL_PRL_FILE"].append(prl); QTextStream t(&ft); writePrlFile(t); ft.close(); } } if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && - project->isActiveConfig("link_prl")) //load up prl's + project->isActiveConfig("link_prl")) //load up prl's' processPrlFiles(); if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { QTextStream t(&Option::output); writeMakefile(t); } return TRUE; } void MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &src) { QStringList &objl = project->variables()[obj]; QStringList &srcl = project->variables()[src]; QStringList::Iterator oit = objl.begin(); QStringList::Iterator sit = srcl.begin(); QString stringSrc("$src"); QString stringObj("$obj"); for( ;sit != srcl.end() && oit != objl.end(); oit++, sit++) { if((*sit).isEmpty()) continue; if(!doDepends()) { QString sdep, odep = (*sit) + " "; QStringList deps = findDependencies((*sit)); for(QStringList::Iterator dit = deps.begin(); dit != deps.end(); dit++) { if((*dit).endsWith(Option::moc_ext)) odep += (*dit) + " "; else sdep += (*dit) + " "; } t << (*sit) << ": " << sdep << endl << (*oit) << ": " << odep ; } else { t << (*oit) << ": " << (*sit) << " " << findDependencies((*sit)).join(" \\\n\t\t"); } QString comp, cimp; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*sit).endsWith((*cppit))) { comp = "QMAKE_RUN_CXX"; cimp = "QMAKE_RUN_CXX_IMP"; break; } } if(comp.isEmpty()) { comp = "QMAKE_RUN_CC"; cimp = "QMAKE_RUN_CC_IMP"; } bool use_implicit_rule = !project->isEmpty(cimp); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR")) { use_implicit_rule = FALSE; } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if (!use_implicit_rule) { + if (!use_implicit_rule && !project->isEmpty(comp)) { QString p = var(comp); p.replace(stringSrc, (*sit)); p.replace(stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; } } void MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui) { QStringList &uil = project->variables()[ui]; for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; { - QString tmp = (*it); + QString tmp = (*it), impl_dir, decl_dir; decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first()); + decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir); + int dlen = decl.findRev(Option::dir_sep) + 1; tmp = (*it); impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first()); - int dlen = (*it).findRev(Option::dir_sep) + 1; + impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir); + int ilen = decl.findRev(Option::dir_sep) + 1; if(!project->isEmpty("UI_DIR")) { + impl_dir = project->first("UI_DIR"); decl = project->first("UI_DIR") + decl.right(decl.length() - dlen); - impl = project->first("UI_DIR") + impl.right(impl.length() - dlen); + impl = project->first("UI_DIR") + impl.right(impl.length() - ilen); } else { - if(!project->isEmpty("UI_HEADERS_DIR")) + if(!project->isEmpty("UI_HEADERS_DIR")) { + decl_dir = project->first("UI_HEADERS_DIR"); decl = project->first("UI_HEADERS_DIR") + decl.right(decl.length() - dlen); - if(!project->isEmpty("UI_SOURCES_DIR")) - impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - dlen); } + if(!project->isEmpty("UI_SOURCES_DIR")) { + impl_dir = project->first("UI_SOURCES_DIR"); + impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - ilen); + } + } + if(decl_dir.isEmpty()) + decl_dir = decl.left(dlen); + if(impl_dir.isEmpty()) + impl_dir = impl.left(ilen); + if(!impl_dir.isEmpty()) + createDir(Option::output_dir + Option::dir_sep + impl_dir); + if(!decl_dir.isEmpty() && decl_dir != impl_dir) + createDir(Option::output_dir + Option::dir_sep + decl_dir); } t << decl << ": " << (*it) << " " << deps << "\n\t" << "$(UIC) " << (*it) << " -o " << decl << endl << endl; QString mildDecl = decl; int k = mildDecl.findRev( Option::dir_sep ); if ( k != -1 ) mildDecl = mildDecl.mid( k + 1 ); t << impl << ": " << decl << " " << (*it) << " " << deps << "\n\t" << "$(UIC) " << (*it) << " -i " << mildDecl << " -o " << impl << endl << endl; } } void MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString &src) { QStringList &objl = project->variables()[obj], &srcl = project->variables()[src]; QStringList::Iterator oit = objl.begin(), sit = srcl.begin(); QString stringSrc("$src"), stringObj("$obj"); for( ;sit != srcl.end() && oit != objl.end(); oit++, sit++) { QString hdr = findMocSource((*sit)); t << (*oit) << ": " << (*sit) << " " << hdr << " " << findDependencies(hdr).join(" \\\n\t\t"); bool use_implicit_rule = !project->isEmpty("QMAKE_RUN_CXX_IMP"); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR") || !project->isEmpty("MOC_DIR")) { use_implicit_rule = FALSE; } else { int dot = (*sit).findRev('.'); if(dot == -1 || ((*sit).left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if (!use_implicit_rule) { + if (!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { QString p = var("QMAKE_RUN_CXX"); p.replace(stringSrc, (*sit)); p.replace(stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; } } void MakefileGenerator::writeMocSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString m = Option::fixPathToTargetOS(findMocDestination(*it)); if ( !m.isEmpty()) { QString deps; if(!project->isActiveConfig("no_mocdepend")) deps += "$(MOC) "; deps += (*it); t << m << ": " << deps << "\n\t" << "$(MOC) " << (*it) << " -o " << m << endl << endl; } } } void MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; if(project->isActiveConfig("yacc_no_name_mangle") && l.count() > 1) warn_msg(WarnLogic, "yacc_no_name_mangle specified, but multiple parsers expected." "This can lead to link problems.\n"); QString default_out_h = "y.tab.h", default_out_c = "y.tab.c"; if(!project->isEmpty("QMAKE_YACC_HEADER")) default_out_h = project->first("QMAKE_YACC_HEADER"); if(!project->isEmpty("QMAKE_YACC_SOURCE")) default_out_c = project->first("QMAKE_YACC_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); - QString dir = fileFixify(Option::output_dir); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; + QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); QString yaccflags = "$(YACCFLAGS)", mangle = "y"; if(!project->isActiveConfig("yacc_no_name_mangle")) { mangle = fi.baseName(TRUE); yaccflags += " -p " + mangle; } QString out_h = default_out_h, out_c = default_out_c; if(!mangle.isEmpty()) { out_h.replace(stringBase, mangle); out_c.replace(stringBase, mangle); } t << impl << ": " << (*it) << "\n\t" << "$(YACC) " << yaccflags << " " << (*it) << "\n\t" << "-$(DEL_FILE) " << impl << " " << decl << "\n\t" << "-$(MOVE) " << out_h << " " << decl << "\n\t" << "-$(MOVE) " << out_c << " " << impl << endl << endl; t << decl << ": " << impl << endl << endl; } } void MakefileGenerator::writeLexSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; if(project->isActiveConfig("yacc_no_name_mangle") && l.count() > 1) warn_msg(WarnLogic, "yacc_no_name_mangle specified, but multiple parsers expected.\n" "This can lead to link problems.\n"); QString default_out_c = "lex.$base.c"; if(!project->isEmpty("QMAKE_LEX_SOURCE")) default_out_c = project->first("QMAKE_LEX_SOURCE"); QString stringBase("$base"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi((*it)); - QString dir = fileFixify(Option::output_dir); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) dir += Option::dir_sep; QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); QString lexflags = "$(LEXFLAGS)", stub="yy"; if(!project->isActiveConfig("yacc_no_name_mangle")) { stub = fi.baseName(TRUE); lexflags += " -P" + stub; } QString out_c = default_out_c; if(!stub.isEmpty()) out_c.replace(stringBase, stub); t << impl << ": " << (*it) << " " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << ( "$(LEX) " + lexflags + " " ) << (*it) << "\n\t" << "-$(DEL_FILE) " << impl << " " << "\n\t" << "-$(MOVE) " << out_c << " " << impl << endl << endl; } } void MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj) { QStringList &objl = project->variables()[obj]; QString stringSrc("$src"); QString stringObj("$obj"); QString uidir; for(QStringList::Iterator oit = objl.begin(); oit != objl.end(); oit++) { QString src(project->first("QMAKE_IMAGE_COLLECTION")); t << (*oit) << ": " << src; bool use_implicit_rule = !project->isEmpty("QMAKE_RUN_CXX_IMP"); if(use_implicit_rule) { if(!project->isEmpty("OBJECTS_DIR") || !project->isEmpty("UI_DIR") || !project->isEmpty("UI_SOURCES_DIR")) { use_implicit_rule = FALSE; } else { int dot = src.findRev('.'); if(dot == -1 || (src.left(dot) + Option::obj_ext != (*oit))) use_implicit_rule = FALSE; } } - if(!use_implicit_rule) { + if(!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) { QString p = var("QMAKE_RUN_CXX"); p.replace( stringSrc, src); p.replace( stringObj, (*oit)); t << "\n\t" << p; } t << endl << endl; } } void MakefileGenerator::writeImageSrc(QTextStream &t, const QString &src) { QStringList &l = project->variables()[src]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString gen = project->first("MAKEFILE_GENERATOR"); if ( gen == "MSVC" ) { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) -o " << (*it) << " -embed " << project->first("QMAKE_ORIG_TARGET") << " -f <<\n" << findDependencies((*it)).join(" ") << "\n<<" << endl << endl; } else if ( gen == "BMAKE" ) { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) " << " -embed " << project->first("QMAKE_ORIG_TARGET") << " -f &&|\n" << findDependencies((*it)).join(" ") << "\n| -o " << (*it) << endl << endl; } else { t << (*it) << ": " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" << "$(UIC) " << " -embed " << project->first("QMAKE_ORIG_TARGET") << " " << findDependencies((*it)).join(" ") << " -o " << (*it) << endl << endl; } } } void MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs) { QString all_installs, all_uninstalls; QStringList &l = project->variables()[installs]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString pvar = (*it) + ".path"; if(project->variables()[pvar].isEmpty()) { warn_msg(WarnLogic, "%s is not defined: install target not created\n", pvar.latin1()); continue; } bool do_default = TRUE; - QString target, dst="$(INSTALL_ROOT)" + Option::fixPathToTargetOS(project->variables()[pvar].first(), FALSE); + const QString root = "$(INSTALL_ROOT)"; + QString target, dst= fileFixify(project->variables()[pvar].first()); +#ifndef Q_WS_WIN if(dst.right(1) != Option::dir_sep) dst += Option::dir_sep; +#endif QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; //other tmp = project->variables()[(*it) + ".extra"]; if(!tmp.isEmpty()) { do_default = FALSE; if(!target.isEmpty()) target += "\n\t"; target += tmp.join(" "); } //masks tmp = project->variables()[(*it) + ".files"]; if(!tmp.isEmpty()) { if(!target.isEmpty()) target += "\n"; do_default = FALSE; for(QStringList::Iterator wild_it = tmp.begin(); wild_it != tmp.end(); ++wild_it) { QString wild = Option::fixPathToLocalOS((*wild_it), FALSE), wild_var = fileFixify(wild); - if(QFile::exists(wild)) { //real file - QFileInfo fi(wild); - target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + - " \"" + Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + fileFixify(dst) + "\"\n"; - if(!project->isActiveConfig("debug") && - !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + wild) + "\"\n"; - uninst.append(QString("-$(DEL_FILE) -r") + " \"" + fileFixify(dst + wild) + "\""); - continue; - } - QString dirstr = QDir::currentDirPath(), f = wild; //wild - int slsh = f.findRev(Option::dir_sep); + QString dirstr = QDir::currentDirPath(), filestr = wild; + int slsh = filestr.findRev(Option::dir_sep); if(slsh != -1) { - dirstr = f.left(slsh+1); - f = f.right(f.length() - slsh - 1); + dirstr = filestr.left(slsh+1); + filestr = filestr.right(filestr.length() - slsh - 1); } if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep) dirstr += Option::dir_sep; + if(QFile::exists(wild)) { //real file + QString file = wild; + QFileInfo fi(wild); + if(!target.isEmpty()) + target += "\t"; + target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + root + dst + "\"\n"; + if(!project->isActiveConfig("debug") && + !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + filestr) + "\"\n"; if(!uninst.isEmpty()) uninst.append("\n\t"); - uninst.append(QString("-$(DEL_FILE) -r") + " " + fileFixify(dst + f) + ""); - - QDir dir(dirstr, f); + uninst.append( +#ifdef Q_WS_WIN + QString("-$(DEL_FILE)") +#else + QString("-$(DEL_FILE) -r") +#endif + + " \"" + root + fileFixify(dst + filestr) + "\""); + continue; + } + QDir dir(dirstr, filestr); //wild for(uint x = 0; x < dir.count(); x++) { QString file = dir[x]; if(file == "." || file == "..") //blah continue; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append( +#ifdef Q_WS_WIN + QString("-$(DEL_FILE)") +#else + QString("-$(DEL_FILE) -r") +#endif + + " \"" + root + fileFixify(dst + file) + "\""); QFileInfo fi(file); - target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + - " \"" + Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + - "\" \"" + fileFixify(dst) + "\"\n"; + if(!target.isEmpty()) + target += "\t"; + target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" + + Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + + "\" \"" + root + fileFixify(dst) + "\"\n"; if(!project->isActiveConfig("debug") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) - target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + file) + "\"\n"; + target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + file) + "\"\n"; } } } //default? if(do_default) target = defaultInstall((*it)); if(!target.isEmpty()) { - t << "install_" << (*it) << ": " << "\n\t" - << "@test -d " << dst << " || mkdir -p " << dst << "\n\t" - << target << endl << endl; + t << "install_" << (*it) << ": " << "\n\t"; + const QStringList &dirs = project->variables()[pvar]; + for(QStringList::ConstIterator pit = dirs.begin(); pit != dirs.end(); ++pit) { + QString tmp_dst = fileFixify((*pit)); +#ifndef Q_WS_WIN + if(tmp_dst.right(1) != Option::dir_sep) + tmp_dst += Option::dir_sep; +#endif + t << mkdir_p_asstring(root+tmp_dst) << "\n\t"; + } + t << target << endl << endl; all_installs += QString("install_") + (*it) + " "; if(!uninst.isEmpty()) { t << "uninstall_" << (*it) << ": " << "\n\t" << uninst.join(" ") << "\n\t" - << "-$(DEL_DIR) \"" << dst << "\"" << endl << endl; + << "-$(DEL_DIR) \"" << ( root + dst ) << "\"" << endl << endl; all_uninstalls += "uninstall_" + (*it) + " "; } t << endl; } else { debug_msg(1, "no definition for install %s: install target not created",(*it).latin1()); } } t << "install: all " << all_installs << "\n\n"; t << "uninstall: " << all_uninstalls << "\n\n"; } QString MakefileGenerator::var(const QString &var) { return val(project->variables()[var]); } QString MakefileGenerator::val(const QStringList &varList) { return valGlue(varList, "", " ", ""); } QString MakefileGenerator::varGlue(const QString &var, const QString &before, const QString &glue, const QString &after) { return valGlue(project->variables()[var], before, glue, after); } QString MakefileGenerator::valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) { QString ret; for(QStringList::ConstIterator it = varList.begin(); it != varList.end(); ++it) { if(!(*it).isEmpty()) { if(!ret.isEmpty()) ret += glue; ret += (*it); } } return ret.isEmpty() ? QString("") : before + ret + after; } QString MakefileGenerator::varList(const QString &var) { return valList(project->variables()[var]); } QString MakefileGenerator::valList(const QStringList &varList) { return valGlue(varList, "", " \\\n\t\t", ""); } QStringList MakefileGenerator::createObjectList(const QString &var) { QStringList &l = project->variables()[var], ret; QString objdir, dir; if(!project->variables()["OBJECTS_DIR"].isEmpty()) objdir = project->first("OBJECTS_DIR"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it))); if(objdir.isEmpty() && project->isActiveConfig("object_with_source")) { QString fName = Option::fixPathToTargetOS((*it), FALSE); int dl = fName.findRev(Option::dir_sep); if(dl != -1) dir = fName.left(dl + 1); } else { dir = objdir; } ret.append(dir + fi.baseName(TRUE) + Option::obj_ext); } return ret; } bool MakefileGenerator::writeMakefile(QTextStream &t) { t << "####### Compile" << endl << endl; writeObj(t, "OBJECTS", "SOURCES"); writeUicSrc(t, "FORMS"); writeObj(t, "UICOBJECTS", "UICIMPLS"); writeMocObj(t, "OBJMOC", "SRCMOC" ); writeMocSrc(t, "HEADERS"); writeMocSrc(t, "SOURCES"); writeMocSrc(t, "UICDECLS"); writeYaccSrc(t, "YACCSOURCES"); writeLexSrc(t, "LEXSOURCES"); writeImageObj(t, "IMAGEOBJECTS"); writeImageSrc(t, "QMAKE_IMAGE_COLLECTION"); t << "####### Install" << endl << endl; writeInstalls(t, "INSTALLS"); return TRUE; } QString MakefileGenerator::buildArgs() { static QString ret; if(ret.isEmpty()) { //special variables if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) ret += " QMAKE_ABSOLUTE_SOURCE_PATH=\"" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + "\""; //warnings else if(Option::warn_level == WarnNone) ret += " -Wnone"; else if(Option::warn_level == WarnAll) ret += " -Wall"; else if(Option::warn_level & WarnParser) ret += " -Wparser"; //other options if(!Option::user_template.isEmpty()) ret += " -t " + Option::user_template; if(!Option::mkfile::do_cache) ret += " -nocache"; if(!Option::mkfile::do_deps) ret += " -nodepend"; if(!Option::mkfile::do_mocs) ret += " -nomoc"; if(!Option::mkfile::do_dep_heuristics) ret += " -nodependheuristics"; if(!Option::mkfile::qmakespec_commandline.isEmpty()) ret += " -spec " + Option::mkfile::qmakespec_commandline; //arguments for(QStringList::Iterator it = Option::before_user_vars.begin(); it != Option::before_user_vars.end(); ++it) { if((*it).left(qstrlen("QMAKE_ABSOLUTE_SOURCE_PATH")) != "QMAKE_ABSOLUTE_SOURCE_PATH") ret += " \"" + (*it) + "\""; } if(Option::after_user_vars.count()) { ret += " -after "; for(QStringList::Iterator it = Option::after_user_vars.begin(); it != Option::after_user_vars.end(); ++it) { if((*it).left(qstrlen("QMAKE_ABSOLUTE_SOURCE_PATH")) != "QMAKE_ABSOLUTE_SOURCE_PATH") ret += " \"" + (*it) + "\""; } } } return ret; } //could get stored argv, but then it would have more options than are //probably necesary this will try to guess the bare minimum.. QString MakefileGenerator::build_args() { static QString ret; if(ret.isEmpty()) { ret = "$(QMAKE)"; // general options and arguments ret += buildArgs(); //output QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); if (!ofile.isEmpty() && ofile != project->first("QMAKE_MAKEFILE")) ret += " -o " + ofile; //inputs QStringList files = fileFixify(Option::mkfile::project_files); ret += " " + files.join(" "); } return ret; } bool MakefileGenerator::writeHeader(QTextStream &t) { time_t foo = time(NULL); t << "#############################################################################" << endl; t << "# Makefile for building: " << var("TARGET") << endl; - t << "# Generated by qmake (" << qmake_version() << ") on: " << ctime(&foo); + t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: " << ctime(&foo); t << "# Project: " << fileFixify(project->projectFile()) << endl; t << "# Template: " << var("TEMPLATE") << endl; t << "# Command: " << build_args() << endl; t << "#############################################################################" << endl; t << endl; return TRUE; } //makes my life easier.. bool MakefileGenerator::writeMakeQmake(QTextStream &t) { QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); - if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && + if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QStringList files = fileFixify(Option::mkfile::project_files); t << project->first("QMAKE_INTERNAL_PRL_FILE") << ": " << "\n\t" << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl; } QString pfile = project->projectFile(); if(pfile != "(stdin)") { QString qmake = build_args(); if(!ofile.isEmpty() && !project->isActiveConfig("no_autoqmake")) { t << ofile << ": " << fileFixify(pfile) << " "; if(Option::mkfile::do_cache) t << fileFixify(Option::mkfile::cachefile) << " "; if(!specdir().isEmpty()) t << specdir() << Option::dir_sep << "qmake.conf" << " "; t << project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"].join(" \\\n\t\t") << "\n\t" << qmake <<endl; } if(project->first("QMAKE_ORIG_TARGET") != "qmake") { t << "qmake: " << project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].join(" \\\n\t\t") << "\n\t" << "@" << qmake << endl << endl; } } return TRUE; } QStringList MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir, const QString &in_dir, bool force_fix) const { if(files.isEmpty()) return files; QStringList ret; for(QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) { if(!(*it).isEmpty()) ret << fileFixify((*it), out_dir, in_dir, force_fix); } return ret; } QString MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const { + if(file0.isEmpty()) + return file0; + QString key = file0; + if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix) + key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "-"); + if(fileFixed.contains(key)) + return fileFixed[key]; + QString file = file0; - if(file.isEmpty()) - return file; int depth = 4; if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { if(project && !project->isEmpty("QMAKE_PROJECT_DEPTH")) depth = project->first("QMAKE_PROJECT_DEPTH").toInt(); else if(Option::mkfile::cachefile_depth != -1) depth = Option::mkfile::cachefile_depth; } QChar quote; if((file.startsWith("'") || file.startsWith("\"")) && file.startsWith(file.right(1))) { quote = file.at(0); file = file.mid(1, file.length() - 2); } QString orig_file = file; if(!force_fix && project->isActiveConfig("no_fixpath")) { if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) { //absoluteify it QString qfile = Option::fixPathToLocalOS(file); if(QDir::isRelativePath(file)) { //already absolute QFileInfo fi(qfile); if(!fi.convertToAbs()) //strange file = fi.filePath(); } } } else { //fix it.. QString qfile(Option::fixPathToLocalOS(file, TRUE)), in_dir(in_d), out_dir(out_d); { if(out_dir.isNull()) out_dir = Option::output_dir; if(out_dir == ".") out_dir = QDir::currentDirPath(); if(in_dir.isEmpty() || in_dir == ".") in_dir = QDir::currentDirPath(); if(!QDir::isRelativePath(in_dir) || !QDir::isRelativePath(out_dir)) { QFileInfo in_fi(in_dir); if(!in_fi.convertToAbs()) in_dir = in_fi.filePath(); QFileInfo out_fi(out_dir); if(!out_fi.convertToAbs()) out_dir = out_fi.filePath(); } + QString in_canonical_dir = QDir(in_dir).canonicalPath(), + out_canonical_dir = QDir(out_dir).canonicalPath(); + if(!in_canonical_dir.isEmpty()) + in_dir = in_canonical_dir; + if(!out_canonical_dir.isEmpty()) + out_dir = out_canonical_dir; } if(out_dir != in_dir || !QDir::isRelativePath(qfile)) { if(QDir::isRelativePath(qfile)) { if(file.left(Option::dir_sep.length()) != Option::dir_sep && in_dir.right(Option::dir_sep.length()) != Option::dir_sep) file.prepend(Option::dir_sep); file.prepend(in_dir); } file = Option::fixPathToTargetOS(file, FALSE); + if(QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE)) { + QString real_file = QDir(file).canonicalPath(); + if(!real_file.isEmpty()) + file = real_file; + } QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); if(file == match_dir) { file = ""; } else if(file.startsWith(match_dir) && file.mid(match_dir.length(), Option::dir_sep.length()) == Option::dir_sep) { file = file.right(file.length() - (match_dir.length() + 1)); } else { for(int i = 1; i <= depth; i++) { int sl = match_dir.findRev(Option::dir_sep); if(sl == -1) break; match_dir = match_dir.left(sl); if(match_dir.isEmpty()) break; if(file.startsWith(match_dir) && file.mid(match_dir.length(), Option::dir_sep.length()) == Option::dir_sep) { //concat int remlen = file.length() - (match_dir.length() + 1); if (remlen < 0) remlen = 0; file = file.right(remlen); //prepend for(int o = 0; o < i; o++) file.prepend(".." + Option::dir_sep); } } } } } file = Option::fixPathToTargetOS(file, FALSE); + if(file.isEmpty()) + file = "."; if(!quote.isNull()) file = quote + file + quote; debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth); + ((MakefileGenerator*)this)->fileFixed.insert(key, file); return file; } QString MakefileGenerator::cleanFilePath(const QString &file) const { return fileFixify(Option::fixPathToTargetOS(file)); } void MakefileGenerator::logicWarn(const QString &f, const QString &w) { if(!(Option::warn_level & WarnLogic)) return; QString file = f; int slsh = f.findRev(Option::dir_sep); if(slsh != -1) file = file.right(file.length() - slsh - 1); QStringList &l = project->variables()[w]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { QString file2((*val_it)); slsh = file2.findRev(Option::dir_sep); if(slsh != -1) file2 = file2.right(file2.length() - slsh - 1); if(file2 == file) { warn_msg(WarnLogic, "Found potential symbol conflict of %s (%s) in %s", file.latin1(), (*val_it).latin1(), w.latin1()); break; } } } QStringList &MakefileGenerator::findDependencies(const QString &file) { QString key = file; Option::fixPathToTargetOS(key); if(key.find(Option::dir_sep)) key = key.right(key.length() - key.findRev(Option::dir_sep) - 1); if(!depKeyMap.contains(key)) depKeyMap.insert(key, file); return depends[key]; } QString MakefileGenerator::specdir() { if(!spec.isEmpty()) return spec; spec = Option::mkfile::qmakespec; const char *d = getenv("QTDIR"); if(d) { QString qdir = Option::fixPathToTargetOS(QString(d)); if(qdir.endsWith(QString(QChar(QDir::separator())))) qdir.truncate(qdir.length()-1); //fix path QFileInfo fi(spec); QString absSpec(fi.absFilePath()); absSpec = Option::fixPathToTargetOS(absSpec); //replace what you can if(absSpec.startsWith(qdir)) { absSpec.replace(0, qdir.length(), "$(QTDIR)"); spec = absSpec; } } return spec; } bool MakefileGenerator::openOutput(QFile &file) const { { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString fname = "Makefile"; if(!project->isEmpty("MAKEFILE")) fname = project->first("MAKEFILE"); file.setName(outdir + fname); } } if(QDir::isRelativePath(file.name())) file.setName(Option::output_dir + file.name()); //pwd when qmake was run if(project->isEmpty("QMAKE_MAKEFILE")) project->variables()["QMAKE_MAKEFILE"].append(file.name()); int slsh = file.name().findRev(Option::dir_sep); if(slsh != -1) createDir(file.name().left(slsh)); if(file.open(IO_WriteOnly | IO_Translate)) { QFileInfo fi(Option::output); QString od = Option::fixPathToTargetOS((fi.isSymLink() ? fi.readLink() : fi.dirPath()) ); if(QDir::isRelativePath(od)) od.prepend(Option::output_dir); Option::output_dir = od; return TRUE; } return FALSE; } //Factory thing #include "unixmake.h" -#include "borland_bmake.h" #include "msvc_nmake.h" +#include "borland_bmake.h" +#include "mingw_make.h" #include "msvc_dsp.h" #include "msvc_vcproj.h" #include "metrowerks_xml.h" #include "pbuilder_pbx.h" #include "projectgenerator.h" MakefileGenerator * MakefileGenerator::create(QMakeProject *proj) { if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) return new ProjectGenerator(proj); MakefileGenerator *mkfile = NULL; QString gen = proj->first("MAKEFILE_GENERATOR"); if(gen.isEmpty()) { fprintf(stderr, "No generator specified in config file: %s\n", proj->projectFile().latin1()); } else if(gen == "UNIX") { mkfile = new UnixMakefileGenerator(proj); } else if(gen == "MSVC") { // Visual Studio =< v6.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) mkfile = new DspMakefileGenerator(proj); else mkfile = new NmakeMakefileGenerator(proj); } else if(gen == "MSVC.NET") { // Visual Studio >= v7.0 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) mkfile = new VcprojGenerator(proj); else mkfile = new NmakeMakefileGenerator(proj); } else if(gen == "BMAKE") { mkfile = new BorlandMakefileGenerator(proj); + } else if(gen == "MINGW") { + mkfile = new MingwMakefileGenerator(proj); } else if(gen == "METROWERKS") { mkfile = new MetrowerksMakefileGenerator(proj); } else if(gen == "PROJECTBUILDER") { mkfile = new ProjectBuilderMakefileGenerator(proj); } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.latin1()); } return mkfile; } diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 1d19d98..4fdabe8 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -1,173 +1,173 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef __MAKEFILE_H__ #define __MAKEFILE_H__ #include "option.h" #include "project.h" #include <qtextstream.h> class MakefileGenerator { QString spec; bool init_opath_already, init_already, moc_aware, no_io; QStringList createObjectList(const QString &var); QString build_args(); - QMap<QString, QString> depHeuristics, depKeyMap; + QMap<QString, QString> depHeuristics, depKeyMap, fileFixed; QMap<QString, QString> mocablesToMOC, mocablesFromMOC; QMap<QString, QStringList> depends; protected: void writeObj(QTextStream &, const QString &obj, const QString &src); void writeUicSrc(QTextStream &, const QString &ui); void writeMocObj(QTextStream &, const QString &obj, const QString &src); void writeMocSrc(QTextStream &, const QString &src); void writeLexSrc(QTextStream &, const QString &lex); void writeYaccSrc(QTextStream &, const QString &yac); void writeInstalls(QTextStream &t, const QString &installs); void writeImageObj(QTextStream &t, const QString &obj); void writeImageSrc(QTextStream &t, const QString &images); protected: QMakeProject *project; class MakefileDependDir { public: - MakefileDependDir(QString r, QString l) : real_dir(r), local_dir(l) { } + MakefileDependDir(const QString &r, const QString &l) : real_dir(r), local_dir(l) { } QString real_dir, local_dir; }; - bool generateDependencies(QPtrList<MakefileDependDir> &dirs, QString x, bool recurse); + bool generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &x, bool recurse); QString buildArgs(); QString specdir(); QString cleanFilePath(const QString &file) const; - bool generateMocList(QString fn); + bool generateMocList(const QString &fn); QString findMocSource(const QString &moc_file) const; QString findMocDestination(const QString &src_file) const; QStringList &findDependencies(const QString &file); void setNoIO(bool o); bool noIO() const; void setMocAware(bool o); bool mocAware() const; void logicWarn(const QString &, const QString &); virtual bool doDepends() const { return Option::mkfile::do_deps; } bool writeHeader(QTextStream &); virtual bool writeMakefile(QTextStream &); virtual bool writeMakeQmake(QTextStream &); void initOutPaths(); virtual void init(); //for installs virtual QString defaultInstall(const QString &); //for prl bool processPrlFile(QString &); virtual void processPrlVariable(const QString &, const QStringList &); virtual void processPrlFiles(); virtual void writePrlFile(QTextStream &); //make sure libraries are found virtual bool findLibraries(); QString var(const QString &var); QString varGlue(const QString &var, const QString &before, const QString &glue, const QString &after); QString varList(const QString &var); QString val(const QStringList &varList); QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after); QString valList(const QStringList &varList); QString fileFixify(const QString& file, const QString &out_dir=QString::null, const QString &in_dir=QString::null, bool force_fix=FALSE) const; QStringList fileFixify(const QStringList& files, const QString &out_dir=QString::null, const QString &in_dir=QString::null, bool force_fix=FALSE) const; public: MakefileGenerator(QMakeProject *p); virtual ~MakefileGenerator(); static MakefileGenerator *create(QMakeProject *); bool write(); virtual bool openOutput(QFile &) const; }; inline QString MakefileGenerator::findMocSource(const QString &moc_file) const { QString tmp = cleanFilePath(moc_file); if (mocablesFromMOC.contains(tmp)) return mocablesFromMOC[tmp]; else return QString(""); } inline QString MakefileGenerator::findMocDestination(const QString &src_file) const { QString tmp = cleanFilePath(src_file); if (mocablesToMOC.contains(tmp)) return mocablesToMOC[tmp]; else return QString(""); } inline void MakefileGenerator::setMocAware(bool o) { moc_aware = o; } inline bool MakefileGenerator::mocAware() const { return moc_aware; } inline void MakefileGenerator::setNoIO(bool o) { no_io = o; } inline bool MakefileGenerator::noIO() const { return no_io; } inline QString MakefileGenerator::defaultInstall(const QString &) { return QString(""); } inline bool MakefileGenerator::findLibraries() { return TRUE; } inline MakefileGenerator::~MakefileGenerator() { } #endif /* __MAKEFILE_H__ */ diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 5ff6250..1515216 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -1,462 +1,482 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "projectgenerator.h" #include "option.h" #include <qdir.h> #include <qfile.h> #include <qfileinfo.h> #include <qregexp.h> +QString project_builtin_regx() //calculate the builtin regular expression.. +{ + QString ret; + QStringList builtin_exts(".c"); + builtin_exts << Option::ui_ext << Option::yacc_ext << Option::lex_ext << ".ts"; + builtin_exts += Option::h_ext + Option::cpp_ext; + for(QStringList::Iterator ext_it = builtin_exts.begin(); + ext_it != builtin_exts.end(); ++ext_it) { + if(!ret.isEmpty()) + ret += "; "; + ret += QString("*") + (*ext_it); + } + return ret; +} + + ProjectGenerator::ProjectGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE) { } void ProjectGenerator::init() { if(init_flag) return; int file_count = 0; init_flag = TRUE; QMap<QString, QStringList> &v = project->variables(); QString templ = Option::user_template.isEmpty() ? QString("app") : Option::user_template; if(!Option::user_template_prefix.isEmpty()) templ.prepend(Option::user_template_prefix); v["TEMPLATE_ASSIGN"] += templ; //figure out target if(Option::output.name() == "-" || Option::output.name().isEmpty()) v["TARGET"] = QStringList("unknown"); //the scary stuff if(project->first("TEMPLATE_ASSIGN") != "subdirs") { - QString builtin_regex; - { //calculate the builtin regular expression.. - QStringList builtin_exts(".c"); - builtin_exts << Option::ui_ext << Option::yacc_ext << Option::lex_ext; - builtin_exts += Option::h_ext + Option::cpp_ext; - for(QStringList::Iterator ext_it = builtin_exts.begin(); - ext_it != builtin_exts.end(); ++ext_it) { - if(!builtin_regex.isEmpty()) - builtin_regex += "; "; - builtin_regex += QString("*") + (*ext_it); - } - } + QString builtin_regex = project_builtin_regx(); QStringList dirs = Option::projfile::project_dirs; - if(Option::projfile::do_pwd) + if(Option::projfile::do_pwd) { + if(!v["INCLUDEPATH"].contains(".")) + v["INCLUDEPATH"] += "."; dirs.prepend(QDir::currentDirPath()); + } for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { QString dir, regex; bool add_depend = FALSE; if(QFile::exists((*pd))) { QFileInfo fi((*pd)); if(fi.isDir()) { dir = (*pd); add_depend = TRUE; if(dir.right(1) != Option::dir_sep) dir += Option::dir_sep; if(Option::projfile::do_recursive) { QDir d(dir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { if(d[i] != "." && d[i] != "..") dirs.append(dir + d[i] + QDir::separator() + builtin_regex); } } regex = builtin_regex; } else { QString file = (*pd); int s = file.findRev(Option::dir_sep); if(s != -1) dir = file.left(s+1); if(addFile(file)) { add_depend = TRUE; file_count++; } } } else { //regexp regex = (*pd); } if(!regex.isEmpty()) { int s = regex.findRev(Option::dir_sep); if(s != -1) { dir = regex.left(s+1); regex = regex.right(regex.length() - (s+1)); } if(Option::projfile::do_recursive) { QDir d(dir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { if(d[i] != "." && d[i] != "..") dirs.append(dir + d[i] + QDir::separator() + regex); } } QDir d(dir, regex); for(int i = 0; i < (int)d.count(); i++) { QString file = dir + d[i]; if (addFile(file)) { add_depend = TRUE; file_count++; } } } if(add_depend && !dir.isEmpty() && !v["DEPENDPATH"].contains(dir)) { QFileInfo fi(dir); - if(fi.absFilePath() != QDir::currentDirPath()) { + if(fi.absFilePath() != QDir::currentDirPath()) v["DEPENDPATH"] += fileFixify(dir); } } } - } if(!file_count) { //shall we try a subdir? QStringList dirs = Option::projfile::project_dirs; if(Option::projfile::do_pwd) dirs.prepend("."); for(QStringList::Iterator pd = dirs.begin(); pd != dirs.end(); pd++) { if(QFile::exists((*pd))) { QString newdir = (*pd); QFileInfo fi(newdir); if(fi.isDir()) { newdir = fileFixify(newdir); QStringList &subdirs = v["SUBDIRS"]; if(QFile::exists(fi.filePath() + QDir::separator() + fi.fileName() + ".pro") && !subdirs.contains(newdir)) { subdirs.append(newdir); } else { QDir d(newdir, "*.pro"); d.setFilter(QDir::Files); for(int i = 0; i < (int)d.count(); i++) { QString nd = newdir + QDir::separator() + d[i]; fileFixify(nd); if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd)) { if(newdir + d[i] != Option::output_dir + Option::output.name()) subdirs.append(nd); } } } if(Option::projfile::do_recursive) { QDir d(newdir); d.setFilter(QDir::Dirs); for(int i = 0; i < (int)d.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + d[i]); if(d[i] != "." && d[i] != ".." && !dirs.contains(nd)) dirs.append(nd); } } } } else { //regexp QString regx = (*pd), dir; int s = regx.findRev(Option::dir_sep); if(s != -1) { dir = regx.left(s+1); regx = regx.right(regx.length() - (s+1)); } QDir d(dir, regx); d.setFilter(QDir::Dirs); QStringList &subdirs = v["SUBDIRS"]; for(int i = 0; i < (int)d.count(); i++) { QString newdir(dir + d[i]); QFileInfo fi(newdir); if(fi.fileName() != "." && fi.fileName() != "..") { newdir = fileFixify(newdir); if(QFile::exists(fi.filePath() + QDir::separator() + fi.fileName() + ".pro") && !subdirs.contains(newdir)) { subdirs.append(newdir); } else { QDir d(newdir, "*.pro"); d.setFilter(QDir::Files); for(int i = 0; i < (int)d.count(); i++) { QString nd = newdir + QDir::separator() + d[i]; fileFixify(nd); if(d[i] != "." && d[i] != ".." && !subdirs.contains(nd)) { if(newdir + d[i] != Option::output_dir + Option::output.name()) subdirs.append(nd); } } } if(Option::projfile::do_recursive && !dirs.contains(newdir)) dirs.append(newdir); } } } } v["TEMPLATE_ASSIGN"] = "subdirs"; return; } QPtrList<MakefileDependDir> deplist; deplist.setAutoDelete(TRUE); { QStringList &d = v["DEPENDPATH"]; for(QStringList::Iterator it = d.begin(); it != d.end(); ++it) { QString r = (*it), l = Option::fixPathToLocalOS((*it)); deplist.append(new MakefileDependDir(r, l)); } } QStringList &h = v["HEADERS"]; bool no_qt_files = TRUE; QString srcs[] = { "SOURCES", "YACCSOURCES", "LEXSOURCES", "INTERFACES", QString::null }; for(int i = 0; !srcs[i].isNull(); i++) { QStringList &l = v[srcs[i]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { if(generateDependencies(deplist, (*val_it), TRUE)) { QStringList &tmp = findDependencies((*val_it)); if(!tmp.isEmpty()) { for(QStringList::Iterator dep_it = tmp.begin(); dep_it != tmp.end(); ++dep_it) { - QString file_no_path = (*dep_it).right( - (*dep_it).length() - ((*dep_it).findRev(Option::dir_sep)+1)); + QString file_dir = (*dep_it).section(Option::dir_sep, 0, -2), + file_no_path = (*dep_it).section(Option::dir_sep, -1); + if(!file_dir.isEmpty()) { + for(MakefileDependDir *mdd = deplist.first(); mdd; mdd = deplist.next()) { + if(mdd->local_dir == file_dir && !v["INCLUDEPATH"].contains(mdd->real_dir)) + v["INCLUDEPATH"] += mdd->real_dir; + } + } if(no_qt_files && file_no_path.find(QRegExp("^q[a-z_0-9].h$")) != -1) no_qt_files = FALSE; QString h_ext; - for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { + for(QStringList::Iterator hit = Option::h_ext.begin(); + hit != Option::h_ext.end(); ++hit) { if((*dep_it).endsWith((*hit))) { h_ext = (*hit); break; } } if(!h_ext.isEmpty()) { if((*dep_it).left(1).lower() == "q") { QString qhdr = (*dep_it).lower(); if(file_no_path == "qthread.h") addConfig("thread"); } for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { - QString src((*dep_it).left((*dep_it).length() - h_ext.length()) + (*cppit)); + QString src((*dep_it).left((*dep_it).length() - h_ext.length()) + + (*cppit)); if(QFile::exists(src)) { bool exists = FALSE; QStringList &srcl = v["SOURCES"]; - for(QStringList::Iterator src_it = srcl.begin(); src_it != srcl.end(); ++src_it) { + for(QStringList::Iterator src_it = srcl.begin(); + src_it != srcl.end(); ++src_it) { if((*src_it).lower() == src.lower()) { exists = TRUE; break; } } if(!exists) srcl.append(src); } } } else if((*dep_it).endsWith(Option::lex_ext) && file_no_path.startsWith(Option::lex_mod)) { addConfig("lex_included"); } if(!h.contains((*dep_it))) { if(generateMocList((*dep_it)) && !findMocDestination((*dep_it)).isEmpty()) h += (*dep_it); } } } } } } if(h.isEmpty()) addConfig("moc", FALSE); //if we find a file that matches an forms it needn't be included in the project QStringList &u = v["INTERFACES"]; QString no_ui[] = { "SOURCES", "HEADERS", QString::null }; { for(int i = 0; !no_ui[i].isNull(); i++) { QStringList &l = v[no_ui[i]]; for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ) { bool found = FALSE; for(QStringList::Iterator ui_it = u.begin(); ui_it != u.end(); ++ui_it) { QString s1 = (*val_it).right((*val_it).length() - ((*val_it).findRev(Option::dir_sep) + 1)); if(s1.findRev('.') != -1) s1 = s1.left(s1.findRev('.')) + Option::ui_ext; QString u1 = (*ui_it).right((*ui_it).length() - ((*ui_it).findRev(Option::dir_sep) + 1)); if(s1 == u1) { found = TRUE; break; } } if(!found && (*val_it).endsWith(Option::moc_ext)) found = TRUE; if(found) val_it = l.remove(val_it); else ++val_it; } } } } bool ProjectGenerator::writeMakefile(QTextStream &t) { t << "######################################################################" << endl; t << "# Automatically generated by qmake (" << qmake_version() << ") " << QDateTime::currentDateTime().toString() << endl; t << "######################################################################" << endl << endl; QStringList::Iterator it; for(it = Option::before_user_vars.begin(); it != Option::before_user_vars.end(); ++it) t << (*it) << endl; t << getWritableVar("TEMPLATE_ASSIGN", FALSE); if(project->first("TEMPLATE_ASSIGN") == "subdirs") { t << endl << "# Directories" << "\n" << getWritableVar("SUBDIRS"); } else { t << getWritableVar("TARGET") << getWritableVar("CONFIG", FALSE) << getWritableVar("CONFIG_REMOVE", FALSE) - << getWritableVar("DEPENDPATH") << endl; + << getWritableVar("DEPENDPATH") + << getWritableVar("INCLUDEPATH") << endl; t << "# Input" << "\n"; t << getWritableVar("HEADERS") << getWritableVar("INTERFACES") << getWritableVar("LEXSOURCES") << getWritableVar("YACCSOURCES") - << getWritableVar("SOURCES"); + << getWritableVar("SOURCES") + << getWritableVar("TRANSLATIONS"); } for(it = Option::after_user_vars.begin(); it != Option::after_user_vars.end(); ++it) t << (*it) << endl; return TRUE; } bool ProjectGenerator::addConfig(const QString &cfg, bool add) { QString where = "CONFIG"; if(!add) where = "CONFIG_REMOVE"; if(!project->variables()[where].contains(cfg)) { project->variables()[where] += cfg; return TRUE; } return FALSE; } bool ProjectGenerator::addFile(QString file) { file = fileFixify(file, QDir::currentDirPath()); QString dir; int s = file.findRev(Option::dir_sep); if(s != -1) dir = file.left(s+1); if(file.mid(dir.length(), Option::moc_mod.length()) == Option::moc_mod) return FALSE; QString where; for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if(file.endsWith((*cppit))) { if(QFile::exists(file.left(file.length() - (*cppit).length()) + Option::ui_ext)) return FALSE; else where = "SOURCES"; break; } } if(where.isEmpty()) { for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { if(file.endsWith((*hit))) { where = "HEADERS"; break; } } } if(where.isEmpty()) { if(file.endsWith(Option::ui_ext)) where = "INTERFACES"; else if(file.endsWith(".c")) where = "SOURCES"; else if(file.endsWith(Option::lex_ext)) where = "LEXSOURCES"; else if(file.endsWith(Option::yacc_ext)) where = "YACCSOURCES"; + else if(file.endsWith(".ts")) + where = "TRANSLATIONS"; } QString newfile = fileFixify(file); if(!where.isEmpty() && !project->variables()[where].contains(file)) { project->variables()[where] += newfile; return TRUE; } return FALSE; } QString ProjectGenerator::getWritableVar(const QString &v, bool /*fixPath*/) { QStringList &vals = project->variables()[v]; if(vals.isEmpty()) return ""; QString ret; if(v.endsWith("_REMOVE")) ret = v.left(v.length() - 7) + " -= "; else if(v.endsWith("_ASSIGN")) ret = v.left(v.length() - 7) + " = "; else ret = v + " += "; QString join = vals.join(" "); if(ret.length() + join.length() > 80) { QString spaces; for(unsigned int i = 0; i < ret.length(); i++) spaces += " "; join = vals.join(" \\\n" + spaces); } // ### Commented out for now so that project generation works. // Sam: can you look at why this was needed? /* if(fixPath) join = join.replace("\\", "/");*/ return ret + join + "\n"; } bool ProjectGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = fi.dirPath() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString dir = QDir::currentDirPath(); int s = dir.findRev('/'); if(s != -1) dir = dir.right(dir.length() - (s + 1)); file.setName(outdir + dir + ".pro"); } return MakefileGenerator::openOutput(file); } diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 7df95b2..e274481 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -1,520 +1,604 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "unixmake.h" #include "option.h" #include <qregexp.h> #include <qfile.h> #include <qdict.h> #include <qdir.h> #include <time.h> void UnixMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */ return; QStringList &configs = project->variables()["CONFIG"]; /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "lib") project->variables()["QMAKE_LIB_FLAG"].append("1"); else if(project->first("TEMPLATE") == "subdirs") { MakefileGenerator::init(); if(project->isEmpty("MAKEFILE")) project->variables()["MAKEFILE"].append("Makefile"); if(project->isEmpty("QMAKE")) project->variables()["QMAKE"].append("qmake"); if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); return; /* subdirs is done */ } if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) { - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); - if ( os == "cygwin" ) { - project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" ); - } else { + if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" ); + } else { + project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" ); } } if( project->isEmpty("QMAKE_COPY_FILE") ) project->variables()["QMAKE_COPY_FILE"].append( "$(COPY) -p" ); if( project->isEmpty("QMAKE_COPY_DIR") ) project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -pR" ); //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET if(!project->isEmpty("TARGET")) { QString targ = project->first("TARGET"); int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep)); if(slsh != -1) { if(project->isEmpty("DESTDIR")) project->values("DESTDIR").append(""); else if(project->first("DESTDIR").right(1) != Option::dir_sep) project->variables()["DESTDIR"] = project->first("DESTDIR") + Option::dir_sep; project->variables()["DESTDIR"] = project->first("DESTDIR") + targ.left(slsh+1); project->variables()["TARGET"] = targ.mid(slsh+1); } } project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; bool is_qt = (project->first("TARGET") == "qt" || project->first("TARGET") == "qte" || project->first("TARGET") == "qt-mt" || project->first("TARGET") == "qte-mt"); bool extern_libs = !project->isEmpty("QMAKE_APP_FLAG") || (!project->isEmpty("QMAKE_LIB_FLAG") && project->isActiveConfig("dll")) || is_qt; if(!project->isActiveConfig("global_init_link_order")) project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) || (project->isActiveConfig("qt") && project->isActiveConfig( "plugin" ) )) { if(configs.findIndex("dll") == -1) configs.append("dll"); } else if ( !project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll") ) { configs.remove("staticlib"); } if ( project->isActiveConfig("warn_off") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"]; } else if ( project->isActiveConfig("warn_on") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"]; } if ( project->isActiveConfig("debug") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"]; } if(!project->isEmpty("QMAKE_INCREMENTAL")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"]; else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() && project->isActiveConfig("dll")) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"]; if(!project->isEmpty("QMAKE_INCDIR")) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; if(!project->isEmpty("QMAKE_LIBDIR")) { if ( !project->isEmpty("QMAKE_RPATH") ) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"), " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" ); } if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) { if(configs.findIndex("x11lib") == -1) configs.append("x11lib"); if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 ) configs.append("x11inc"); } if ( project->isActiveConfig("x11") ) { if(configs.findIndex("x11lib") == -1) configs.append("x11lib"); if(configs.findIndex("x11inc") == -1) configs.append("x11inc"); } if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig("accessibility" ) ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); if ( project->isActiveConfig("tablet") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); if(configs.findIndex("moc")) configs.append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( !is_qt ) { if ( !project->isEmpty("QMAKE_LIBDIR_QT") ) { if ( !project->isEmpty("QMAKE_RPATH") ) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"), " " + var("QMAKE_RPATH"), ""); project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", ""); } if (project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD")) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; } } - if ( project->isActiveConfig("thread") ) { - if(project->isActiveConfig("qt")) - project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); - if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) - project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; - if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) - project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; - project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; - if(!project->isEmpty("QMAKE_LFLAGS_THREAD")) - project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"]; - } if ( project->isActiveConfig("opengl") ) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"]; if(!project->isEmpty("QMAKE_LIBDIR_OPENGL")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", ""); if ( is_qt ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; } if(project->isActiveConfig("global_init_link_order")) project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; - if ( project->isActiveConfig("x11sm") ) - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"]; - if ( project->isActiveConfig("dylib") ) - project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"]; if ( project->isActiveConfig("x11inc") ) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"]; if ( project->isActiveConfig("x11lib") ) { if(!project->isEmpty("QMAKE_LIBDIR_X11")) project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", ""); project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"]; } + if ( project->isActiveConfig("x11sm") ) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"]; + if ( project->isActiveConfig("dylib") ) + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"]; + if ( project->isActiveConfig("thread") ) { + if(project->isActiveConfig("qt")) + project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); + if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"]; + if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"]; + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"]; + if(!project->isEmpty("QMAKE_LFLAGS_THREAD")) + project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"]; + } if ( project->isActiveConfig("moc") ) setMocAware(TRUE); if ( project->isEmpty("QMAKE_RUN_CC") ) project->variables()["QMAKE_RUN_CC"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src"); if ( project->isEmpty("QMAKE_RUN_CC_IMP") ) project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<"); if ( project->isEmpty("QMAKE_RUN_CXX") ) project->variables()["QMAKE_RUN_CXX"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src"); if ( project->isEmpty("QMAKE_RUN_CXX_IMP") ) project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<"); project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " "); if ( !project->isEmpty("PRECOMPH") ) { initOutPaths(); // Need to fix MOC_DIR since we do this before init() QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir); project->variables()["SOURCES"].prepend(allmoc); project->variables()["HEADERS_ORIG"] = project->variables()["HEADERS"]; project->variables()["HEADERS"].clear(); } if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS")) include_deps = TRUE; //do not generate deps MakefileGenerator::init(); if ( project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { if(!project->isEmpty("QMAKE_APP_FLAG")) { if(project->isEmpty("DESTDIR")) project->values("DESTDIR").append(""); project->variables()["DESTDIR"].first() += project->variables()["TARGET"].first() + ".app/Contents/MacOS/"; project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + "../PkgInfo"); project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO"); QString plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE"); if(QFile::exists(Option::fixPathToLocalOS(plist))) { project->variables()["QMAKE_INFO_PLIST"].append(plist); project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") + "../Info.plist"); project->variables()["ALL_DEPS"] += project->first("QMAKE_INFO_PLIST_OUT"); if(!project->isEmpty("RC_FILE")) project->variables()["ALL_DEPS"] += project->first("DESTDIR") + "../Resources/application.icns"; } } } if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; project->variables()["DISTFILES"] += Option::mkfile::project_files; init2(); project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) { bool ok; int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok); QStringList ar_sublibs, objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"]; if(ok && max_files > 5 && max_files < (int)objs.count()) { int obj_cnt = 0, lib_cnt = 0; QString lib; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { if((++obj_cnt) >= max_files) { if(lib_cnt) { lib.sprintf("lib%s-tmp%d.a", project->first("QMAKE_ORIG_TARGET").latin1(), lib_cnt); ar_sublibs << lib; obj_cnt = 0; } lib_cnt++; } } } if(!ar_sublibs.isEmpty()) { project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs; project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS"; } } } QStringList UnixMakefileGenerator::uniqueSetLFlags(const QStringList &list1, QStringList &list2) { QStringList ret; for(QStringList::ConstIterator it = list1.begin(); it != list1.end(); ++it) { bool unique = TRUE; if((*it).startsWith("-")) { if((*it).startsWith("-l") || (*it).startsWith("-L")) { unique = list2.findIndex((*it)) == -1; } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) { int as_one = TRUE; QString framework_in; if((*it).length() > 11) { framework_in = (*it).mid(11); } else { if(it != list1.end()) { ++it; as_one = FALSE; framework_in = (*it); } } if(!framework_in.isEmpty()) { for(QStringList::ConstIterator outit = list2.begin(); outit != list2.end(); ++outit) { if((*outit).startsWith("-framework")) { QString framework_out; if((*outit).length() > 11) { framework_out = (*outit).mid(11); } else { if(it != list2.end()) { ++outit; framework_out = (*outit); } } if(framework_out == framework_in) { unique = FALSE; break; } } } if(unique) { unique = FALSE; //because I'm about to just insert it myself if(as_one) { ret.append("-framework " + framework_in); } else { ret.append("-framework"); ret.append(framework_in); } } } } else { unique = (list2.findIndex((*it)) == -1); } } else if(QFile::exists((*it))) { unique = (list2.findIndex((*it)) == -1); } if(unique) ret.append((*it)); } return ret; } void UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_LIBS") project->variables()["QMAKE_CURRENT_PRL_LIBS"] += uniqueSetLFlags(l, project->variables()["QMAKE_LIBS"]); else MakefileGenerator::processPrlVariable(var, l); } +bool +UnixMakefileGenerator::findLibraries() +{ + QPtrList<MakefileDependDir> libdirs; + libdirs.setAutoDelete(TRUE); + const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; + for(int i = 0; !lflags[i].isNull(); i++) { + QStringList &l = project->variables()[lflags[i]]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QString stub, dir, extn, opt = (*it).stripWhiteSpace(); + if(opt.startsWith("-")) { + if(opt.startsWith("-L")) { + QString r = opt.right(opt.length() - 2), l = r; + fixEnvVariables(l); + libdirs.append(new MakefileDependDir(r.replace("\"",""), + l.replace("\"",""))); + } else if(opt.startsWith("-l")) { + stub = opt.mid(2); + } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) { + if(opt.length() > 11) { + opt = opt.mid(11); + } else { + ++it; + opt = (*it); + } + extn = ""; + dir = "/System/Library/Frameworks/" + opt + ".framework/"; + stub = opt; + } + } else { + extn = dir = ""; + stub = opt; + int slsh = opt.findRev(Option::dir_sep); + if(slsh != -1) { + dir = opt.left(slsh); + stub = opt.mid(slsh+1); + } + QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); + if(stub_reg.exactMatch(stub)) { + stub = stub_reg.cap(1); + extn = stub_reg.cap(2); + } + } + if(!stub.isEmpty()) { + const QString modifs[] = { "-mt", QString::null }; + for(int modif = 0; !modifs[modif].isNull(); modif++) { + bool found = FALSE; + QStringList extens; + if(!extn.isNull()) + extens << extn; + else + extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a"; + for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { + if(dir.isNull()) { + QString lib_stub; + for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { + if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + + modifs[modif] + "." + (*extit))) { + lib_stub = stub + modifs[modif]; + break; + } + } + if(!lib_stub.isNull()) { + (*it) = "-l" + lib_stub; + found = TRUE; + break; + } + } else { + if(QFile::exists("lib" + stub + modifs[modif] + "." + (*extit))) { + (*it) = "lib" + stub + modifs[modif] + "." + (*extit); + found = TRUE; + break; + } + } + } + if(found) + break; + } + } + } + } + return FALSE; +} + void UnixMakefileGenerator::processPrlFiles() { QDict<void> processed; QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null }; for(int i = 0; !lflags[i].isNull(); i++) { for(bool ret = FALSE; TRUE; ret = FALSE) { QStringList l_out; QStringList &l = project->variables()[lflags[i]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear(); QString opt = (*it).stripWhiteSpace();; if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString r = opt.right(opt.length() - 2), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } else if(opt.startsWith("-l") && !processed[opt]) { QString lib = opt.right(opt.length() - 2), prl; for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { prl = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::prl_ext; if(processPrlFile(prl)) { if(prl.startsWith(mdd->local_dir)) prl.replace(0, mdd->local_dir.length(), mdd->real_dir); QRegExp reg("^.*lib(" + lib + "[^./=]*)\\..*$"); if(reg.exactMatch(prl)) prl = "-l" + reg.cap(1); opt = prl; processed.insert(opt, (void*)1); ret = TRUE; break; } } } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) { if(opt.length() > 11) { opt = opt.mid(11); } else { ++it; opt = (*it); } QString prl = "/System/Library/Frameworks/" + opt + ".framework/" + opt + Option::prl_ext; if(processPrlFile(prl)) ret = TRUE; l_out.append("-framework"); } if(!opt.isEmpty()) l_out.append(opt); l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); } else { if(!processed[opt] && processPrlFile(opt)) { processed.insert(opt, (void*)1); ret = TRUE; } if(!opt.isEmpty()) l_out.append(opt); l_out += uniqueSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"], l_out); } } if(ret && l != l_out) l = l_out; else break; } } } QString UnixMakefileGenerator::defaultInstall(const QString &t) { if(t != "target" || project->first("TEMPLATE") == "subdirs") return QString(); bool resource = FALSE; + const QString root = "$(INSTALL_ROOT)"; QStringList &uninst = project->variables()[t + ".uninstall"]; - QString ret, destdir=fileFixify(project->first("DESTDIR")); + QString ret, destdir=project->first("DESTDIR"); QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; - targetdir = "$(INSTALL_ROOT)" + Option::fixPathToTargetOS(targetdir, FALSE); + targetdir = fileFixify(targetdir); if(targetdir.right(1) != Option::dir_sep) targetdir += Option::dir_sep; QStringList links; QString target="$(TARGET)"; if(project->first("TEMPLATE") == "app") { target = "$(QMAKE_TARGET)"; if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) { destdir += "../../../"; target += ".app"; resource = TRUE; } } else if(project->first("TEMPLATE") == "lib") { if(project->isActiveConfig("create_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE"); int slsh = dst_prl.findRev('/'); if(slsh != -1) dst_prl = dst_prl.right(dst_prl.length() - slsh - 1); - dst_prl = targetdir + dst_prl; - ret += "-$(COPY) " + project->first("QMAKE_INTERNAL_PRL_FILE") + " " + dst_prl; + dst_prl = root + targetdir + dst_prl; + ret += "-$(COPY) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\""; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_prl + "\""); } - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); - if ( os != "cygwin" ) { + if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) { if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) { - if ( os == "hpux" ) { - links << "$(TARGET0)"; - } else { + if ( project->isEmpty("QMAKE_HPUX_SHLIB") ) { links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)"; + } else { + links << "$(TARGET0)"; } } } } QString src_targ = target; if(!destdir.isEmpty()) src_targ = Option::fixPathToTargetOS(destdir + target, FALSE); - QString dst_targ = fileFixify(targetdir + target); + QString dst_targ = root + fileFixify(targetdir + target); if(!ret.isEmpty()) ret += "\n\t"; ret += QString(resource ? "-$(COPY_DIR)" : "-$(COPY)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; - if(!project->isEmpty("QMAKE_STRIP")) { + if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP")) { ret += "\n\t-" + var("QMAKE_STRIP"); + if(!project->isEmpty("QMAKE_STRIPFLAGS_LIB") && project->first("TEMPLATE") == "lib") + ret += " " + var("QMAKE_STRIPFLAGS_LIB"); if(resource) - ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)"; + ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\""; else ret += " \"" + dst_targ + "\""; } if(!uninst.isEmpty()) uninst.append("\n\t"); if(resource) uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\""); else uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); if(!links.isEmpty()) { for(QStringList::Iterator it = links.begin(); it != links.end(); it++) { if(Option::target_mode == Option::TARG_WIN_MODE || Option::target_mode == Option::TARG_MAC9_MODE) { } else if(Option::target_mode == Option::TARG_UNIX_MODE || Option::target_mode == Option::TARG_MACX_MODE) { QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE); int lslash = link.findRev(Option::dir_sep); if(lslash != -1) link = link.right(link.length() - (lslash + 1)); - QString dst_link = fileFixify(targetdir + link); + QString dst_link = root + fileFixify(targetdir + link); ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\""; if(!uninst.isEmpty()) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_link + "\""); } } } return ret; } - diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index e889dcc..3d00214 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -1,71 +1,72 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef __UNIXMAKE_H__ #define __UNIXMAKE_H__ #include "makefile.h" class UnixMakefileGenerator : public MakefileGenerator { bool init_flag, include_deps; bool writeMakefile(QTextStream &); QStringList uniqueSetLFlags(const QStringList &list1, QStringList &list2); public: UnixMakefileGenerator(QMakeProject *p); ~UnixMakefileGenerator(); protected: virtual bool doDepends() const { return !include_deps && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); virtual void processPrlVariable(const QString &, const QStringList &); virtual void processPrlFiles(); + virtual bool findLibraries(); virtual void init(); void writeMakeParts(QTextStream &); void writeSubdirs(QTextStream &, bool=TRUE); private: void init2(); }; inline UnixMakefileGenerator::~UnixMakefileGenerator() { } #endif /* __UNIXMAKE_H__ */ diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9bb6f6b..7fbb9f4 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1,1050 +1,1109 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "unixmake.h" #include "option.h" #include <qregexp.h> #include <qfile.h> #include <qdir.h> #include <time.h> UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE) { } bool UnixMakefileGenerator::writeMakefile(QTextStream &t) { writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { t << "all clean:" << "\n\t" << "@echo \"Some of the required modules (" << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" << "@echo \"Skipped.\"" << endl << endl; writeMakeQmake(t); return TRUE; } if (project->variables()["TEMPLATE"].first() == "app" || project->variables()["TEMPLATE"].first() == "lib") { writeMakeParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->variables()["TEMPLATE"].first() == "subdirs") { writeSubdirs(t); return TRUE; } return FALSE; } void UnixMakefileGenerator::writeMakeParts(QTextStream &t) { QString deps = fileFixify(Option::output.name()), prl; bool do_incremental = (project->isActiveConfig("incremental") && !project->variables()["QMAKE_INCREMENTAL"].isEmpty() && (!project->variables()["QMAKE_APP_FLAG"].isEmpty() || !project->isActiveConfig("staticlib"))), src_incremental=FALSE, moc_incremental=FALSE; - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); t << "####### Compiler, tools and options" << endl << endl; t << "CC = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_CC_THREAD"].isEmpty()) t << var("QMAKE_CC_THREAD") << endl; else t << var("QMAKE_CC") << endl; t << "CXX = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_CXX_THREAD"].isEmpty()) t << var("QMAKE_CXX_THREAD") << endl; else t << var("QMAKE_CXX") << endl; t << "LEX = " << var("QMAKE_LEX") << endl; t << "YACC = " << var("QMAKE_YACC") << endl; t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl; t << "YACCFLAGS= " << var("QMAKE_YACCFLAGS") << endl; - t << "INCPATH = " << varGlue("INCLUDEPATH","-I", " -I", "") << " -I" << specdir() << endl; + t << "INCPATH = " << "-I" << specdir(); + if(!project->isActiveConfig("no_include_pwd")) { + QString pwd = fileFixify(QDir::currentDirPath()); + if(pwd.isEmpty()) + pwd = "."; + t << " -I" << pwd; + } + t << varGlue("INCLUDEPATH"," -I", " -I", "") << endl; if(!project->isActiveConfig("staticlib")) { t << "LINK = "; if (project->isActiveConfig("thread") && ! project->variables()["QMAKE_LINK_THREAD"].isEmpty()) t << var("QMAKE_LINK_THREAD") << endl; else t << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; t << "LIBS = " << "$(SUBLIBS) " << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << endl; } t << "AR = " << var("QMAKE_AR") << endl; t << "RANLIB = " << var("QMAKE_RANLIB") << endl; t << "MOC = " << var("QMAKE_MOC") << endl; t << "UIC = " << var("QMAKE_UIC") << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; t << "TAR = " << var("QMAKE_TAR") << endl; t << "GZIP = " << var("QMAKE_GZIP") << endl; t << "COPY = " << var("QMAKE_COPY") << endl; t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl; t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; - t << "PRO = " << fileFixify(project->projectFile() )<< endl; + t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Output directory" << endl << endl; if (! project->variables()["OBJECTS_DIR"].isEmpty()) t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl; else t << "OBJECTS_DIR = ./" << endl; t << endl; /* files */ t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; if(do_incremental) { QStringList &objs = project->variables()["OBJECTS"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out; t << "OBJECTS = "; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { bool increment = FALSE; for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) { if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) { increment = TRUE; incrs_out.append((*objit)); break; } } if(!increment) t << "\\\n\t\t" << (*objit); } if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done! t << incrs_out.join(" \\\n\t\t") << endl; } else if(!incrs_out.count()) { t << endl; } else { src_incremental = TRUE; t << endl; t << "INCREMENTAL_OBJECTS = " << incrs_out.join(" \\\n\t\t") << endl; } } else { t << "OBJECTS = " << varList("OBJECTS") << endl; } t << "FORMS = " << varList("FORMS") << endl; t << "UICDECLS = " << varList("UICDECLS") << endl; t << "UICIMPLS = " << varList("UICIMPLS") << endl; QString srcMoc = varList("SRCMOC"), objMoc = varList("OBJMOC"); t << "SRCMOC = " << srcMoc << endl; if(do_incremental) { QStringList &objs = project->variables()["OBJMOC"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out; t << "OBJMOC = "; for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) { bool increment = FALSE; for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) { if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) { increment = TRUE; incrs_out.append((*objit)); break; } } if(!increment) t << "\\\n\t\t" << (*objit); } if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done! t << incrs_out.join(" \\\n\t\t") << endl; } else if(!incrs_out.count()) { t << endl; } else { moc_incremental = TRUE; t << endl; t << "INCREMENTAL_OBJMOC = " << incrs_out.join(" \\\n\t\t") << endl; } } else { t << "OBJMOC = " << objMoc << endl; } if(do_incremental && !moc_incremental && !src_incremental) do_incremental = FALSE; - t << "DIST = " << varList("DISTFILES") << endl; - t << "PRO = " << fileFixify(project->projectFile()) << endl; + t << "DIST = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl; t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl; t << "DESTDIR = " << var("DESTDIR") << endl; t << "TARGET = " << var("TARGET") << endl; if(project->isActiveConfig("plugin") ) { t << "TARGETD = " << var("TARGET") << endl; } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) { t << "TARGETA = " << var("TARGETA") << endl; - if (os == "hpux") { - t << "TARGETD = " << var("TARGET_x") << endl; - t << "TARGET0 = " << var("TARGET_") << endl; - } - else { + if (project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "TARGETD = " << var("TARGET_x.y.z") << endl; t << "TARGET0 = " << var("TARGET_") << endl; t << "TARGET1 = " << var("TARGET_x") << endl; t << "TARGET2 = " << var("TARGET_x.y") << endl; + } else { + t << "TARGETD = " << var("TARGET_x") << endl; + t << "TARGET0 = " << var("TARGET_") << endl; } } t << endl; // blasted incldues QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"]; QStringList::Iterator it; for( it = qeui.begin(); it != qeui.end(); ++it) t << "include " << (*it) << endl; /* rules */ t << "first: all" << endl; t << "####### Implicit rules" << endl << endl; t << ".SUFFIXES: .c"; QStringList::Iterator cppit; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << " " << (*cppit); t << endl << endl; for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) t << (*cppit) << ".o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; if(include_deps) { QString cmd=var("QMAKE_CFLAGS_DEPS") + " "; cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D",""); if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " "; cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", ""); QString odir; if(!project->variables()["OBJECTS_DIR"].isEmpty()) odir = project->first("OBJECTS_DIR"); - t << "###### Dependancies" << endl << endl; + t << "###### Dependencies" << endl << endl; t << odir << ".deps/%.d: %.cpp\n\t" << "@echo Creating depend for $<" << "\n\t" << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t" << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; t << odir << ".deps/%.d: %.c\n\t" << "@echo Creating depend for $<" << "\n\t" << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t" << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl; QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null }; for(int x = 0; !src[x].isNull(); x++) { QStringList &l = project->variables()[src[x]]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { if(!(*it).isEmpty()) { QString d_file; if((*it).endsWith(".c")) { d_file = (*it).left((*it).length() - 2); } else { for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { if((*it).endsWith((*cppit))) { d_file = (*it).left((*it).length() - (*cppit).length()); break; } } } if(!d_file.isEmpty()) { d_file = odir + ".deps/" + d_file + ".d"; QStringList deps = findDependencies((*it)).grep(QRegExp(Option::moc_ext + "$")); if(!deps.isEmpty()) t << d_file << ": " << deps.join(" ") << endl; t << "-include " << d_file << endl; } } } } } t << "####### Build rules" << endl << endl; if(!project->variables()["SUBLIBS"].isEmpty()) { QString libdir = "tmp/"; if(!project->isEmpty("SUBLIBS_DIR")) libdir = project->first("SUBLIBS_DIR"); t << "SUBLIBS= "; QStringList &l = project->variables()["SUBLIBS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) t << libdir << "lib" << (*it) << ".a "; t << endl << endl; } if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) { QStringList &l = project->variables()["QMAKE_PRL_INTERNAL_FILES"]; QStringList::Iterator it; for(it = l.begin(); it != l.end(); ++it) { QMakeProject proj; if(proj.read((*it), QDir::currentDirPath()) && !proj.isEmpty("QMAKE_PRL_BUILD_DIR")) { QString dir; int slsh = (*it).findRev(Option::dir_sep); if(slsh != -1) dir = (*it).left(slsh + 1); QString targ = dir + proj.first("QMAKE_PRL_TARGET"); deps += " " + targ; t << targ << ":" << "\n\t" << "@echo \"Creating '" << targ << "'\"" << "\n\t" << "(cd " << proj.first("QMAKE_PRL_BUILD_DIR") << ";" << "$(MAKE) )" << endl; } } } if(!project->variables()["QMAKE_APP_FLAG"].isEmpty()) { QString destdir = project->first("DESTDIR"); if(do_incremental) { //incremental target QString incr_target = var("TARGET") + "_incremental"; if(incr_target.find(Option::dir_sep) != -1) incr_target = incr_target.right(incr_target.length() - (incr_target.findRev(Option::dir_sep) + 1)); QString incr_deps, incr_objs; if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; //actual target t << incr_target_dir << ": $(OBJECTS)" << "\n\t" << "ld -r -o "<< incr_target_dir << " $(OBJECTS)" << endl; //communicated below deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC) $(OBJMOC)"; if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += incr_target_dir; } else { //actual target QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + project->variables()["QMAKE_EXTENSION_SHLIB"].first(); QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(project->isActiveConfig("debug")) incr_lflags += var("QMAKE_LFLAGS_DEBUG"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t"; if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl; //communicated below if(!destdir.isEmpty()) { if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += "-L" + destdir; } else { if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += "-L" + QDir::currentDirPath(); } if(!incr_objs.isEmpty()) incr_objs += " "; incr_objs += " -l" + incr_target; deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; } t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; //real target - t << var("TARGET") << ": " << " " << incr_deps << " " << var("TARGETDEPS") << "\n\t"; + t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps + << " " << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS") << "\n\t"; + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; if(!project->isEmpty("QMAKE_PRE_LINK")) t << var("QMAKE_PRE_LINK") << "\n\t"; t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } } else if(!project->isActiveConfig("staticlib")) { QString destdir = project->first("DESTDIR"), incr_deps; if(do_incremental) { QString s_ext = project->variables()["QMAKE_EXTENSION_SHLIB"].first(); QString incr_target = var("QMAKE_ORIG_TARGET").replace( QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental"; if(incr_target.find(Option::dir_sep) != -1) incr_target = incr_target.right(incr_target.length() - (incr_target.findRev(Option::dir_sep) + 1)); if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") { QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext; //actual target const QString link_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; t << incr_target_dir << ": " << link_deps << "\n\t" << "ld -r -o " << incr_target_dir << " " << link_deps << endl; //communicated below QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"]; cmd.first().replace("$(OBJECTS) $(OBJMOC)", "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"); //ick cmd.append(incr_target_dir); deps.prepend(incr_target_dir + " "); incr_deps = "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; } else { //actual target QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + s_ext; QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " "; if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL")) incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " "; if(project->isActiveConfig("debug")) incr_lflags += var("QMAKE_LFLAGS_DEBUG"); else incr_lflags += var("QMAKE_LFLAGS_RELEASE"); t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t"; if(!destdir.isEmpty()) t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl; //communicated below QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"]; if(!destdir.isEmpty()) cmd.append(" -L" + destdir); cmd.append(" -l" + incr_target); deps.prepend(incr_target_dir + " "); incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)"; } t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; //real target - t << var("DESTDIR_TARGET") << ": " << incr_deps << " $(SUBLIBS) " << - var("TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " " + << incr_deps << " $(SUBLIBS) " << var("POST_TARGETDEPS"); } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " << var("DESTDIR_TARGET") << endl << endl; - t << var("DESTDIR_TARGET") << ": $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << - var("TARGETDEPS"); + t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) " << var("POST_TARGETDEPS"); } if(!destdir.isEmpty()) t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir; if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" << var("QMAKE_PRE_LINK"); if(project->isActiveConfig("plugin")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD"); if(!destdir.isEmpty()) t << "\n\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t"; t << endl << endl; - } else if ( os == "hpux" ) { + } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "\n\t" - << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t" + << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; - t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)"); + t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" + << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); if(!destdir.isEmpty()) t << "\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" - << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR"); + << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t" + << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t" + << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } else { t << "\n\t" - << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" + << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t" << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"; - t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t" - << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)"); + t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)"); if(!destdir.isEmpty()) t << "\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t" - << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t" - << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t" - << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR"); + << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR"); if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; } t << endl << endl; if (! project->isActiveConfig("plugin")) { t << "staticlib: $(TARGETA)" << endl << endl; - t << "$(TARGETA): $(UICDECLS) $(OBJECTS) $(OBJMOC)"; + t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC)"; if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; - t << var("TARGETDEPS") << "\n\t" + t << var("POST_TARGETDEPS") << "\n\t" << "-$(DEL_FILE) $(TARGETA) " << "\n\t" << var("QMAKE_AR_CMD"); if(do_incremental) t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\n\t" << "$(RANLIB) $(TARGETA)"; t << endl << endl; } } else { t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) " << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n" << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n"; if(project->isEmpty("QMAKE_AR_SUBLIBS")) { - t << var("DESTDIR") << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(TARGETDEPS) " << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("POST_TARGETDEPS") << "\n\t"; if(!project->isEmpty("DESTDIR")) { QString destdir = project->first("DESTDIR"); t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; } t << "-$(DEL_FILE) $(TARGET)" << "\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) $(TARGET)" << "\n"; if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n" << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n"; } else { - int cnt = 0, max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); + int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"], libs = project->variables()["QMAKE_AR_SUBLIBS"]; libs.prepend("$(TARGET)"); for(QStringList::Iterator libit = libs.begin(), objit = objs.begin(); libit != libs.end(); ++libit) { QStringList build; - for(cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) + for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); QString ar; if((*libit) == "$(TARGET)") { - t << var("DESTDIR") << "$(TARGET): $(UICDECLS) " << " $(TARGETDEPS) " - << valList(build) << "\n\t"; + t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS") + << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t"; ar = project->variables()["QMAKE_AR_CMD"].first(); ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)", build.join(" ")); } else { t << (*libit) << ": " << valList(build) << "\n\t"; ar = "$(AR) " + (*libit) + " " + build.join(" "); } if(!project->isEmpty("DESTDIR")) { QString destdir = project->first("DESTDIR"); t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; } t << "-$(DEL_FILE) " << (*libit) << "\n\t" << ar << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t" << "$(RANLIB) " << (*libit) << "\n"; if(!project->isEmpty("DESTDIR")) t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n" << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n"; } } t << endl << endl; } t << "mocables: $(SRCMOC)" << endl << endl; if(!project->isActiveConfig("no_mocdepend")) { //this is an implicity depend on moc, so it will be built if necesary, however - //moc itself shouldn't have this dependancy - this is a little kludgy but it is + //moc itself shouldn't have this dependency - this is a little kludgy but it is //better than the alternative for now. QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"); fixEnvVariables(target); fixEnvVariables(moc); if(target != moc) t << "$(MOC): \n\t" << "( cd $(QTDIR)/src/moc ; $(MAKE) )" << endl << endl; } writeMakeQmake(t); if(!project->first("QMAKE_PKGINFO").isEmpty()) { QString pkginfo = project->first("QMAKE_PKGINFO"); QString destdir = project->first("DESTDIR"); t << pkginfo << ": " << "\n\t"; if(!destdir.isEmpty()) t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "@$(DEL_FILE) " << pkginfo << "\n\t" << "@echo \"APPL????\" >" << pkginfo << endl; } if(!project->first("QMAKE_INFO_PLIST").isEmpty()) { QString info_plist = project->first("QMAKE_INFO_PLIST"), info_plist_out = project->first("QMAKE_INFO_PLIST_OUT"); QString destdir = project->first("DESTDIR"); t << info_plist_out << ": " << "\n\t"; if(!destdir.isEmpty()) t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t"; t << "@$(DEL_FILE) " << info_plist_out << "\n\t" << "@cp \"" << info_plist << "\" \"" << info_plist_out << "\"" << endl; if(!project->first("RC_FILE").isEmpty()) { QString dir = destdir + "../Resources/"; t << dir << "application.icns:" << "\n\t" << "@test -d " << dir << " || mkdir -p " << dir << "\n\t" << "@cp " << var("RC_FILE") << " " << dir << "application.icns" << endl; } } QString ddir = project->isEmpty("QMAKE_DISTDIR") ? project->first("QMAKE_ORIG_TARGET") : project->first("QMAKE_DISTDIR"); QString ddir_c = fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") : project->first("OBJECTS_DIR")) + ddir); t << "dist: " << "\n\t" << "@mkdir -p " << ddir_c << " && " << "$(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("TRANSLATIONS")) t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && "; if(!project->isEmpty("FORMS")) { QStringList &forms = project->variables()["FORMS"], ui_headers; for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { QString ui_h = fileFixify((*formit) + Option::h_ext.first()); if(QFile::exists(ui_h) ) ui_headers << ui_h; } if(!ui_headers.isEmpty()) t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && "; } t << "( cd `dirname " << ddir_c << "` && " << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && " << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && " << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && " - << "$(DEL_DIR) " << ddir_c + << "$(DEL_FILE) -r " << ddir_c << endl << endl; QString clean_targets; if(mocAware()) { t << "mocclean:" << "\n"; if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) { if(!objMoc.isEmpty()) t << "\t-$(DEL_FILE) $(OBJMOC)" << '\n'; if(!srcMoc.isEmpty()) t << "\t-$(DEL_FILE) $(SRCMOC)" << '\n'; if(moc_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n'; clean_targets += " mocclean"; } t << endl; } t << "uiclean:" << "\n"; if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) { t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n"; clean_targets += " uiclean"; } t << endl; + t << "yaccclean:" << "\n"; + if(!var("YACCSOURCES").isEmpty()) { + QStringList clean, &l = project->variables()["YACCSOURCES"]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QFileInfo fi((*it)); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); + if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) + dir += Option::dir_sep; + clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); + clean << dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); + } + if(!clean.isEmpty()) { + t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; + clean_targets += " yaccclean"; + } + } + + t << "lexclean:" << "\n"; + if(!var("LEXSOURCES").isEmpty()) { + QStringList clean, &l = project->variables()["LEXSOURCES"]; + for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { + QFileInfo fi((*it)); + QString dir; + if(fi.dirPath() != ".") + dir = fi.dirPath() + Option::dir_sep; + dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir); + if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) + dir += Option::dir_sep; + clean << dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); + } + if(!clean.isEmpty()) { + t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n"; + clean_targets += " lexclean"; + } + } + if(do_incremental) { t << "incrclean:" << "\n"; if(src_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n"; if(moc_incremental) t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n'; t << endl; } t << "clean:" << clean_targets << "\n\t"; if(!project->isEmpty("OBJECTS")) t << "-$(DEL_FILE) $(OBJECTS) " << "\n\t"; if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t"; if(src_incremental) t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t"; t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t") << "-$(DEL_FILE) *~ core *.core" << "\n" << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl; t << "####### Sub-libraries" << endl << endl; if ( !project->variables()["SUBLIBS"].isEmpty() ) { QString libdir = "tmp/"; if(!project->isEmpty("SUBLIBS_DIR")) libdir = project->first("SUBLIBS_DIR"); QStringList &l = project->variables()["SUBLIBS"]; for(it = l.begin(); it != l.end(); ++it) t << libdir << "lib" << (*it) << ".a" << ":\n\t" << var(QString("MAKELIB") + (*it)) << endl << endl; } QString destdir = project->first("DESTDIR"); if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep) destdir += Option::dir_sep; - t << "distclean: " << "clean\n\t" - << "-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; + t << "distclean: " << "clean\n"; + if(project->first("TEMPLATE") == "app" && + project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) + t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n"; + else + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n"; if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() && !project->isActiveConfig("plugin")) t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " << destdir << "$(TARGET2) $(TARGETA)" << "\n"; t << endl << endl; if ( !project->isEmpty("PRECOMPH") ) { QString outdir = project->first("MOC_DIR"); QString qt_dot_h = Option::fixPathToLocalOS(project->first("PRECOMPH")); t << "###### Combined headers" << endl << endl; //XXX t << outdir << "allmoc.cpp: " << qt_dot_h << " " << varList("HEADERS_ORIG") << "\n\t" << "echo '#include \"" << qt_dot_h << "\"' >" << outdir << "allmoc.cpp" << "\n\t" << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h " << outdir << "allmoc.cpp" << "\n\t" << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t" << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \"" << qt_dot_h << "\"}' " << outdir << "allmoc.cpp" << "\n\t" << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl; } // blasted user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"]; for(it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), cmd = var((*it) + ".commands"), deps; if(targ.isEmpty()) targ = (*it); QStringList &deplist = project->variables()[(*it) + ".depends"]; for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { QString dep = var((*dep_it) + ".target"); if(dep.isEmpty()) dep = (*dep_it); deps += " " + dep; } t << targ << ":" << deps << "\n\t" << cmd << endl << endl; } t <<"FORCE:" << endl << endl; } struct SubDir { QString directory, profile, target, makefile; }; void UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct) { QPtrList<SubDir> subdirs; { QStringList subdirs_in = project->variables()["SUBDIRS"]; for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) { QString file = (*it); fileFixify(file); SubDir *sd = new SubDir; subdirs.append(sd); sd->makefile = "$(MAKEFILE)"; if((*it).right(4) == ".pro") { int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { sd->directory = file.left(slsh+1); sd->profile = file.mid(slsh+1); } else { sd->profile = file; } } else { sd->directory = file; } while(sd->directory.right(1) == Option::dir_sep) sd->directory = sd->directory.left(sd->directory.length() - 1); if(!sd->profile.isEmpty()) { QString basename = sd->directory; int new_slsh = basename.findRev(Option::dir_sep); if(new_slsh != -1) basename = basename.mid(new_slsh+1); if(sd->profile != basename + ".pro") sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro } sd->target = "sub-" + (*it); sd->target.replace('/', '-'); sd->target.replace('.', '_'); } } QPtrListIterator<SubDir> it(subdirs); QString ofile = Option::output.name(); if(ofile.findRev(Option::dir_sep) != -1) ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1); t << "MAKEFILE = " << var("MAKEFILE") << endl; t << "QMAKE = " << var("QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "SUBTARGETS = "; // subdirectory targets are sub-directory for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl; // generate target rules for( it.toFirst(); it.current(); ++it) { bool have_dir = !(*it)->directory.isEmpty(); QString mkfile = (*it)->makefile, out; if(have_dir) mkfile.prepend((*it)->directory + Option::dir_sep); if(direct || (*it)->makefile != "$(MAKEFILE)") out = " -o " + (*it)->makefile; //qmake it t << mkfile << ": " << "\n\t"; if(have_dir) t << "cd " << (*it)->directory << " && "; t << "$(QMAKE) " << (*it)->profile << buildArgs() << out << endl; //actually compile t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t"; if(have_dir) t << "cd " << (*it)->directory << " && "; t << "$(MAKE) -f " << (*it)->makefile << endl << endl; } if (project->isActiveConfig("ordered")) { // generate dependencies for( it.toFirst(); it.current(); ) { QString tar = it.current()->target; ++it; if (it.current()) t << it.current()->target << ": " << tar << endl; } t << endl; } writeMakeQmake(t); if(project->isEmpty("SUBDIRS")) { - t << "all qmake_all distclean install uiclean mocclean clean: FORCE" << endl; + t << "all qmake_all distclean install uiclean mocclean lexclean yaccclean clean: FORCE" << endl; } else { t << "all: $(SUBTARGETS)" << endl; t << "qmake_all:"; for( it.toFirst(); it.current(); ++it) { t << " "; if(!(*it)->directory.isEmpty()) t << (*it)->directory << Option::dir_sep; t << (*it)->makefile; } for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; t << "grep \"^qmake_all:\" " << (*it)->makefile << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true"; } t << endl; - t << "clean uninstall install uiclean mocclean: qmake_all FORCE"; + t << "clean uninstall install uiclean mocclean lexclean yaccclean: qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true"; } t << endl; t << "distclean: qmake_all FORCE"; for( it.toFirst(); it.current(); ++it) { t << "\n\t ( "; if(!(*it)->directory.isEmpty()) t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; "; t << "$(MAKE) -f " << (*it)->makefile << " $@; $(DEL_FILE) " << (*it)->makefile << "; ) || true"; } t << endl << endl; } t <<"FORCE:" << endl << endl; } void UnixMakefileGenerator::init2() { //version handling if(project->variables()["VERSION"].isEmpty()) project->variables()["VERSION"].append("1.0." + (project->isEmpty("VER_PAT") ? QString("0") : project->first("VER_PAT")) ); QStringList l = QStringList::split('.', project->first("VERSION")); l << "0" << "0"; //make sure there are three project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); project->variables()["VER_PAT"].append(l[2]); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { #if 0 if ( project->isActiveConfig("dll") ) { project->variables()["TARGET"] += project->variables()["TARGET.so"]; if(project->variables()["QMAKE_LFLAGS_SHAPP"].isEmpty()) project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); } #endif project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); + if ( !project->variables()["QMAKE_CYGWIN_EXE"].isEmpty() ) + project->variables()["TARGET_EXT"].append(".exe"); } else if ( project->isActiveConfig("staticlib") ) { project->variables()["TARGET"].first().prepend("lib"); project->variables()["TARGET"].first() += ".a"; if(project->variables()["QMAKE_AR_CMD"].isEmpty()) project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)"); } else { project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() ) project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)"); else project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)"); - QString os = project->variables()["QMAKESPEC"].first().section( '-', 0, 0 ); if( project->isActiveConfig("plugin") ) { project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); if(project->isActiveConfig("lib_version_first")) project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("QMAKE_EXTENSION_SHLIB")); else project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; if(project->isActiveConfig("qt")) project->variables()["DEFINES"].append("QT_PLUGIN"); - } else if ( os == "hpux" ) { + } else if ( !project->isEmpty("QMAKE_HPUX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl"); if(project->isActiveConfig("lib_version_first")) project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." + project->first("TARGET")); else project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ")); project->variables()["TARGET"] = project->variables()["TARGET_x"]; - } else if ( os == "aix" ) { + } else if ( !project->isEmpty("QMAKE_AIX_SHLIB") ) { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a"); if(project->isActiveConfig("lib_version_first")) { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT") + "." + project->first("QMAKE_EXTENSION_SHLIB")); } else { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT")); } project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; } else { project->variables()["TARGET_"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); if(project->isActiveConfig("lib_version_first")) { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT") + "." + project->variables()["QMAKE_EXTENSION_SHLIB"].first()); } else { project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ")); project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB") + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN")); project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." + project->variables()[ "QMAKE_EXTENSION_SHLIB"].first() + "." + project->first("VER_MAJ") + "." + project->first("VER_MIN") + "." + project->first("VER_PAT")); } project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"]; } if(project->isEmpty("QMAKE_LN_SHLIB")) project->variables()["QMAKE_LN_SHLIB"].append("ln -s"); project->variables()["DESTDIR_TARGET"].append("$(TARGET)"); if ( !project->variables()["DESTDIR"].isEmpty() ) project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR")); - if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty() && !project->variables()["TARGET_x"].isEmpty() ) + if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) { + if(project->isActiveConfig("plugin")) { + if(!project->variables()["TARGET"].isEmpty() ) + project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET"); + } else { + if(!project->variables()["TARGET_x"].isEmpty() ) project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x"); + } + } if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() ) project->variables()["QMAKE_LINK_SHLIB_CMD"].append( "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)"); } if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf"); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHAPP"]; } else if ( project->isActiveConfig("dll") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"]; if ( project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"]; if( !project->isActiveConfig("plugin_no_soname") ) project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; } else { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"]; } QString destdir = project->first("DESTDIR"); if ( !destdir.isEmpty() && !project->variables()["QMAKE_RPATH"].isEmpty() ) { QString rpath_destdir = destdir; if(QDir::isRelativePath(rpath_destdir)) { QFileInfo fi(Option::fixPathToLocalOS(rpath_destdir)); if(fi.convertToAbs()) //strange, shouldn't really happen rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE); else rpath_destdir = fi.filePath(); } else { rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE); } project->variables()["QMAKE_LFLAGS"] += project->first("QMAKE_RPATH") + rpath_destdir; } } } diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index ae7b47b..26eea88 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -39,439 +39,471 @@ #include "option.h" #include <qdir.h> #include <qregexp.h> #include <time.h> #include <stdlib.h> BorlandMakefileGenerator::BorlandMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } bool BorlandMakefileGenerator::writeMakefile(QTextStream &t) { writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { t << "all clean:" << "\n\t" << "@echo \"Some of the required modules (" << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" << "@echo \"Skipped.\"" << endl << endl; return TRUE; } if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { writeBorlandParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->first("TEMPLATE") == "subdirs") { writeSubDirs(t); return TRUE; } return FALSE; } void BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) { t << "!if !$d(BCB)" << endl; t << "BCB = $(MAKEDIR)\\.." << endl; t << "!endif" << endl << endl; t << "####### Compiler, tools and options" << endl << endl; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; t << "LEX = " << var("QMAKE_LEX") << endl; t << "YACC = " << var("QMAKE_YACC") << endl; t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "CXXFLAGS= " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "LEXFLAGS=" << var("QMAKE_LEXFLAGS") << endl; t << "YACCFLAGS=" << var("QMAKE_YACCFLAGS") << endl; t << "INCPATH = "; QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace(QRegExp("\\\\*$"), ""); inc.replace("\"", ""); t << " -I\"" << inc << "\""; } t << " -I\"" << specdir() << "\"" << endl; if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "LINK = " << var("QMAKE_LINK") << endl; t << "LFLAGS = "; if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) t << varGlue("QMAKE_LIBDIR","-L",";","") << " "; t << var("QMAKE_LFLAGS") << endl; t << "LIBS = " << var("QMAKE_LIBS") << endl; } else { t << "LIB = " << var("QMAKE_LIB") << endl; } t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl; t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl; t << "ZIP = " << var("QMAKE_ZIP") << endl; t << "DEF_FILE = " << varList("DEF_FILE") << endl; t << "RES_FILE = " << varList("RES_FILE") << endl; t << "COPY_FILE = " << var("QMAKE_COPY") << endl; t << "COPY_DIR = " << var("QMAKE_COPY") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; t << "OBJECTS = " << varList("OBJECTS") << endl; t << "FORMS = " << varList("FORMS") << endl; t << "UICDECLS = " << varList("UICDECLS") << endl; t << "UICIMPLS = " << varList("UICIMPLS") << endl; t << "SRCMOC = " << varList("SRCMOC") << endl; t << "OBJMOC = " << varList("OBJMOC") << endl; t << "DIST = " << varList("DISTFILES") << endl; t << "TARGET = " << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")) << endl; t << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl; - t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << ".SUFFIXES: .c"; + QStringList::Iterator cppit; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << " " << (*cppit); + t << endl << endl; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; t << "####### Build rules" << endl << endl; t << "all: " << varGlue("ALL_DEPS",""," "," ") << " $(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS"); + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) @&&|" << "\n\t" << "$(LFLAGS) $(OBJECTS) $(OBJMOC),$(TARGET),,$(LIBS),$(DEF_FILE),$(RES_FILE)"; } else { t << "\n\t-del $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+" << project->variables()["OBJMOC"].join(" \\\n+"); } t << endl << "|" << endl; + + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + t << "\t" <<var("QMAKE_POST_LINK") << endl; + if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { t << "\n\t" << "-copy $(TARGET) " << *dlldir; } } QString targetfilename = project->variables()["TARGET"].first(); if(project->isActiveConfig("activeqt")) { QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; if ( project->isActiveConfig("dll")) { t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); t << "\n\t" << ("-$(TARGET) -regserver"); } } t << endl << endl; if(!project->variables()["RC_FILE"].isEmpty()) { t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl; } t << "mocables: $(SRCMOC)" << endl << endl; writeMakeQmake(t); t << "dist:" << "\n\t" << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; t << "clean:\n" << varGlue("OBJECTS","\t-del ","\n\t-del ","") << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") - << "\n\t-del $(TARGET)" << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); if ( project->isActiveConfig("activeqt")) { t << ("\n\t-del tmp\\" + targetfilename + ".*"); t << "\n\t-del tmp\\dump.*"; } - if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) - t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); // blasted user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), cmd = var((*it) + ".commands"), deps; if(targ.isEmpty()) targ = (*it); QStringList &deplist = project->variables()[(*it) + ".depends"]; for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { QString dep = var((*dep_it) + ".target"); if(dep.isEmpty()) dep = (*dep_it); deps += " " + dep; } t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } t << endl << endl; + + t << "distclean: clean" + << "\n\t-del $(TARGET)" + << endl << endl; } void BorlandMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "lib") project->variables()["QMAKE_LIB_FLAG"].append("1"); else if(project->first("TEMPLATE") == "subdirs") { MakefileGenerator::init(); if(project->variables()["MAKEFILE"].isEmpty()) project->variables()["MAKEFILE"].append("Makefile"); if(project->variables()["QMAKE"].isEmpty()) project->variables()["QMAKE"].append("qmake"); return; } bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qtmt"QTDLL_POSTFIX); QStringList &configs = project->variables()["CONFIG"]; if (project->isActiveConfig("shared")) project->variables()["DEFINES"].append("QT_DLL"); if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig("plugin") ) { project->variables()["CONFIG"].append("dll"); project->variables()["DEFINES"].append("QT_PLUGIN"); } if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) && ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 || project->variables()["DEFINES"].findIndex("QT_DLL") != -1) || (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) { project->variables()["QMAKE_QT_DLL"].append("1"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) project->variables()["CONFIG"].append("dll"); } } if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["CONFIG"].remove("staticlib"); project->variables()["QMAKE_APP_OR_DLL"].append("1"); } else { project->variables()["CONFIG"].append("staticlib"); } if ( project->isActiveConfig("warn_off") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"]; } else if ( project->isActiveConfig("warn_on") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"]; } if(project->isActiveConfig("qt")) { if ( project->isActiveConfig("thread") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); if ( project->isActiveConfig("accessibility" ) ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); if ( project->isActiveConfig("tablet") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); } if ( project->isActiveConfig("debug") ) { if ( project->isActiveConfig("thread") ) { if ( project->isActiveConfig("dll") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; } } project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"]; } else { if ( project->isActiveConfig("thread") ) { if ( project->isActiveConfig("dll") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"]; } } project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"]; } if ( !project->variables()["QMAKE_INCDIR"].isEmpty()) { project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; } if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) { project->variables()["CONFIG"].append("windows"); } if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) { project->variables()["DEFINES"].append("QT_MAKEDLL"); project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"]; } } else { if(project->isActiveConfig("thread")) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if ( hver == -1 ) - hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); + hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qtmt"); if(hver != -1) { QString ver; ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(mt)?\\.lib"), ver); } } if ( project->isActiveConfig( "activeqt" ) ) { project->variables().remove("QMAKE_LIBS_QT_ENTRY"); project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib"; if ( project->isActiveConfig( "dll" ) ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; } if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; } } } if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } if ( project->isActiveConfig("dll") ) { project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) { project->variables()["TARGET_EXT"].append( QStringList::split('.',project->first("VERSION")).join("") + ".dll"); } else { project->variables()["TARGET_EXT"].append(".dll"); } } else { project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) { project->variables()["TARGET_EXT"].append(".exe"); } else { project->variables()["TARGET_EXT"].append(".lib"); } } if ( project->isActiveConfig("windows") ) { if ( project->isActiveConfig("console") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } else { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; } project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + if ( project->isActiveConfig("thread") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RTMT"]; } else { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_RT"]; } if ( project->isActiveConfig("moc") ) { setMocAware(TRUE); } project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) (*inner) = Option::fixPathToTargetOS((*inner), FALSE); } if ( !project->variables()["RC_FILE"].isEmpty()) { if ( !project->variables()["RES_FILE"].isEmpty()) { fprintf(stderr, "Both .rc and .res file specified.\n"); fprintf(stderr, "Please specify one of them, not both."); exit(666); } project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; project->variables()["RES_FILE"].first().replace(".rc",".res"); - project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; } MakefileGenerator::init(); if ( !project->variables()["VERSION"].isEmpty()) { QStringList l = QStringList::split('.', project->first("VERSION")); project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); } if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { // bcc does not generate a .tds file for static libs QString tdsPostfix; if ( !project->variables()["VERSION"].isEmpty() ) { tdsPostfix = QStringList::split( '.', project->first("VERSION") ).join("") + ".tds"; } else { tdsPostfix = ".tds"; } project->variables()["QMAKE_CLEAN"].append( project->first("DESTDIR") + project->first("TARGET") + tdsPostfix ); } } - diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h index 90f8229..5ffed58 100644 --- a/qmake/generators/win32/borland_bmake.h +++ b/qmake/generators/win32/borland_bmake.h @@ -1,59 +1,58 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __BORLANDMAKE_H__ -#define __BORLANDMAKE_H__ +#ifndef __BORLAND_BMAKE_H__ +#define __BORLAND_BMAKE_H__ #include "winmakefile.h" class BorlandMakefileGenerator : public Win32MakefileGenerator { bool init_flag; void writeBorlandParts(QTextStream &); bool writeMakefile(QTextStream &); void init(); public: BorlandMakefileGenerator(QMakeProject *p); ~BorlandMakefileGenerator(); }; inline BorlandMakefileGenerator::~BorlandMakefileGenerator() { } - -#endif /* __BORLANDMAKE_H__ */ +#endif /* __BORLAND_BMAKE_H__ */ diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp new file mode 100644 index 0000000..7f58a55 --- a/dev/null +++ b/qmake/generators/win32/mingw_make.cpp @@ -0,0 +1,524 @@ +/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mingw_make.h"
+#include "option.h"
+#include <qregexp.h>
+#include <qdir.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+MingwMakefileGenerator::MingwMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
+{
+ Option::obj_ext = ".o";
+}
+
+bool
+MingwMakefileGenerator::writeMakefile(QTextStream &t)
+{
+ writeHeader(t);
+ if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
+ t << "all clean:" << "\n\t"
+ << "@echo \"Some of the required modules ("
+ << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
+ << "@echo \"Skipped.\"" << endl << endl;
+ writeMakeQmake(t);
+ return TRUE;
+ }
+
+ if(project->first("TEMPLATE") == "app" ||
+ project->first("TEMPLATE") == "lib") {
+ writeMingwParts(t);
+ return MakefileGenerator::writeMakefile(t);
+ }
+ else if(project->first("TEMPLATE") == "subdirs") {
+ writeSubDirs(t);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+MingwMakefileGenerator::writeMingwParts(QTextStream &t)
+{
+ t << "####### Compiler, tools and options" << endl << endl;
+ t << "CC = " << var("QMAKE_CC") << endl;
+ t << "CXX = " << var("QMAKE_CXX") << endl;
+ t << "LEX = " << var("QMAKE_LEX") << endl;
+ t << "YACC = " << var("QMAKE_YACC") << endl;
+ t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
+ << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
+ << varGlue("DEFINES","-D"," -D","") << endl;
+ t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
+ << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
+ << varGlue("DEFINES","-D"," -D","") << endl;
+ t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl;
+ t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl;
+
+ t << "INCPATH = ";
+ QStringList &incs = project->variables()["INCLUDEPATH"];
+ for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
+ QString inc = (*incit);
+ inc.replace(QRegExp("\\\\$"), "\\\\");
+ inc.replace(QRegExp("\""), "");
+ t << " -I" << inc ;
+ }
+ t << " -I" << specdir()
+ << endl;
+ if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
+ t << "LINK = " << var("QMAKE_LINK") << endl;
+ t << "LFLAGS = ";
+ if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() )
+ t << varGlue("QMAKE_LIBDIR","-L",";","") << " ";
+ t << var("QMAKE_LFLAGS") << endl;
+ t << "LIBS = " << var("QMAKE_LIBS").replace(QRegExp("(\\slib|^lib)")," -l") << endl;
+ }
+ else {
+ t << "LIB = " << var("QMAKE_LIB") << endl;
+ }
+ t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") :
+ Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl;
+ t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") :
+ Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl;
+ t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") :
+ Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl;
+ t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") :
+ Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl;
+ t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") :
+ Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl;
+ t << "ZIP = " << var("QMAKE_ZIP") << endl;
+ t << "DEF_FILE = " << varList("DEF_FILE") << endl;
+ t << "COPY_FILE = " << var("QMAKE_COPY") << endl;
+ t << "COPY_DIR = " << var("QMAKE_COPY") << endl;
+ t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
+ t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
+ t << "MOVE = " << var("QMAKE_MOVE") << endl;
+ t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl;
+ t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
+ t << endl;
+
+ t << "####### Output directory" << endl << endl;
+ if (! project->variables()["OBJECTS_DIR"].isEmpty())
+ t << "OBJECTS_DIR = " << var("OBJECTS_DIR").replace(QRegExp("\\\\$"),"") << endl;
+ else
+ t << "OBJECTS_DIR = . " << endl;
+ if (! project->variables()["MOC_DIR"].isEmpty())
+ t << "MOC_DIR = " << var("MOC_DIR").replace(QRegExp("\\\\$"),"") << endl;
+ else
+ t << "MOC_DIR = . " << endl;
+ t << endl;
+
+ t << "####### Files" << endl << endl;
+ t << "HEADERS = " << varList("HEADERS") << endl;
+ t << "SOURCES = " << varList("SOURCES") << endl;
+// t << "OBJECTS = " << varList("OBJECTS").replace(QRegExp("\\.obj"),".o") << endl;
+ t << "OBJECTS = " << varList("OBJECTS") << endl;
+ t << "FORMS = " << varList("FORMS") << endl;
+ t << "UICDECLS = " << varList("UICDECLS") << endl;
+ t << "UICIMPLS = " << varList("UICIMPLS") << endl;
+ t << "SRCMOC = " << varList("SRCMOC") << endl;
+ t << "OBJMOC = " << varList("OBJMOC") << endl;
+// t << "OBJMOC = " << varList("OBJMOC").replace(QRegExp("\\.obj"),".o") << endl;
+ t << "DIST = " << varList("DISTFILES") << endl;
+ t << "TARGET = ";
+ if( !project->variables()[ "DESTDIR" ].isEmpty() )
+ t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT"));
+ else
+ t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
+ t << endl;
+ t << endl;
+
+ t << "####### Implicit rules" << endl << endl;
+ t << ".SUFFIXES: .cpp .cxx .cc .C .c" << endl << endl;
+ t << ".cpp.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".cxx.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".cc.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".C.o:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
+ t << ".c.o:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
+
+ t << "####### Build rules" << endl << endl;
+ t << "all: " << "$(OBJECTS_DIR) " << "$(MOC_DIR) " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl;
+ t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
+ << var("POST_TARGETDEPS");
+ if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
+ t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
+ } else {
+ t << "\n\t" << "$(LIB) $(TARGET) $(OBJECTS) $(OBJMOC)";
+ }
+
+ if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) {
+ QStringList dlldirs = project->variables()["DLLDESTDIR"];
+ for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
+ t << "\n\t" << "copy $(TARGET) " << *dlldir;
+ }
+ }
+ QString targetfilename = project->variables()["TARGET"].first();
+ if(project->isActiveConfig("activeqt")) {
+ QString version = project->variables()["VERSION"].first();
+ if ( version.isEmpty() )
+ version = "1.0";
+
+ if ( project->isActiveConfig("dll")) {
+ t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version);
+ t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" );
+ } else {
+ t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version);
+ t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl");
+ t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb");
+ t << "\n\t" << "-$(TARGET) -regserver";
+ }
+ }
+ t << endl << endl;
+
+ if(!project->variables()["RC_FILE"].isEmpty()) {
+ t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t"
+ << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << endl << endl;
+ }
+ project->variables()["RES_FILE"].first().replace(QRegExp("\\.rc"),".o");
+
+ t << "mocables: $(SRCMOC)" << endl << endl;
+
+ t << "$(OBJECTS_DIR):" << "\n\t"
+ << "@if not exist $(OBJECTS_DIR) mkdir $(OBJECTS_DIR)" << endl << endl;
+
+ t << "$(MOC_DIR):" << "\n\t"
+ << "@if not exist $(MOC_DIR) mkdir $(MOC_DIR)" << endl << endl;
+
+ writeMakeQmake(t);
+
+ t << "dist:" << "\n\t"
+ << "$(ZIP) " << var("PROJECT") << ".zip "
+ << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl;
+
+ t << "clean:"
+ << varGlue("OBJECTS","\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
+ << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","")
+ << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","").replace(QRegExp("\\.obj"),".o")
+ << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","")
+ << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","")
+ << "\n\t-del $(TARGET)"
+ << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","")
+ << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ","");
+ if ( project->isActiveConfig("activeqt")) {
+ t << ("\n\t-del tmp\\" + targetfilename + ".*");
+ t << "\n\t-del tmp\\dump.*";
+ }
+ if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty())
+ t << "\n\t-del " << var("DLLDESTDIR") << "\\" << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first();
+ if(!project->isEmpty("IMAGES"))
+ t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", "");
+
+ // blasted user defined targets
+ QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
+ for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
+ QString targ = var((*it) + ".target"),
+ cmd = var((*it) + ".commands"), deps;
+ if(targ.isEmpty())
+ targ = (*it);
+ QStringList &deplist = project->variables()[(*it) + ".depends"];
+ for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
+ QString dep = var((*dep_it) + ".target");
+ if(dep.isEmpty())
+ dep = (*dep_it);
+ deps += " " + dep;
+ }
+ t << "\n\n" << targ << ":" << deps << "\n\t"
+ << cmd;
+ }
+
+ t << endl << endl;
+}
+
+
+void
+MingwMakefileGenerator::init()
+{
+ if(init_flag)
+ return;
+ init_flag = TRUE;
+
+ /* this should probably not be here, but I'm using it to wrap the .t files */
+ if(project->first("TEMPLATE") == "app")
+ project->variables()["QMAKE_APP_FLAG"].append("1");
+ else if(project->first("TEMPLATE") == "lib")
+ project->variables()["QMAKE_LIB_FLAG"].append("1");
+ else if(project->first("TEMPLATE") == "subdirs") {
+ MakefileGenerator::init();
+ if(project->variables()["MAKEFILE"].isEmpty())
+ project->variables()["MAKEFILE"].append("Makefile");
+ if(project->variables()["QMAKE"].isEmpty())
+ project->variables()["QMAKE"].append("qmake");
+ return;
+ }
+
+ bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX);
+ project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
+
+ // LIBS defined in Profile comes first for gcc
+ project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
+
+ QString targetfilename = project->variables()["TARGET"].first();
+ QStringList &configs = project->variables()["CONFIG"];
+ if (project->isActiveConfig("qt") && project->isActiveConfig("shared"))
+ project->variables()["DEFINES"].append("QT_DLL");
+ if (project->isActiveConfig("qt_dll"))
+ if(configs.findIndex("qt") == -1) configs.append("qt");
+ if ( project->isActiveConfig("qt") ) {
+ if ( project->isActiveConfig( "plugin" ) ) {
+ project->variables()["CONFIG"].append("dll");
+ if(project->isActiveConfig("qt"))
+ project->variables()["DEFINES"].append("QT_PLUGIN");
+ }
+ if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) &&
+ ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 ||
+ project->variables()["DEFINES"].findIndex("QT_DLL") != -1) ||
+ (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) {
+ project->variables()["QMAKE_QT_DLL"].append("1");
+ if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
+ project->variables()["CONFIG"].append("dll");
+ }
+ if ( project->isActiveConfig("thread") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
+ if ( project->isActiveConfig("accessibility" ) )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
+ if ( project->isActiveConfig("tablet") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
+ }
+ if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
+ project->variables()["CONFIG"].remove("staticlib");
+ project->variables()["QMAKE_APP_OR_DLL"].append("1");
+ } else {
+ project->variables()["CONFIG"].append("staticlib");
+ }
+ if ( project->isActiveConfig("warn_off") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
+ } else if ( project->isActiveConfig("warn_on") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
+ }
+ if ( project->isActiveConfig("debug") ) {
+ if ( project->isActiveConfig("thread") ) {
+ // use the DLL RT even here
+ if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"];
+ }
+ }
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
+ } else {
+ if ( project->isActiveConfig("thread") ) {
+ if ( project->variables()["DEFINES"].contains("QT_DLL") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"];
+ }
+ }
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
+ }
+
+ if ( !project->variables()["QMAKE_INCDIR"].isEmpty())
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
+ if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") )
+ project->variables()["CONFIG"].append("windows");
+ if ( project->isActiveConfig("qt") ) {
+ project->variables()["CONFIG"].append("moc");
+ project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
+ project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
+ if ( !project->isActiveConfig("debug") )
+ project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
+ if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
+ if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) {
+ project->variables()["DEFINES"].append("QT_MAKEDLL");
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"];
+ }
+ } else {
+ if(project->isActiveConfig("thread"))
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
+ else
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
+ if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
+ int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
+ if ( hver == -1 )
+ hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt");
+ if(hver != -1) {
+ QString ver;
+ ver.sprintf("libqt-%s" QTDLL_POSTFIX "%d.a", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
+ QStringList &libs = project->variables()["QMAKE_LIBS"];
+// @@@HGTODO maybe we must change the replace regexp if we understand what's going on
+ for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
+ (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
+ }
+ }
+ if ( project->isActiveConfig( "activeqt" ) ) {
+ project->variables().remove("QMAKE_LIBS_QT_ENTRY");
+ project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
+ if ( project->isActiveConfig( "dll" ) )
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
+ }
+ if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
+ project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
+ }
+ }
+ }
+ if ( project->isActiveConfig("opengl") ) {
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
+ }
+ if ( project->isActiveConfig("dll") ) {
+ project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"];
+ project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"];
+ if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) {
+ project->variables()["TARGET_EXT"].append(
+ QStringList::split('.',project->first("VERSION")).join("") + ".dll");
+ } else {
+ project->variables()["TARGET_EXT"].append(".dll");
+ }
+ } else {
+ project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"];
+ project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"];
+ project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"];
+ project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"];
+ if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
+ project->variables()["TARGET_EXT"].append(".exe");
+ } else {
+ project->variables()["TARGET_EXT"].append(".a");
+ project->variables()["QMAKE_LFLAGS"].append("-static");
+ if(project->variables()["TARGET"].first().left(3) != "lib")
+ project->variables()["TARGET"].first().prepend("lib");
+ }
+ }
+ if ( project->isActiveConfig("windows") ) {
+ if ( project->isActiveConfig("console") ) {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
+ } else {
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"];
+ }
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
+ } else {
+ project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"];
+ project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"];
+ }
+
+ if ( project->isActiveConfig("moc") )
+ setMocAware(TRUE);
+ project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ',
+ "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
+ QStringList &l = project->variables()["QMAKE_FILETAGS"];
+ for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
+ QStringList &gdmf = project->variables()[(*it)];
+ for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
+ (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
+ }
+
+ if ( project->isActiveConfig("dll") )
+ project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + project->first("DESTDIR") + "\\lib"+ project->first("TARGET") + ".a");
+
+ if ( !project->variables()["DEF_FILE"].isEmpty() )
+ project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--output-def,") + project->first("DEF_FILE"));
+// if(!project->isActiveConfig("incremental"))
+// project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no"));
+
+#if 0
+ if ( !project->variables()["VERSION"].isEmpty() ) {
+ QString version = project->variables()["VERSION"][0];
+ int firstDot = version.find( "." );
+ QString major = version.left( firstDot );
+ QString minor = version.right( version.length() - firstDot - 1 );
+ minor.replace( ".", "" );
+ project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
+ }
+#endif
+ if ( !project->variables()["RC_FILE"].isEmpty()) {
+ if ( !project->variables()["RES_FILE"].isEmpty()) {
+ fprintf(stderr, "Both .rc and .res file specified.\n");
+ fprintf(stderr, "Please specify one of them, not both.");
+ exit(666);
+ }
+ project->variables()["RES_FILE"] = project->variables()["RC_FILE"];
+ project->variables()["RES_FILE"].first().replace(".rc",".o");
+ project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"];
+ }
+ if ( !project->variables()["RES_FILE"].isEmpty())
+ project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"];
+
+ MakefileGenerator::init();
+ if ( !project->variables()["VERSION"].isEmpty()) {
+ QStringList l = QStringList::split('.', project->first("VERSION"));
+ project->variables()["VER_MAJ"].append(l[0]);
+ project->variables()["VER_MIN"].append(l[1]);
+ }
+ if(project->isActiveConfig("dll")) {
+ project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") +"lib" + project->first("TARGET") + ".a");
+ }
+}
+
+void
+MingwMakefileGenerator::writeSubDirs(QTextStream &t)
+{
+ QString qs ;
+ QTextStream ts (&qs, IO_WriteOnly) ;
+ Win32MakefileGenerator::writeSubDirs( ts ) ;
+ QRegExp rx("(\\n\\tcd [^\\n\\t]+)(\\n\\t.+)\\n\\t@cd ..") ;
+ rx.setMinimal(true);
+ int pos = 0 ;
+ while ( -1 != (pos = rx.search( qs, pos)))
+ {
+ QString qsMatch = rx.cap(2);
+ qsMatch.replace("\n\t"," && \\\n\t");
+ qs.replace(pos+rx.cap(1).length(), rx.cap(2).length(), qsMatch );
+ pos += (rx.cap(1).length()+qsMatch.length());
+ }
+ t << qs ;
+}
diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h new file mode 100644 index 0000000..c00bf1b --- a/dev/null +++ b/qmake/generators/win32/mingw_make.h @@ -0,0 +1,58 @@ +/****************************************************************************
+** $Id$
+**
+** Definition of ________ class.
+**
+** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+**
+** This file is part of the network module of the Qt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech AS of Norway and appearing in the file
+** LICENSE.QPL included in the packaging of this file.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid Qt Enterprise Edition licenses may use this
+** file in accordance with the Qt Commercial License Agreement provided
+** with the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about Qt Commercial License Agreements.
+** See http://www.trolltech.com/qpl/ for QPL licensing information.
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __MINGW_MAKE_H__
+#define __MINGW_MAKE_H__
+
+#include "winmakefile.h"
+
+class MingwMakefileGenerator : public Win32MakefileGenerator
+{
+ bool init_flag;
+ void writeMingwParts(QTextStream &);
+ void writeSubDirs(QTextStream &t) ;
+
+ bool writeMakefile(QTextStream &);
+ void init();
+
+public:
+ MingwMakefileGenerator(QMakeProject *p);
+ ~MingwMakefileGenerator();
+
+};
+
+inline MingwMakefileGenerator::~MingwMakefileGenerator()
+{ }
+
+#endif /* __MINGW_MAKE_H__ */
diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp index 8b08c78..3fa0496 100644 --- a/qmake/generators/win32/msvc_dsp.cpp +++ b/qmake/generators/win32/msvc_dsp.cpp @@ -415,541 +415,584 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) QStringList list = project->variables()["LEXSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString fname = (*it); // beginGroupForFile(fname, t); t << "# Begin Source File\n\nSOURCE=" << fname << endl; fname.replace(".l", Option::lex_mod + Option::cpp_ext.first()); QString build = "\n\n# Begin Custom Build - Lex'ing " + (*it) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + fname + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t" + lexpath + (*it) + "\\\n" "\tdel " + fname + "\\\n" "\tcopy lex.yy.c " + fname + "\n\n" + "# End Custom Build\n\n"; t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build << "!ENDIF \n\n" << build << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if(variable == "MSVCDSP_YACCSOURCES") { if(project->variables()["YACCSOURCES"].isEmpty()) continue; t << "# Begin Group \"Yaccables\"\n" << "# Prop Default_Filter \"y\"\n"; QString yaccpath = var("QMAKE_YACC") + varGlue("QMAKE_YACCFLAGS", " ", " ", "") + " "; QStringList list = project->variables()["YACCSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString fname = (*it); // beginGroupForFile(fname, t); t << "# Begin Source File\n\nSOURCE=" << fname << endl; fname.replace(".y", Option::yacc_mod); QString build = "\n\n# Begin Custom Build - Yacc'ing " + (*it) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + fname + Option::cpp_ext.first() + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t" + yaccpath + (*it) + "\\\n" "\tdel " + fname + Option::h_ext.first() + "\\\n" "\tmove y.tab.h " + fname + Option::h_ext.first() + "\n\n" + "\tdel " + fname + Option::cpp_ext.first() + "\\\n" "\tmove y.tab.c " + fname + Option::cpp_ext.first() + "\n\n" + "# End Custom Build\n\n"; t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build << "!ENDIF \n\n" << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if( variable == "MSVCDSP_CONFIGMODE" ) { if( project->isActiveConfig( "debug" ) ) t << "Debug"; else t << "Release"; } else if( variable == "MSVCDSP_IDLSOURCES" ) { QStringList list = project->variables()["MSVCDSP_IDLSOURCES"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { t << "# Begin Source File" << endl << endl; t << "SOURCE=" << (*it) << endl; t << "# PROP Exclude_From_Build 1" << endl; t << "# End Source File" << endl << endl; } } else t << var(variable); } t << line << endl; } t << endl; file.close(); return TRUE; } void DspMakefileGenerator::init() { if(init_flag) return; QStringList::Iterator it; init_flag = TRUE; + const bool thread = project->isActiveConfig("thread"); + + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") ); bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; QStringList &configs = project->variables()["CONFIG"]; if (project->isActiveConfig("shared")) project->variables()["DEFINES"].append("QT_DLL"); if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig( "plugin" ) ) { project->variables()["CONFIG"].append("dll"); project->variables()["DEFINES"].append("QT_PLUGIN"); } if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) && ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 || project->variables()["DEFINES"].findIndex("QT_DLL") != -1) || (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) { project->variables()["QMAKE_QT_DLL"].append("1"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) project->variables()["CONFIG"].append("dll"); } } if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["CONFIG"].remove("staticlib"); project->variables()["QMAKE_APP_OR_DLL"].append("1"); } else { project->variables()["CONFIG"].append("staticlib"); } if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) { project->variables()["CONFIG"].append("windows"); } if ( !project->variables()["VERSION"].isEmpty() ) { QString version = project->variables()["VERSION"][0]; int firstDot = version.find( "." ); QString major = version.left( firstDot ); QString minor = version.right( version.length() - firstDot - 1 ); minor.replace( ".", "" ); project->variables()["MSVCDSP_VERSION"].append( "/VERSION:" + major + "." + minor ); } if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["DEFINES"].append("QT_MAKEDLL"); project->variables()["QMAKE_LFLAGS"].append("/base:\"0x39D00000\""); } } else { - if(project->isActiveConfig("thread")) + if( thread ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if ( hver == -1 ) hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); if(hver != -1) { QString ver; - ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); + ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (thread ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); } } if ( project->isActiveConfig( "activeqt" ) ) { project->variables().remove("QMAKE_LIBS_QT_ENTRY"); project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib"; if ( project->isActiveConfig( "dll" ) ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; } if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; } } } if ( project->isActiveConfig("debug") ) { if ( !project->first("OBJECTS_DIR").isEmpty() ) project->variables()["MSVCDSP_OBJECTSDIRDEB"] = project->first("OBJECTS_DIR"); else project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; if ( !project->first("DESTDIR").isEmpty() ) project->variables()["MSVCDSP_TARGETDIRDEB"] = project->first("DESTDIR"); else project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug"; project->variables()["MSVCDSP_TARGETDIRREL"] = "Release"; } else { if ( !project->first("OBJECTS_DIR").isEmpty() ) project->variables()["MSVCDSP_OBJECTSDIRREL"] = project->first("OBJECTS_DIR"); project->variables()["MSVCDSP_OBJECTSDIRDEB"] = "Debug"; if ( !project->first("DESTDIR").isEmpty() ) project->variables()["MSVCDSP_TARGETDIRREL"] = project->first("DESTDIR"); else project->variables()["MSVCDSP_TARGETDIRREL"] = "Release"; project->variables()["MSVCDSP_TARGETDIRDEB"] = "Debug"; } if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } - if ( project->isActiveConfig("thread") ) { + if ( thread ) { if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" ); if ( project->isActiveConfig("dll") || project->first("TARGET") == "qtmain" || !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; } else { // YES we want to use the DLL even in a static build project->variables()["MSVCDSP_MTDEFD"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; project->variables()["MSVCDSP_MTDEF"] += project->variables()["QMAKE_CXXFLAGS_MT"]; } if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt && project->first("TARGET") != "qtmain" ) project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\""); } if(project->isActiveConfig("qt")) { if ( project->isActiveConfig("accessibility" ) ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); if ( project->isActiveConfig("tablet") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); } if ( project->isActiveConfig("dll") ) { if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { QString ver_xyz(project->first("VERSION")); ver_xyz.replace(".", ""); project->variables()["TARGET_EXT"].append(ver_xyz + ".dll"); } else { project->variables()["TARGET_EXT"].append(".dll"); } } else { if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) project->variables()["TARGET_EXT"].append(".exe"); else project->variables()["TARGET_EXT"].append(".lib"); } project->variables()["MSVCDSP_VER"] = "6.00"; project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /ZI"; if(!project->isActiveConfig("incremental")) { project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); if ( is_qt ) project->variables()["MSVCDSP_DEBUG_OPT"] = "/GZ /Zi"; } QString msvcdsp_project; if ( project->variables()["TARGET"].count() ) msvcdsp_project = project->variables()["TARGET"].first(); QString targetfilename = project->variables()["TARGET"].first(); project->variables()["TARGET"].first() += project->first("TARGET_EXT"); if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) (*inner) = Option::fixPathToTargetOS((*inner), FALSE); } MakefileGenerator::init(); if ( msvcdsp_project.isEmpty() ) msvcdsp_project = Option::output.name(); msvcdsp_project = msvcdsp_project.right( msvcdsp_project.length() - msvcdsp_project.findRev( "\\" ) - 1 ); msvcdsp_project = msvcdsp_project.left( msvcdsp_project.findRev( "." ) ); msvcdsp_project.replace("-", ""); project->variables()["MSVCDSP_PROJECT"].append(msvcdsp_project); QStringList &proj = project->variables()["MSVCDSP_PROJECT"]; for(it = proj.begin(); it != proj.end(); ++it) (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), ""); if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["MSVCDSP_TEMPLATE"].append("win32app" + project->first( "DSP_EXTENSION" ) ); if ( project->isActiveConfig("console") ) { project->variables()["MSVCDSP_CONSOLE"].append("Console"); project->variables()["MSVCDSP_WINCONDEF"].append("_CONSOLE"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0103"); project->variables()["MSVCDSP_SUBSYSTEM"].append("console"); } else { project->variables()["MSVCDSP_CONSOLE"].clear(); project->variables()["MSVCDSP_WINCONDEF"].append("_WINDOWS"); project->variables()["MSVCDSP_DSPTYPE"].append("0x0101"); project->variables()["MSVCDSP_SUBSYSTEM"].append("windows"); } } else { if ( project->isActiveConfig("dll") ) { project->variables()["MSVCDSP_TEMPLATE"].append("win32dll" + project->first( "DSP_EXTENSION" ) ); } else { project->variables()["MSVCDSP_TEMPLATE"].append("win32lib" + project->first( "DSP_EXTENSION" ) ); } } project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; project->variables()["MSVCDSP_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) project->variables()["MSVCDSP_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\"")); project->variables()["MSVCDSP_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; project->variables()["MSVCDSP_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); project->variables()["MSVCDSP_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); + processPrlFiles(); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); lib.replace(QRegExp("\""), ""); project->variables()["MSVCDSP_LIBS"].append(" \"" + lib + "\""); } QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace("\"", ""); project->variables()["MSVCDSP_INCPATH"].append("/I \"" + inc + "\""); } project->variables()["MSVCDSP_INCPATH"].append("/I \"" + specdir() + "\""); if ( project->isActiveConfig("qt") ) { project->variables()["MSVCDSP_RELDEFS"].append("/D \"QT_NO_DEBUG\""); } else { project->variables()["MSVCDSP_RELDEFS"].clear(); } QString dest; + QString postLinkStep; + QString copyDllStep; + QString activeQtStepPreCopyDll; + QString activeQtStepPostCopyDll; + QString activeQtStepPreCopyDllDebug; + QString activeQtStepPostCopyDllDebug; + QString activeQtStepPreCopyDllRelease; + QString activeQtStepPostCopyDllRelease; + + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + postLinkStep += var("QMAKE_POST_LINK"); + if ( !project->variables()["DESTDIR"].isEmpty() ) { project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); Option::fixPathToTargetOS(project->first("TARGET")); dest = project->first("TARGET"); if ( project->first("TARGET").startsWith("$(QTDIR)") ) dest.replace( "$(QTDIR)", getenv("QTDIR") ); project->variables()["MSVCDSP_TARGET"].append( QString("/out:\"") + dest + "\""); if ( project->isActiveConfig("dll") ) { QString imp = dest; imp.replace(".dll", ".lib"); project->variables()["MSVCDSP_TARGET"].append(QString(" /implib:\"") + imp + "\""); } } if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; - QString copydll = "# Begin Special Build Tool\n" - "TargetPath=" + dest + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n" - "PostBuild_Cmds="; - + if ( dlldirs.count() ) + copyDllStep += "\t"; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; + copyDllStep += "copy \"$(TargetPath)\" \"" + *dlldir + "\"\t"; } - - copydll += "\n# End Special Build Tool"; - project->variables()["MSVCDSP_COPY_DLL_REL"].append( copydll ); - project->variables()["MSVCDSP_COPY_DLL_DBG"].append( copydll ); } + if ( project->isActiveConfig("activeqt") ) { QString idl = project->variables()["QMAKE_IDL"].first(); QString idc = project->variables()["QMAKE_IDC"].first(); QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); project->variables()["MSVCDSP_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); if ( project->isActiveConfig( "dll" ) ) { - QString regcmd = "# Begin Special Build Tool\n" - "TargetPath=" + targetfilename + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Finalizing ActiveQt server...\n" - "PostBuild_Cmds=" + - idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + + activeQtStepPreCopyDll += + "\t" + idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" - "\t" + idc + " %1 /regserver\n" - "# End Special Build Tool"; + "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + activeQtStepPostCopyDll += + "\t" + idc + " %1 /regserver\n"; - QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".dll"; + activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); - executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".dll"; + activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } else { - QString regcmd = "# Begin Special Build Tool\n" - "TargetPath=" + targetfilename + "\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Finalizing ActiveQt server...\n" - "PostBuild_Cmds=" - "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + + activeQtStepPreCopyDll += + "\t%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" - "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" - "\t%1 -regserver\n" - "# End Special Build Tool"; + "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb"; + activeQtStepPostCopyDll += + "\t%1 -regserver\n"; + QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + targetfilename + ".exe"; + activeQtStepPreCopyDllRelease = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllRelease = activeQtStepPostCopyDll.arg(executable); - QString executable = project->variables()["MSVCDSP_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); + executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".exe"; + activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); + activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); + } - executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); - project->variables()["MSVCDSP_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } + + if ( !postLinkStep.isEmpty() || !copyDllStep.isEmpty() || !activeQtStepPreCopyDllDebug.isEmpty() || !activeQtStepPreCopyDllRelease.isEmpty() ) { + project->variables()["MSVCDSP_POST_LINK_DBG"].append( + "# Begin Special Build Tool\n" + "SOURCE=$(InputPath)\n" + "PostBuild_Desc=Post Build Step\n" + "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllDebug + copyDllStep + activeQtStepPostCopyDllDebug + "\n" + "# End Special Build Tool\n" ); + project->variables()["MSVCDSP_POST_LINK_REL"].append( + "# Begin Special Build Tool\n" + "SOURCE=$(InputPath)\n" + "PostBuild_Desc=Post Build Step\n" + "PostBuild_Cmds=" + postLinkStep + activeQtStepPreCopyDllRelease + copyDllStep + activeQtStepPostCopyDllRelease + "\n" + "# End Special Build Tool\n" ); } + if ( !project->variables()["SOURCES"].isEmpty() || !project->variables()["RC_FILE"].isEmpty() ) { project->variables()["SOURCES"] += project->variables()["RC_FILE"]; } QStringList &list = project->variables()["FORMS"]; for( it = list.begin(); it != list.end(); ++it ) { if ( QFile::exists( *it + ".h" ) ) project->variables()["SOURCES"].append( *it + ".h" ); } project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCDSP_LIBS"; } QString -DspMakefileGenerator::findTemplate(QString file) +DspMakefileGenerator::findTemplate(const QString &file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) return ""; return ret; } void DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_DEFINES") { QStringList &out = project->variables()["MSVCDSP_DEFINES"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(out.findIndex((*it)) == -1) out.append((" /D \"" + *it + "\"")); } } else { MakefileGenerator::processPrlVariable(var, l); } } -int +void DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, - QString filter) + const QString& filter) { if(project->isActiveConfig("flat")) - return 0; + return; fileFixify(file, QDir::currentDirPath(), QDir::currentDirPath(), TRUE); file = file.section(Option::dir_sep, 0, -2); if(file.right(Option::dir_sep.length()) != Option::dir_sep) file += Option::dir_sep; if(file == currentGroup) - return 0; + return; if(file.isEmpty() || !QDir::isRelativePath(file)) { endGroups(t); - return 0; + return; } if(file.startsWith(currentGroup)) file = file.mid(currentGroup.length()); - else - endGroups(t); - int lvl = file.contains(Option::dir_sep), old_lvl = currentGroup.contains(Option::dir_sep); - if(lvl > old_lvl) { - QStringList dirs = QStringList::split(Option::dir_sep, file); + int dirSep = currentGroup.findRev( Option::dir_sep ); + while( !file.startsWith( currentGroup ) && dirSep != -1 ) { + currentGroup.truncate( dirSep ); + dirSep = currentGroup.findRev( Option::dir_sep ); + if ( !file.startsWith( currentGroup ) && dirSep != -1 ) + t << "\n# End Group\n"; + } + if ( !file.startsWith( currentGroup ) ) { + t << "\n# End Group\n"; + currentGroup = ""; + } + QStringList dirs = QStringList::split(Option::dir_sep, file.right( file.length() - currentGroup.length() ) ); for(QStringList::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { t << "# Begin Group \"" << (*dir_it) << "\"\n" << "# Prop Default_Filter \"" << filter << "\"\n"; } - } else { - for(int x = old_lvl - lvl; x; x--) - t << "\n# End Group\n"; - } currentGroup = file; - return lvl - old_lvl; } -int +void DspMakefileGenerator::endGroups(QTextStream &t) { if(project->isActiveConfig("flat")) - return 0; + return; else if(currentGroup.isEmpty()) - return 0; + return; QStringList dirs = QStringList::split(Option::dir_sep, currentGroup); for(QStringList::Iterator dir_it = dirs.end(); dir_it != dirs.begin(); --dir_it) { t << "\n# End Group\n"; } currentGroup = ""; - return dirs.count(); } bool DspMakefileGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) file.setName(outdir + project->first("TARGET") + project->first("DSP_EXTENSION")); if(QDir::isRelativePath(file.name())) { QString ofile; ofile = file.name(); int slashfind = ofile.findRev('\\'); if (slashfind == -1) { ofile = ofile.replace(QRegExp("-"), "_"); } else { int hypenfind = ofile.find('-', slashfind); while (hypenfind != -1 && slashfind < hypenfind) { ofile = ofile.replace(hypenfind, 1, "_"); hypenfind = ofile.find('-', hypenfind + 1); } } file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile)); } return Win32MakefileGenerator::openOutput(file); } diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h index a7fc3e7..3a7d18e 100644 --- a/qmake/generators/win32/msvc_dsp.h +++ b/qmake/generators/win32/msvc_dsp.h @@ -1,73 +1,73 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __DSPMAKE_H__ -#define __DSPMAKE_H__ +#ifndef __MSVC_DSP_H__ +#define __MSVC_DSP_H__ #include "winmakefile.h" #include <qvaluestack.h> class DspMakefileGenerator : public Win32MakefileGenerator { QString currentGroup; - int beginGroupForFile(QString file, QTextStream &, const QString filter=""); - int endGroups(QTextStream &); + void beginGroupForFile(QString file, QTextStream &, const QString& filter=""); + void endGroups(QTextStream &); bool init_flag; bool writeDspParts(QTextStream &); bool writeMakefile(QTextStream &); - QString findTemplate(QString file); + QString findTemplate(const QString &file); void init(); public: DspMakefileGenerator(QMakeProject *p); ~DspMakefileGenerator(); bool openOutput(QFile &file) const; protected: virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); }; inline DspMakefileGenerator::~DspMakefileGenerator() { } inline bool DspMakefileGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); } -#endif /* __DSPMAKE_H__ */ +#endif /* __MSVC_DSP_H__ */ diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 9cc9a69..ecef34d 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,488 +1,562 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "msvc_nmake.h" #include "option.h" #include <qregexp.h> +#include <qdict.h> #include <qdir.h> #include <stdlib.h> #include <time.h> NmakeMakefileGenerator::NmakeMakefileGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } bool NmakeMakefileGenerator::writeMakefile(QTextStream &t) { writeHeader(t); if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { t << "all clean:" << "\n\t" << "@echo \"Some of the required modules (" << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t" << "@echo \"Skipped.\"" << endl << endl; writeMakeQmake(t); return TRUE; } if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { writeNmakeParts(t); return MakefileGenerator::writeMakefile(t); } else if(project->first("TEMPLATE") == "subdirs") { writeSubDirs(t); return TRUE; } return FALSE; } void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) { t << "####### Compiler, tools and options" << endl << endl; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; t << "LEX = " << var("QMAKE_LEX") << endl; t << "YACC = " << var("QMAKE_YACC") << endl; t << "CFLAGS = " << var("QMAKE_CFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " " << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " " << varGlue("DEFINES","-D"," -D","") << endl; t << "LEXFLAGS =" << var("QMAKE_LEXFLAGS") << endl; t << "YACCFLAGS =" << var("QMAKE_YACCFLAGS") << endl; t << "INCPATH = "; QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace(QRegExp("\\\\$"), "\\\\"); inc.replace("\"", ""); t << " -I\"" << inc << "\""; } t << " -I\"" << specdir() << "\"" << endl; if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "LINK = " << var("QMAKE_LINK") << endl; t << "LFLAGS = " << var("QMAKE_LFLAGS"); if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) t << " " << varGlue("QMAKE_LIBDIR","/LIBPATH:\"","\" /LIBPATH:\"","\""); t << endl; t << "LIBS = "; QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { QString lib = (*libit); lib.replace(QRegExp("\\\\$"), "\\\\"); lib.replace(QRegExp("\""), ""); t << " \"" << lib << "\""; } t << endl; } else { t << "LIB = " << var("QMAKE_LIB") << endl; } t << "MOC = " << (project->isEmpty("QMAKE_MOC") ? QString("moc") : Option::fixPathToTargetOS(var("QMAKE_MOC"), FALSE)) << endl; t << "UIC = " << (project->isEmpty("QMAKE_UIC") ? QString("uic") : Option::fixPathToTargetOS(var("QMAKE_UIC"), FALSE)) << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : Option::fixPathToTargetOS(var("QMAKE_QMAKE"), FALSE)) << endl; t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : Option::fixPathToTargetOS(var("QMAKE_IDC"), FALSE)) << endl; t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : Option::fixPathToTargetOS(var("QMAKE_IDL"), FALSE)) << endl; t << "ZIP = " << var("QMAKE_ZIP") << endl; t << "COPY_FILE = " << var("QMAKE_COPY") << endl; t << "COPY_DIR = " << var("QMAKE_COPY") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; + t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; + t << "MKDIR = " << var("QMAKE_MKDIR") << endl; t << endl; t << "####### Files" << endl << endl; t << "HEADERS = " << varList("HEADERS") << endl; t << "SOURCES = " << varList("SOURCES") << endl; t << "OBJECTS = " << varList("OBJECTS") << endl; t << "FORMS = " << varList("FORMS") << endl; t << "UICDECLS = " << varList("UICDECLS") << endl; t << "UICIMPLS = " << varList("UICIMPLS") << endl; t << "SRCMOC = " << varList("SRCMOC") << endl; t << "OBJMOC = " << varList("OBJMOC") << endl; t << "DIST = " << varList("DISTFILES") << endl; t << "TARGET = "; if( !project->variables()[ "DESTDIR" ].isEmpty() ) t << varGlue("TARGET",project->first("DESTDIR"),"",project->first("TARGET_EXT")); else t << project->variables()[ "TARGET" ].first() << project->variables()[ "TARGET_EXT" ].first(); t << endl; t << endl; t << "####### Implicit rules" << endl << endl; - t << ".SUFFIXES: .cpp .cxx .cc .c" << endl << endl; - t << ".cpp.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cxx.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".cc.obj:\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - t << ".c.obj:\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << ".SUFFIXES: .c"; + QStringList::Iterator cppit; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << " " << (*cppit); + t << endl << endl; + if(!project->isActiveConfig("no_batch")) { + // Batchmode doesn't use the non implicit rules QMAKE_RUN_CXX & QMAKE_RUN_CC + project->variables().remove("QMAKE_RUN_CXX"); + project->variables().remove("QMAKE_RUN_CC"); + + QDict<void> source_directories; + source_directories.insert(".", (void*)1); + if(!project->isEmpty("MOC_DIR")) + source_directories.insert(project->first("MOC_DIR"), (void*)1); + if(!project->isEmpty("UI_SOURCES_DIR")) + source_directories.insert(project->first("UI_SOURCES_DIR"), (void*)1); + else if(!project->isEmpty("UI_DIR")) + source_directories.insert(project->first("UI_DIR"), (void*)1); + QString srcs[] = { QString("SOURCES"), QString("UICIMPLS"), QString("SRCMOC"), QString::null }; + for(int x = 0; !srcs[x].isNull(); x++) { + QStringList &l = project->variables()[srcs[x]]; + for(QStringList::Iterator sit = l.begin(); sit != l.end(); ++sit) { + QString sep = "\\"; + if((*sit).find(sep) == -1) + sep = "/"; + QString dir = (*sit).section(sep, 0, -2); + if(!dir.isEmpty() && !source_directories[dir]) + source_directories.insert(dir, (void*)1); + } + } + + for(QDictIterator<void> it(source_directories); it.current(); ++it) { + if(it.currentKey().isEmpty()) + continue; + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << "{" << it.currentKey() << "}" << (*cppit) << "{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CXX_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; + t << "{" << it.currentKey() << "}" << ".c{" << var("OBJECTS_DIR") << "}" << Option::obj_ext << "::\n\t" + << var("QMAKE_RUN_CC_IMP_BATCH").replace( QRegExp( "\\$@" ), var("OBJECTS_DIR") ) << endl << "\t$<" << endl << "<<" << endl << endl; + } + } else { + for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) + t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; + t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + } t << "####### Build rules" << endl << endl; t << "all: " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)" << endl << endl; - t << "$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) " << var("TARGETDEPS"); + t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " + << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) { t << "\n\t" << "$(LINK) $(LFLAGS) /OUT:$(TARGET) @<< " << "\n\t " << "$(OBJECTS) $(OBJMOC) $(LIBS)"; } else { t << "\n\t" << "$(LIB) /OUT:$(TARGET) @<<" << "\n\t " << "$(OBJECTS) $(OBJMOC)"; } t << endl << "<<" << endl; + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) + t << "\t" << var( "QMAKE_POST_LINK" ) << endl; if(project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty()) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { t << "\n\t" << "-copy $(TARGET) " << *dlldir; } } QString targetfilename = project->variables()["TARGET"].first(); if(project->isActiveConfig("activeqt")) { QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; if ( project->isActiveConfig("dll")) { t << "\n\t" << ("-$(IDC) $(TARGET) /idl tmp\\" + targetfilename + ".idl -version " + version); t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); t << "\n\t" << ("-$(IDC) $(TARGET) /regserver" ); } else { t << "\n\t" << ("-$(TARGET) -dumpidl tmp\\" + targetfilename + ".idl -version " + version); t << "\n\t" << ("-$(IDL) tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl"); t << "\n\t" << ("-$(IDC) $(TARGET) /tlb tmp\\" + targetfilename + ".tlb"); t << "\n\t" << "-$(TARGET) -regserver"; } } t << endl << endl; if(!project->variables()["RC_FILE"].isEmpty()) { t << var("RES_FILE") << ": " << var("RC_FILE") << "\n\t" << var("QMAKE_RC") << " " << var("RC_FILE") << endl << endl; } t << "mocables: $(SRCMOC)" << endl << endl; writeMakeQmake(t); t << "dist:" << "\n\t" << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" << endl << endl; t << "clean:" << varGlue("OBJECTS","\n\t-del ","\n\t-del ","") << varGlue("SRCMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("OBJMOC" ,"\n\t-del ","\n\t-del ","") << varGlue("UICDECLS" ,"\n\t-del ","\n\t-del ","") << varGlue("UICIMPLS" ,"\n\t-del ","\n\t-del ","") << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); + if ( project->isActiveConfig("activeqt")) { t << ("\n\t-del tmp\\" + targetfilename + ".*"); t << "\n\t-del tmp\\dump.*"; } if(!project->isEmpty("IMAGES")) t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); // blasted user defined targets QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { QString targ = var((*it) + ".target"), cmd = var((*it) + ".commands"), deps; if(targ.isEmpty()) targ = (*it); QStringList &deplist = project->variables()[(*it) + ".depends"]; for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) { QString dep = var((*dep_it) + ".target"); if(dep.isEmpty()) dep = (*dep_it); deps += " " + dep; } t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } t << endl << endl; + + t << "distclean: clean" + << "\n\t-del $(TARGET)" + << endl << endl; } void NmakeMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; /* this should probably not be here, but I'm using it to wrap the .t files */ if(project->first("TEMPLATE") == "app") project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "lib") project->variables()["QMAKE_LIB_FLAG"].append("1"); else if(project->first("TEMPLATE") == "subdirs") { MakefileGenerator::init(); if(project->variables()["MAKEFILE"].isEmpty()) project->variables()["MAKEFILE"].append("Makefile"); if(project->variables()["QMAKE"].isEmpty()) project->variables()["QMAKE"].append("qmake"); return; } bool is_qt = (project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX); project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; QString targetfilename = project->variables()["TARGET"].first(); QStringList &configs = project->variables()["CONFIG"]; if (project->isActiveConfig("qt") && project->isActiveConfig("shared")) project->variables()["DEFINES"].append("QT_DLL"); if (project->isActiveConfig("qt_dll")) if(configs.findIndex("qt") == -1) configs.append("qt"); if ( project->isActiveConfig("qt") ) { if ( project->isActiveConfig( "plugin" ) ) { project->variables()["CONFIG"].append("dll"); if(project->isActiveConfig("qt")) project->variables()["DEFINES"].append("QT_PLUGIN"); } if ( (project->variables()["DEFINES"].findIndex("QT_NODLL") == -1) && ((project->variables()["DEFINES"].findIndex("QT_MAKEDLL") != -1 || project->variables()["DEFINES"].findIndex("QT_DLL") != -1) || (getenv("QT_DLL") && !getenv("QT_NODLL"))) ) { project->variables()["QMAKE_QT_DLL"].append("1"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) project->variables()["CONFIG"].append("dll"); } if ( project->isActiveConfig("thread") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT"); if ( project->isActiveConfig("accessibility" ) ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); if ( project->isActiveConfig("tablet") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); } if ( project->isActiveConfig("dll") || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["CONFIG"].remove("staticlib"); project->variables()["QMAKE_APP_OR_DLL"].append("1"); } else { project->variables()["CONFIG"].append("staticlib"); } if ( project->isActiveConfig("warn_off") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"]; } else if ( project->isActiveConfig("warn_on") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"]; } if ( project->isActiveConfig("debug") ) { if ( project->isActiveConfig("thread") ) { // use the DLL RT even here if ( project->variables()["DEFINES"].contains("QT_DLL") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLLDBG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DBG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DBG"]; } } project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"]; } else { if ( project->isActiveConfig("thread") ) { if ( project->variables()["DEFINES"].contains("QT_DLL") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT_DLL"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT_DLL"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_MT"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_MT"]; } } project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"]; } if ( project->isActiveConfig("thread") && !project->variables()["DEFINES"].contains("QT_DLL") && !is_qt && project->first("TARGET") != "qtmain") { project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:\"libc\""); } if ( !project->variables()["QMAKE_INCDIR"].isEmpty()) project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"]; if ( project->isActiveConfig("qt") || project->isActiveConfig("opengl") ) project->variables()["CONFIG"].append("windows"); if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if ( !project->isActiveConfig("debug") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG"); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { if ( !project->variables()["QMAKE_QT_DLL"].isEmpty()) { project->variables()["DEFINES"].append("QT_MAKEDLL"); project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_QT_DLL"]; } } else { if(project->isActiveConfig("thread")) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if ( hver == -1 ) hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt-mt"); if(hver != -1) { QString ver; ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); } } if ( project->isActiveConfig( "activeqt" ) ) { project->variables().remove("QMAKE_LIBS_QT_ENTRY"); project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib"; if ( project->isActiveConfig( "dll" ) ) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; } if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; } } } if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } if ( project->isActiveConfig("dll") ) { project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE_DLL"]; project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS_DLL"]; if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty()) { project->variables()["TARGET_EXT"].append( QStringList::split('.',project->first("VERSION")).join("") + ".dll"); } else { project->variables()["TARGET_EXT"].append(".dll"); } } else { project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CFLAGS_CONSOLE"]; project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_CXXFLAGS_CONSOLE"]; project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"] = project->variables()["QMAKE_LFLAGS_CONSOLE"]; project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"] = project->variables()["QMAKE_LFLAGS_WINDOWS"]; if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty()) { project->variables()["TARGET_EXT"].append(".exe"); } else { project->variables()["TARGET_EXT"].append(".lib"); } } if ( project->isActiveConfig("windows") ) { if ( project->isActiveConfig("console") ) { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } else { project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_WINDOWS_ANY"]; } project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; } else { project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_CONSOLE_ANY"]; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_CONSOLE"]; } + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) (*inner) = Option::fixPathToTargetOS((*inner), FALSE); } if ( !project->variables()["DEF_FILE"].isEmpty() ) project->variables()["QMAKE_LFLAGS"].append(QString("/DEF:") + project->first("DEF_FILE")); if(!project->isActiveConfig("incremental")) project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); if ( !project->variables()["VERSION"].isEmpty() ) { QString version = project->variables()["VERSION"][0]; int firstDot = version.find( "." ); QString major = version.left( firstDot ); QString minor = version.right( version.length() - firstDot - 1 ); minor.replace( ".", "" ); project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor ); } if ( !project->variables()["RC_FILE"].isEmpty()) { if ( !project->variables()["RES_FILE"].isEmpty()) { fprintf(stderr, "Both .rc and .res file specified.\n"); fprintf(stderr, "Please specify one of them, not both."); exit(666); } project->variables()["RES_FILE"] = project->variables()["RC_FILE"]; project->variables()["RES_FILE"].first().replace(".rc",".res"); - project->variables()["TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; } if ( !project->variables()["RES_FILE"].isEmpty()) project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; MakefileGenerator::init(); if ( !project->variables()["VERSION"].isEmpty()) { QStringList l = QStringList::split('.', project->first("VERSION")); project->variables()["VER_MAJ"].append(l[0]); project->variables()["VER_MIN"].append(l[1]); } + + QString version = QStringList::split('.', project->first("VERSION")).join(""); if(project->isActiveConfig("dll")) { - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".lib"); - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".exp"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); } if(project->isActiveConfig("debug")) { - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".pdb"); - project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + ".ilk"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"); + project->variables()["QMAKE_CLEAN"].append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); project->variables()["QMAKE_CLEAN"].append("vc*.pdb"); } } diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index d3e170f..579fc35 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,59 +1,59 @@ /**************************************************************************** ** $Id$ ** ** Definition of ________ class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __NMAKEMAKE_H__ -#define __NMAKEMAKE_H__ +#ifndef __MSVC_NMAKE_H__ +#define __MSVC_NMAKE_H__ #include "winmakefile.h" class NmakeMakefileGenerator : public Win32MakefileGenerator { bool init_flag; void writeNmakeParts(QTextStream &); bool writeMakefile(QTextStream &); void init(); public: NmakeMakefileGenerator(QMakeProject *p); ~NmakeMakefileGenerator(); }; inline NmakeMakefileGenerator::~NmakeMakefileGenerator() { } -#endif /* __NMAKEMAKE_H__ */ +#endif /* __MSVC_NMAKE_H__ */ diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index c2b9e30..7ffe4f7 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -290,1666 +290,1703 @@ QTextStream &operator<<( QTextStream &strm, const TPair &prop ) strm << prop.name << "FALSE\""; break; case _True: strm << prop.name << "TRUE\""; break; case unset: default: break; } return strm; } /* Be sure to check that each enum is not set to default before streaming it out. Defaults seem to not be in the XML file. */ QTextStream &operator<<( QTextStream &strm, const EPair &prop ) { strm << prop.name << prop.value << "\""; return strm; } QTextStream &operator<<( QTextStream &strm, const LPair &prop ) { strm << prop.name << prop.value << "\""; return strm; } QTextStream &operator<<( QTextStream &strm, const SPair &prop ) { if ( !prop.value.isEmpty() ) strm << prop.name << prop.value.latin1() << "\""; return strm; } QTextStream &operator<<( QTextStream &strm, const XPair &prop ) { if ( !prop.value.isEmpty() ) strm << prop.name << prop.value.join(prop.sep).latin1() << "\""; return strm; } // VCCLCompilerTool ------------------------------------------------- VCCLCompilerTool::VCCLCompilerTool() : AssemblerOutput( asmListingNone ), BasicRuntimeChecks( runtimeBasicCheckNone ), BrowseInformation( brInfoNone ), BufferSecurityCheck( unset ), CallingConvention( callConventionDefault ), CompileAs( compileAsDefault ), CompileAsManaged( managedDefault ), CompileOnly( unset ), DebugInformationFormat( debugDisabled ), DefaultCharIsUnsigned( unset ), Detect64BitPortabilityProblems( unset ), DisableLanguageExtensions( unset ), EnableFiberSafeOptimizations( unset ), EnableFunctionLevelLinking( unset ), EnableIntrinsicFunctions( unset ), ExceptionHandling( unset ), ExpandAttributedSource( unset ), FavorSizeOrSpeed( favorNone ), ForceConformanceInForLoopScope( unset ), GeneratePreprocessedFile( preprocessNo ), GlobalOptimizations( unset ), IgnoreStandardIncludePath( unset ), ImproveFloatingPointConsistency( unset ), InlineFunctionExpansion( expandOnlyInline ), KeepComments( unset ), MinimalRebuild( unset ), OmitFramePointers( unset ), Optimization( optimizeDisabled ), OptimizeForProcessor( procOptimizeBlended ), OptimizeForWindowsApplication( unset ), RuntimeLibrary( rtMultiThreaded ), RuntimeTypeInfo( unset ), ShowIncludes( unset ), SmallerTypeCheck( unset ), StringPooling( unset ), StructMemberAlignment( alignNotSet ), SuppressStartupBanner( unset ), TreatWChar_tAsBuiltInType( unset ), TurnOffAssemblyGeneration( unset ), UndefineAllPreprocessorDefinitions( unset ), UsePrecompiledHeader( pchGenerateAuto ), WarnAsError( unset ), WarningLevel( warningLevel_0 ), WholeProgramOptimization( unset ) { } QTextStream &operator<<( QTextStream &strm, const VCCLCompilerTool &tool ) { strm << _begTool3; strm << _VCCLCompilerToolName; strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AdditionalUsingDirectories, tool.AdditionalUsingDirectories ); strm << SPair( _AssemblerListingLocation, tool.AssemblerListingLocation ); if ( tool.AssemblerOutput != asmListingNone ) strm << EPair( _AssemblerOutput, tool.AssemblerOutput ); if ( tool.BasicRuntimeChecks != runtimeBasicCheckNone ) strm << EPair( _BasicRuntimeChecks, tool.BasicRuntimeChecks ); if ( tool.BrowseInformation != brInfoNone ) strm << EPair( _BrowseInformation, tool.BrowseInformation ); strm << SPair( _BrowseInformationFile, tool.BrowseInformationFile ); strm << TPair( _BufferSecurityCheck, tool.BufferSecurityCheck ); if ( tool.CallingConvention != callConventionDefault ) strm << EPair( _CallingConvention, tool.CallingConvention ); if ( tool.CompileAs != compileAsDefault ) strm << EPair( _CompileAs, tool.CompileAs ); if ( tool.CompileAsManaged != managedDefault ) strm << EPair( _CompileAsManaged, tool.CompileAsManaged ); strm << TPair( _CompileOnly, tool.CompileOnly ); strm << EPair( _DebugInformationFormat, tool.DebugInformationFormat ); strm << TPair( _DefaultCharIsUnsigned, tool.DefaultCharIsUnsigned ); strm << TPair( _Detect64BitPortabilityProblems, tool.Detect64BitPortabilityProblems ); strm << TPair( _DisableLanguageExtensions, tool.DisableLanguageExtensions ); strm << XPair( _DisableSpecificWarnings, tool.DisableSpecificWarnings ); strm << TPair( _EnableFiberSafeOptimizations, tool.EnableFiberSafeOptimizations ); strm << TPair( _EnableFunctionLevelLinking, tool.EnableFunctionLevelLinking ); strm << TPair( _EnableIntrinsicFunctions, tool.EnableIntrinsicFunctions ); strm << TPair( _ExceptionHandling, tool.ExceptionHandling ); strm << TPair( _ExpandAttributedSource, tool.ExpandAttributedSource ); if ( tool.FavorSizeOrSpeed != favorNone ) strm << EPair( _FavorSizeOrSpeed, tool.FavorSizeOrSpeed ); strm << TPair( _ForceConformanceInForLoopScope, tool.ForceConformanceInForLoopScope ); strm << XPair( _ForcedIncludeFiles, tool.ForcedIncludeFiles ); strm << XPair( _ForcedUsingFiles, tool.ForcedUsingFiles ); strm << EPair( _GeneratePreprocessedFile, tool.GeneratePreprocessedFile ); strm << TPair( _GlobalOptimizations, tool.GlobalOptimizations ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << TPair( _ImproveFloatingPointConsistency, tool.ImproveFloatingPointConsistency ); strm << EPair( _InlineFunctionExpansion, tool.InlineFunctionExpansion ); strm << TPair( _KeepComments, tool.KeepComments ); strm << TPair( _MinimalRebuild, tool.MinimalRebuild ); strm << SPair( _ObjectFile, tool.ObjectFile ); strm << TPair( _OmitFramePointers, tool.OmitFramePointers ); strm << EPair( _Optimization, tool.Optimization ); if ( tool.OptimizeForProcessor != procOptimizeBlended ) strm << EPair( _OptimizeForProcessor, tool.OptimizeForProcessor ); strm << TPair( _OptimizeForWindowsApplication, tool.OptimizeForWindowsApplication ); strm << SPair( _OutputFile, tool.OutputFile ); strm << SPair( _PrecompiledHeaderFile, tool.PrecompiledHeaderFile ); strm << SPair( _PrecompiledHeaderThrough, tool.PrecompiledHeaderThrough ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); strm << SPair( _ProgramDataBaseFileName, tool.ProgramDataBaseFileName ); strm << EPair( _RuntimeLibrary, tool.RuntimeLibrary ); strm << TPair( _RuntimeTypeInfo, tool.RuntimeTypeInfo ); strm << TPair( _ShowIncludes, tool.ShowIncludes ); strm << TPair( _SmallerTypeCheck, tool.SmallerTypeCheck ); strm << TPair( _StringPooling, tool.StringPooling ); if ( tool.StructMemberAlignment != alignNotSet ) strm << EPair( _StructMemberAlignment, tool.StructMemberAlignment ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << TPair( _TreatWChar_tAsBuiltInType, tool.TreatWChar_tAsBuiltInType ); strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration ); strm << TPair( _UndefineAllPreprocessorDefinitions, tool.UndefineAllPreprocessorDefinitions ); strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions ); if ( !tool.PrecompiledHeaderFile.isEmpty() || !tool.PrecompiledHeaderThrough.isEmpty() ) strm << EPair( _UsePrecompiledHeader, tool.UsePrecompiledHeader ); strm << TPair( _WarnAsError, tool.WarnAsError ); strm << EPair( _WarningLevel, tool.WarningLevel ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << "/>"; return strm; } bool VCCLCompilerTool::parseOption( const char* option ) { // skip index 0 ('/' or '-') char first = option[1]; char second = option[2]; char third = option[3]; char fourth = option[4]; + bool found = TRUE; switch ( first ) { case '?': case 'h': qWarning( "Generator: Option '/?', '/help': MSVC.NET projects do not support outputting help info" ); - return FALSE; + found = FALSE; + break; case '@': qWarning( "Generator: Option '/@': MSVC.NET projects do not support the use of a response file" ); - return FALSE; + found = FALSE; + break; case 'l': qWarning( "Generator: Option '/link': qmake generator does not support passing link options through the compiler tool" ); - return FALSE; - + found = FALSE; + break; case 'A': - if ( second != 'I' ) - return FALSE; + if ( second != 'I' ) { + found = FALSE; break; + } AdditionalUsingDirectories += option+2; break; case 'C': KeepComments = _True; break; case 'D': PreprocessorDefinitions += option+1; break; case 'E': if ( second == 'H' ) { if ( third == 'a' || third == 'c' || third == 's' ) { // ExceptionHandling must be false, or it will override // with an /EHsc option ExceptionHandling = _False; AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; } GeneratePreprocessedFile = preprocessYes; break; case 'F': if ( second <= '9' && second >= '0' ) { AdditionalOptions += option; break; } else { switch ( second ) { case 'A': if ( third == 'c' ) { AssemblerOutput = asmListingAsmMachine; if ( fourth == 's' ) AssemblerOutput = asmListingAsmMachineSrc; } else if ( third == 's' ) { AssemblerOutput = asmListingAsmSrc; } else { AssemblerOutput = asmListingAssemblyOnly; } break; case 'a': AssemblerListingLocation = option+3; break; case 'I': ForcedIncludeFiles += option+3; break; case 'R': BrowseInformation = brAllInfo; BrowseInformationFile = option+3; break; case 'r': BrowseInformation = brNoLocalSymbols; BrowseInformationFile = option+3; break; case 'U': ForcedUsingFiles += option+3; break; case 'd': ProgramDataBaseFileName = option+3; break; case 'e': OutputFile = option+3; break; case 'm': AdditionalOptions += option; break; case 'o': ObjectFile = option+3; break; case 'p': PrecompiledHeaderFile = option+3; break; case 'x': ExpandAttributedSource = _True; break; default: - return FALSE; + found = FALSE; break; } } break; case 'G': switch ( second ) { case '3': case '4': qWarning( "Option '/G3' and '/G4' were phased out in Visual C++ 5.0" ); - return FALSE; + found = FALSE; break; case '5': OptimizeForProcessor = procOptimizePentium; break; case '6': case 'B': OptimizeForProcessor = procOptimizePentiumProAndAbove; break; case 'A': OptimizeForWindowsApplication = _True; break; case 'F': StringPooling = _True; break; case 'H': AdditionalOptions += option; break; case 'L': WholeProgramOptimization = _True; if ( third == '-' ) WholeProgramOptimization = _False; break; case 'R': RuntimeTypeInfo = _True; if ( third == '-' ) RuntimeTypeInfo = _False; break; case 'S': BufferSecurityCheck = _True; break; case 'T': EnableFiberSafeOptimizations = _True; break; case 'X': case 'Z': case 'e': case 'h': AdditionalOptions += option; break; case 'd': CallingConvention = callConventionCDecl; break; case 'f': StringPooling = _True; AdditionalOptions += option; break; case 'm': MinimalRebuild = _True; if ( third == '-' ) MinimalRebuild = _False; break; case 'r': CallingConvention = callConventionFastCall; break; case 's': // Warning: following [num] is not used, // were should we put it? BufferSecurityCheck = _True; break; case 'y': EnableFunctionLevelLinking = _True; break; case 'z': CallingConvention = callConventionStdCall; break; default: - return FALSE; + found = FALSE; break; } break; case 'H': AdditionalOptions += option; break; case 'I': AdditionalIncludeDirectories += option+2; break; case 'L': if ( second == 'D' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'M': if ( second == 'D' ) { RuntimeLibrary = rtMultiThreadedDLL; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebugDLL; break; } else if ( second == 'L' ) { RuntimeLibrary = rtSingleThreaded; if ( third == 'd' ) RuntimeLibrary = rtSingleThreadedDebug; break; } else if ( second == 'T' ) { RuntimeLibrary = rtMultiThreaded; if ( third == 'd' ) RuntimeLibrary = rtMultiThreadedDebug; break; } - return FALSE; + found = FALSE; break; case 'O': switch ( second ) { case '1': Optimization = optimizeMinSpace; break; case '2': Optimization = optimizeMaxSpeed; break; case 'a': AdditionalOptions += option; break; case 'b': if ( third == '0' ) InlineFunctionExpansion = expandDisable; else if ( third == '1' ) InlineFunctionExpansion = expandOnlyInline; else if ( third == '2' ) InlineFunctionExpansion = expandAnySuitable; else - return FALSE; + found = FALSE; break; case 'd': Optimization = optimizeDisabled; break; case 'g': GlobalOptimizations = _True; break; case 'i': EnableIntrinsicFunctions = _True; break; case 'p': ImproveFloatingPointConsistency = _True; if ( third == '-' ) ImproveFloatingPointConsistency = _False; break; case 's': FavorSizeOrSpeed = favorSize; break; case 't': FavorSizeOrSpeed = favorSpeed; break; case 'w': AdditionalOptions += option; break; case 'x': Optimization = optimizeFull; break; case 'y': OmitFramePointers = _True; if ( third == '-' ) OmitFramePointers = _False; break; default: - return FALSE; + found = FALSE; break; } break; case 'P': GeneratePreprocessedFile = preprocessYes; break; case 'Q': if ( second == 'I' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'R': if ( second == 'T' && third == 'C' ) { if ( fourth == '1' ) BasicRuntimeChecks = runtimeBasicCheckAll; else if ( fourth == 'c' ) SmallerTypeCheck = _True; else if ( fourth == 's' ) BasicRuntimeChecks = runtimeCheckStackFrame; else if ( fourth == 'u' ) BasicRuntimeChecks = runtimeCheckUninitVariables; else - return FALSE; + found = FALSE; break; } break; case 'T': if ( second == 'C' ) { CompileAs = compileAsC; } else if ( second == 'P' ) { CompileAs = compileAsCPlusPlus; } else { qWarning( "Generator: Options '/Tp<filename>' and '/Tc<filename>' are not supported by qmake" ); - return FALSE; + found = FALSE; break; } break; case 'U': UndefinePreprocessorDefinitions += option+2; break; case 'V': AdditionalOptions += option; break; case 'W': switch ( second ) { case 'a': case '4': WarningLevel = warningLevel_4; break; case '3': WarningLevel = warningLevel_3; break; case '2': WarningLevel = warningLevel_2; break; case '1': WarningLevel = warningLevel_1; break; case '0': WarningLevel = warningLevel_0; break; case 'L': AdditionalOptions += option; break; case 'X': WarnAsError = _True; break; case 'p': if ( third == '6' && fourth == '4' ) { Detect64BitPortabilityProblems = _True; break; } // Fallthrough default: - return FALSE; + found = FALSE; break; } break; case 'X': IgnoreStandardIncludePath = _True; break; case 'Y': switch ( second ) { case '\0': case '-': AdditionalOptions += option; break; case 'X': UsePrecompiledHeader = pchGenerateAuto; PrecompiledHeaderFile = option+3; break; case 'c': UsePrecompiledHeader = pchCreateUsingSpecific; PrecompiledHeaderFile = option+3; break; case 'd': case 'l': AdditionalOptions =+ option; break; case 'u': UsePrecompiledHeader = pchUseUsingSpecific; PrecompiledHeaderFile = option+3; break; default: - return FALSE; + found = FALSE; break; } break; case 'Z': switch ( second ) { case '7': DebugInformationFormat = debugOldStyleInfo; break; case 'I': DebugInformationFormat = debugEditAndContinue; break; case 'd': DebugInformationFormat = debugLineInfoOnly; break; case 'i': DebugInformationFormat = debugEnabled; break; case 'l': DebugInformationFormat = debugEditAndContinue; break; case 'a': DisableLanguageExtensions = _True; break; case 'e': DisableLanguageExtensions = _False; break; case 'c': if ( third == ':' ) { if ( fourth == 'f' ) ForceConformanceInForLoopScope = _True; else if ( fourth == 'w' ) TreatWChar_tAsBuiltInType = _True; else - return FALSE; + found = FALSE; } else { - return FALSE; + found = FALSE; break; } break; case 'g': case 'm': case 's': AdditionalOptions += option; break; case 'p': switch ( third ) { case '\0': case '1': StructMemberAlignment = alignSingleByte; if ( fourth == '6' ) StructMemberAlignment = alignSixteenBytes; break; case '2': StructMemberAlignment = alignTwoBytes; break; case '4': StructMemberAlignment = alignFourBytes; break; case '8': StructMemberAlignment = alignEightBytes; break; default: - return FALSE; + found = FALSE; break; } break; default: - return FALSE; + found = FALSE; break; } break; case 'c': if ( second == '\0' ) { CompileOnly = _True; } else if ( second == 'l' ) { if ( *(option+5) == 'n' ) { CompileAsManaged = managedAssembly; TurnOffAssemblyGeneration = _True; } else { CompileAsManaged = managedAssembly; } } else { - return FALSE; + found = FALSE; break; } break; case 'd': - if ( second != 'r' ) - return FALSE; + if ( second != 'r' ) { + found = FALSE; break; + } CompileAsManaged = managedAssembly; break; case 'n': if ( second == 'o' && third == 'B' && fourth == 'o' ) { AdditionalOptions += "/noBool"; break; } if ( second == 'o' && third == 'l' && fourth == 'o' ) { SuppressStartupBanner = _True; break; } - return FALSE; + found = FALSE; break; case 's': if ( second == 'h' && third == 'o' && fourth == 'w' ) { ShowIncludes = _True; break; } - return FALSE; + found = FALSE; break; case 'u': UndefineAllPreprocessorDefinitions = _True; break; case 'v': if ( second == 'd' || second == 'm' ) { AdditionalOptions += option; break; } - return FALSE; + found = FALSE; break; case 'w': switch ( second ) { case '\0': WarningLevel = warningLevel_0; break; case 'd': DisableSpecificWarnings += option+3; break; default: AdditionalOptions += option; } break; default: - return FALSE; + found = FALSE; break; } + if( !found ) + warn_msg( WarnLogic, "Could not parse Compiler option: %s", option ); return TRUE; } // VCLinkerTool ----------------------------------------------------- VCLinkerTool::VCLinkerTool() : EnableCOMDATFolding( optFoldingDefault ), GenerateDebugInformation( unset ), GenerateMapFile( unset ), HeapCommitSize( -1 ), HeapReserveSize( -1 ), IgnoreAllDefaultLibraries( unset ), IgnoreEmbeddedIDL( unset ), IgnoreImportLibrary( unset ), LargeAddressAware( addrAwareDefault ), LinkDLL( unset ), LinkIncremental( linkIncrementalYes ), LinkTimeCodeGeneration( unset ), MapExports( unset ), MapLines( unset ), OptimizeForWindows98( optWin98Default ), OptimizeReferences( optReferencesDefault ), RegisterOutput( unset ), ResourceOnlyDLL( unset ), SetChecksum( unset ), ShowProgress( linkProgressNotSet ), StackCommitSize( -1 ), StackReserveSize( -1 ), SubSystem( subSystemNotSet ), SupportUnloadOfDelayLoadedDLL( unset ), SuppressStartupBanner( unset ), SwapRunFromCD( unset ), SwapRunFromNet( unset ), TargetMachine( machineNotSet ), TerminalServerAware( termSvrAwareDefault ), TurnOffAssemblyGeneration( unset ), TypeLibraryResourceID( 0 ) { } QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) { strm << _begTool3; strm << _VCLinkerToolName; strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, " " ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _AddModuleNamesToAssembly, tool.AddModuleNamesToAssembly ); strm << SPair( _BaseAddress, tool.BaseAddress ); strm << XPair( _DelayLoadDLLs, tool.DelayLoadDLLs ); if ( tool.EnableCOMDATFolding != optFoldingDefault ) strm << EPair( _EnableCOMDATFolding, tool.EnableCOMDATFolding ); strm << SPair( _EntryPointSymbol, tool.EntryPointSymbol ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); strm << SPair( _FunctionOrder, tool.FunctionOrder ); strm << TPair( _GenerateDebugInformation, tool.GenerateDebugInformation ); strm << TPair( _GenerateMapFile, tool.GenerateMapFile ); if ( tool.HeapCommitSize != -1 ) strm << LPair( _HeapCommitSize, tool.HeapCommitSize ); if ( tool.HeapReserveSize != -1 ) strm << LPair( _HeapReserveSize, tool.HeapReserveSize ); strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries ); strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames ); strm << TPair( _IgnoreEmbeddedIDL, tool.IgnoreEmbeddedIDL ); strm << TPair( _IgnoreImportLibrary, tool.IgnoreImportLibrary ); strm << SPair( _ImportLibrary, tool.ImportLibrary ); if ( tool.LargeAddressAware != addrAwareDefault ) strm << EPair( _LargeAddressAware, tool.LargeAddressAware ); strm << TPair( _LinkDLL, tool.LinkDLL ); if ( tool.LinkIncremental != linkIncrementalDefault ) strm << EPair( _LinkIncremental, tool.LinkIncremental ); strm << TPair( _LinkTimeCodeGeneration, tool.LinkTimeCodeGeneration ); strm << SPair( _LinkToManagedResourceFile, tool.LinkToManagedResourceFile ); strm << TPair( _MapExports, tool.MapExports ); strm << SPair( _MapFileName, tool.MapFileName ); strm << TPair( _MapLines, tool.MapLines ); strm << SPair( _MergedIDLBaseFileName, tool.MergedIDLBaseFileName ); strm << SPair( _MergeSections, tool.MergeSections ); strm << SPair( _MidlCommandFile, tool.MidlCommandFile ); strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile ); if ( tool.OptimizeForWindows98 != optWin98Default ) strm << EPair( _OptimizeForWindows98, tool.OptimizeForWindows98 ); if ( tool.OptimizeReferences != optReferencesDefault ) strm << EPair( _OptimizeReferences, tool.OptimizeReferences ); strm << SPair( _OutputFile, tool.OutputFile ); strm << SPair( _ProgramDatabaseFile, tool.ProgramDatabaseFile ); strm << TPair( _RegisterOutput, tool.RegisterOutput ); strm << TPair( _ResourceOnlyDLL, tool.ResourceOnlyDLL ); strm << TPair( _SetChecksum, tool.SetChecksum ); if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress ); if ( tool.StackCommitSize != -1 ) strm << LPair( _StackCommitSize, tool.StackCommitSize ); if ( tool.StackReserveSize != -1 ) strm << LPair( _StackReserveSize, tool.StackReserveSize ); strm << SPair( _StripPrivateSymbols, tool.StripPrivateSymbols ); strm << EPair( _SubSystem, tool.SubSystem ); strm << TPair( _SupportUnloadOfDelayLoadedDLL, tool.SupportUnloadOfDelayLoadedDLL ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << TPair( _SwapRunFromCD, tool.SwapRunFromCD ); strm << TPair( _SwapRunFromNet, tool.SwapRunFromNet ); if ( tool.TargetMachine != machineNotSet ) strm << EPair( _TargetMachine, tool.TargetMachine ); if ( tool.TerminalServerAware != termSvrAwareDefault ) strm << EPair( _TerminalServerAware, tool.TerminalServerAware ); strm << TPair( _TurnOffAssemblyGeneration, tool.TurnOffAssemblyGeneration ); strm << SPair( _TypeLibraryFile, tool.TypeLibraryFile ); if ( tool.TypeLibraryResourceID != rcUseDefault ) strm << LPair( _TypeLibraryResourceID, tool.TypeLibraryResourceID ); strm << SPair( _Version4, tool.Version ); strm << "/>"; return strm; } // Hashing routine to do fast option lookups ---- // Slightly rewritten to stop on ':' ',' and '\0' // Original routine in qtranslator.cpp ---------- static uint elfHash( const char* name ) { const uchar *k; uint h = 0; uint g; if ( name ) { k = (const uchar *) name; while ( (*k) && (*k)!= ':' && (*k)!=',' && (*k)!=' ' ) { h = ( h << 4 ) + *k++; if ( (g = (h & 0xf0000000)) != 0 ) h ^= g >> 24; h &= ~g; } } if ( !h ) h = 1; return h; } + +//#define USE_DISPLAY_HASH +#ifdef USE_DISPLAY_HASH static void displayHash( const char* str ) { printf( "case 0x%07x: // %s\n break;\n", elfHash(str), str ); } +#endif bool VCLinkerTool::parseOption( const char* option ) { -#if 0 +#ifdef USE_DISPLAY_HASH // Main options displayHash( "/ALIGN" ); displayHash( "/ALLOWBIND" ); displayHash( "/ASSEMBLYMODULE" ); displayHash( "/ASSEMBLYRESOURCE" ); displayHash( "/BASE" ); displayHash( "/DEBUG" ); displayHash( "/DEF" ); displayHash( "/DEFAULTLIB" ); displayHash( "/DELAY" ); displayHash( "/DELAYLOAD" ); displayHash( "/DLL" ); displayHash( "/DRIVER" ); displayHash( "/ENTRY" ); displayHash( "/EXETYPE" ); displayHash( "/EXPORT" ); displayHash( "/FIXED" ); displayHash( "/FORCE" ); displayHash( "/HEAP" ); displayHash( "/IDLOUT" ); displayHash( "/IGNOREIDL" ); displayHash( "/IMPLIB" ); displayHash( "/INCLUDE" ); displayHash( "/INCREMENTAL" ); displayHash( "/LARGEADDRESSAWARE" ); displayHash( "/LIBPATH" ); displayHash( "/LTCG" ); displayHash( "/MACHINE" ); displayHash( "/MAP" ); displayHash( "/MAPINFO" ); displayHash( "/MERGE" ); displayHash( "/MIDL" ); displayHash( "/NOASSEMBLY" ); displayHash( "/NODEFAULTLIB" ); displayHash( "/NOENTRY" ); displayHash( "/NOLOGO" ); displayHash( "/OPT" ); displayHash( "/ORDER" ); displayHash( "/OUT" ); displayHash( "/PDB" ); displayHash( "/PDBSTRIPPED" ); displayHash( "/RELEASE" ); displayHash( "/SECTION" ); displayHash( "/STACK" ); displayHash( "/STUB" ); displayHash( "/SUBSYSTEM" ); displayHash( "/SWAPRUN" ); displayHash( "/TLBID" ); displayHash( "/TLBOUT" ); displayHash( "/TSAWARE" ); displayHash( "/VERBOSE" ); displayHash( "/VERSION" ); displayHash( "/VXD" ); displayHash( "/WS " ); #endif -#if 0 +#ifdef USE_DISPLAY_HASH // Sub options displayHash( "UNLOAD" ); displayHash( "NOBIND" ); displayHash( "no" ); displayHash( "NOSTATUS" ); displayHash( "STATUS" ); displayHash( "AM33" ); displayHash( "ARM" ); displayHash( "CEE" ); displayHash( "IA64" ); displayHash( "X86" ); displayHash( "M32R" ); displayHash( "MIPS" ); displayHash( "MIPS16" ); displayHash( "MIPSFPU" ); displayHash( "MIPSFPU16" ); displayHash( "MIPSR41XX" ); displayHash( "PPC" ); displayHash( "SH3" ); displayHash( "SH4" ); displayHash( "SH5" ); displayHash( "THUMB" ); displayHash( "TRICORE" ); displayHash( "EXPORTS" ); displayHash( "LINES" ); displayHash( "REF" ); displayHash( "NOREF" ); displayHash( "ICF" ); displayHash( "WIN98" ); displayHash( "NOWIN98" ); displayHash( "CONSOLE" ); displayHash( "EFI_APPLICATION" ); displayHash( "EFI_BOOT_SERVICE_DRIVER" ); displayHash( "EFI_ROM" ); displayHash( "EFI_RUNTIME_DRIVER" ); displayHash( "NATIVE" ); displayHash( "POSIX" ); displayHash( "WINDOWS" ); displayHash( "WINDOWSCE" ); displayHash( "NET" ); displayHash( "CD" ); displayHash( "NO" ); #endif - + bool found = TRUE; switch ( elfHash(option) ) { case 0x3360dbe: // /ALIGN[:number] case 0x1485c34: // /ALLOWBIND[:NO] case 0x6b21972: // /DEFAULTLIB:library case 0x396ea92: // /DRIVER[:UPONLY | :WDM] case 0xaca9d75: // /EXETYPE[:DYNAMIC | :DEV386] case 0x3ad5444: // /EXPORT:entryname[,@ordinal[,NONAME]][,DATA] case 0x33aec94: // /FIXED[:NO] case 0x33b4675: // /FORCE:[MULTIPLE|UNRESOLVED] case 0x7988f7e: // /SECTION:name,[E][R][W][S][D][K][L][P][X][,ALIGN=#] case 0x0348992: // /STUB:filename case 0x0034bc4: // /VXD case 0x0034c50: // /WS AdditionalOptions += option; break; case 0x679c075: // /ASSEMBLYMODULE:filename AddModuleNamesToAssembly += option+15; break; case 0x062d065: // /ASSEMBLYRESOURCE:filename LinkToManagedResourceFile = option+18; break; case 0x0336675: // /BASE:{address | @filename,key} // Do we need to do a manual lookup when '@filename,key'? // Seems BaseAddress only can contain the location... // We don't use it in Qt, so keep it simple for now BaseAddress = option+6; break; case 0x3389797: // /DEBUG GenerateDebugInformation = _True; break; case 0x0033896: // /DEF:filename ModuleDefinitionFile = option+5; break; case 0x338a069: // /DELAY:{UNLOAD | NOBIND} // MS documentation does not specify what to do with // this option, so we'll put it in AdditionalOptions AdditionalOptions += option; break; case 0x06f4bf4: // /DELAYLOAD:dllname DelayLoadDLLs += option+11; break; // case 0x003390c: // /DLL // This option is not used for vcproj files // break; case 0x33a3979: // /ENTRY:function EntryPointSymbol = option+7; break; case 0x033c960: // /HEAP:reserve[,commit] { QStringList both = QStringList::split( ",", option+6 ); HeapReserveSize = both[0].toLong(); if ( both.count() == 2 ) HeapCommitSize = both[1].toLong(); } break; case 0x3d91494: // /IDLOUT:[path\]filename MergedIDLBaseFileName = option+8; break; case 0x345a04c: // /IGNOREIDL IgnoreEmbeddedIDL = _True; break; case 0x3e250e2: // /IMPLIB:filename ImportLibrary = option+8; break; case 0xe281ab5: // /INCLUDE:symbol ForceSymbolReferences += option+9; break; case 0xb28103c: // /INCREMENTAL[:no] if ( *(option+12) == ':' && *(option+13) == 'n' ) LinkIncremental = linkIncrementalNo; else LinkIncremental = linkIncrementalYes; break; case 0x26e4675: // /LARGEADDRESSAWARE[:no] if ( *(option+18) == ':' && *(option+19) == 'n' ) LargeAddressAware = addrAwareNoLarge; else LargeAddressAware = addrAwareLarge; break; case 0x0d745c8: // /LIBPATH:dir AdditionalLibraryDirectories += option+9; break; case 0x0341877: // /LTCG[:NOSTATUS|:STATUS] config->WholeProgramOptimization = _True; LinkTimeCodeGeneration = _True; if ( *(option+5) == ':' && *(option+6) == 'S' ) ShowProgress = linkProgressAll; break; case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE} switch ( elfHash(option+9) ) { // Very limited documentation on all options but X86, // so we put the others in AdditionalOptions... case 0x0046063: // AM33 case 0x000466d: // ARM case 0x0004795: // CEE case 0x004d494: // IA64 case 0x0050672: // M32R case 0x0051e53: // MIPS case 0x51e5646: // MIPS16 case 0x1e57b05: // MIPSFPU case 0x57b09a6: // MIPSFPU16 case 0x5852738: // MIPSR41XX case 0x0005543: // PPC case 0x00057b3: // SH3 case 0x00057b4: // SH4 case 0x00057b5: // SH5 case 0x058da12: // THUMB case 0x96d8435: // TRICORE AdditionalOptions += option; break; case 0x0005bb6: // X86 TargetMachine = machineX86; break; default: - return FALSE; + found = FALSE; } break; case 0x0034160: // /MAP[:filename] GenerateMapFile = _True; MapFileName = option+5; break; case 0x164e1ef: // /MAPINFO:{EXPORTS|LINES} if ( *(option+9) == 'E' ) MapExports = _True; else if ( *(option+9) == 'L' ) MapLines = _True; break; case 0x341a6b5: // /MERGE:from=to MergeSections = option+7; break; case 0x0341d8c: // /MIDL:@file MidlCommandFile = option+7; break; case 0x84e2679: // /NOASSEMBLY TurnOffAssemblyGeneration = _True; break; case 0x2b21942: // /NODEFAULTLIB[:library] if ( *(option+13) == '\0' ) IgnoreAllDefaultLibraries = _True; else IgnoreDefaultLibraryNames += option+14; break; case 0x33a3a39: // /NOENTRY ResourceOnlyDLL = _True; break; case 0x434138f: // /NOLOGO SuppressStartupBanner = _True; break; case 0x0034454: // /OPT:{REF | NOREF | ICF[=iterations] | NOICF | WIN98 | NOWIN98} { char third = *(option+7); switch ( third ) { case 'F': // REF if ( *(option+5) == 'R' ) { OptimizeReferences = optReferences; } else { // ICF[=iterations] EnableCOMDATFolding = optFolding; // [=iterations] case is not documented } break; case 'R': // NOREF OptimizeReferences = optNoReferences; break; case 'I': // NOICF EnableCOMDATFolding = optNoFolding; break; case 'N': // WIN98 OptimizeForWindows98 = optWin98Yes; break; case 'W': // NOWIN98 OptimizeForWindows98 = optWin98No; break; default: - return FALSE; + found = FALSE; } } break; case 0x34468a2: // /ORDER:@filename FunctionOrder = option+8; break; case 0x00344a4: // /OUT:filename OutputFile = option+5; break; case 0x0034482: // /PDB:filename ProgramDatabaseFile = option+5; break; case 0xa2ad314: // /PDBSTRIPPED:pdb_file_name StripPrivateSymbols = option+13; break; case 0x6a09535: // /RELEASE SetChecksum = _True; break; case 0x348857b: // /STACK:reserve[,commit] { QStringList both = QStringList::split( ",", option+7 ); StackReserveSize = both[0].toLong(); if ( both.count() == 2 ) StackCommitSize = both[1].toLong(); } break; case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]] { // Split up in subsystem, and version number QStringList both = QStringList::split( ",", option+11 ); switch ( elfHash(both[0].latin1()) ) { case 0x8438445: // CONSOLE SubSystem = subSystemConsole; break; case 0xbe29493: // WINDOWS SubSystem = subSystemWindows; break; // The following are undocumented, so add them to AdditionalOptions case 0x240949e: // EFI_APPLICATION case 0xe617652: // EFI_BOOT_SERVICE_DRIVER case 0x9af477d: // EFI_ROM case 0xd34df42: // EFI_RUNTIME_DRIVER case 0x5268ea5: // NATIVE case 0x05547e8: // POSIX case 0x2949c95: // WINDOWSCE AdditionalOptions += option; break; default: - return FALSE; + found = FALSE; } } break; case 0x8b654de: // /SWAPRUN:{NET | CD} if ( *(option+9) == 'N' ) SwapRunFromNet = _True; else if ( *(option+9) == 'C' ) SwapRunFromCD = _True; else - return FALSE; + found = FALSE; break; case 0x34906d4: // /TLBID:id TypeLibraryResourceID = QString( option+7 ).toLong(); break; case 0x4907494: // /TLBOUT:[path\]filename TypeLibraryFile = option+8; break; case 0x976b525: // /TSAWARE[:NO] if ( *(option+8) == ':' ) TerminalServerAware = termSvrAwareNo; else TerminalServerAware = termSvrAwareYes; break; case 0xaa67735: // /VERBOSE[:lib] if ( *(option+9) == ':' ) { ShowProgress = linkProgressLibs; AdditionalOptions += option; } else { ShowProgress = linkProgressAll; } break; case 0xaa77f7e: // /VERSION:major[.minor] Version = option+9; break; default: - return FALSE; + found = FALSE; } - return TRUE; + if( !found ) + warn_msg( WarnLogic, "Could not parse Linker options: %s", option ); + return found; } // VCMIDLTool ------------------------------------------------------- VCMIDLTool::VCMIDLTool() : DefaultCharType( midlCharUnsigned ), EnableErrorChecks( midlDisableAll ), ErrorCheckAllocations( unset ), ErrorCheckBounds( unset ), ErrorCheckEnumRange( unset ), ErrorCheckRefPointers( unset ), ErrorCheckStubData( unset ), GenerateStublessProxies( unset ), GenerateTypeLibrary( unset ), IgnoreStandardIncludePath( unset ), MkTypLibCompatible( unset ), StructMemberAlignment( midlAlignNotSet ), SuppressStartupBanner( unset ), TargetEnvironment( midlTargetNotSet ), ValidateParameters( unset ), WarnAsError( unset ), WarningLevel( midlWarningLevel_0 ) { } QTextStream &operator<<( QTextStream &strm, const VCMIDLTool &tool ) { strm << _begTool3; strm << _VCMIDLToolName; strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _CPreprocessOptions, tool.CPreprocessOptions ); strm << EPair( _DefaultCharType, tool.DefaultCharType ); strm << SPair( _DLLDataFileName, tool.DLLDataFileName ); strm << EPair( _EnableErrorChecks, tool.EnableErrorChecks ); strm << TPair( _ErrorCheckAllocations, tool.ErrorCheckAllocations ); strm << TPair( _ErrorCheckBounds, tool.ErrorCheckBounds ); strm << TPair( _ErrorCheckEnumRange, tool.ErrorCheckEnumRange ); strm << TPair( _ErrorCheckRefPointers, tool.ErrorCheckRefPointers ); strm << TPair( _ErrorCheckStubData, tool.ErrorCheckStubData ); strm << XPair( _FullIncludePath, tool.FullIncludePath ); strm << TPair( _GenerateStublessProxies, tool.GenerateStublessProxies ); strm << TPair( _GenerateTypeLibrary, tool.GenerateTypeLibrary ); strm << SPair( _HeaderFileName, tool.HeaderFileName ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << SPair( _InterfaceIdentifierFileName, tool.InterfaceIdentifierFileName ); strm << TPair( _MkTypLibCompatible, tool.MkTypLibCompatible ); strm << SPair( _OutputDirectory4, tool.OutputDirectory ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); strm << SPair( _ProxyFileName, tool.ProxyFileName ); strm << SPair( _RedirectOutputAndErrors, tool.RedirectOutputAndErrors ); if ( tool.StructMemberAlignment != midlAlignNotSet) strm << EPair( _StructMemberAlignment, tool.StructMemberAlignment ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); if ( tool.TargetEnvironment != midlTargetNotSet ) strm << EPair( _TargetEnvironment, tool.TargetEnvironment ); strm << SPair( _TypeLibraryName, tool.TypeLibraryName ); strm << XPair( _UndefinePreprocessorDefinitions, tool.UndefinePreprocessorDefinitions ); strm << TPair( _ValidateParameters, tool.ValidateParameters ); strm << TPair( _WarnAsError, tool.WarnAsError ); strm << EPair( _WarningLevel, tool.WarningLevel ); strm << "/>"; return strm; } bool VCMIDLTool::parseOption( const char* option ) { -#if 0 +#ifdef USE_DISPLAY_HASH displayHash( "/D name[=def]" ); displayHash( "/I directory-list" ); displayHash( "/Oi" ); displayHash( "/Oic" ); displayHash( "/Oicf" ); displayHash( "/Oif" ); displayHash( "/Os" ); displayHash( "/U name" ); displayHash( "/WX" ); displayHash( "/W{0|1|2|3|4}" ); displayHash( "/Zp {N}" ); displayHash( "/Zs" ); displayHash( "/acf filename" ); displayHash( "/align {N}" ); displayHash( "/app_config" ); displayHash( "/c_ext" ); displayHash( "/char ascii7" ); displayHash( "/char signed" ); displayHash( "/char unsigned" ); displayHash( "/client none" ); displayHash( "/client stub" ); displayHash( "/confirm" ); displayHash( "/cpp_cmd cmd_line" ); displayHash( "/cpp_opt options" ); displayHash( "/cstub filename" ); displayHash( "/dlldata filename" ); displayHash( "/env win32" ); displayHash( "/env win64" ); displayHash( "/error all" ); displayHash( "/error allocation" ); displayHash( "/error bounds_check" ); displayHash( "/error enum" ); displayHash( "/error none" ); displayHash( "/error ref" ); displayHash( "/error stub_data" ); displayHash( "/h filename" ); displayHash( "/header filename" ); displayHash( "/iid filename" ); displayHash( "/lcid" ); displayHash( "/mktyplib203" ); displayHash( "/ms_ext" ); displayHash( "/ms_union" ); displayHash( "/msc_ver <nnnn>" ); displayHash( "/newtlb" ); displayHash( "/no_cpp" ); displayHash( "/no_def_idir" ); displayHash( "/no_default_epv" ); displayHash( "/no_format_opt" ); displayHash( "/no_warn" ); displayHash( "/nocpp" ); displayHash( "/nologo" ); displayHash( "/notlb" ); displayHash( "/o filename" ); displayHash( "/oldnames" ); displayHash( "/oldtlb" ); displayHash( "/osf" ); displayHash( "/out directory" ); displayHash( "/pack {N}" ); displayHash( "/prefix all" ); displayHash( "/prefix client" ); displayHash( "/prefix server" ); displayHash( "/prefix switch" ); displayHash( "/protocol all" ); displayHash( "/protocol dce" ); displayHash( "/protocol ndr64" ); displayHash( "/proxy filename" ); displayHash( "/robust" ); displayHash( "/rpcss" ); displayHash( "/savePP" ); displayHash( "/server none" ); displayHash( "/server stub" ); displayHash( "/sstub filename" ); displayHash( "/syntax_check" ); displayHash( "/target {system}" ); displayHash( "/tlb filename" ); displayHash( "/use_epv" ); displayHash( "/win32" ); displayHash( "/win64" ); #endif + bool found = TRUE; int offset = 0; switch( elfHash(option) ) { case 0x0000334: // /D name[=def] PreprocessorDefinitions += option+3; break; case 0x0000339: // /I directory-list AdditionalIncludeDirectories += option+3; break; case 0x0345f96: // /Oicf case 0x00345f6: // /Oif GenerateStublessProxies = _True; break; case 0x0000345: // /U name UndefinePreprocessorDefinitions += option+3; break; case 0x00034c8: // /WX WarnAsError = _True; break; case 0x3582fde: // /align {N} offset = 3; // Fallthrough case 0x0003510: // /Zp {N} switch ( *(option+offset+4) ) { case '1': StructMemberAlignment = ( *(option+offset+5) == '\0' ) ? midlAlignSingleByte : midlAlignSixteenBytes; break; case '2': StructMemberAlignment = midlAlignTwoBytes; break; case '4': StructMemberAlignment = midlAlignFourBytes; break; case '8': StructMemberAlignment = midlAlignEightBytes; break; default: - return FALSE; + found = FALSE; } break; case 0x0359e82: // /char {ascii7|signed|unsigned} switch( *(option+6) ) { case 'a': DefaultCharType = midlCharAscii7; break; case 's': DefaultCharType = midlCharSigned; break; case 'u': DefaultCharType = midlCharUnsigned; break; default: - return FALSE; + found = FALSE; } break; case 0xa766524: // /cpp_opt options CPreprocessOptions += option+9; break; case 0xb32abf1: // /dlldata filename DLLDataFileName = option + 9; break; case 0x0035c56: // /env {win32|win64} TargetEnvironment = ( *(option+8) == '6' ) ? midlTargetWin64 : midlTargetWin32; break; case 0x35c9962: // /error {all|allocation|bounds_check|enum|none|ref|stub_data} EnableErrorChecks = midlEnableCustom; switch ( *(option+7) ) { case 'a': if ( *(option+10) == '\0' ) EnableErrorChecks = midlEnableAll; else ErrorCheckAllocations = _True; break; case 'b': ErrorCheckBounds = _True; break; case 'e': ErrorCheckEnumRange = _True; break; case 'n': EnableErrorChecks = midlDisableAll; break; case 'r': - break; ErrorCheckRefPointers = _True; - case 's': break; + case 's': ErrorCheckStubData = _True; + break; default: - return FALSE; + found = FALSE; } break; case 0x5eb7af2: // /header filename offset = 5; case 0x0000358: // /h filename HeaderFileName = option + offset + 3; break; case 0x0035ff4: // /iid filename InterfaceIdentifierFileName = option+5; break; case 0x64b7933: // /mktyplib203 MkTypLibCompatible = _True; break; case 0x8e0b0a2: // /no_def_idir IgnoreStandardIncludePath = _True; break; case 0x65635ef: // /nologo SuppressStartupBanner = _True; break; case 0x3656b22: // /notlb GenerateTypeLibrary = _True; break; case 0x000035f: // /o filename RedirectOutputAndErrors = option+3; break; case 0x00366c4: // /out directory OutputDirectory = option+5; break; case 0x36796f9: // /proxy filename ProxyFileName = option+7; break; case 0x6959c94: // /robust ValidateParameters = _True; break; case 0x6a88df4: // /target {system} if ( *(option+11) == '6' ) TargetEnvironment = midlTargetWin64; else TargetEnvironment = midlTargetWin32; break; case 0x0036b22: // /tlb filename TypeLibraryName = option+5; break; case 0x36e0162: // /win32 TargetEnvironment = midlTargetWin32; break; case 0x36e0194: // /win64 TargetEnvironment = midlTargetWin64; break; case 0x0003459: // /Oi case 0x00345f3: // /Oic case 0x0003463: // /Os case 0x0003513: // /Zs case 0x0035796: // /acf filename case 0x5b1cb97: // /app_config case 0x3595cf4: // /c_ext case 0x5a2fc64: // /client {none|stub} case 0xa64d3dd: // /confirm case 0xa765b64: // /cpp_cmd cmd_line case 0x35aabb2: // /cstub filename case 0x03629f4: // /lcid case 0x6495cc4: // /ms_ext case 0x96c7a1e: // /ms_union case 0x4996fa2: // /msc_ver <nnnn> case 0x64ceb12: // /newtlb case 0x6555a40: // /no_cpp case 0xf64d6a6: // /no_default_epv case 0x6dd9384: // /no_format_opt case 0x556dbee: // /no_warn case 0x3655a70: // /nocpp case 0x2b455a3: // /oldnames case 0x662bb12: // /oldtlb case 0x0036696: // /osf case 0x036679b: // /pack {N} case 0x678bd38: // /prefix {all|client|server|switch} case 0x96b702c: // /protocol {all|dce|ndr64} case 0x3696aa3: // /rpcss case 0x698ca60: // /savePP case 0x69c9cf2: // /server {none|stub} case 0x36aabb2: // /sstub filename case 0xce9b12b: // /syntax_check case 0xc9b5f16: // /use_epv AdditionalOptions += option; break; default: // /W{0|1|2|3|4} case if ( *(option+1) == 'W' ) { switch ( *(option+2) ) { case '0': WarningLevel = midlWarningLevel_0; break; case '1': WarningLevel = midlWarningLevel_1; break; case '2': WarningLevel = midlWarningLevel_2; break; case '3': WarningLevel = midlWarningLevel_3; break; case '4': WarningLevel = midlWarningLevel_4; break; default: - return FALSE; + found = FALSE; } } break; } + if( !found ) + warn_msg( WarnLogic, "Could not parse MIDL option: %s", option ); return TRUE; } // VCLibrarianTool -------------------------------------------------- VCLibrarianTool::VCLibrarianTool() : IgnoreAllDefaultLibraries( unset ), SuppressStartupBanner( _True ) { } QTextStream &operator<<( QTextStream &strm, const VCLibrarianTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, QString( "VCLibrarianTool" ) ); strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies ); strm << XPair( _AdditionalLibraryDirectories, tool.AdditionalLibraryDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); strm << XPair( _ExportNamedFunctions, tool.ExportNamedFunctions ); strm << XPair( _ForceSymbolReferences, tool.ForceSymbolReferences ); strm << TPair( _IgnoreAllDefaultLibraries, tool.IgnoreAllDefaultLibraries ); strm << XPair( _IgnoreDefaultLibraryNames, tool.IgnoreDefaultLibraryNames ); strm << SPair( _ModuleDefinitionFile, tool.ModuleDefinitionFile ); strm << SPair( _OutputFile, tool.OutputFile ); strm << TPair( _SuppressStartupBanner, tool.SuppressStartupBanner ); strm << "/>"; return strm; } // VCCustomBuildTool ------------------------------------------------ VCCustomBuildTool::VCCustomBuildTool() { ToolName = "VCCustomBuildTool"; } QTextStream &operator<<( QTextStream &strm, const VCCustomBuildTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, tool.ToolName ); strm << XPair( _AdditionalDependencies4, tool.AdditionalDependencies, ";" ); strm << SPair( _CommandLine4, tool.CommandLine ); strm << SPair( _Description4, tool.Description ); strm << SPair( _Outputs4, tool.Outputs ); strm << SPair( _ToolPath, tool.ToolPath ); strm << "/>"; return strm; } // VCResourceCompilerTool ------------------------------------------- VCResourceCompilerTool::VCResourceCompilerTool() : Culture( rcUseDefault ), IgnoreStandardIncludePath( unset ), ShowProgress( linkProgressNotSet ) { PreprocessorDefinitions = "NDEBUG"; } QTextStream &operator<<( QTextStream &strm, const VCResourceCompilerTool &tool ) { strm << _begTool3; strm << _VCResourceCompilerToolName; strm << SPair( _ToolPath, tool.ToolPath ); strm << XPair( _AdditionalIncludeDirectories, tool.AdditionalIncludeDirectories ); - strm << XPair( _AdditionalOptions, tool.AdditionalOptions ); + strm << XPair( _AdditionalOptions, tool.AdditionalOptions, " " ); if ( tool.Culture != rcUseDefault ) strm << EPair( _Culture, tool.Culture ); strm << XPair( _FullIncludePath, tool.FullIncludePath ); strm << TPair( _IgnoreStandardIncludePath, tool.IgnoreStandardIncludePath ); strm << XPair( _PreprocessorDefinitions, tool.PreprocessorDefinitions ); strm << SPair( _ResourceOutputFileName, tool.ResourceOutputFileName ); if ( tool.ShowProgress != linkProgressNotSet ) strm << EPair( _ShowProgress, tool.ShowProgress ); strm << "/>"; return strm; } // VCEventTool ------------------------------------------------- QTextStream &operator<<( QTextStream &strm, const VCEventTool &tool ) { strm << _begTool3; strm << SPair( _ToolName, tool.ToolName ); strm << SPair( _ToolPath, tool.ToolPath ); strm << SPair( _CommandLine4, tool.CommandLine ); strm << SPair( _Description4, tool.Description ); strm << TPair( _ExcludedFromBuild, tool.ExcludedFromBuild ); strm << "/>"; return strm; } // VCPostBuildEventTool --------------------------------------------- VCPostBuildEventTool::VCPostBuildEventTool() { ToolName = "VCPostBuildEventTool"; } // VCPreBuildEventTool ---------------------------------------------- VCPreBuildEventTool::VCPreBuildEventTool() { ToolName = "VCPreBuildEventTool"; } // VCPreLinkEventTool ----------------------------------------------- VCPreLinkEventTool::VCPreLinkEventTool() { ToolName = "VCPreLinkEventTool"; } // VCConfiguration -------------------------------------------------- VCConfiguration::VCConfiguration() : ATLMinimizesCRunTimeLibraryUsage( unset ), BuildBrowserInformation( unset ), CharacterSet( charSetNotSet ), ConfigurationType( typeApplication ), RegisterOutput( unset ), UseOfATL( useATLNotSet ), UseOfMfc( useMfcStdWin ), WholeProgramOptimization( unset ) { compiler.config = this; linker.config = this; idl.config = this; } QTextStream &operator<<( QTextStream &strm, const VCConfiguration &tool ) { strm << _begConfiguration; strm << SPair( _Name3, tool.Name ); strm << SPair( _OutputDirectory3, tool.OutputDirectory ); strm << TPair( _ATLMinimizesCRunTimeLibraryUsage, tool.ATLMinimizesCRunTimeLibraryUsage ); strm << TPair( _BuildBrowserInformation, tool.BuildBrowserInformation ); if ( tool.CharacterSet != charSetNotSet) strm << EPair( _CharacterSet, tool.CharacterSet ); strm << EPair( _ConfigurationType, tool.ConfigurationType ); strm << SPair( _DeleteExtensionsOnClean, tool.DeleteExtensionsOnClean ); strm << SPair( _ImportLibrary, tool.ImportLibrary ); strm << SPair( _IntermediateDirectory, tool.IntermediateDirectory ); strm << SPair( _PrimaryOutput, tool.PrimaryOutput ); strm << SPair( _ProgramDatabase, tool.ProgramDatabase ); strm << TPair( _RegisterOutput, tool.RegisterOutput ); if ( tool.UseOfATL != useATLNotSet) strm << EPair( _UseOfATL, tool.UseOfATL ); strm << EPair( _UseOfMfc, tool.UseOfMfc ); strm << TPair( _WholeProgramOptimization, tool.WholeProgramOptimization ); strm << ">"; strm << tool.compiler; strm << tool.custom; if ( tool.ConfigurationType == typeStaticLibrary ) strm << tool.librarian; else strm << tool.linker; strm << tool.idl; strm << tool.postBuild; strm << tool.preBuild; strm << tool.preLink; strm << tool.resource; strm << _endConfiguration; return strm; } // VCFilter --------------------------------------------------------- VCFilter::VCFilter() : ParseFiles( unset ) { } void VCFilter::generateMOC( QTextStream &strm, QString str ) const { QString mocOutput = Project->findMocDestination( str ); QString mocApp = Project->var( "QMAKE_MOC" ); if( mocOutput.isEmpty() ) { // In specialcases we DO moc .cpp files // when the result is an .moc file if ( !str.endsWith(".moc") ) return; mocOutput = str; str = Project->findMocSource( mocOutput ); } strm << _begFileConfiguration; strm << _Name5; strm << Config->Name; strm << "\">"; strm << _begTool5; strm << _VCCustomBuildTool; strm << _Description6; strm << "Moc'ing " << str << "...\""; strm << _CommandLine6; strm << mocApp; strm << " " << str << " -o " << mocOutput << "\""; strm << _AdditionalDependencies6; strm << mocApp << "\""; strm << _Outputs6; strm << mocOutput << "\""; strm << "/>"; strm << _endFileConfiguration; } void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const { QString uicApp = Project->var("QMAKE_UIC"); QString mocApp = Project->var( "QMAKE_MOC" ); QString fname = str.section( '\\', -1 ); QString mocDir = Project->var( "MOC_DIR" ); - int dot = fname.findRev( '.' ); - if( dot != -1 ) - fname.truncate( dot ); + QString uiDir = Project->var( "UI_DIR" ); + QString uiHeaders; + QString uiSources; + // Determining the paths for the output files. int slash = str.findRev( '\\' ); QString pname = ( slash != -1 ) ? str.left( slash+1 ) : QString(".\\"); + if( !uiDir.isEmpty() ) { + uiHeaders = uiDir; + uiSources = uiDir; + } else { + uiHeaders = Project->var( "UI_HEADERS_DIR" ); + uiSources = Project->var( "UI_SOURCES_DIR" ); + if( uiHeaders.isEmpty() ) + uiHeaders = pname; + if( uiSources.isEmpty() ) + uiSources = pname; + } + if( !uiHeaders.endsWith( "\\" ) ) + uiHeaders += "\\"; + if( !uiSources.endsWith( "\\" ) ) + uiSources += "\\"; + + // Determine the file name. + int dot = fname.findRev( '.' ); + if( dot != -1 ) + fname.truncate( dot ); strm << _begFileConfiguration; strm << _Name5; strm << Config->Name; strm << "\">"; strm << _begTool5; strm << _VCCustomBuildTool; strm << _Description6; strm << "Uic'ing " << str << "...\""; strm << _CommandLine6; - strm << uicApp << " " << str << " -o " << pname << fname << ".h && "; // Create .h from .ui file - strm << uicApp << " " << str << " -i " << fname << ".h -o " << pname << fname << ".cpp && "; // Create .cpp from .ui file - strm << mocApp << " " << pname << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; + strm << uicApp << " " << str << " -o " << uiHeaders << fname << ".h && "; // Create .h from .ui file + strm << uicApp << " " << str << " -i " << fname << ".h -o " << uiSources << fname << ".cpp && "; // Create .cpp from .ui file + strm << mocApp << " " << uiHeaders << fname << ".h -o " << mocDir << "moc_" << fname << ".cpp\""; strm << _AdditionalDependencies6; strm << mocApp << ";" << uicApp << "\""; strm << _Outputs6; - strm << pname << fname << ".h;" << pname << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; + strm << uiHeaders << fname << ".h;" << uiSources << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; strm << "/>"; strm << _endFileConfiguration; } QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) { if ( tool.Files.count() == 0 ) return strm; strm << _begFilter; strm << SPair( _Name3, tool.Name ); strm << TPair( _ParseFiles, tool.ParseFiles ); strm << SPair( _Filter, tool.Filter ); strm << ">"; for ( QStringList::ConstIterator it = tool.Files.begin(); it != tool.Files.end(); ++it ) { strm << _begFile; strm << SPair( _RelativePath, *it ); strm << ">"; if ( tool.CustomBuild == moc ) tool.generateMOC( strm, *it ); else if ( tool.CustomBuild == uic ) tool.generateUIC( strm, *it ); strm << _endFile; } strm << _endFilter; return strm; } // VCProject -------------------------------------------------------- VCProject::VCProject() { - QUuid uniqueId; #if defined(Q_WS_WIN32) GUID guid; + QUuid uniqueId; HRESULT h = CoCreateGuid( &guid ); if ( h == S_OK ) uniqueId = QUuid( guid ); ProjectGUID = uniqueId.toString(); #else // Qt doesn't support GUID on other platforms yet ProjectGUID = ""; #endif } QTextStream &operator<<( QTextStream &strm, const VCProject &tool ) { strm << _xmlInit; strm << _begVisualStudioProject; strm << _ProjectType; strm << SPair( _Version1, tool.Version ); strm << SPair( _Name1, tool.Name ); strm << SPair( _ProjectGUID, tool.ProjectGUID ); strm << SPair( _SccProjectName, tool.SccProjectName ); strm << SPair( _SccLocalPath, tool.SccLocalPath ); strm << ">"; strm << _begPlatforms; strm << _begPlatform; strm << SPair( _Name3, tool.PlatformName ); strm << "/>"; strm << _endPlatforms; strm << _begConfigurations; strm << tool.Configuration; strm << _endConfigurations; strm << _begFiles; strm << tool.SourceFiles; strm << tool.HeaderFiles; strm << tool.MOCFiles; strm << tool.UICFiles; strm << tool.FormFiles; strm << tool.TranslationFiles; strm << tool.LexYaccFiles; strm << tool.ResourceFiles; strm << _endFiles; strm << _begGlobals; strm << _endGlobals; strm << _endVisualStudioProject; return strm; } diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 2d09280..1dca68d 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -297,479 +297,477 @@ enum optimizeOption { optimizeMaxSpeed, optimizeFull, optimizeCustom }; enum optRefType { optReferencesDefault, optNoReferences, optReferences }; enum optWin98Type { optWin98Default, optWin98No, optWin98Yes }; enum pchOption { pchNone, pchCreateUsingSpecific, pchGenerateAuto, pchUseUsingSpecific }; enum preprocessOption { preprocessNo, preprocessYes, preprocessNoLineNumbers }; enum ProcessorOptimizeOption { procOptimizeBlended, procOptimizePentium, procOptimizePentiumProAndAbove }; enum RemoteDebuggerType { DbgLocal, DbgRemote, DbgRemoteTCPIP }; enum runtimeLibraryOption { rtMultiThreaded, rtMultiThreadedDebug, rtMultiThreadedDLL, rtMultiThreadedDebugDLL, rtSingleThreaded, rtSingleThreadedDebug }; enum structMemberAlignOption { alignNotSet, alignSingleByte, alignTwoBytes, alignFourBytes, alignEightBytes, alignSixteenBytes }; enum subSystemOption { subSystemNotSet, subSystemConsole, subSystemWindows }; enum termSvrAwarenessType { termSvrAwareDefault, termSvrAwareNo, termSvrAwareYes }; enum toolSetType { toolSetUtility, toolSetMakefile, toolSetLinker, toolSetLibrarian, toolSetAll }; enum TypeOfDebugger { DbgNativeOnly, DbgManagedOnly, DbgMixed, DbgAuto }; enum useOfATL { useATLNotSet, useATLStatic, useATLDynamic }; enum useOfMfc { useMfcStdWin, useMfcStatic, useMfcDynamic }; enum warningLevelOption { warningLevel_0, warningLevel_1, warningLevel_2, warningLevel_3, warningLevel_4 }; class VCToolBase { protected: // Functions VCToolBase(){}; - ~VCToolBase(){}; + virtual ~VCToolBase(){} virtual bool parseOption( const char* option ) = 0; public: - bool parseOptions( QStringList& options ) { - bool result = TRUE; - for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()) && result; it++ ) - result = parseOption( (*it).latin1() ); - return result; + void parseOptions( QStringList& options ) { + for ( QStringList::ConstIterator it=options.begin(); (it!=options.end()); it++ ) + parseOption( (*it).latin1() ); } }; class VCConfiguration; class VCProject; class VCCLCompilerTool : public VCToolBase { public: // Functions VCCLCompilerTool(); - ~VCCLCompilerTool(){}; - virtual bool parseOption( const char* option ); + virtual ~VCCLCompilerTool(){} + bool parseOption( const char* option ); // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList AdditionalUsingDirectories; QString AssemblerListingLocation; asmListingOption AssemblerOutput; basicRuntimeCheckOption BasicRuntimeChecks; browseInfoOption BrowseInformation; QString BrowseInformationFile; triState BufferSecurityCheck; callingConventionOption CallingConvention; CompileAsOptions CompileAs; compileAsManagedOptions CompileAsManaged; triState CompileOnly; debugOption DebugInformationFormat; triState DefaultCharIsUnsigned; triState Detect64BitPortabilityProblems; triState DisableLanguageExtensions; QStringList DisableSpecificWarnings; triState EnableFiberSafeOptimizations; triState EnableFunctionLevelLinking; triState EnableIntrinsicFunctions; triState ExceptionHandling; triState ExpandAttributedSource; favorSizeOrSpeedOption FavorSizeOrSpeed; triState ForceConformanceInForLoopScope; QStringList ForcedIncludeFiles; QStringList ForcedUsingFiles; preprocessOption GeneratePreprocessedFile; triState GlobalOptimizations; triState IgnoreStandardIncludePath; triState ImproveFloatingPointConsistency; inlineExpansionOption InlineFunctionExpansion; triState KeepComments; triState MinimalRebuild; QString ObjectFile; triState OmitFramePointers; optimizeOption Optimization; ProcessorOptimizeOption OptimizeForProcessor; triState OptimizeForWindowsApplication; QString OutputFile; QString PrecompiledHeaderFile; QString PrecompiledHeaderThrough; QStringList PreprocessorDefinitions; QString ProgramDataBaseFileName; runtimeLibraryOption RuntimeLibrary; triState RuntimeTypeInfo; triState ShowIncludes; triState SmallerTypeCheck; triState StringPooling; structMemberAlignOption StructMemberAlignment; triState SuppressStartupBanner; triState TreatWChar_tAsBuiltInType; triState TurnOffAssemblyGeneration; triState UndefineAllPreprocessorDefinitions; QStringList UndefinePreprocessorDefinitions; pchOption UsePrecompiledHeader; triState WarnAsError; warningLevelOption WarningLevel; triState WholeProgramOptimization; VCConfiguration* config; }; class VCLinkerTool : public VCToolBase { public: // Functions VCLinkerTool(); - ~VCLinkerTool(){}; - virtual bool parseOption( const char* option ); + virtual ~VCLinkerTool(){} + bool parseOption( const char* option ); // Variables QStringList AdditionalDependencies; QStringList AdditionalLibraryDirectories; QStringList AdditionalOptions; QStringList AddModuleNamesToAssembly; QString BaseAddress; QStringList DelayLoadDLLs; optFoldingType EnableCOMDATFolding; QString EntryPointSymbol; QStringList ForceSymbolReferences; QString FunctionOrder; triState GenerateDebugInformation; triState GenerateMapFile; long HeapCommitSize; long HeapReserveSize; triState IgnoreAllDefaultLibraries; QStringList IgnoreDefaultLibraryNames; triState IgnoreEmbeddedIDL; triState IgnoreImportLibrary; QString ImportLibrary; addressAwarenessType LargeAddressAware; triState LinkDLL; linkIncrementalType LinkIncremental; triState LinkTimeCodeGeneration; QString LinkToManagedResourceFile; triState MapExports; QString MapFileName; triState MapLines; QString MergedIDLBaseFileName; QString MergeSections; // Should be list? QString MidlCommandFile; QString ModuleDefinitionFile; // Should be list? optWin98Type OptimizeForWindows98; optRefType OptimizeReferences; QString OutputFile; QString ProgramDatabaseFile; triState RegisterOutput; triState ResourceOnlyDLL; triState SetChecksum; linkProgressOption ShowProgress; long StackCommitSize; long StackReserveSize; QString StripPrivateSymbols; // Should be list? subSystemOption SubSystem; triState SupportUnloadOfDelayLoadedDLL; triState SuppressStartupBanner; triState SwapRunFromCD; triState SwapRunFromNet; machineTypeOption TargetMachine; termSvrAwarenessType TerminalServerAware; triState TurnOffAssemblyGeneration; QString TypeLibraryFile; long TypeLibraryResourceID; QString Version; VCConfiguration* config; }; class VCMIDLTool : public VCToolBase { public: // Functions VCMIDLTool(); - ~VCMIDLTool(){}; - virtual bool parseOption( const char* option ); + virtual ~VCMIDLTool(){} + bool parseOption( const char* option ); // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; QStringList CPreprocessOptions; midlCharOption DefaultCharType; QString DLLDataFileName; // Should be list? midlErrorCheckOption EnableErrorChecks; triState ErrorCheckAllocations; triState ErrorCheckBounds; triState ErrorCheckEnumRange; triState ErrorCheckRefPointers; triState ErrorCheckStubData; QStringList FullIncludePath; triState GenerateStublessProxies; triState GenerateTypeLibrary; QString HeaderFileName; triState IgnoreStandardIncludePath; QString InterfaceIdentifierFileName; triState MkTypLibCompatible; QString OutputDirectory; QStringList PreprocessorDefinitions; QString ProxyFileName; QString RedirectOutputAndErrors; midlStructMemberAlignOption StructMemberAlignment; triState SuppressStartupBanner; midlTargetEnvironment TargetEnvironment; QString TypeLibraryName; QStringList UndefinePreprocessorDefinitions; triState ValidateParameters; triState WarnAsError; midlWarningLevelOption WarningLevel; VCConfiguration* config; }; class VCLibrarianTool : public VCToolBase { public: // Functions VCLibrarianTool(); - ~VCLibrarianTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCLibrarianTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; QStringList AdditionalLibraryDirectories; QStringList AdditionalOptions; QStringList ExportNamedFunctions; QStringList ForceSymbolReferences; triState IgnoreAllDefaultLibraries; QStringList IgnoreDefaultLibraryNames; QString ModuleDefinitionFile; QString OutputFile; triState SuppressStartupBanner; }; class VCCustomBuildTool : public VCToolBase { public: // Functions VCCustomBuildTool(); - ~VCCustomBuildTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCCustomBuildTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; QString CommandLine; QString Description; QString Outputs; QString ToolName; QString ToolPath; }; class VCResourceCompilerTool : public VCToolBase { public: // Functions VCResourceCompilerTool(); - ~VCResourceCompilerTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCResourceCompilerTool(){} + bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalIncludeDirectories; QStringList AdditionalOptions; enumResourceLangID Culture; QStringList FullIncludePath; triState IgnoreStandardIncludePath; QStringList PreprocessorDefinitions; QString ResourceOutputFileName; linkProgressOption ShowProgress; QString ToolPath; }; class VCEventTool : public VCToolBase { protected: // Functions VCEventTool() : ExcludedFromBuild( unset ){}; - ~VCEventTool(){}; - virtual bool parseOption( const char* option ){ return FALSE; }; + virtual ~VCEventTool(){} + bool parseOption( const char* ){ return FALSE; }; public: // Variables QString CommandLine; QString Description; triState ExcludedFromBuild; QString ToolName; QString ToolPath; }; class VCPostBuildEventTool : public VCEventTool { public: VCPostBuildEventTool(); - ~VCPostBuildEventTool(){}; + ~VCPostBuildEventTool(){} }; class VCPreBuildEventTool : public VCEventTool { public: VCPreBuildEventTool(); - ~VCPreBuildEventTool(){}; + ~VCPreBuildEventTool(){} }; class VCPreLinkEventTool : public VCEventTool { public: VCPreLinkEventTool(); - ~VCPreLinkEventTool(){}; + ~VCPreLinkEventTool(){} }; class VCConfiguration { public: // Functions VCConfiguration(); - ~VCConfiguration(){}; + ~VCConfiguration(){} // Variables triState ATLMinimizesCRunTimeLibraryUsage; triState BuildBrowserInformation; charSet CharacterSet; ConfigurationTypes ConfigurationType; QString DeleteExtensionsOnClean; QString ImportLibrary; QString IntermediateDirectory; QString Name; QString OutputDirectory; QString PrimaryOutput; QString ProgramDatabase; triState RegisterOutput; useOfATL UseOfATL; useOfMfc UseOfMfc; triState WholeProgramOptimization; // XML sub-parts VCCLCompilerTool compiler; VCLinkerTool linker; VCLibrarianTool librarian; VCCustomBuildTool custom; VCMIDLTool idl; VCPostBuildEventTool postBuild; VCPreBuildEventTool preBuild; VCPreLinkEventTool preLink; VCResourceCompilerTool resource; }; class VcprojGenerator; class VCFilter { public: // Functions VCFilter(); - ~VCFilter(){}; + ~VCFilter(){} void generateMOC( QTextStream &strm, QString str ) const; void generateUIC( QTextStream &strm, const QString& str ) const; // Variables QString Name; QString Filter; triState ParseFiles; QStringList Files; VcprojGenerator* Project; VCConfiguration* Config; customBuildCheck CustomBuild; }; class VCProject { public: // Functions VCProject(); - ~VCProject(){}; + ~VCProject(){} // Variables QString Name; QString Version; QString ProjectGUID; QString SccProjectName; QString SccLocalPath; QString PlatformName; // XML sub-parts VCConfiguration Configuration; VCFilter SourceFiles; VCFilter HeaderFiles; VCFilter MOCFiles; VCFilter UICFiles; VCFilter FormFiles; VCFilter TranslationFiles; VCFilter LexYaccFiles; VCFilter ResourceFiles; }; QTextStream &operator<<( QTextStream &, const VCCLCompilerTool & ); QTextStream &operator<<( QTextStream &, const VCLinkerTool & ); QTextStream &operator<<( QTextStream &, const VCMIDLTool & ); QTextStream &operator<<( QTextStream &, const VCCustomBuildTool & ); QTextStream &operator<<( QTextStream &, const VCLibrarianTool & ); QTextStream &operator<<( QTextStream &, const VCResourceCompilerTool & ); QTextStream &operator<<( QTextStream &, const VCEventTool & ); QTextStream &operator<<( QTextStream &, const VCConfiguration & ); QTextStream &operator<<( QTextStream &, const VCFilter & ); QTextStream &operator<<( QTextStream &, const VCProject & ); #endif //__MSVC_OBJECTMODEL_H__ diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index a2bb6e9..d2cbc31 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,1050 +1,1214 @@ /**************************************************************************** ** $Id$ ** ** Definition of VcprojGenerator class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "msvc_vcproj.h" #include "option.h" #include <qdir.h> -#include <stdlib.h> #include <qregexp.h> +#include <qdict.h> +#include <quuid.h> +#include <stdlib.h> #if defined(Q_OS_WIN32) #include <objbase.h> +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + ulong Data1; + ushort Data2; + ushort Data3; + uchar Data4[8]; +} GUID; +#endif #endif +// Flatfile Tags ---------------------------------------------------- +const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; + // The following UUID _may_ change for later servicepacks... + // If so we need to search through the registry at + // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects + // to find the subkey that contains a "PossibleProjectExtension" + // containing "vcproj"... + // Use the hardcoded value for now so projects generated on other + // platforms are actually usable. +const char* _snlMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; +const char* _snlProjectBeg = "\nProject(\""; +const char* _snlProjectMid = "\") = "; +const char* _snlProjectEnd = "\nEndProject"; +const char* _snlGlobalBeg = "\nGlobal"; +const char* _snlGlobalEnd = "\nEndGlobal"; +const char* _snlSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" + "\n\t\tConfigName.0 = Release" + "\n\tEndGlobalSection"; +const char* _snlProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; +const char* _snlProjDepEnd = "\n\tEndGlobalSection"; +const char* _snlProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; +const char* _snlProjConfTag1 = ".Release.ActiveCfg = Release|Win32"; +const char* _snlProjConfTag2 = ".Release.Build.0 = Release|Win32"; +const char* _snlProjConfEnd = "\n\tEndGlobalSection"; +const char* _snlExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" + "\n\tEndGlobalSection" + "\n\tGlobalSection(ExtensibilityAddIns) = postSolution" + "\n\tEndGlobalSection"; +// ------------------------------------------------------------------ + VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE) { } /* \internal Generates a project file for the given profile. Options are either a Visual Studio projectfiles, or - recursive projectfiles.. Maybe we can make .sln files - someday? + solutionfiles by parsing recursive projectdirectories. */ bool VcprojGenerator::writeMakefile(QTextStream &t) { // Check if all requirements are fullfilled if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } - // Generate full project file + // Generate project file if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { debug_msg(1, "Generator: MSVC.NET: Writing project file" ); t << vcProject; return TRUE; - } else if(project->first("TEMPLATE") == "vcsubdirs") { // Generate recursive project + } + // Generate solution file + else if(project->first("TEMPLATE") == "vcsubdirs") { debug_msg(1, "Generator: MSVC.NET: Writing solution file" ); writeSubDirs(t); return TRUE; } return FALSE; } struct VcsolutionDepend { + QString uuid; QString vcprojFile, orig_target, target; + ::target targetType; QStringList dependencies; }; +QUuid VcprojGenerator::increaseUUID( const QUuid &id ) +{ + QUuid result( id ); + Q_LONG dataFirst = (result.data4[0] << 24) + + (result.data4[1] << 16) + + (result.data4[2] << 8) + + result.data4[3]; + Q_LONG dataLast = (result.data4[4] << 24) + + (result.data4[5] << 16) + + (result.data4[6] << 8) + + result.data4[7]; + + if ( !(dataLast++) ) + dataFirst++; + + result.data4[0] = uchar((dataFirst >> 24) & 0xff); + result.data4[1] = uchar((dataFirst >> 16) & 0xff); + result.data4[2] = uchar((dataFirst >> 8) & 0xff); + result.data4[3] = uchar( dataFirst & 0xff); + result.data4[4] = uchar((dataLast >> 24) & 0xff); + result.data4[5] = uchar((dataLast >> 16) & 0xff); + result.data4[6] = uchar((dataLast >> 8) & 0xff); + result.data4[7] = uchar( dataLast & 0xff); + return result; +} + void VcprojGenerator::writeSubDirs(QTextStream &t) { if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); Win32MakefileGenerator::writeSubDirs(t); return; } - QPtrList<VcsolutionDepend> solution_depends; - solution_depends.setAutoDelete(TRUE); + t << _snlHeader; + QUuid solutionGUID; +#if defined(Q_WS_WIN32) + GUID guid; + HRESULT h = CoCreateGuid( &guid ); + if ( h == S_OK ) + solutionGUID = QUuid( guid ); +#else + // Qt doesn't support GUID on other platforms yet, + // so we use the all-zero uuid, and increase that. +#endif + + + QDict<VcsolutionDepend> solution_depends; + QPtrList<VcsolutionDepend> solution_cleanup; + solution_cleanup.setAutoDelete(TRUE); QStringList subdirs = project->variables()["SUBDIRS"]; QString oldpwd = QDir::currentDirPath(); for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); if(fi.exists()) { if(fi.isDir()) { QString profile = (*it); if(!profile.endsWith(Option::dir_sep)) profile += Option::dir_sep; profile += fi.baseName() + ".pro"; subdirs.append(profile); } else { QMakeProject tmp_proj; QString dir = fi.dirPath(), fn = fi.fileName(); if(!dir.isEmpty()) { if(!QDir::setCurrent(dir)) fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); } if(tmp_proj.read(fn, oldpwd)) { if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]); subdirs += tmp_subdirs; - } else if(tmp_proj.first("TEMPLATE") == "vcapp" || - tmp_proj.first("TEMPLATE") == "vclib") { - QString vcproj = fi.baseName() + project->first("VCPROJ_EXTENSION"); - if(QFile::exists(vcproj) || 1) { - VcprojGenerator tmp_dsp(&tmp_proj); - tmp_dsp.setNoIO(TRUE); - tmp_dsp.init(); + } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { + // Initialize a 'fake' project to get the correct variables + // and to be able to extract all the dependencies + VcprojGenerator tmp_vcproj(&tmp_proj); + tmp_vcproj.setNoIO(TRUE); + tmp_vcproj.init(); if(Option::debug_level) { QMap<QString, QStringList> &vars = tmp_proj.variables(); for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { if(it.key().left(1) != "." && !it.data().isEmpty()) debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), it.data().join(" :: ").latin1()); } } + + // We assume project filename is [QMAKE_ORIG_TARGET].vcproj + QString vcproj = fixFilename(tmp_vcproj.project->first("QMAKE_ORIG_TARGET")) + project->first("VCPROJ_EXTENSION"); + + // If file doesn't exsist, then maybe the users configuration + // doesn't allow it to be created. Skip to next... + if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) { + qDebug( "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); + goto nextfile; // # Dirty! + } + VcsolutionDepend *newDep = new VcsolutionDepend; newDep->vcprojFile = fileFixify(vcproj); newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); + newDep->targetType = tmp_vcproj.projectTarget; + { + static QUuid uuid = solutionGUID; + uuid = increaseUUID( uuid ); + newDep->uuid = uuid.toString().upper(); + } if(newDep->target.endsWith(".dll")) newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; if(!tmp_proj.isEmpty("FORMS")) newDep->dependencies << "uic.exe"; { QStringList where("QMAKE_LIBS"); if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; for(QStringList::iterator wit = where.begin(); wit != where.end(); ++wit) { QStringList &l = tmp_proj.variables()[(*wit)]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); if(!opt.startsWith("/")) //Not a switch newDep->dependencies << opt.section(Option::dir_sep, -1); } } } - solution_depends.append(newDep); + solution_cleanup.append(newDep); + solution_depends.insert(newDep->target, newDep); + { + QRegExp libVersion("[0-9]{3,3}\\.lib$"); + if(libVersion.search(newDep->target) != -1) + solution_depends.insert(newDep->target.left(newDep->target.length() - + libVersion.matchedLength()) + ".lib", newDep); } + t << _snlProjectBeg << _snlMSVCvcprojGUID << _snlProjectMid + << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile + << "\", \"" << newDep->uuid << "\""; + t << _snlProjectEnd; } } +nextfile: QDir::setCurrent(oldpwd); } } } - + t << _snlGlobalBeg; + t << _snlSolutionConf; + t << _snlProjDepBeg; + for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + int cnt = 0; + for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); + dit != solution_cleanup.current()->dependencies.end(); + ++dit) { VcsolutionDepend *vc; - QMap<QString, int> uuids; - QRegExp libVersion("[0-9]{3,3}\\.lib$"); - for(vc = solution_depends.first(); vc; vc = solution_depends.next()) { - static int uuid = 666; - uuids.insert(vc->target, uuid); - if(libVersion.match(vc->target) != -1) - uuids.insert(vc->target.left(vc->target.length() - libVersion.matchedLength()) + ".lib", - uuid); - t << "\"" << vc->orig_target << "\" \"" << vc->vcprojFile << "\" { " << uuid << " }" << endl; - uuid++; + if((vc=solution_depends[*dit])) { + if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) + t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; } - for(vc = solution_depends.first(); vc; vc = solution_depends.next()) { - int uuid = uuids[vc->target], cnt = 0; - for(QStringList::iterator dit = vc->dependencies.begin(); dit != vc->dependencies.end(); ++dit) { - if(uuids.contains((*dit))) - t << uuid << "." << cnt++ << " = " << uuids[(*dit)] << endl; } } + t << _snlProjDepEnd; + t << _snlProjConfBeg; + for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag2; + } + t << _snlProjConfEnd; + t << _snlExtSections; + t << _snlGlobalEnd; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void VcprojGenerator::init() { if( init_flag ) return; if(project->first("TEMPLATE") == "vcsubdirs") { //too much work for subdirs init_flag = TRUE; return; } debug_msg(1, "Generator: MSVC.NET: Initializing variables" ); /* // Once to be nice and clean code... // Wouldn't life be great? // Are we building Qt? bool is_qt = ( project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX ); // Are we using Qt? bool isQtActive = project->isActiveConfig("qt"); if ( isQtActive ) { project->variables()["CONFIG"] += "moc"; project->variables()["CONFIG"] += "windows"; project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if( projectTarget == SharedLib ) project->variables()["DEFINES"] += "QT_DLL"; if( project->isActiveConfig("accessibility" ) ) project->variables()["DEFINES"] += "QT_ACCESSIBILITY_SUPPORT"; if ( project->isActiveConfig("plugin")) { project->variables()["DEFINES"] += "QT_PLUGIN"; project->variables()["CONFIG"] += "dll"; } if( project->isActiveConfig("thread") ) { project->variables()["DEFINES"] += "QT_THREAD_SUPPORT"; project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; } else { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; } } if ( project->isActiveConfig("opengl") ) { project->variables()["CONFIG"] += "windows"; // <-- Also in 'qt' above project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } */ initOld(); // Currently calling old DSP code to set variables. CLEAN UP! // Figure out what we're trying to build if ( project->first("TEMPLATE") == "vcapp" ) { projectTarget = Application; } else if ( project->first("TEMPLATE") == "vclib") { if ( project->isActiveConfig( "staticlib" ) ) projectTarget = StaticLib; else projectTarget = SharedLib; } initProject(); // Fills the whole project with proper data } void VcprojGenerator::initProject() { // Initialize XML sub elements // - Do this first since project elements may need // - to know of certain configuration options initConfiguration(); initSourceFiles(); initHeaderFiles(); initMOCFiles(); initUICFiles(); initFormsFiles(); initTranslationFiles(); initLexYaccFiles(); initResourceFiles(); // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET"); vcProject.Version = "7.00"; vcProject.PlatformName = ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); // These are not used by Qt, but may be used by customers vcProject.SccProjectName = project->first("SCCPROJECTNAME"); vcProject.SccLocalPath = project->first("SCCLOCALPATH"); } void VcprojGenerator::initConfiguration() { // Initialize XML sub elements // - Do this first since main configuration elements may need // - to know of certain compiler/linker options initCompilerTool(); if ( projectTarget == StaticLib ) initLibrarianTool(); else initLinkerTool(); initIDLTool(); // Own elements ----------------------------- QString temp = project->first("BuildBrowserInformation"); switch ( projectTarget ) { case SharedLib: vcProject.Configuration.ConfigurationType = typeDynamicLibrary; break; case StaticLib: vcProject.Configuration.ConfigurationType = typeStaticLibrary; break; case Application: default: vcProject.Configuration.ConfigurationType = typeApplication; break; } - vcProject.Configuration.Name = ( project->isActiveConfig( "release" ) ? "Release|" : "Debug|" ); + vcProject.Configuration.Name = ( project->isActiveConfig( "debug" ) ? "Debug|" : "Release|" ); vcProject.Configuration.Name += ( vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" ); vcProject.Configuration.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); - vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? unset : temp.toShort() ); + vcProject.Configuration.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); temp = project->first("CharacterSet"); - vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? charSetNotSet : temp.toShort() ); + vcProject.Configuration.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); vcProject.Configuration.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); vcProject.Configuration.ImportLibrary = vcProject.Configuration.linker.ImportLibrary; vcProject.Configuration.IntermediateDirectory = project->first("OBJECTS_DIR"); // temp = (projectTarget == StaticLib) ? project->first("DESTDIR"):project->first("DLLDESTDIR"); vcProject.Configuration.OutputDirectory = "."; //( temp.isEmpty() ? QString(".") : temp ); vcProject.Configuration.PrimaryOutput = project->first("PrimaryOutput"); vcProject.Configuration.WholeProgramOptimization = vcProject.Configuration.compiler.WholeProgramOptimization; temp = project->first("UseOfATL"); if ( !temp.isEmpty() ) vcProject.Configuration.UseOfATL = useOfATL( temp.toShort() ); temp = project->first("UseOfMfc"); if ( !temp.isEmpty() ) vcProject.Configuration.UseOfMfc = useOfMfc( temp.toShort() ); // Configuration does not need parameters from // these sub XML items; initCustomBuildTool(); initPreBuildEventTools(); initPostBuildEventTools(); initPreLinkEventTools(); } void VcprojGenerator::initCompilerTool() { QString placement = project->first("OBJECTS_DIR"); if ( placement.isEmpty() ) - placement = project->isActiveConfig( "release" )? ".\\Release\\":".\\Debug\\"; + placement = ".\\"; vcProject.Configuration.compiler.AssemblerListingLocation = placement ; vcProject.Configuration.compiler.ProgramDataBaseFileName = placement ; vcProject.Configuration.compiler.ObjectFile = placement ; vcProject.Configuration.compiler.PrecompiledHeaderFile = placement + project->first("QMAKE_ORIG_TARGET") + ".pch"; if ( project->isActiveConfig("debug") ){ // Debug version vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); else vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); } else { vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST_DBG"] ); } } else { // Release version vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); vcProject.Configuration.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + vcProject.Configuration.compiler.PreprocessorDefinitions += "NDEBUG"; if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); else vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); } else { vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST"] ); } } // Common for both release and debug if ( project->isActiveConfig("warn_off") ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); - else + else if ( project->isActiveConfig("warn_on") ) vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); if ( project->isActiveConfig("windows") ) vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; // Can this be set for ALL configs? // If so, use qmake.conf! if ( projectTarget == SharedLib ) vcProject.Configuration.compiler.PreprocessorDefinitions += "_WINDOWS"; vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; vcProject.Configuration.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); } void VcprojGenerator::initLibrarianTool() { vcProject.Configuration.librarian.OutputFile = project->first( "DESTDIR" ); if( vcProject.Configuration.librarian.OutputFile.isEmpty() ) vcProject.Configuration.librarian.OutputFile = ".\\"; if( !vcProject.Configuration.librarian.OutputFile.endsWith("\\") ) vcProject.Configuration.librarian.OutputFile += '\\'; vcProject.Configuration.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); } void VcprojGenerator::initLinkerTool() { vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); vcProject.Configuration.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; switch ( projectTarget ) { case Application: vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); break; case SharedLib: vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); break; + case StaticLib: //unhandled - added to remove warnings.. + break; } if( vcProject.Configuration.linker.OutputFile.isEmpty() ) vcProject.Configuration.linker.OutputFile = ".\\"; if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") ) vcProject.Configuration.linker.OutputFile += '\\'; vcProject.Configuration.linker.OutputFile += project->first("MSVCPROJ_TARGET"); vcProject.Configuration.linker.ProgramDatabaseFile = project->first("OBJECTS_DIR") + project->first("QMAKE_ORIG_TARGET") + ".pdb"; if ( project->isActiveConfig("debug") ){ vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); } else { vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); } if ( project->isActiveConfig("dll") ){ vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); } if ( project->isActiveConfig("console") ){ vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); } else { vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); } } void VcprojGenerator::initIDLTool() { } void VcprojGenerator::initCustomBuildTool() { } void VcprojGenerator::initPreBuildEventTools() { QString collectionName = project->first("QMAKE_IMAGE_COLLECTION"); if( !collectionName.isEmpty() ) { QStringList& list = project->variables()["IMAGES"]; vcProject.Configuration.preBuild.Description = "Generate imagecollection"; //vcProject.Configuration.preBuild.AdditionalDependencies += list; - vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " " + list.join(" ") + " -o " + collectionName; + + QFile imgs( ".imgcol" ); + imgs.open( IO_WriteOnly ); + QTextStream s( &imgs ); + QStringList::ConstIterator it = list.begin(); + while( it!=list.end() ) { + s << *it << " "; + it++; + } + + vcProject.Configuration.preBuild.CommandLine = project->first("QMAKE_UIC") + " -embed " + project->first("QMAKE_ORIG_TARGET") + " -f .imgcol -o " + collectionName; //vcProject.Configuration.preBuild.Outputs = collectionName; } } void VcprojGenerator::initPostBuildEventTools() { + if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) { + vcProject.Configuration.postBuild.Description = var("QMAKE_POST_LINK"); + vcProject.Configuration.postBuild.CommandLine = var("QMAKE_POST_LINK"); + } if( project->isActiveConfig( "activeqt" ) ) { QString name = project->first( "QMAKE_ORIG_TARGET" ); QString nameext = project->first( "TARGET" ); QString objdir = project->first( "OBJECTS_DIR" ); QString idc = project->first( "QMAKE_IDC" ); vcProject.Configuration.postBuild.Description = "Finalizing ActiveQt server..."; + if ( !vcProject.Configuration.postBuild.CommandLine.isEmpty() ) + vcProject.Configuration.postBuild.CommandLine += " && "; if( project->isActiveConfig( "dll" ) ) { // In process - vcProject.Configuration.postBuild.CommandLine = + vcProject.Configuration.postBuild.CommandLine += // call idc to generate .idl file from .dll idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + objdir + "dump.midl && " + // call idc to replace tlb... idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + // register server idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /regserver"; } else { // out of process vcProject.Configuration.postBuild.CommandLine = // call application to dump idl vcProject.Configuration.OutputDirectory + "\\" + nameext + " -dumpidl " + objdir + name + ".idl -version 1.0 && " + // call midl to create implementations of the .idl file project->first( "QMAKE_IDL" ) + " " + objdir + name + ".idl /nologo /o " + objdir + name + ".midl /tlb " + objdir + name + ".tlb /iid " + objdir + "dump.midl /dlldata " + objdir + "dump.midl /cstub " + objdir + "dump.midl /header " + objdir + "dump.midl /proxy " + objdir + "dump.midl /sstub " + objdir + "dump.midl && " + // call idc to replace tlb... idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + // call app to register vcProject.Configuration.OutputDirectory + "\\" + nameext + " -regserver"; } } } void VcprojGenerator::initPreLinkEventTools() { } void VcprojGenerator::initSourceFiles() { vcProject.SourceFiles.Name = "Source Files"; vcProject.SourceFiles.Filter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"; vcProject.SourceFiles.Files += project->variables()["SOURCES"]; vcProject.SourceFiles.Files.sort(); vcProject.SourceFiles.Project = this; vcProject.SourceFiles.Config = &(vcProject.Configuration); vcProject.SourceFiles.CustomBuild = none; } void VcprojGenerator::initHeaderFiles() { vcProject.HeaderFiles.Name = "Header Files"; vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl"; vcProject.HeaderFiles.Files += project->variables()["HEADERS"]; vcProject.HeaderFiles.Files.sort(); vcProject.HeaderFiles.Project = this; vcProject.HeaderFiles.Config = &(vcProject.Configuration); vcProject.HeaderFiles.CustomBuild = moc; } void VcprojGenerator::initMOCFiles() { vcProject.MOCFiles.Name = "Generated MOC Files"; vcProject.MOCFiles.Filter = "cpp;c;cxx;moc"; vcProject.MOCFiles.Files += project->variables()["SRCMOC"]; vcProject.MOCFiles.Files.sort(); vcProject.MOCFiles.Project = this; vcProject.MOCFiles.Config = &(vcProject.Configuration); vcProject.MOCFiles.CustomBuild = moc; } void VcprojGenerator::initUICFiles() { vcProject.UICFiles.Name = "Generated UI Files"; vcProject.UICFiles.Filter = "cpp;c;cxx;h;hpp;hxx;"; vcProject.UICFiles.Project = this; vcProject.UICFiles.Files += project->variables()["UICDECLS"]; vcProject.UICFiles.Files += project->variables()["UICIMPLS"]; vcProject.UICFiles.Files.sort(); vcProject.UICFiles.Config = &(vcProject.Configuration); vcProject.UICFiles.CustomBuild = none; } void VcprojGenerator::initFormsFiles() { vcProject.FormFiles.Name = "Forms"; vcProject.FormFiles.ParseFiles = _False; vcProject.FormFiles.Filter = "ui"; vcProject.FormFiles.Files += project->variables()["FORMS"]; vcProject.FormFiles.Files.sort(); vcProject.FormFiles.Project = this; vcProject.FormFiles.Config = &(vcProject.Configuration); vcProject.FormFiles.CustomBuild = uic; } void VcprojGenerator::initTranslationFiles() { vcProject.TranslationFiles.Name = "Translations Files"; vcProject.TranslationFiles.ParseFiles = _False; vcProject.TranslationFiles.Filter = "ts"; vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"]; vcProject.TranslationFiles.Files.sort(); vcProject.TranslationFiles.Project = this; vcProject.TranslationFiles.Config = &(vcProject.Configuration); vcProject.TranslationFiles.CustomBuild = none; } void VcprojGenerator::initLexYaccFiles() { vcProject.LexYaccFiles.Name = "Lex / Yacc Files"; vcProject.LexYaccFiles.ParseFiles = _False; vcProject.LexYaccFiles.Filter = "l;y"; vcProject.LexYaccFiles.Files += project->variables()["LEXSOURCES"]; vcProject.LexYaccFiles.Files += project->variables()["YACCSOURCES"]; vcProject.LexYaccFiles.Files.sort(); vcProject.LexYaccFiles.Project = this; vcProject.LexYaccFiles.CustomBuild = lexyacc; } void VcprojGenerator::initResourceFiles() { vcProject.ResourceFiles.Name = "Resources"; vcProject.ResourceFiles.ParseFiles = _False; vcProject.ResourceFiles.Filter = "cpp;ico;png;jpg;jpeg;gif;xpm;bmp;rc;ts"; vcProject.ResourceFiles.Files += project->variables()["RC_FILE"]; vcProject.ResourceFiles.Files += project->variables()["QMAKE_IMAGE_COLLECTION"]; vcProject.ResourceFiles.Files += project->variables()["IMAGES"]; vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"]; vcProject.ResourceFiles.Files.sort(); vcProject.ResourceFiles.Project = this; vcProject.ResourceFiles.CustomBuild = none; } -/* -// $$MSVCPROJ_IDLSOURCES --------------------------------------------- -void VcprojGenerator::writeIDLs( QTextStream &t ) -{ - QStringList &l = project->variables()["MSVCPROJ_IDLSOURCES"]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - t << "# Begin Source File" << endl << endl; - t << "SOURCE=" << (*it) << endl; - t << "# PROP Exclude_From_Build 1" << endl; - t << "# End Source File" << endl << endl; - } - debug_msg(3, "Generator: MSVC.NET: Added IDLs" ); -} -*/ - /* \internal Sets up all needed variables from the environment and all the different caches and .conf files */ void VcprojGenerator::initOld() { if( init_flag ) return; init_flag = TRUE; QStringList::Iterator it; + if ( project->isActiveConfig("stl") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"]; + } + if ( project->isActiveConfig("exceptions") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"]; + } + if ( project->isActiveConfig("rtti") ) { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"]; + } else { + project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"]; + project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"]; + } + // this should probably not be here, but I'm using it to wrap the .t files if(project->first("TEMPLATE") == "vcapp" ) project->variables()["QMAKE_APP_FLAG"].append("1"); else if(project->first("TEMPLATE") == "vclib") project->variables()["QMAKE_LIB_FLAG"].append("1"); if ( project->variables()["QMAKESPEC"].isEmpty() ) project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") ); bool is_qt = ( project->first("TARGET") == "qt"QTDLL_POSTFIX || project->first("TARGET") == "qt-mt"QTDLL_POSTFIX ); QStringList &configs = project->variables()["CONFIG"]; if ( project->isActiveConfig( "shared" ) ) project->variables()["DEFINES"].append( "QT_DLL" ); if ( project->isActiveConfig( "qt_dll" ) && configs.findIndex("qt") == -1 ) configs.append("qt"); if ( project->isActiveConfig( "qt" ) ) { if ( project->isActiveConfig( "plugin" ) ) { project->variables()["CONFIG"].append( "dll" ); project->variables()["DEFINES"].append( "QT_PLUGIN" ); } if ( ( project->variables()["DEFINES"].findIndex( "QT_NODLL" ) == -1 ) && (( project->variables()["DEFINES"].findIndex( "QT_MAKEDLL" ) != -1 || project->variables()["DEFINES"].findIndex( "QT_DLL" ) != -1 ) || ( getenv( "QT_DLL" ) && !getenv( "QT_NODLL" ))) ) { project->variables()["QMAKE_QT_DLL"].append( "1" ); if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) project->variables()["CONFIG"].append( "dll" ); } } // If we are a dll, then we cannot be a staticlib at the same time... if ( project->isActiveConfig( "dll" ) || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["CONFIG"].remove( "staticlib" ); project->variables()["QMAKE_APP_OR_DLL"].append( "1" ); } else { project->variables()["CONFIG"].append( "staticlib" ); } // If we need 'qt' and/or 'opengl', then we need windows and not console if ( project->isActiveConfig( "qt" ) || project->isActiveConfig( "opengl" ) ) { project->variables()["CONFIG"].append( "windows" ); } // Decode version, and add it to $$MSVCPROJ_VERSION -------------- if ( !project->variables()["VERSION"].isEmpty() ) { QString version = project->variables()["VERSION"][0]; int firstDot = version.find( "." ); QString major = version.left( firstDot ); QString minor = version.right( version.length() - firstDot - 1 ); minor.replace( QRegExp( "\\." ), "" ); project->variables()["MSVCPROJ_VERSION"].append( "/VERSION:" + major + "." + minor ); } // QT ------------------------------------------------------------ if ( project->isActiveConfig("qt") ) { project->variables()["CONFIG"].append("moc"); project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"]; project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"]; if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { project->variables()["DEFINES"].append("QT_MAKEDLL"); project->variables()["QMAKE_LFLAGS"].append("/BASE:0x39D00000"); } } else { if(project->isActiveConfig("thread")) project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"]; else project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"]; if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) { int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt"); if( hver==-1 ) { hver = findHighestVersion( project->first("QMAKE_LIBDIR_QT"), "qt-mt" ); } if(hver != -1) { QString ver; ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver); QStringList &libs = project->variables()["QMAKE_LIBS"]; for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver); } } if ( project->isActiveConfig( "activeqt" ) ) { project->variables().remove("QMAKE_LIBS_QT_ENTRY"); project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib"; if ( project->isActiveConfig( "dll" ) ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"]; project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); } } if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) { project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"]; } } } // Set target directories ---------------------------------------- // if ( !project->first("OBJECTS_DIR").isEmpty() ) //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->first("OBJECTS_DIR"); // else //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->isActiveConfig( "release" )?"Release":"Debug"; // if ( !project->first("DESTDIR").isEmpty() ) //project->variables()["MSVCPROJ_TARGETDIR"] = project->first("DESTDIR"); // else //project->variables()["MSVCPROJ_TARGETDIR"] = project->isActiveConfig( "release" )?"Release":"Debug"; // OPENGL -------------------------------------------------------- if ( project->isActiveConfig("opengl") ) { project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"]; project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"]; } // THREAD -------------------------------------------------------- if ( project->isActiveConfig("thread") ) { if(project->isActiveConfig("qt")) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" ); if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt && project->first("TARGET") != "qtmain" ) project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:libc"); } // ACCESSIBILITY ------------------------------------------------- if(project->isActiveConfig("qt")) { if ( project->isActiveConfig("accessibility" ) ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT"); if ( project->isActiveConfig("tablet") ) project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT"); } // DLL ----------------------------------------------------------- if ( project->isActiveConfig("dll") ) { if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) { QString ver_xyz(project->first("VERSION")); ver_xyz.replace(QRegExp("\\."), ""); project->variables()["TARGET_EXT"].append(ver_xyz + ".dll"); } else { project->variables()["TARGET_EXT"].append(".dll"); } } // EXE / LIB ----------------------------------------------------- else { if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) project->variables()["TARGET_EXT"].append(".exe"); else project->variables()["TARGET_EXT"].append(".lib"); } project->variables()["MSVCPROJ_VER"] = "7.00"; project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /ZI"; // INCREMENTAL:NO ------------------------------------------------ if(!project->isActiveConfig("incremental")) { - project->variables()["QMAKE_LFLAGS"].append(QString("/incremental:no")); + project->variables()["QMAKE_LFLAGS"].append(QString("/INCREMENTAL:no")); if ( is_qt ) project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /Zi"; } // MOC ----------------------------------------------------------- if ( project->isActiveConfig("moc") ) setMocAware(TRUE); project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"]; + // Update -lname to name.lib, and -Ldir to + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( it = libList.begin(); it != libList.end(); ) { + QString s = *it; + if( s.startsWith( "-l" ) ) { + it = libList.remove( it ); + it = libList.insert( it, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + it = libList.remove( it ); + } else { + it++; + } + } // Run through all variables containing filepaths, and ----------- // slash-slosh them correctly depending on current OS ----------- project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH"); QStringList &l = project->variables()["QMAKE_FILETAGS"]; for(it = l.begin(); it != l.end(); ++it) { QStringList &gdmf = project->variables()[(*it)]; for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner) (*inner) = Option::fixPathToTargetOS((*inner), FALSE); } // Get filename w/o extention ----------------------------------- QString msvcproj_project = ""; QString targetfilename = ""; if ( project->variables()["TARGET"].count() ) { msvcproj_project = project->variables()["TARGET"].first(); targetfilename = msvcproj_project; } // Save filename w/o extention in $$QMAKE_ORIG_TARGET ------------ project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; - // TARGET (add extention to $$TARGET) ---------------------------- - project->variables()["TARGET"].first() += project->first("TARGET_EXT"); + // TARGET (add extention to $$TARGET) + //project->variables()["MSVCPROJ_DEFINES"].append(varGlue(".first() += project->first("TARGET_EXT"); // Init base class too ------------------------------------------- MakefileGenerator::init(); if ( msvcproj_project.isEmpty() ) msvcproj_project = Option::output.name(); msvcproj_project = msvcproj_project.right( msvcproj_project.length() - msvcproj_project.findRev( "\\" ) - 1 ); msvcproj_project = msvcproj_project.left( msvcproj_project.findRev( "." ) ); msvcproj_project.replace(QRegExp("-"), ""); project->variables()["MSVCPROJ_PROJECT"].append(msvcproj_project); QStringList &proj = project->variables()["MSVCPROJ_PROJECT"]; for(it = proj.begin(); it != proj.end(); ++it) (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), ""); // SUBSYSTEM ----------------------------------------------------- if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) { project->variables()["MSVCPROJ_TEMPLATE"].append("win32app" + project->first( "VCPROJ_EXTENSION" ) ); if ( project->isActiveConfig("console") ) { project->variables()["MSVCPROJ_CONSOLE"].append("CONSOLE"); project->variables()["MSVCPROJ_WINCONDEF"].append("_CONSOLE"); project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0103"); project->variables()["MSVCPROJ_SUBSYSTEM"].append("CONSOLE"); } else { project->variables()["MSVCPROJ_CONSOLE"].clear(); project->variables()["MSVCPROJ_WINCONDEF"].append("_WINDOWS"); project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0101"); project->variables()["MSVCPROJ_SUBSYSTEM"].append("WINDOWS"); } } else { if ( project->isActiveConfig("dll") ) { project->variables()["MSVCPROJ_TEMPLATE"].append("win32dll" + project->first( "VCPROJ_EXTENSION" ) ); } else { project->variables()["MSVCPROJ_TEMPLATE"].append("win32lib" + project->first( "VCPROJ_EXTENSION" ) ); } } // $$QMAKE.. -> $$MSVCPROJ.. ------------------------------------- project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS"]; project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"]; project->variables()["MSVCPROJ_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"]; - if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) - project->variables()["MSVCPROJ_LFLAGS" ].append(varGlue("QMAKE_LIBDIR","/LIBPATH:"," /LIBPATH:","")); + if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) { + QStringList strl = project->variables()["QMAKE_LIBDIR"]; + QStringList::iterator stri; + for ( stri = strl.begin(); stri != strl.end(); ++stri ) { + if ( !(*stri).startsWith("/LIBPATH:") ) + (*stri).prepend( "/LIBPATH:" ); + } + project->variables()["MSVCPROJ_LFLAGS"] += strl; + } project->variables()["MSVCPROJ_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"]; // We don't use this... Direct manipulation of compiler object //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ","")); //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); QStringList &incs = project->variables()["INCLUDEPATH"]; for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { QString inc = (*incit); inc.replace(QRegExp("\""), ""); project->variables()["MSVCPROJ_INCPATH"].append("/I" + inc ); } project->variables()["MSVCPROJ_INCPATH"].append("/I" + specdir()); QString dest; project->variables()["MSVCPROJ_TARGET"] = project->first("TARGET"); - if ( !project->variables()["DESTDIR"].isEmpty() ) { - project->variables()["TARGET"].first().prepend(project->first("DESTDIR")); Option::fixPathToTargetOS(project->first("TARGET")); - dest = project->first("TARGET"); + dest = project->first("TARGET") + project->first( "TARGET_EXT" ); if ( project->first("TARGET").startsWith("$(QTDIR)") ) dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") ); - project->variables()["MSVCPROJ_TARGET"].append( - QString("/OUT:") + dest ); + project->variables()["MSVCPROJ_TARGET"] = dest; if ( project->isActiveConfig("dll") ) { - QString imp = dest; + QString imp = project->first( "DESTDIR" ); + if( !imp.isNull() && !imp.endsWith( "\\" ) ) + imp += "\\"; + imp += dest; imp.replace(QRegExp("\\.dll"), ".lib"); - project->variables()["MSVCPROJ_LIBOPTIONS"] += (QString("/IMPLIB:") + imp ); - } + project->variables()["MSVCPROJ_LIBOPTIONS"] += QString("/IMPLIB:") + imp; } // DLL COPY ------------------------------------------------------ if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) { QStringList dlldirs = project->variables()["DLLDESTDIR"]; QString copydll = "# Begin Special Build Tool\n" "TargetPath=" + dest + "\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Copy DLL to " + project->first("DLLDESTDIR") + "\n" "PostBuild_Cmds="; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; } copydll += "\n# End Special Build Tool"; project->variables()["MSVCPROJ_COPY_DLL_REL"].append( copydll ); project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( copydll ); } // ACTIVEQT ------------------------------------------------------ if ( project->isActiveConfig("activeqt") ) { QString idl = project->variables()["QMAKE_IDL"].first(); QString idc = project->variables()["QMAKE_IDC"].first(); QString version = project->variables()["VERSION"].first(); if ( version.isEmpty() ) version = "1.0"; project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".idl" ); project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".tlb" ); project->variables()["MSVCPROJ_IDLSOURCES"].append( "tmp\\" + targetfilename + ".midl" ); if ( project->isActiveConfig( "dll" ) ) { QString regcmd = "# Begin Special Build Tool\n" "TargetPath=" + targetfilename + "\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Finalizing ActiveQt server...\n" "PostBuild_Cmds=" + idc + " %1 -idl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" "\tregsvr32 /s %1\n" "# End Special Build Tool"; QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } else { QString regcmd = "# Begin Special Build Tool\n" "TargetPath=" + targetfilename + "\n" "SOURCE=$(InputPath)\n" "PostBuild_Desc=Finalizing ActiveQt server...\n" "PostBuild_Cmds=" "%1 -dumpidl tmp\\" + targetfilename + ".idl -version " + version + "\t" + idl + " tmp\\" + targetfilename + ".idl /nologo /o tmp\\" + targetfilename + ".midl /tlb tmp\\" + targetfilename + ".tlb /iid tmp\\dump.midl /dlldata tmp\\dump.midl /cstub tmp\\dump.midl /header tmp\\dump.midl /proxy tmp\\dump.midl /sstub tmp\\dump.midl" "\t" + idc + " %1 /tlb tmp\\" + targetfilename + ".tlb" "\t%1 -regserver\n" "# End Special Build Tool"; QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) ); executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first(); project->variables()["MSVCPROJ_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) ); } } // FORMS --------------------------------------------------------- QStringList &list = project->variables()["FORMS"]; for( it = list.begin(); it != list.end(); ++it ) { if ( QFile::exists( *it + ".h" ) ) project->variables()["SOURCES"].append( *it + ".h" ); } project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCPROJ_LFLAGS" << "MSVCPROJ_LIBS"; // Verbose output if "-d -d"... outputVariables(); } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ bool VcprojGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { QFileInfo fi(file); if(fi.isDir()) outdir = file.name() + QDir::separator(); } if(!outdir.isEmpty() || file.name().isEmpty()) { QString ext = project->first("VCPROJ_EXTENSION"); if(project->first("TEMPLATE") == "vcsubdirs") ext = project->first("VCSOLUTION_EXTENSION"); file.setName(outdir + project->first("TARGET") + ext); } if(QDir::isRelativePath(file.name())) { - QString ofile; - ofile = file.name(); + file.setName( Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + fixFilename(file.name())) ); + } + return Win32MakefileGenerator::openOutput(file); +} + +QString VcprojGenerator::fixFilename(QString ofile) const +{ int slashfind = ofile.findRev('\\'); if (slashfind == -1) { - ofile = ofile.replace("-", "_"); + ofile = ofile.replace('-', '_'); } else { int hypenfind = ofile.find('-', slashfind); while (hypenfind != -1 && slashfind < hypenfind) { - ofile = ofile.replace(hypenfind, 1, "_"); + ofile = ofile.replace(hypenfind, 1, '_'); hypenfind = ofile.find('-', hypenfind + 1); } } - file.setName(Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + ofile)); - } - return Win32MakefileGenerator::openOutput(file); + return ofile; } QString VcprojGenerator::findTemplate(QString file) { QString ret; if(!QFile::exists((ret = file)) && !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) && !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc.net/" + file)) && !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file)))) return ""; debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.latin1() ); return ret; } void VcprojGenerator::processPrlVariable(const QString &var, const QStringList &l) { if(var == "QMAKE_PRL_DEFINES") { QStringList &out = project->variables()["MSVCPROJ_DEFINES"]; for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { if(out.findIndex((*it)) == -1) out.append((" /D " + *it )); } } else { MakefileGenerator::processPrlVariable(var, l); } } void VcprojGenerator::outputVariables() { #if 0 - debug_msg(3, "Generator: MSVC.NET: List of current variables:" ); + qDebug( "Generator: MSVC.NET: List of current variables:" ); for ( QMap<QString, QStringList>::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) { - debug_msg(3, "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() ); + qDebug( "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() ); } #endif } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 583b164..69e0c02 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,129 +1,115 @@ /**************************************************************************** ** $Id$ ** ** Definition of VcprojGenerator class. ** ** Created : 970521 ** -** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. +** Copyright (C) 1992-2002 Trolltech AS. All rights reserved. ** ** This file is part of the network module of the Qt GUI Toolkit. ** ** This file may be distributed under the terms of the Q Public License ** as defined by Trolltech AS of Norway and appearing in the file ** LICENSE.QPL included in the packaging of this file. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** ** Licensees holding valid Qt Enterprise Edition licenses may use this ** file in accordance with the Qt Commercial License Agreement provided ** with the Software. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ -#ifndef __VCPROJMAKE_H__ -#define __VCPROJMAKE_H__ +#ifndef __MSVC_VCPROJ_H__ +#define __MSVC_VCPROJ_H__ #include "winmakefile.h" #include "msvc_objectmodel.h" enum target { Application, SharedLib, StaticLib }; +struct QUuid; class VcprojGenerator : public Win32MakefileGenerator { bool init_flag; bool writeVcprojParts(QTextStream &); bool writeMakefile(QTextStream &); virtual void writeSubDirs(QTextStream &t); QString findTemplate(QString file); void init(); public: VcprojGenerator(QMakeProject *p); ~VcprojGenerator(); QString defaultMakefile() const; virtual bool doDepends() const { return FALSE; } //never necesary protected: virtual bool openOutput(QFile &file) const; virtual void processPrlVariable(const QString &, const QStringList &); virtual bool findLibraries(); virtual void outputVariables(); + QString fixFilename(QString ofile) const; void initOld(); void initProject(); void initConfiguration(); void initCompilerTool(); void initLinkerTool(); void initLibrarianTool(); void initIDLTool(); void initCustomBuildTool(); void initPreBuildEventTools(); void initPostBuildEventTools(); void initPreLinkEventTools(); void initSourceFiles(); void initHeaderFiles(); void initMOCFiles(); void initUICFiles(); void initFormsFiles(); void initTranslationFiles(); void initLexYaccFiles(); void initResourceFiles(); - /* - void writeGuid( QTextStream &t ); - void writeAdditionalOptions( QTextStream &t ); - void writeHeaders( QTextStream &t ); - void writeSources( QTextStream &t ); - void writeMocs( QTextStream &t ); - void writeLexs( QTextStream &t ); - void writeYaccs( QTextStream &t ); - void writePictures( QTextStream &t ); - void writeImages( QTextStream &t ); - void writeIDLs( QTextStream &t ); - - void writeForms( QTextStream &t ); - void writeFormsSourceHeaders( QString &variable, QTextStream &t ); - void writeTranslations( QTextStream &t ); - void writeStrippedTranslations( QTextStream &t ); - */ - VCProject vcProject; target projectTarget; +private: + QUuid increaseUUID(const QUuid &id); friend class VCFilter; }; inline VcprojGenerator::~VcprojGenerator() { } inline QString VcprojGenerator::defaultMakefile() const { return project->first("TARGET") + project->first("VCPROJ_EXTENSION"); } inline bool VcprojGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCVCPROJ_LIBS"); } -#endif /* __VCPROJMAKE_H__ */ +#endif /* __MSVC_VCPROJ_H__ */ diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index a07c921..bc3fed9 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -26,335 +26,375 @@ ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for ** information about Qt Commercial License Agreements. ** See http://www.trolltech.com/qpl/ for QPL licensing information. ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "winmakefile.h" #include "option.h" #include "project.h" #include <qtextstream.h> #include <qstring.h> #include <qdict.h> #include <qregexp.h> #include <qstringlist.h> #include <qdir.h> Win32MakefileGenerator::Win32MakefileGenerator(QMakeProject *p) : MakefileGenerator(p) { } struct SubDir { QString directory, profile, target, makefile; }; void Win32MakefileGenerator::writeSubDirs(QTextStream &t) { QPtrList<SubDir> subdirs; { QStringList subdirs_in = project->variables()["SUBDIRS"]; for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) { QString file = (*it); file = fileFixify(file); SubDir *sd = new SubDir; subdirs.append(sd); sd->makefile = "$(MAKEFILE)"; if((*it).right(4) == ".pro") { int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { sd->directory = file.left(slsh+1); sd->profile = file.mid(slsh+1); } else { sd->profile = file; } } else { sd->directory = file; } while(sd->directory.right(1) == Option::dir_sep) sd->directory = sd->directory.left(sd->directory.length() - 1); if(!sd->profile.isEmpty()) { QString basename = sd->directory; int new_slsh = basename.findRev(Option::dir_sep); if(new_slsh != -1) basename = basename.mid(new_slsh+1); if(sd->profile != basename + ".pro") sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro } sd->target = "sub-" + (*it); sd->target.replace('/', '-'); sd->target.replace('.', '_'); } } QPtrListIterator<SubDir> it(subdirs); if(!project->isEmpty("MAKEFILE")) t << "MAKEFILE= " << var("MAKEFILE") << endl; t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; t << "SUBTARGETS = "; for( it.toFirst(); it.current(); ++it) t << " \\\n\t\t" << it.current()->target; t << endl << endl; t << "all: qmake_all $(SUBTARGETS)" << endl << endl; for( it.toFirst(); it.current(); ++it) { bool have_dir = !(*it)->directory.isEmpty(); //make the makefile QString mkfile = (*it)->makefile; if(have_dir) mkfile.prepend((*it)->directory + Option::dir_sep); t << mkfile << ":"; if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << " FORCE"; if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs(); - if((*it)->makefile != "$(MAKEFILE)") t << " -o " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } t << endl; //now actually build t << (*it)->target << ": " << mkfile; if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << " FORCE"; if(have_dir) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(MAKE)"; - if((*it)->makefile != "$(MAKEFILE)") t << " -f " << (*it)->makefile; if(have_dir) { int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } t << endl << endl; } if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); writeMakeQmake(t); t << "qmake_all:"; if ( !subdirs.isEmpty() ) { for( it.toFirst(); it.current(); ++it) { QString subdir = (*it)->directory; + QString profile = (*it)->profile; int subLevels = subdir.contains(Option::dir_sep) + 1; t << "\n\t" << "cd " << subdir << "\n\t"; int lastSlash = subdir.findRev(Option::dir_sep); if(lastSlash != -1) subdir = subdir.mid( lastSlash + 1 ); - t << "$(QMAKE) " << subdir << ".pro" - << (!project->isEmpty("MAKEFILE") ? QString(" -o ") + var("MAKEFILE") : QString("")) + t << "$(QMAKE) " + << ( !profile.isEmpty() ? profile : subdir + ".pro" ) + << " -o " << (*it)->makefile << " " << buildArgs() << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } else { // Borland make does not like empty an empty command section, so insert // a dummy command. t << "\n\t" << "@cd ."; } t << endl << endl; QString targs[] = { QString("clean"), QString("install"), QString("mocclean"), QString::null }; for(int x = 0; targs[x] != QString::null; x++) { t << targs[x] << ": qmake_all"; if(targs[x] == "clean") t << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ", ""); if (!subdirs.isEmpty()) { for( it.toFirst(); it.current(); ++it) { int subLevels = (*it)->directory.contains(Option::dir_sep) + 1; bool have_dir = !(*it)->directory.isEmpty(); if(have_dir) t << "\n\t" << "cd " << (*it)->directory; - QString in_file; - if((*it)->makefile != "$(MAKEFILE)") - in_file = " -f " + (*it)->makefile; + QString in_file = " -f " + (*it)->makefile; t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; if(have_dir) { t << "\n\t" << "@cd .."; for(int i = 1; i < subLevels; i++ ) t << Option::dir_sep << ".."; } } } else { // Borland make does not like empty an empty command section, so // insert a dummy command. t << "\n\t" << "@cd ."; } t << endl << endl; } if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << "FORCE:" << endl << endl; } int -Win32MakefileGenerator::findHighestVersion(const QString &d, const - QString &stem) +Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem) { - if(!QFile::exists(Option::fixPathToLocalOS(d))) + QString bd = Option::fixPathToLocalOS(d, TRUE); + if(!QFile::exists(bd)) return -1; - if(!project->variables()["QMAKE_" + stem.upper() + - "_VERSION_OVERRIDE"].isEmpty()) - return project->variables()["QMAKE_" + stem.upper() + - "_VERSION_OVERRIDE"].first().toInt(); - QString bd = d; - fixEnvVariables(bd); + if(!project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].isEmpty()) + return project->variables()["QMAKE_" + stem.upper() + "_VERSION_OVERRIDE"].first().toInt(); + QDir dir(bd); int biggest=-1; QStringList entries = dir.entryList(); - QRegExp regx( "(" + stem + "([0-9]*)).lib", FALSE ); - for(QStringList::Iterator it = entries.begin(); it != entries.end(); - ++it) { + QString dllStem = stem + QTDLL_POSTFIX; + QRegExp regx( "(" + dllStem + "([0-9]*)).lib", FALSE ); + for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { if(regx.exactMatch((*it))) - biggest = QMAX(biggest, (regx.cap(1) == stem || + biggest = QMAX(biggest, (regx.cap(1) == dllStem || regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); } + if(dir.exists(dllStem + Option::prl_ext)) { + QMakeProject proj; + if(proj.read(bd + dllStem + Option::prl_ext, QDir::currentDirPath(), TRUE)) { + if(!proj.isEmpty("QMAKE_PRL_VERSION")) + biggest = QMAX(biggest, proj.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); + } + } return biggest; } bool Win32MakefileGenerator::findLibraries(const QString &where) { QStringList &l = project->variables()[where]; QPtrList<MakefileDependDir> dirs; + { + QStringList &libpaths = project->variables()["QMAKE_LIBDIR"]; + for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) { + QString r = (*libpathit), l = r; + fixEnvVariables(l); + dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); + } + } dirs.setAutoDelete(TRUE); for(QStringList::Iterator it = l.begin(); it != l.end(); ) { - QString opt = (*it); - bool remove = FALSE; - if(opt.startsWith("-L") || opt.startsWith("/L")) { - QString r = opt.right(opt.length() - 2), l = Option::fixPathToLocalOS(r); + QChar quote; + bool modified_opt = FALSE, remove = FALSE; + QString opt = (*it).stripWhiteSpace(); + if((opt[0] == '\'' || opt[0] == '"') && opt[(int)opt.length()-1] == opt[0]) { + quote = opt[0]; + opt = opt.mid(1, opt.length()-2); + } + if(opt.startsWith("/LIBPATH:")) { + QString r = opt.mid(9), l = Option::fixPathToLocalOS(r); + dirs.append(new MakefileDependDir(r.replace("\"",""), + l.replace("\"",""))); + } else if(opt.startsWith("-L") || opt.startsWith("/L")) { + QString r = opt.mid(2), l = Option::fixPathToLocalOS(r); dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); - remove = TRUE; + remove = TRUE; //we eat this switch } else if(opt.startsWith("-l") || opt.startsWith("/l")) { QString lib = opt.right(opt.length() - 2), out; if(!lib.isEmpty()) { for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { + QString extension; int ver = findHighestVersion(mdd->local_dir, lib); if(ver > 0) - lib += QString::number(ver); - lib += ".lib"; - if(QFile::exists(mdd->local_dir + Option::dir_sep + lib)) { - out = mdd->real_dir + Option::dir_sep + lib; + extension += QString::number(ver); + extension += ".lib"; + if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || + QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) { + out = mdd->real_dir + Option::dir_sep + lib + extension; break; } } } - if(out.isEmpty()) - remove = TRUE; - else + if(out.isEmpty()) { + remove = TRUE; //just eat it since we cannot find one.. + } else { + modified_opt = TRUE; (*it) = out; + } } else if(!QFile::exists(Option::fixPathToLocalOS(opt))) { - QString dir, file = opt; + QPtrList<MakefileDependDir> lib_dirs; + QString file = opt; int slsh = file.findRev(Option::dir_sep); if(slsh != -1) { - dir = file.left(slsh+1); + QString r = file.left(slsh+1), l = r; + fixEnvVariables(l); + lib_dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); file = file.right(file.length() - slsh - 1); + } else { + lib_dirs = dirs; } - if ( !(project->variables()["QMAKE_QT_DLL"].isEmpty() && (file == "qt.lib" || file == "qt-mt.lib")) ) { if(file.endsWith(".lib")) { file = file.left(file.length() - 4); if(!file.at(file.length()-1).isNumber()) { - int ver = findHighestVersion(dir, file); + for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { + QString lib_tmpl(file + "%1" + ".lib"); + int ver = findHighestVersion(mdd->local_dir, file); if(ver != -1) { - file = QString(dir + file + "%1" + ".lib"); if(ver) - (*it) = file.arg(ver); + lib_tmpl = lib_tmpl.arg(ver); else - (*it) = file.arg(""); + lib_tmpl = lib_tmpl.arg(""); + if(slsh != -1) { + QString dir = mdd->real_dir; + if(!dir.endsWith(Option::dir_sep)) + dir += Option::dir_sep; + lib_tmpl.prepend(dir); + } + modified_opt = TRUE; + (*it) = lib_tmpl; + break; } } } } } - if(remove) + if(remove) { it = l.remove(it); - else + } else { + if(!quote.isNull() && modified_opt) + (*it) = quote + (*it) + quote; ++it; } + } return TRUE; } void Win32MakefileGenerator::processPrlFiles() { QDict<void> processed; QPtrList<MakefileDependDir> libdirs; libdirs.setAutoDelete(TRUE); { QStringList &libpaths = project->variables()["QMAKE_LIBDIR"]; for(QStringList::Iterator libpathit = libpaths.begin(); libpathit != libpaths.end(); ++libpathit) { QString r = (*libpathit), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } for(bool ret = FALSE; TRUE; ret = FALSE) { //read in any prl files included.. QStringList l_out; QString where = "QMAKE_LIBS"; if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = project->first("QMAKE_INTERNAL_PRL_LIBS"); QStringList &l = project->variables()[where]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); - if(opt.left(1) == "/") { - if(opt.left(9) == "/LIBPATH:") { + if(opt.startsWith("/")) { + if(opt.startsWith("/LIBPATH:")) { QString r = opt.mid(9), l = r; fixEnvVariables(l); libdirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); } } else { if(!processed[opt]) { if(processPrlFile(opt)) { processed.insert(opt, (void*)1); ret = TRUE; } else { for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) { QString prl = mdd->local_dir + Option::dir_sep + opt; if(processed[prl]) { break; } else if(processPrlFile(prl)) { processed.insert(prl, (void*)1); ret = TRUE; break; } } } } } if(!opt.isEmpty()) l_out.append(opt); } if(ret) l = l_out; else break; } } |