summaryrefslogtreecommitdiff
path: root/qmake/generators/makefile.cpp
Unidiff
Diffstat (limited to 'qmake/generators/makefile.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/generators/makefile.cpp476
1 files changed, 327 insertions, 149 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
@@ -5,7 +5,7 @@
5** 5**
6** Created : 970521 6** Created : 970521
7** 7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9** 9**
10** This file is part of the network module of the Qt GUI Toolkit. 10** This file is part of the network module of the Qt GUI Toolkit.
11** 11**
@@ -59,8 +59,22 @@
59 #define S_ISDIR(m)(((m) & S_IFMT) == S_IFDIR) 59 #define S_ISDIR(m)(((m) & S_IFMT) == S_IFDIR)
60#endif 60#endif
61 61
62static QString mkdir_p_asstring(const QString &dir)
63{
64 QString ret = "@$(CHK_DIR_EXISTS) \"" + dir + "\" ";
65 if(Option::target_mode == Option::TARG_WIN_MODE)
66 ret += "$(MKDIR)";
67 else
68 ret += "|| $(MKDIR)";
69 ret += " \"" + dir + "\"";
70 return ret;
71}
72
62static bool createDir(const QString& fullPath) 73static bool createDir(const QString& fullPath)
63{ 74{
75 if(QFile::exists(fullPath))
76 return FALSE;
77
64 QDir dirTmp; 78 QDir dirTmp;
65 bool ret = TRUE; 79 bool ret = TRUE;
66 QString pathComponent, tmpPath; 80 QString pathComponent, tmpPath;
@@ -77,8 +91,8 @@ static bool createDir(const QString& fullPath)
77} 91}
78 92
79 93
80MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE), 94MakefileGenerator::MakefileGenerator(QMakeProject *p) : init_opath_already(FALSE),
81 init_already(FALSE), moc_aware(FALSE), 95 init_already(FALSE), moc_aware(FALSE),
82 no_io(FALSE), project(p) 96 no_io(FALSE), project(p)
83{ 97{
84} 98}
@@ -88,12 +102,12 @@ static char *gimme_buffer(off_t s)
88 static char *big_buffer = NULL; 102 static char *big_buffer = NULL;
89 static int big_buffer_size = 0; 103 static int big_buffer_size = 0;
90 if(!big_buffer || big_buffer_size < s) 104 if(!big_buffer || big_buffer_size < s)
91 big_buffer = (char *)realloc(big_buffer, s); 105 big_buffer = (char *)realloc(big_buffer, s);
92 return big_buffer; 106 return big_buffer;
93} 107}
94 108
95bool 109bool
96MakefileGenerator::generateMocList(QString fn_target) 110MakefileGenerator::generateMocList(const QString &fn_target)
97{ 111{
98 if(!findMocDestination(fn_target).isEmpty()) 112 if(!findMocDestination(fn_target).isEmpty())
99 return TRUE; 113 return TRUE;
@@ -173,7 +187,8 @@ MakefileGenerator::generateMocList(QString fn_target)
173 interesting = FALSE; 187 interesting = FALSE;
174 if(interesting) { 188 if(interesting) {
175 *(big_buffer+x+len) = '\0'; 189 *(big_buffer+x+len) = '\0';
176 debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(), line_count, big_buffer+x); 190 debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", fn_target.latin1(),
191 line_count, big_buffer+x);
177 192
178 int ext_pos = fn_target.findRev('.'); 193 int ext_pos = fn_target.findRev('.');
179 int ext_len = fn_target.length() - ext_pos; 194 int ext_len = fn_target.length() - ext_pos;
@@ -185,16 +200,17 @@ MakefileGenerator::generateMocList(QString fn_target)
185 mocFile = fn_target.left(dir_pos+1); 200 mocFile = fn_target.left(dir_pos+1);
186 201
187 bool cpp_ext = FALSE; 202 bool cpp_ext = FALSE;
188 for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { 203 for(QStringList::Iterator cppit = Option::cpp_ext.begin();
204 cppit != Option::cpp_ext.end(); ++cppit) {
189 if((cpp_ext = (fn_target.right(ext_len) == (*cppit)))) 205 if((cpp_ext = (fn_target.right(ext_len) == (*cppit))))
190 break; 206 break;
191 } 207 }
192 if(cpp_ext) { 208 if(cpp_ext) {
193 mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext; 209 mocFile += fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + Option::moc_ext;
194 findDependencies(fn_target).append(mocFile);
195 project->variables()["_SRCMOC"].append(mocFile); 210 project->variables()["_SRCMOC"].append(mocFile);
196 } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) { 211 } else if(project->variables()["HEADERS"].findIndex(fn_target) != -1) {
197 for(QStringList::Iterator hit = Option::h_ext.begin(); hit != Option::h_ext.end(); ++hit) { 212 for(QStringList::Iterator hit = Option::h_ext.begin();
213 hit != Option::h_ext.end(); ++hit) {
198 if((fn_target.right(ext_len) == (*hit))) { 214 if((fn_target.right(ext_len) == (*hit))) {
199 mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) + 215 mocFile += Option::moc_mod + fn_target.mid(dir_pos+1, ext_pos - dir_pos-1) +
200 Option::cpp_ext.first(); 216 Option::cpp_ext.first();
@@ -225,13 +241,12 @@ MakefileGenerator::generateMocList(QString fn_target)
225} 241}
226 242
227bool 243bool
228MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QString fn, bool recurse) 244MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, const QString &f, bool recurse)
229{ 245{
230 fn = fileFixify(fn); 246 QStringList &fndeps = findDependencies(f);
231 QStringList &fndeps = findDependencies(fn);
232 if(!fndeps.isEmpty()) 247 if(!fndeps.isEmpty())
233 return TRUE; 248 return TRUE;
234 249 QString fn = fileFixify(f, QDir::currentDirPath(), Option::output_dir);
235 fn = Option::fixPathToLocalOS(fn, FALSE); 250 fn = Option::fixPathToLocalOS(fn, FALSE);
236 QString fix_env_fn = Option::fixPathToLocalOS(fn); 251 QString fix_env_fn = Option::fixPathToLocalOS(fn);
237 int file = open(fix_env_fn.latin1(), O_RDONLY); 252 int file = open(fix_env_fn.latin1(), O_RDONLY);
@@ -288,8 +303,10 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
288 while(x < total_size_read && //Skip spaces after hash 303 while(x < total_size_read && //Skip spaces after hash
289 (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) 304 (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'))
290 x++; 305 x++;
291 if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include ", 8)) { 306 if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) &&
292 for(x+=8; //skip spaces after keyword 307 (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '\t' ||
308 *(big_buffer + x + 7) == '<' || *(big_buffer + x + 7) == '"')) {
309 for(x+=7; //skip spaces after keyword
293 x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'); 310 x < total_size_read && (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t');
294 x++); 311 x++);
295 char term = *(big_buffer + x); 312 char term = *(big_buffer + x);
@@ -328,7 +345,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
328 } else if(ui_file) { 345 } else if(ui_file) {
329 // skip whitespaces 346 // skip whitespaces
330 while(x < total_size_read && 347 while(x < total_size_read &&
331 (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t')) 348 (*(big_buffer+x) == ' ' || *(big_buffer+x) == '\t'))
332 x++; 349 x++;
333 if(*(big_buffer + x) == '<') { 350 if(*(big_buffer + x) == '<') {
334 x++; 351 x++;
@@ -342,7 +359,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
342 } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) && 359 } else if(total_size_read >= x + 8 && !strncmp(big_buffer + x, "include", 7) &&
343 (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) { 360 (*(big_buffer + x + 7) == ' ' || *(big_buffer + x + 7) == '>')) {
344 for(x += 8; *(big_buffer + x) != '>'; x++) { 361 for(x += 8; *(big_buffer + x) != '>'; x++) {
345 if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' && 362 if(total_size_read >= x + 9 && *(big_buffer + x) == 'i' &&
346 !strncmp(big_buffer + x, "impldecl", 8)) { 363 !strncmp(big_buffer + x, "impldecl", 8)) {
347 for(x += 8; *(big_buffer + x) != '='; x++); 364 for(x += 8; *(big_buffer + x) != '='; x++);
348 if(*(big_buffer + x) != '=') 365 if(*(big_buffer + x) != '=')
@@ -369,7 +386,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
369 *(big_buffer + x + val_len) = saved; 386 *(big_buffer + x + val_len) = saved;
370 if(where == "in implementation") { 387 if(where == "in implementation") {
371 QString cpp = fn.left(fn.length() - Option::ui_ext.length()) + 388 QString cpp = fn.left(fn.length() - Option::ui_ext.length()) +
372 Option::cpp_ext.first(); 389 Option::cpp_ext.first();
373 outdeps = &findDependencies(cpp); 390 outdeps = &findDependencies(cpp);
374 } 391 }
375 } 392 }
@@ -383,6 +400,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
383 } 400 }
384 401
385 if(!inc.isEmpty()) { 402 if(!inc.isEmpty()) {
403 bool from_source_dir = TRUE;
386 debug_msg(5, "%s:%d Found dependency to %s", fix_env_fn.latin1(), 404 debug_msg(5, "%s:%d Found dependency to %s", fix_env_fn.latin1(),
387 line_count, inc.latin1()); 405 line_count, inc.latin1());
388 if(!project->isEmpty("SKIP_DEPENDS")) { 406 if(!project->isEmpty("SKIP_DEPENDS")) {
@@ -404,6 +422,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
404 if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") && 422 if(project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH") &&
405 !stat(fix_env_fndir + inc, &fst) && !S_ISDIR(fst.st_mode)) { 423 !stat(fix_env_fndir + inc, &fst) && !S_ISDIR(fst.st_mode)) {
406 fqn = fndir + inc; 424 fqn = fndir + inc;
425 goto handle_fqn;
407 } else { 426 } else {
408 if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) || 427 if((Option::target_mode == Option::TARG_MAC9_MODE && inc.find(':')) ||
409 (Option::target_mode == Option::TARG_WIN_MODE && inc[1] != ':') || 428 (Option::target_mode == Option::TARG_WIN_MODE && inc[1] != ':') ||
@@ -415,17 +434,17 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
415 if(!stat(mdd->local_dir + QDir::separator() + inc, &fst) && 434 if(!stat(mdd->local_dir + QDir::separator() + inc, &fst) &&
416 !S_ISDIR(fst.st_mode)) { 435 !S_ISDIR(fst.st_mode)) {
417 fqn = mdd->real_dir + QDir::separator() + inc; 436 fqn = mdd->real_dir + QDir::separator() + inc;
418 break; 437 goto handle_fqn;
419 } 438 }
420 } 439 }
421 } 440 }
422 } 441 }
423 if(fqn.isEmpty()) { 442 if(fqn.isEmpty() && Option::mkfile::do_dep_heuristics) {
424 //these are some hacky heuristics it will try to do on an include 443 //these are some hacky heuristics it will try to do on an include
425 //however these can be turned off at runtime, I'm not sure how 444 //however these can be turned off at runtime, I'm not sure how
426 //reliable these will be, most likely when problems arise turn it off 445 //reliable these will be, most likely when problems arise turn it off
427 //and see if they go away.. 446 //and see if they go away..
428 if(Option::mkfile::do_dep_heuristics && depHeuristics.contains(inc)) { 447 if(depHeuristics.contains(inc)) {
429 fqn = depHeuristics[inc]; 448 fqn = depHeuristics[inc];
430 } else if(Option::mkfile::do_dep_heuristics) { //some heuristics.. 449 } else if(Option::mkfile::do_dep_heuristics) { //some heuristics..
431 //is it a file from a .ui? 450 //is it a file from a .ui?
@@ -447,11 +466,34 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
447 if(!fqn.isEmpty() && !fqn.endsWith(Option::dir_sep)) 466 if(!fqn.isEmpty() && !fqn.endsWith(Option::dir_sep))
448 fqn += Option::dir_sep; 467 fqn += Option::dir_sep;
449 fqn += inc_file; 468 fqn += inc_file;
450 break; 469 from_source_dir = FALSE; //uics go in the output_dir (so don't fix them)
470 fqn = fileFixify(fqn, QDir::currentDirPath(), Option::output_dir);
471 goto handle_fqn;
472 }
473 }
474 }
475 if(project->isActiveConfig("lex_included")) { //is this the lex file?
476 QString rhs = Option::lex_mod + Option::cpp_ext.first();
477 if(inc.endsWith(rhs)) {
478 QString lhs = inc.left(inc.length() - rhs.length()) + Option::lex_ext;
479 QStringList ll = project->variables()["LEXSOURCES"];
480 for(QStringList::Iterator it = ll.begin(); it != ll.end(); ++it) {
481 QString s = (*it), d;
482 int slsh = s.findRev(Option::dir_sep);
483 if(slsh != -1) {
484 d = s.left(slsh + 1);
485 s = s.right(s.length() - slsh - 1);
486 }
487 if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
488 d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH");
489 if(s == lhs) {
490 fqn = d + inc;
491 goto handle_fqn;
492 }
451 } 493 }
452 } 494 }
453 } 495 }
454 if(fqn.isEmpty()) { //is it from a .y? 496 { //is it from a .y?
455 QString rhs = Option::yacc_mod + Option::h_ext.first(); 497 QString rhs = Option::yacc_mod + Option::h_ext.first();
456 if(inc.endsWith(rhs)) { 498 if(inc.endsWith(rhs)) {
457 QString lhs = inc.left(inc.length() - rhs.length()) + Option::yacc_ext; 499 QString lhs = inc.left(inc.length() - rhs.length()) + Option::yacc_ext;
@@ -467,19 +509,48 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
467 d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH"); 509 d = project->first("QMAKE_ABSOLUTE_SOURCE_PATH");
468 if(s == lhs) { 510 if(s == lhs) {
469 fqn = d + inc; 511 fqn = d + inc;
470 break; 512 goto handle_fqn;
513 }
514 }
515 }
516 }
517 if(mocAware() && //is it a moc file?
518 (inc.endsWith(Option::cpp_ext.first()) || inc.endsWith(Option::moc_ext))) {
519 QString mocs[] = { QString("_HDRMOC"), QString("_SRCMOC"), QString::null };
520 for(int moc = 0; !mocs[moc].isNull(); moc++) {
521 QStringList &l = project->variables()[mocs[moc]];
522 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
523 QString file = Option::fixPathToTargetOS((*it));
524 if(file.section(Option::dir_sep, -(inc.contains('/')+1)) == inc) {
525 fqn = (*it);
526 if(mocs[moc] == "_HDRMOC") {
527 //Since it is include, no need to link it in as well
528 project->variables()["_SRCMOC"].append((*it));
529 l.remove(it);
530 } else if(!findMocSource(fqn).endsWith(fn)) {
531 /* Not really a very good test, but this will at least avoid
532 confusion if it really does happen (since tmake/qmake
533 previously didn't even allow this the test is mostly accurate) */
534 warn_msg(WarnLogic,
535 "Found potential multiple MOC include %s (%s) in '%s'",
536 inc.latin1(), fqn.latin1(), fix_env_fn.latin1());
537 }
538 from_source_dir = FALSE; //mocs go in the output_dir (so don't fix them)
539 goto handle_fqn;
471 } 540 }
472 } 541 }
473 } 542 }
474 } 543 }
475 depHeuristics.insert(inc, fqn); 544 depHeuristics.insert(inc, fqn);
476 } 545 }
477 if(!Option::mkfile::do_dep_heuristics || fqn.isEmpty()) //I give up
478 continue;
479 } 546 }
480 547 handle_fqn:
481 fqn = fileFixify(Option::fixPathToTargetOS(fqn, FALSE)); 548 if(fqn.isEmpty()) //I give up
482 debug_msg(4, "Resolved dependancy of %s to %s", inc.latin1(), fqn.latin1()); 549 continue;
550 fqn = Option::fixPathToTargetOS(fqn, FALSE);
551 if(from_source_dir)
552 fqn = fileFixify(fqn);
553 debug_msg(4, "Resolved dependency of %s to %s", inc.latin1(), fqn.latin1());
483 if(outdeps && outdeps->findIndex(fqn) == -1) 554 if(outdeps && outdeps->findIndex(fqn) == -1)
484 outdeps->append(fqn); 555 outdeps->append(fqn);
485 } 556 }
@@ -497,7 +568,7 @@ MakefileGenerator::generateDependencies(QPtrList<MakefileDependDir> &dirs, QStri
497 fndeps.append((*it)); 568 fndeps.append((*it));
498 } 569 }
499 } 570 }
500 debug_msg(2, "Dependancies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1()); 571 debug_msg(2, "Dependencies: %s -> %s", fn.latin1(), fndeps.join(" :: ").latin1());
501 return TRUE; 572 return TRUE;
502} 573}
503 574
@@ -613,7 +684,11 @@ MakefileGenerator::init()
613 684
614 /* get deps and mocables */ 685 /* get deps and mocables */
615 QDict<void> cache_found_files; 686 QDict<void> cache_found_files;
616 QString cache_file(Option::output_dir + QDir::separator() + ".qmake.internal.cache"); 687 QString cache_file(".qmake.internal.cache");
688 if(!project->isEmpty("QMAKE_INTERNAL_CACHE_FILE"))
689 cache_file = Option::fixPathToLocalOS(project->first("QMAKE_INTERNAL_CACHE_FILE"));
690 if(cache_file.find(QDir::separator()) == -1) //guess they know what they are doing..
691 cache_file.prepend(Option::output_dir + QDir::separator());
617 if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT || 692 if((Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT ||
618 Option::mkfile::do_deps || Option::mkfile::do_mocs) && !noIO()) { 693 Option::mkfile::do_deps || Option::mkfile::do_mocs) && !noIO()) {
619 QPtrList<MakefileDependDir> deplist; 694 QPtrList<MakefileDependDir> deplist;
@@ -628,7 +703,7 @@ MakefileGenerator::init()
628 deplist.append(new MakefileDependDir(r.replace("\"",""), 703 deplist.append(new MakefileDependDir(r.replace("\"",""),
629 l.replace("\"",""))); 704 l.replace("\"","")));
630 } 705 }
631 debug_msg(1, "Dependancy Directories: %s", incDirs.join(" :: ").latin1()); 706 debug_msg(1, "Dependency Directories: %s", incDirs.join(" :: ").latin1());
632 if(Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) { 707 if(Option::output.name() != "-" && project->isActiveConfig("qmake_cache")) {
633 QFile cachef(cache_file); 708 QFile cachef(cache_file);
634 if(cachef.open(IO_ReadOnly | IO_Translate)) { 709 if(cachef.open(IO_ReadOnly | IO_Translate)) {
@@ -683,7 +758,7 @@ MakefileGenerator::init()
683 } 758 }
684 } 759 }
685 if(found) { 760 if(found) {
686 debug_msg(2, "Dependancies (cached): %s -> %s", file.latin1(), 761 debug_msg(2, "Dependencies (cached): %s -> %s", file.latin1(),
687 files.join(" :: ").latin1()); 762 files.join(" :: ").latin1());
688 findDependencies(file) = files; 763 findDependencies(file) = files;
689 } 764 }
@@ -743,6 +818,7 @@ MakefileGenerator::init()
743 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { 818 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
744 if(!(*val_it).isEmpty()) { 819 if(!(*val_it).isEmpty()) {
745 QString file = Option::fixPathToLocalOS((*val_it)); 820 QString file = Option::fixPathToLocalOS((*val_it));
821 QStringList file_list(file);
746 if(!QFile::exists(file)) { 822 if(!QFile::exists(file)) {
747 bool found = FALSE; 823 bool found = FALSE;
748 if(QDir::isRelativePath(file)) { 824 if(QDir::isRelativePath(file)) {
@@ -769,7 +845,7 @@ MakefileGenerator::init()
769 QString dir, regex = (*val_it), real_dir; 845 QString dir, regex = (*val_it), real_dir;
770 if(regex.findRev(Option::dir_sep) != -1) { 846 if(regex.findRev(Option::dir_sep) != -1) {
771 dir = regex.left(regex.findRev(Option::dir_sep) + 1); 847 dir = regex.left(regex.findRev(Option::dir_sep) + 1);
772 real_dir = fileFixify(Option::fixPathToLocalOS(dir), 848 real_dir = fileFixify(Option::fixPathToLocalOS(dir),
773 QDir::currentDirPath(), Option::output_dir); 849 QDir::currentDirPath(), Option::output_dir);
774 regex = regex.right(regex.length() - dir.length()); 850 regex = regex.right(regex.length() - dir.length());
775 } 851 }
@@ -782,9 +858,14 @@ MakefileGenerator::init()
782 warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1()); 858 warn_msg(WarnLogic, "Failure to find: %s", (*val_it).latin1());
783 continue; 859 continue;
784 } else { 860 } else {
785 (*val_it) = dir + d[0]; 861 file_list.clear();
786 for(int i = 1; i < (int)d.count(); i++) 862 for(int i = 0; i < (int)d.count(); i++) {
787 l.insert(val_it, dir + d[i]); 863 file_list.append(dir + d[i]);
864 if(i == (int)d.count() - 1)
865 (*val_it) = dir + d[i];
866 else
867 l.insert(val_it, dir + d[i]);
868 }
788 } 869 }
789 } else { 870 } else {
790 debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.", 871 debug_msg(1, "%s:%d Cannot match %s%c%s, as %s does not exist.",
@@ -795,39 +876,43 @@ MakefileGenerator::init()
795 } 876 }
796 } 877 }
797 } 878 }
798 879 for(QStringList::Iterator file_it = file_list.begin();
799 QString val_file = fileFixify((*val_it)); 880 file_it != file_list.end(); ++file_it) {
800 bool found_cache_moc = FALSE, found_cache_dep = FALSE; 881 QString file_list_file = fileFixify((*file_it));
801 if(read_cache && Option::output.name() != "-" && 882 bool found_cache_moc = FALSE, found_cache_dep = FALSE;
802 project->isActiveConfig("qmake_cache")) { 883 if(read_cache && Option::output.name() != "-" &&
803 if(!findDependencies(val_file).isEmpty()) 884 project->isActiveConfig("qmake_cache")) {
804 found_cache_dep = TRUE; 885 if(!findDependencies(file_list_file).isEmpty())
805 if(cache_found_files[(*val_it)] == (void *)2) 886 found_cache_dep = TRUE;
806 found_cache_moc = TRUE; 887 if(cache_found_files[(*file_it)] == (void *)2)
807 if(!found_cache_moc || !found_cache_dep) 888 found_cache_moc = TRUE;
808 write_cache = TRUE; 889 if(!found_cache_moc || !found_cache_dep)
809 } 890 write_cache = TRUE;
810 if(!found_cache_dep && sources[x] != "OBJECTS") { 891 }
811 debug_msg(5, "Looking for dependancies for %s", (*val_it).latin1()); 892 /* Do moc before dependency checking since some includes can come from
812 generateDependencies(deplist, (*val_it), doDepends()); 893 moc_*.cpp files */
813 } 894 if(found_cache_moc) {
814 if(found_cache_moc) { 895 QString moc = findMocDestination(file_list_file);
815 QString moc = findMocDestination(val_file); 896 if(!moc.isEmpty()) {
816 if(!moc.isEmpty()) { 897 for(QStringList::Iterator cppit = Option::cpp_ext.begin();
817 for(QStringList::Iterator cppit = Option::cpp_ext.begin(); 898 cppit != Option::cpp_ext.end(); ++cppit) {
818 cppit != Option::cpp_ext.end(); ++cppit) { 899 if(file_list_file.endsWith((*cppit))) {
819 if(val_file.endsWith((*cppit))) { 900 QStringList &deps = findDependencies(file_list_file);
820 QStringList &deps = findDependencies(val_file); 901 if(!deps.contains(moc))
821 if(!deps.contains(moc)) 902 deps.append(moc);
822 deps.append(moc); 903 break;
823 break; 904 }
824 } 905 }
825 } 906 }
907 } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") &&
908 (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT ||
909 Option::mkfile::do_mocs)) {
910 generateMocList((*file_it));
911 }
912 if(!found_cache_dep && sources[x] != "OBJECTS") {
913 debug_msg(5, "Looking for dependencies for %s", (*file_it).latin1());
914 generateDependencies(deplist, (*file_it), doDepends());
826 } 915 }
827 } else if(mocAware() && (sources[x] == "SOURCES" || sources[x] == "HEADERS") &&
828 (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT ||
829 Option::mkfile::do_mocs)) {
830 generateMocList((*val_it));
831 } 916 }
832 } 917 }
833 } 918 }
@@ -853,11 +938,12 @@ MakefileGenerator::init()
853 for(int x = 0; moc_sources[x] != QString::null; x++) { 938 for(int x = 0; moc_sources[x] != QString::null; x++) {
854 QStringList &l = v[moc_sources[x]]; 939 QStringList &l = v[moc_sources[x]];
855 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) { 940 for(QStringList::Iterator val_it = l.begin(); val_it != l.end(); ++val_it) {
856 if(!(*val_it).isEmpty()) { 941 QString f = fileFixify((*val_it));
857 mc = mocablesToMOC[(*val_it)]; 942 if(!f.isEmpty()) {
943 mc = mocablesToMOC[f];
858 if(mc.isEmpty()) 944 if(mc.isEmpty())
859 mc = "*qmake_ignore*"; 945 mc = "*qmake_ignore*";
860 cachet << (*val_it) << " = " << mc << endl; 946 cachet << f << " = " << mc << endl;
861 } 947 }
862 } 948 }
863 } 949 }
@@ -946,10 +1032,11 @@ MakefileGenerator::init()
946 1032
947 //UI files 1033 //UI files
948 { 1034 {
1035 QStringList &includepath = project->variables()["INCLUDEPATH"];
949 if(!project->isEmpty("UI_DIR")) 1036 if(!project->isEmpty("UI_DIR"))
950 project->variables()["INCLUDEPATH"].append(project->first("UI_DIR")); 1037 includepath.append(project->first("UI_DIR"));
951 else if(!project->isEmpty("UI_HEADERS_DIR")) 1038 else if(!project->isEmpty("UI_HEADERS_DIR"))
952 project->variables()["INCLUDEPATH"].append(project->first("UI_HEADERS_DIR")); 1039 includepath.append(project->first("UI_HEADERS_DIR"));
953 QStringList &decls = v["UICDECLS"], &impls = v["UICIMPLS"]; 1040 QStringList &decls = v["UICDECLS"], &impls = v["UICIMPLS"];
954 QStringList &l = v["FORMS"]; 1041 QStringList &l = v["FORMS"];
955 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { 1042 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
@@ -960,19 +1047,20 @@ MakefileGenerator::init()
960 QString d = fi.dirPath(); 1047 QString d = fi.dirPath();
961 if( d == ".") 1048 if( d == ".")
962 d = QDir::currentDirPath(); 1049 d = QDir::currentDirPath();
963 d = fileFixify(d); 1050 d = fileFixify(d, QDir::currentDirPath(), Option::output_dir);
964 if( !project->variables()["INCLUDEPATH"].contains(d)) 1051 if(!includepath.contains(d))
965 project->variables()["INCLUDEPATH"].append(d); 1052 includepath.append(d);
966 } else { 1053 } else {
967 if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR")) 1054 if(decl.isEmpty() && !project->isEmpty("UI_HEADERS_DIR"))
968 decl = project->first("UI_HEADERS_DIR"); 1055 decl = project->first("UI_HEADERS_DIR");
969 if ( !decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") && !project->isEmpty("UI_SOURCES_DIR")) ) { 1056 if(!decl.isEmpty() || (project->isEmpty("UI_HEADERS_DIR") &&
1057 !project->isEmpty("UI_SOURCES_DIR")) ) {
970 QString d = fi.dirPath(); 1058 QString d = fi.dirPath();
971 if( d == ".") 1059 if( d == ".")
972 d = QDir::currentDirPath(); 1060 d = QDir::currentDirPath();
973 d = fileFixify(d); 1061 d = fileFixify(d, QDir::currentDirPath(), Option::output_dir);
974 if( !project->variables()["INCLUDEPATH"].contains(d)) 1062 if(includepath.contains(d))
975 project->variables()["INCLUDEPATH"].append(d); 1063 includepath.append(d);
976 } 1064 }
977 if(impl.isEmpty() && !project->isEmpty("UI_SOURCES_DIR")) 1065 if(impl.isEmpty() && !project->isEmpty("UI_SOURCES_DIR"))
978 impl = project->first("UI_SOURCES_DIR"); 1066 impl = project->first("UI_SOURCES_DIR");
@@ -983,7 +1071,21 @@ MakefileGenerator::init()
983 decl = fi.dirPath() + Option::dir_sep; 1071 decl = fi.dirPath() + Option::dir_sep;
984 } 1072 }
985 } 1073 }
986 impl += fi.baseName(TRUE) + Option::cpp_ext.first(), 1074 impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir);
1075 if(!impl.isEmpty())
1076 impl += Option::dir_sep;
1077 impl += fi.baseName(TRUE) + Option::cpp_ext.first();
1078 if(Option::output_dir != QDir::currentDirPath() &&
1079 project->isEmpty("UI_DIR") && project->isEmpty("UI_HEADERS_DIR")) {
1080 QString decl_fixed = fileFixify(decl, QDir::currentDirPath(), Option::output_dir);
1081 if(!includepath.contains(decl_fixed))
1082 includepath.append(decl_fixed);
1083 if(!includepath.contains(decl))
1084 project->variables()["INCLUDEPATH"].append(decl);
1085 }
1086 decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir);
1087 if(!decl.isEmpty())
1088 decl += Option::dir_sep;
987 decl += fi.baseName(TRUE) + Option::h_ext.first(); 1089 decl += fi.baseName(TRUE) + Option::h_ext.first();
988 logicWarn(impl, "SOURCES"); 1090 logicWarn(impl, "SOURCES");
989 logicWarn(decl, "HEADERS"); 1091 logicWarn(decl, "HEADERS");
@@ -1030,9 +1132,9 @@ MakefileGenerator::init()
1030 } 1132 }
1031 v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION")); 1133 v["OBJECTS"] += (v["IMAGEOBJECTS"] = createObjectList("QMAKE_IMAGE_COLLECTION"));
1032 } 1134 }
1033 1135 if(Option::output_dir != QDir::currentDirPath())
1034 if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) 1136 project->variables()["INCLUDEPATH"].append(fileFixify(Option::output_dir, Option::output_dir,
1035 project->variables()["INCLUDEPATH"].append(Option::output_dir); 1137 Option::output_dir));
1036 1138
1037 //moc files 1139 //moc files
1038 if ( mocAware() ) { 1140 if ( mocAware() ) {
@@ -1066,7 +1168,7 @@ MakefileGenerator::processPrlFile(QString &file)
1066 prl_file = tmp + Option::prl_ext; 1168 prl_file = tmp + Option::prl_ext;
1067 } 1169 }
1068 prl_file = fileFixify(prl_file); 1170 prl_file = fileFixify(prl_file);
1069 if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) && 1171 if(!QFile::exists(fileFixify(prl_file, QDir::currentDirPath(), Option::output_dir)) &&
1070 project->isActiveConfig("qt")) { 1172 project->isActiveConfig("qt")) {
1071 QString stem = prl_file, dir, extn; 1173 QString stem = prl_file, dir, extn;
1072 int slsh = stem.findRev('/'), hadlib = 0; 1174 int slsh = stem.findRev('/'), hadlib = 0;
@@ -1104,7 +1206,7 @@ MakefileGenerator::processPrlFile(QString &file)
1104 QMakeProject proj; 1206 QMakeProject proj;
1105 debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1()); 1207 debug_msg(1, "Processing PRL file: %s", real_prl_file.latin1());
1106 if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir), 1208 if(!proj.read(fileFixify(real_prl_file, QDir::currentDirPath(), Option::output_dir),
1107 QDir::currentDirPath())) { 1209 QDir::currentDirPath(), TRUE)) {
1108 fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1()); 1210 fprintf(stderr, "Error processing prl file: %s\n", real_prl_file.latin1());
1109 } else { 1211 } else {
1110 ret = TRUE; 1212 ret = TRUE;
@@ -1196,6 +1298,8 @@ MakefileGenerator::writePrlFile(QTextStream &t)
1196 t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl; 1298 t << "QMAKE_PRL_DEFINES = " << project->variables()["PRL_EXPORT_DEFINES"].join(" ") << endl;
1197 if(!project->isEmpty("CONFIG")) 1299 if(!project->isEmpty("CONFIG"))
1198 t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl; 1300 t << "QMAKE_PRL_CONFIG = " << project->variables()["CONFIG"].join(" ") << endl;
1301 if(!project->isEmpty("VERSION"))
1302 t << "QMAKE_PRL_VERSION = " << project->first("VERSION") << endl;
1199 if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) { 1303 if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) {
1200 QStringList libs; 1304 QStringList libs;
1201 if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) 1305 if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
@@ -1228,8 +1332,7 @@ MakefileGenerator::write()
1228 prl += Option::prl_ext; 1332 prl += Option::prl_ext;
1229 if(!project->isEmpty("DESTDIR")) 1333 if(!project->isEmpty("DESTDIR"))
1230 prl.prepend(var("DESTDIR")); 1334 prl.prepend(var("DESTDIR"));
1231 QString local_prl = fileFixify(prl, QDir::currentDirPath(), Option::output_dir); 1335 QString local_prl = Option::fixPathToLocalOS(fileFixify(prl, QDir::currentDirPath(), Option::output_dir));
1232 fixEnvVariables(local_prl);
1233 QFile ft(local_prl); 1336 QFile ft(local_prl);
1234 if(ft.open(IO_WriteOnly)) { 1337 if(ft.open(IO_WriteOnly)) {
1235 project->variables()["ALL_DEPS"].append(prl); 1338 project->variables()["ALL_DEPS"].append(prl);
@@ -1240,7 +1343,7 @@ MakefileGenerator::write()
1240 } 1343 }
1241 } 1344 }
1242 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && 1345 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE &&
1243 project->isActiveConfig("link_prl")) //load up prl's 1346 project->isActiveConfig("link_prl")) //load up prl's'
1244 processPrlFiles(); 1347 processPrlFiles();
1245 1348
1246 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || 1349 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
@@ -1302,7 +1405,7 @@ MakefileGenerator::writeObj(QTextStream &t, const QString &obj, const QString &s
1302 use_implicit_rule = FALSE; 1405 use_implicit_rule = FALSE;
1303 } 1406 }
1304 } 1407 }
1305 if (!use_implicit_rule) { 1408 if (!use_implicit_rule && !project->isEmpty(comp)) {
1306 QString p = var(comp); 1409 QString p = var(comp);
1307 p.replace(stringSrc, (*sit)); 1410 p.replace(stringSrc, (*sit));
1308 p.replace(stringObj, (*oit)); 1411 p.replace(stringObj, (*oit));
@@ -1320,20 +1423,36 @@ MakefileGenerator::writeUicSrc(QTextStream &t, const QString &ui)
1320 for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) { 1423 for(QStringList::Iterator it = uil.begin(); it != uil.end(); it++) {
1321 QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl; 1424 QString deps = findDependencies((*it)).join(" \\\n\t\t"), decl, impl;
1322 { 1425 {
1323 QString tmp = (*it); 1426 QString tmp = (*it), impl_dir, decl_dir;
1324 decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first()); 1427 decl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::h_ext.first());
1428 decl = fileFixify(decl, QDir::currentDirPath(), Option::output_dir);
1429 int dlen = decl.findRev(Option::dir_sep) + 1;
1325 tmp = (*it); 1430 tmp = (*it);
1326 impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first()); 1431 impl = tmp.replace(QRegExp("\\" + Option::ui_ext + "$"), Option::cpp_ext.first());
1327 int dlen = (*it).findRev(Option::dir_sep) + 1; 1432 impl = fileFixify(impl, QDir::currentDirPath(), Option::output_dir);
1433 int ilen = decl.findRev(Option::dir_sep) + 1;
1328 if(!project->isEmpty("UI_DIR")) { 1434 if(!project->isEmpty("UI_DIR")) {
1435 impl_dir = project->first("UI_DIR");
1329 decl = project->first("UI_DIR") + decl.right(decl.length() - dlen); 1436 decl = project->first("UI_DIR") + decl.right(decl.length() - dlen);
1330 impl = project->first("UI_DIR") + impl.right(impl.length() - dlen); 1437 impl = project->first("UI_DIR") + impl.right(impl.length() - ilen);
1331 } else { 1438 } else {
1332 if(!project->isEmpty("UI_HEADERS_DIR")) 1439 if(!project->isEmpty("UI_HEADERS_DIR")) {
1440 decl_dir = project->first("UI_HEADERS_DIR");
1333 decl = project->first("UI_HEADERS_DIR") + decl.right(decl.length() - dlen); 1441 decl = project->first("UI_HEADERS_DIR") + decl.right(decl.length() - dlen);
1334 if(!project->isEmpty("UI_SOURCES_DIR")) 1442 }
1335 impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - dlen); 1443 if(!project->isEmpty("UI_SOURCES_DIR")) {
1336 } 1444 impl_dir = project->first("UI_SOURCES_DIR");
1445 impl = project->first("UI_SOURCES_DIR") + impl.right(impl.length() - ilen);
1446 }
1447 }
1448 if(decl_dir.isEmpty())
1449 decl_dir = decl.left(dlen);
1450 if(impl_dir.isEmpty())
1451 impl_dir = impl.left(ilen);
1452 if(!impl_dir.isEmpty())
1453 createDir(Option::output_dir + Option::dir_sep + impl_dir);
1454 if(!decl_dir.isEmpty() && decl_dir != impl_dir)
1455 createDir(Option::output_dir + Option::dir_sep + decl_dir);
1337 } 1456 }
1338 t << decl << ": " << (*it) << " " << deps << "\n\t" 1457 t << decl << ": " << (*it) << " " << deps << "\n\t"
1339 << "$(UIC) " << (*it) << " -o " << decl << endl << endl; 1458 << "$(UIC) " << (*it) << " -o " << decl << endl << endl;
@@ -1370,7 +1489,7 @@ MakefileGenerator::writeMocObj(QTextStream &t, const QString &obj, const QString
1370 use_implicit_rule = FALSE; 1489 use_implicit_rule = FALSE;
1371 } 1490 }
1372 } 1491 }
1373 if (!use_implicit_rule) { 1492 if (!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) {
1374 QString p = var("QMAKE_RUN_CXX"); 1493 QString p = var("QMAKE_RUN_CXX");
1375 p.replace(stringSrc, (*sit)); 1494 p.replace(stringSrc, (*sit));
1376 p.replace(stringObj, (*oit)); 1495 p.replace(stringObj, (*oit));
@@ -1413,9 +1532,13 @@ MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src)
1413 QString stringBase("$base"); 1532 QString stringBase("$base");
1414 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { 1533 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
1415 QFileInfo fi((*it)); 1534 QFileInfo fi((*it));
1416 QString dir = fileFixify(Option::output_dir); 1535 QString dir;
1536 if(fi.dirPath() != ".")
1537 dir = fi.dirPath() + Option::dir_sep;
1538 dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
1417 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) 1539 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
1418 dir += Option::dir_sep; 1540 dir += Option::dir_sep;
1541
1419 QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first(); 1542 QString impl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first();
1420 QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first(); 1543 QString decl = dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first();
1421 1544
@@ -1423,7 +1546,7 @@ MakefileGenerator::writeYaccSrc(QTextStream &t, const QString &src)
1423 if(!project->isActiveConfig("yacc_no_name_mangle")) { 1546 if(!project->isActiveConfig("yacc_no_name_mangle")) {
1424 mangle = fi.baseName(TRUE); 1547 mangle = fi.baseName(TRUE);
1425 yaccflags += " -p " + mangle; 1548 yaccflags += " -p " + mangle;
1426 } 1549 }
1427 QString out_h = default_out_h, out_c = default_out_c; 1550 QString out_h = default_out_h, out_c = default_out_c;
1428 if(!mangle.isEmpty()) { 1551 if(!mangle.isEmpty()) {
1429 out_h.replace(stringBase, mangle); 1552 out_h.replace(stringBase, mangle);
@@ -1452,7 +1575,10 @@ MakefileGenerator::writeLexSrc(QTextStream &t, const QString &src)
1452 QString stringBase("$base"); 1575 QString stringBase("$base");
1453 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { 1576 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
1454 QFileInfo fi((*it)); 1577 QFileInfo fi((*it));
1455 QString dir = fileFixify(Option::output_dir); 1578 QString dir;
1579 if(fi.dirPath() != ".")
1580 dir = fi.dirPath() + Option::dir_sep;
1581 dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
1456 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep) 1582 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
1457 dir += Option::dir_sep; 1583 dir += Option::dir_sep;
1458 QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first(); 1584 QString impl = dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first();
@@ -1463,7 +1589,7 @@ MakefileGenerator::writeLexSrc(QTextStream &t, const QString &src)
1463 lexflags += " -P" + stub; 1589 lexflags += " -P" + stub;
1464 } 1590 }
1465 QString out_c = default_out_c; 1591 QString out_c = default_out_c;
1466 if(!stub.isEmpty()) 1592 if(!stub.isEmpty())
1467 out_c.replace(stringBase, stub); 1593 out_c.replace(stringBase, stub);
1468 1594
1469 t << impl << ": " << (*it) << " " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t" 1595 t << impl << ": " << (*it) << " " << findDependencies((*it)).join(" \\\n\t\t") << "\n\t"
@@ -1494,7 +1620,7 @@ MakefileGenerator::writeImageObj(QTextStream &t, const QString &obj)
1494 use_implicit_rule = FALSE; 1620 use_implicit_rule = FALSE;
1495 } 1621 }
1496 } 1622 }
1497 if(!use_implicit_rule) { 1623 if(!use_implicit_rule && !project->isEmpty("QMAKE_RUN_CXX")) {
1498 QString p = var("QMAKE_RUN_CXX"); 1624 QString p = var("QMAKE_RUN_CXX");
1499 p.replace( stringSrc, src); 1625 p.replace( stringSrc, src);
1500 p.replace( stringObj, (*oit)); 1626 p.replace( stringObj, (*oit));
@@ -1541,76 +1667,105 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs)
1541 } 1667 }
1542 1668
1543 bool do_default = TRUE; 1669 bool do_default = TRUE;
1544 QString target, dst="$(INSTALL_ROOT)" + Option::fixPathToTargetOS(project->variables()[pvar].first(), FALSE); 1670 const QString root = "$(INSTALL_ROOT)";
1671 QString target, dst= fileFixify(project->variables()[pvar].first());
1672#ifndef Q_WS_WIN
1545 if(dst.right(1) != Option::dir_sep) 1673 if(dst.right(1) != Option::dir_sep)
1546 dst += Option::dir_sep; 1674 dst += Option::dir_sep;
1547 QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"]; 1675#endif
1548 //other 1676 QStringList tmp, &uninst = project->variables()[(*it) + ".uninstall"];
1549 tmp = project->variables()[(*it) + ".extra"]; 1677 //other
1550 if(!tmp.isEmpty()) { 1678 tmp = project->variables()[(*it) + ".extra"];
1679 if(!tmp.isEmpty()) {
1551 do_default = FALSE; 1680 do_default = FALSE;
1552 if(!target.isEmpty()) 1681 if(!target.isEmpty())
1553 target += "\n\t"; 1682 target += "\n\t";
1554 target += tmp.join(" "); 1683 target += tmp.join(" ");
1555 } 1684 }
1556 //masks 1685 //masks
1557 tmp = project->variables()[(*it) + ".files"]; 1686 tmp = project->variables()[(*it) + ".files"];
1558 if(!tmp.isEmpty()) { 1687 if(!tmp.isEmpty()) {
1559 if(!target.isEmpty()) 1688 if(!target.isEmpty())
1560 target += "\n"; 1689 target += "\n";
1561 do_default = FALSE; 1690 do_default = FALSE;
1562 for(QStringList::Iterator wild_it = tmp.begin(); wild_it != tmp.end(); ++wild_it) { 1691 for(QStringList::Iterator wild_it = tmp.begin(); wild_it != tmp.end(); ++wild_it) {
1563 QString wild = Option::fixPathToLocalOS((*wild_it), FALSE), wild_var = fileFixify(wild); 1692 QString wild = Option::fixPathToLocalOS((*wild_it), FALSE), wild_var = fileFixify(wild);
1693 QString dirstr = QDir::currentDirPath(), filestr = wild;
1694 int slsh = filestr.findRev(Option::dir_sep);
1695 if(slsh != -1) {
1696 dirstr = filestr.left(slsh+1);
1697 filestr = filestr.right(filestr.length() - slsh - 1);
1698 }
1699 if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep)
1700 dirstr += Option::dir_sep;
1564 if(QFile::exists(wild)) { //real file 1701 if(QFile::exists(wild)) { //real file
1702 QString file = wild;
1565 QFileInfo fi(wild); 1703 QFileInfo fi(wild);
1566 target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + 1704 if(!target.isEmpty())
1567 " \"" + Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + fileFixify(dst) + "\"\n"; 1705 target += "\t";
1706 target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" +
1707 Option::fixPathToTargetOS(fileFixify(wild), FALSE) + "\" \"" + root + dst + "\"\n";
1568 if(!project->isActiveConfig("debug") && 1708 if(!project->isActiveConfig("debug") &&
1569 !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) 1709 !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP"))
1570 target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + wild) + "\"\n"; 1710 target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + filestr) + "\"\n";
1571 uninst.append(QString("-$(DEL_FILE) -r") + " \"" + fileFixify(dst + wild) + "\""); 1711 if(!uninst.isEmpty())
1712 uninst.append("\n\t");
1713 uninst.append(
1714#ifdef Q_WS_WIN
1715 QString("-$(DEL_FILE)")
1716#else
1717 QString("-$(DEL_FILE) -r")
1718#endif
1719 + " \"" + root + fileFixify(dst + filestr) + "\"");
1572 continue; 1720 continue;
1573 } 1721 }
1574 QString dirstr = QDir::currentDirPath(), f = wild; //wild 1722 QDir dir(dirstr, filestr); //wild
1575 int slsh = f.findRev(Option::dir_sep);
1576 if(slsh != -1) {
1577 dirstr = f.left(slsh+1);
1578 f = f.right(f.length() - slsh - 1);
1579 }
1580 if(dirstr.right(Option::dir_sep.length()) != Option::dir_sep)
1581 dirstr += Option::dir_sep;
1582 if(!uninst.isEmpty())
1583 uninst.append("\n\t");
1584 uninst.append(QString("-$(DEL_FILE) -r") + " " + fileFixify(dst + f) + "");
1585
1586 QDir dir(dirstr, f);
1587 for(uint x = 0; x < dir.count(); x++) { 1723 for(uint x = 0; x < dir.count(); x++) {
1588 QString file = dir[x]; 1724 QString file = dir[x];
1589 if(file == "." || file == "..") //blah 1725 if(file == "." || file == "..") //blah
1590 continue; 1726 continue;
1727 if(!uninst.isEmpty())
1728 uninst.append("\n\t");
1729 uninst.append(
1730#ifdef Q_WS_WIN
1731 QString("-$(DEL_FILE)")
1732#else
1733 QString("-$(DEL_FILE) -r")
1734#endif
1735 + " \"" + root + fileFixify(dst + file) + "\"");
1591 QFileInfo fi(file); 1736 QFileInfo fi(file);
1592 target += QString("\t-") + (fi.isDir() ? "$(COPY_DIR)" : "$(COPY_FILE)") + 1737 if(!target.isEmpty())
1593 " \"" + Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) + 1738 target += "\t";
1594 "\" \"" + fileFixify(dst) + "\"\n"; 1739 target += QString(fi.isDir() ? "-$(COPY_DIR)" : "-$(COPY_FILE)") + " \"" +
1740 Option::fixPathToTargetOS(fileFixify(dirstr + file), FALSE) +
1741 "\" \"" + root + fileFixify(dst) + "\"\n";
1595 if(!project->isActiveConfig("debug") && 1742 if(!project->isActiveConfig("debug") &&
1596 !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) 1743 !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP"))
1597 target += QString("\t") + var("QMAKE_STRIP") + " \"" + fileFixify(dst + file) + "\"\n"; 1744 target += QString("\t-") + var("QMAKE_STRIP") + " \"" + root + fileFixify(dst + file) + "\"\n";
1598 } 1745 }
1599 } 1746 }
1600 } 1747 }
1601 //default? 1748 //default?
1602 if(do_default) 1749 if(do_default)
1603 target = defaultInstall((*it)); 1750 target = defaultInstall((*it));
1604 1751
1605 if(!target.isEmpty()) { 1752 if(!target.isEmpty()) {
1606 t << "install_" << (*it) << ": " << "\n\t" 1753 t << "install_" << (*it) << ": " << "\n\t";
1607 << "@test -d " << dst << " || mkdir -p " << dst << "\n\t" 1754 const QStringList &dirs = project->variables()[pvar];
1608 << target << endl << endl; 1755 for(QStringList::ConstIterator pit = dirs.begin(); pit != dirs.end(); ++pit) {
1756 QString tmp_dst = fileFixify((*pit));
1757#ifndef Q_WS_WIN
1758 if(tmp_dst.right(1) != Option::dir_sep)
1759 tmp_dst += Option::dir_sep;
1760#endif
1761 t << mkdir_p_asstring(root+tmp_dst) << "\n\t";
1762 }
1763 t << target << endl << endl;
1609 all_installs += QString("install_") + (*it) + " "; 1764 all_installs += QString("install_") + (*it) + " ";
1610 if(!uninst.isEmpty()) { 1765 if(!uninst.isEmpty()) {
1611 t << "uninstall_" << (*it) << ": " << "\n\t" 1766 t << "uninstall_" << (*it) << ": " << "\n\t"
1612 << uninst.join(" ") << "\n\t" 1767 << uninst.join("") << "\n\t"
1613 << "-$(DEL_DIR) \"" << dst << "\"" << endl << endl; 1768 << "-$(DEL_DIR) \"" << ( root + dst ) << "\"" << endl << endl;
1614 all_uninstalls += "uninstall_" + (*it) + " "; 1769 all_uninstalls += "uninstall_" + (*it) + " ";
1615 } 1770 }
1616 t << endl; 1771 t << endl;
@@ -1787,7 +1942,7 @@ MakefileGenerator::writeHeader(QTextStream &t)
1787 time_t foo = time(NULL); 1942 time_t foo = time(NULL);
1788 t << "#############################################################################" << endl; 1943 t << "#############################################################################" << endl;
1789 t << "# Makefile for building: " << var("TARGET") << endl; 1944 t << "# Makefile for building: " << var("TARGET") << endl;
1790 t << "# Generated by qmake (" << qmake_version() << ") on: " << ctime(&foo); 1945 t << "# Generated by qmake (" << qmake_version() << ") (Qt " << QT_VERSION_STR << ") on: " << ctime(&foo);
1791 t << "# Project: " << fileFixify(project->projectFile()) << endl; 1946 t << "# Project: " << fileFixify(project->projectFile()) << endl;
1792 t << "# Template: " << var("TEMPLATE") << endl; 1947 t << "# Template: " << var("TEMPLATE") << endl;
1793 t << "# Command: " << build_args() << endl; 1948 t << "# Command: " << build_args() << endl;
@@ -1802,7 +1957,7 @@ bool
1802MakefileGenerator::writeMakeQmake(QTextStream &t) 1957MakefileGenerator::writeMakeQmake(QTextStream &t)
1803{ 1958{
1804 QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name())); 1959 QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.name()));
1805 if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && 1960 if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake") &&
1806 !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) { 1961 !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
1807 QStringList files = fileFixify(Option::mkfile::project_files); 1962 QStringList files = fileFixify(Option::mkfile::project_files);
1808 t << project->first("QMAKE_INTERNAL_PRL_FILE") << ": " << "\n\t" 1963 t << project->first("QMAKE_INTERNAL_PRL_FILE") << ": " << "\n\t"
@@ -1846,9 +2001,15 @@ MakefileGenerator::fileFixify(const QStringList& files, const QString &out_dir,
1846QString 2001QString
1847MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const 2002MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const QString &in_d, bool force_fix) const
1848{ 2003{
2004 if(file0.isEmpty())
2005 return file0;
2006 QString key = file0;
2007 if(!in_d.isEmpty() || !out_d.isEmpty() || force_fix)
2008 key.prepend(in_d + "--" + out_d + "--" + QString::number((int)force_fix) + "-");
2009 if(fileFixed.contains(key))
2010 return fileFixed[key];
2011
1849 QString file = file0; 2012 QString file = file0;
1850 if(file.isEmpty())
1851 return file;
1852 int depth = 4; 2013 int depth = 4;
1853 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || 2014 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
1854 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { 2015 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
@@ -1890,6 +2051,12 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const
1890 if(!out_fi.convertToAbs()) 2051 if(!out_fi.convertToAbs())
1891 out_dir = out_fi.filePath(); 2052 out_dir = out_fi.filePath();
1892 } 2053 }
2054 QString in_canonical_dir = QDir(in_dir).canonicalPath(),
2055 out_canonical_dir = QDir(out_dir).canonicalPath();
2056 if(!in_canonical_dir.isEmpty())
2057 in_dir = in_canonical_dir;
2058 if(!out_canonical_dir.isEmpty())
2059 out_dir = out_canonical_dir;
1893 } 2060 }
1894 if(out_dir != in_dir || !QDir::isRelativePath(qfile)) { 2061 if(out_dir != in_dir || !QDir::isRelativePath(qfile)) {
1895 if(QDir::isRelativePath(qfile)) { 2062 if(QDir::isRelativePath(qfile)) {
@@ -1899,6 +2066,11 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const
1899 file.prepend(in_dir); 2066 file.prepend(in_dir);
1900 } 2067 }
1901 file = Option::fixPathToTargetOS(file, FALSE); 2068 file = Option::fixPathToTargetOS(file, FALSE);
2069 if(QFile::exists(file) && file == Option::fixPathToTargetOS(file, TRUE)) {
2070 QString real_file = QDir(file).canonicalPath();
2071 if(!real_file.isEmpty())
2072 file = real_file;
2073 }
1902 QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE); 2074 QString match_dir = Option::fixPathToTargetOS(out_dir, FALSE);
1903 if(file == match_dir) { 2075 if(file == match_dir) {
1904 file = ""; 2076 file = "";
@@ -1929,9 +2101,12 @@ MakefileGenerator::fileFixify(const QString& file0, const QString &out_d, const
1929 } 2101 }
1930 } 2102 }
1931 file = Option::fixPathToTargetOS(file, FALSE); 2103 file = Option::fixPathToTargetOS(file, FALSE);
2104 if(file.isEmpty())
2105 file = ".";
1932 if(!quote.isNull()) 2106 if(!quote.isNull())
1933 file = quote + file + quote; 2107 file = quote + file + quote;
1934 debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth); 2108 debug_msg(3, "Fixed %s :: to :: %s (%d)", orig_file.latin1(), file.latin1(), depth);
2109 ((MakefileGenerator*)this)->fileFixed.insert(key, file);
1935 return file; 2110 return file;
1936} 2111}
1937 2112
@@ -2039,8 +2214,9 @@ MakefileGenerator::openOutput(QFile &file) const
2039 2214
2040//Factory thing 2215//Factory thing
2041#include "unixmake.h" 2216#include "unixmake.h"
2042#include "borland_bmake.h"
2043#include "msvc_nmake.h" 2217#include "msvc_nmake.h"
2218#include "borland_bmake.h"
2219#include "mingw_make.h"
2044#include "msvc_dsp.h" 2220#include "msvc_dsp.h"
2045#include "msvc_vcproj.h" 2221#include "msvc_vcproj.h"
2046#include "metrowerks_xml.h" 2222#include "metrowerks_xml.h"
@@ -2061,19 +2237,21 @@ MakefileGenerator::create(QMakeProject *proj)
2061 } else if(gen == "UNIX") { 2237 } else if(gen == "UNIX") {
2062 mkfile = new UnixMakefileGenerator(proj); 2238 mkfile = new UnixMakefileGenerator(proj);
2063 } else if(gen == "MSVC") { 2239 } else if(gen == "MSVC") {
2064 // Visual Studio =< v6.0 2240 // Visual Studio =< v6.0
2065 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) 2241 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1)
2066 mkfile = new DspMakefileGenerator(proj); 2242 mkfile = new DspMakefileGenerator(proj);
2067 else 2243 else
2068 mkfile = new NmakeMakefileGenerator(proj); 2244 mkfile = new NmakeMakefileGenerator(proj);
2069 } else if(gen == "MSVC.NET") { 2245 } else if(gen == "MSVC.NET") {
2070 // Visual Studio >= v7.0 2246 // Visual Studio >= v7.0
2071 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1) 2247 if(proj->first("TEMPLATE").find(QRegExp("^vc.*")) != -1)
2072 mkfile = new VcprojGenerator(proj); 2248 mkfile = new VcprojGenerator(proj);
2073 else 2249 else
2074 mkfile = new NmakeMakefileGenerator(proj); 2250 mkfile = new NmakeMakefileGenerator(proj);
2075 } else if(gen == "BMAKE") { 2251 } else if(gen == "BMAKE") {
2076 mkfile = new BorlandMakefileGenerator(proj); 2252 mkfile = new BorlandMakefileGenerator(proj);
2253 } else if(gen == "MINGW") {
2254 mkfile = new MingwMakefileGenerator(proj);
2077 } else if(gen == "METROWERKS") { 2255 } else if(gen == "METROWERKS") {
2078 mkfile = new MetrowerksMakefileGenerator(proj); 2256 mkfile = new MetrowerksMakefileGenerator(proj);
2079 } else if(gen == "PROJECTBUILDER") { 2257 } else if(gen == "PROJECTBUILDER") {