summaryrefslogtreecommitdiff
path: root/qmake/generators/win32/winmakefile.cpp
Unidiff
Diffstat (limited to 'qmake/generators/win32/winmakefile.cpp') (more/less context) (show whitespace changes)
-rw-r--r--qmake/generators/win32/winmakefile.cpp121
1 files changed, 98 insertions, 23 deletions
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index bc3fed9..cd733c6 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -1,16 +1,14 @@
1/**************************************************************************** 1/****************************************************************************
2** $Id$
3** 2**
4** Definition of ________ class.
5** 3**
6** Created : 970521 4** Implementation of Win32MakefileGenerator class.
7** 5**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved. 6** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
9** 7**
10** This file is part of the network module of the Qt GUI Toolkit. 8** This file is part of qmake.
11** 9**
12** This file may be distributed under the terms of the Q Public License 10** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file 11** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file. 12** LICENSE.QPL included in the packaging of this file.
15** 13**
16** This file may be distributed and/or modified under the terms of the 14** This file may be distributed and/or modified under the terms of the
@@ -35,12 +33,13 @@
35** 33**
36**********************************************************************/ 34**********************************************************************/
37 35
38#include "winmakefile.h" 36#include "winmakefile.h"
39#include "option.h" 37#include "option.h"
40#include "project.h" 38#include "project.h"
39#include "meta.h"
41#include <qtextstream.h> 40#include <qtextstream.h>
42#include <qstring.h> 41#include <qstring.h>
43#include <qdict.h> 42#include <qdict.h>
44#include <qregexp.h> 43#include <qregexp.h>
45#include <qstringlist.h> 44#include <qstringlist.h>
46#include <qdir.h> 45#include <qdir.h>
@@ -94,31 +93,28 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t)
94 sd->target.replace('/', '-'); 93 sd->target.replace('/', '-');
95 sd->target.replace('.', '_'); 94 sd->target.replace('.', '_');
96 } 95 }
97 } 96 }
98 QPtrListIterator<SubDir> it(subdirs); 97 QPtrListIterator<SubDir> it(subdirs);
99 98
100 if(!project->isEmpty("MAKEFILE")) 99 t << "MAKEFILE = " << (project->isEmpty("MAKEFILE") ? QString("Makefile") : var("MAKEFILE")) << endl;
101 t << "MAKEFILE=" << var("MAKEFILE") << endl;
102 t << "QMAKE =" << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; 100 t << "QMAKE =" << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
103 t << "SUBTARGETS= "; 101 t << "SUBTARGETS= ";
104 for( it.toFirst(); it.current(); ++it) 102 for( it.toFirst(); it.current(); ++it)
105 t << " \\\n\t\t" << it.current()->target; 103 t << " \\\n\t\t" << it.current()->target;
106 t << endl << endl; 104 t << endl << endl;
107 t << "all: qmake_all $(SUBTARGETS)" << endl << endl; 105 t << "all: $(MAKEFILE) $(SUBTARGETS)" << endl << endl;
108 106
109 for( it.toFirst(); it.current(); ++it) { 107 for( it.toFirst(); it.current(); ++it) {
110 bool have_dir = !(*it)->directory.isEmpty(); 108 bool have_dir = !(*it)->directory.isEmpty();
111 109
112 //make the makefile 110 //make the makefile
113 QString mkfile = (*it)->makefile; 111 QString mkfile = (*it)->makefile;
114 if(have_dir) 112 if(have_dir)
115 mkfile.prepend((*it)->directory + Option::dir_sep); 113 mkfile.prepend((*it)->directory + Option::dir_sep);
116 t << mkfile << ":"; 114 t << mkfile << ":";
117 if(project->variables()["QMAKE_NOFORCE"].isEmpty())
118 t << " FORCE";
119 if(have_dir) 115 if(have_dir)
120 t << "\n\t" << "cd " << (*it)->directory; 116 t << "\n\t" << "cd " << (*it)->directory;
121 t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs(); 117 t << "\n\t" << "$(QMAKE) " << (*it)->profile << " " << buildArgs();
122 t << " -o " << (*it)->makefile; 118 t << " -o " << (*it)->makefile;
123 if(have_dir) { 119 if(have_dir) {
124 int subLevels = it.current()->directory.contains(Option::dir_sep) + 1; 120 int subLevels = it.current()->directory.contains(Option::dir_sep) + 1;
@@ -142,12 +138,22 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t)
142 for(int i = 1; i < subLevels; i++ ) 138 for(int i = 1; i < subLevels; i++ )
143 t << Option::dir_sep << ".."; 139 t << Option::dir_sep << "..";
144 } 140 }
145 t << endl << endl; 141 t << endl << endl;
146 } 142 }
147 143
144 if (project->isActiveConfig("ordered")) { // generate dependencies
145 for( it.toFirst(); it.current(); ) {
146 QString tar = it.current()->target;
147 ++it;
148 if (it.current())
149 t << it.current()->target << ": " << tar << endl;
150 }
151 t << endl;
152 }
153
148 if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1) 154 if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1)
149 project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all"); 155 project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
150 writeMakeQmake(t); 156 writeMakeQmake(t);
151 157
152 t << "qmake_all:"; 158 t << "qmake_all:";
153 if ( !subdirs.isEmpty() ) { 159 if ( !subdirs.isEmpty() ) {
@@ -172,25 +178,32 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t)
172 // Borland make does not like empty an empty command section, so insert 178 // Borland make does not like empty an empty command section, so insert
173 // a dummy command. 179 // a dummy command.
174 t << "\n\t" << "@cd ."; 180 t << "\n\t" << "@cd .";
175 } 181 }
176 t << endl << endl; 182 t << endl << endl;
177 183
178 QString targs[] = { QString("clean"), QString("install"), QString("mocclean"), QString::null }; 184 QStringList targs;
179 for(int x = 0; targs[x] != QString::null; x++) { 185 targs << "clean" << "install_subdirs" << "mocables" << "uicables" << "uiclean" << "mocclean";
180 t << targs[x] << ": qmake_all"; 186 targs += project->values("SUBDIR_TARGETS");
181 if(targs[x] == "clean") 187 for(QStringList::Iterator targ_it = targs.begin(); targ_it != targs.end(); ++targ_it) {
182 t << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ", ""); 188 t << (*targ_it) << ": qmake_all";
189 QString targ = (*targ_it);
190 if(targ == "install_subdirs")
191 targ = "install";
192 else if(targ == "uninstall_subdirs")
193 targ = "uninstall";
194 if(targ == "clean")
195 t << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ", "");
183 if (!subdirs.isEmpty()) { 196 if (!subdirs.isEmpty()) {
184 for( it.toFirst(); it.current(); ++it) { 197 for( it.toFirst(); it.current(); ++it) {
185 int subLevels = (*it)->directory.contains(Option::dir_sep) + 1; 198 int subLevels = (*it)->directory.contains(Option::dir_sep) + 1;
186 bool have_dir = !(*it)->directory.isEmpty(); 199 bool have_dir = !(*it)->directory.isEmpty();
187 if(have_dir) 200 if(have_dir)
188 t << "\n\t" << "cd " << (*it)->directory; 201 t << "\n\t" << "cd " << (*it)->directory;
189 QString in_file = " -f " + (*it)->makefile; 202 QString in_file = " -f " + (*it)->makefile;
190 t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; 203 t << "\n\t" << "$(MAKE) " << in_file << " " << targ;
191 if(have_dir) { 204 if(have_dir) {
192 t << "\n\t" << "@cd .."; 205 t << "\n\t" << "@cd ..";
193 for(int i = 1; i < subLevels; i++ ) 206 for(int i = 1; i < subLevels; i++ )
194 t << Option::dir_sep << ".."; 207 t << Option::dir_sep << "..";
195 } 208 }
196 } 209 }
@@ -199,12 +212,38 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t)
199 // insert a dummy command. 212 // insert a dummy command.
200 t << "\n\t" << "@cd ."; 213 t << "\n\t" << "@cd .";
201 } 214 }
202 t << endl << endl; 215 t << endl << endl;
203 } 216 }
204 217
218 //installations
219 project->variables()["INSTALLDEPS"] += "install_subdirs";
220 project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs";
221 writeInstalls(t, "INSTALLS");
222
223 // user defined targets
224 QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
225 for(QStringList::Iterator sit = qut.begin(); sit != qut.end(); ++sit) {
226 QString targ = var((*sit) + ".target"),
227 cmd = var((*sit) + ".commands"), deps;
228 if(targ.isEmpty())
229 targ = (*sit);
230 QStringList &deplist = project->variables()[(*sit) + ".depends"];
231 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
232 QString dep = var((*dep_it) + ".target");
233 if(dep.isEmpty())
234 dep = (*dep_it);
235 deps += " " + dep;
236 }
237 if(!project->variables()["QMAKE_NOFORCE"].isEmpty() &&
238 project->variables()[(*sit) + ".CONFIG"].findIndex("phony") != -1)
239 deps += QString(" ") + "FORCE";
240 t << "\n\n" << targ << ":" << deps << "\n\t"
241 << cmd;
242 }
243
205 if(project->variables()["QMAKE_NOFORCE"].isEmpty()) 244 if(project->variables()["QMAKE_NOFORCE"].isEmpty())
206 t << "FORCE:" << endl << endl; 245 t << "FORCE:" << endl << endl;
207} 246}
208 247
209 248
210int 249int
@@ -223,22 +262,56 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem
223 QRegExp regx( "(" + dllStem + "([0-9]*)).lib", FALSE ); 262 QRegExp regx( "(" + dllStem + "([0-9]*)).lib", FALSE );
224 for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { 263 for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) {
225 if(regx.exactMatch((*it))) 264 if(regx.exactMatch((*it)))
226 biggest = QMAX(biggest, (regx.cap(1) == dllStem || 265 biggest = QMAX(biggest, (regx.cap(1) == dllStem ||
227 regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt()); 266 regx.cap(2).isEmpty()) ? -1 : regx.cap(2).toInt());
228 } 267 }
229 if(dir.exists(dllStem + Option::prl_ext)) { 268 QMakeMetaInfo libinfo;
230 QMakeProject proj; 269 if(libinfo.readLib(bd + dllStem)) {
231 if(proj.read(bd + dllStem + Option::prl_ext, QDir::currentDirPath(), TRUE)) { 270 if(!libinfo.isEmpty("QMAKE_PRL_VERSION"))
232 if(!proj.isEmpty("QMAKE_PRL_VERSION")) 271 biggest = QMAX(biggest, libinfo.first("QMAKE_PRL_VERSION").replace(".", "").toInt());
233 biggest = QMAX(biggest, proj.first("QMAKE_PRL_VERSION").replace(".", "").toInt());
234 }
235 } 272 }
236 return biggest; 273 return biggest;
237} 274}
238 275
276QString
277Win32MakefileGenerator::findDependency(const QString &dep)
278{
279 {
280 QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
281 for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
282 QString targ = var((*it) + ".target");
283 if(targ.isEmpty())
284 targ = (*it);
285 if(targ.endsWith(dep))
286 return targ;
287 }
288 }
289 {
290 QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"];
291 for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) {
292 QString tmp_out = project->variables()[(*it) + ".output"].first();
293 QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" ");
294 if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
295 continue;
296 QStringList &tmp = project->variables()[(*it) + ".input"];
297 for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
298 QStringList &inputs = project->variables()[(*it2)];
299 for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
300 QString out = tmp_out;
301 QFileInfo fi(Option::fixPathToLocalOS((*input)));
302 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
303 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
304 if(out.endsWith(dep))
305 return out;
306 }
307 }
308 }
309 }
310 return MakefileGenerator::findDependency(dep);
311}
239 312
240bool 313bool
241Win32MakefileGenerator::findLibraries(const QString &where) 314Win32MakefileGenerator::findLibraries(const QString &where)
242{ 315{
243 316
244 QStringList &l = project->variables()[where]; 317 QStringList &l = project->variables()[where];
@@ -275,13 +348,13 @@ Win32MakefileGenerator::findLibraries(const QString &where)
275 for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) { 348 for(MakefileDependDir *mdd = dirs.first(); mdd; mdd = dirs.next() ) {
276 QString extension; 349 QString extension;
277 int ver = findHighestVersion(mdd->local_dir, lib); 350 int ver = findHighestVersion(mdd->local_dir, lib);
278 if(ver > 0) 351 if(ver > 0)
279 extension += QString::number(ver); 352 extension += QString::number(ver);
280 extension += ".lib"; 353 extension += ".lib";
281 if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || 354 if(QMakeMetaInfo::libExists(mdd->local_dir + Option::dir_sep + lib) ||
282 QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) { 355 QFile::exists(mdd->local_dir + Option::dir_sep + lib + extension)) {
283 out = mdd->real_dir + Option::dir_sep + lib + extension; 356 out = mdd->real_dir + Option::dir_sep + lib + extension;
284 break; 357 break;
285 } 358 }
286 } 359 }
287 } 360 }
@@ -300,12 +373,13 @@ Win32MakefileGenerator::findLibraries(const QString &where)
300 fixEnvVariables(l); 373 fixEnvVariables(l);
301 lib_dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); 374 lib_dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"","")));
302 file = file.right(file.length() - slsh - 1); 375 file = file.right(file.length() - slsh - 1);
303 } else { 376 } else {
304 lib_dirs = dirs; 377 lib_dirs = dirs;
305 } 378 }
379 if (!project->variables()["QMAKE_QT_DLL"].isEmpty()) {
306 if(file.endsWith(".lib")) { 380 if(file.endsWith(".lib")) {
307 file = file.left(file.length() - 4); 381 file = file.left(file.length() - 4);
308 if(!file.at(file.length()-1).isNumber()) { 382 if(!file.at(file.length()-1).isNumber()) {
309 for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) { 383 for(MakefileDependDir *mdd = lib_dirs.first(); mdd; mdd = lib_dirs.next() ) {
310 QString lib_tmpl(file + "%1" + ".lib"); 384 QString lib_tmpl(file + "%1" + ".lib");
311 int ver = findHighestVersion(mdd->local_dir, file); 385 int ver = findHighestVersion(mdd->local_dir, file);
@@ -325,12 +399,13 @@ Win32MakefileGenerator::findLibraries(const QString &where)
325 break; 399 break;
326 } 400 }
327 } 401 }
328 } 402 }
329 } 403 }
330 } 404 }
405 }
331 if(remove) { 406 if(remove) {
332 it = l.remove(it); 407 it = l.remove(it);
333 } else { 408 } else {
334 if(!quote.isNull() && modified_opt) 409 if(!quote.isNull() && modified_opt)
335 (*it) = quote + (*it) + quote; 410 (*it) = quote + (*it) + quote;
336 ++it; 411 ++it;