author | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-07-15 17:36:57 (UTC) |
commit | 323e9a7472a110b4befba7320540263147505bae (patch) (side-by-side diff) | |
tree | 14c810bdb9c0603a30356b17b4bdf9ccb72741c6 /qmake/generators/win32 | |
parent | aa292b322f1ecb43dd8f4e3cd295855730dd9f59 (diff) | |
download | opie-323e9a7472a110b4befba7320540263147505bae.zip opie-323e9a7472a110b4befba7320540263147505bae.tar.gz opie-323e9a7472a110b4befba7320540263147505bae.tar.bz2 |
Manually updatet to qmake1.06a which includes support for precompiled
headers.
Opies 'PRO' keyword was already reintroduced
-rw-r--r-- | qmake/generators/win32/borland_bmake.cpp | 218 | ||||
-rw-r--r-- | qmake/generators/win32/borland_bmake.h | 9 | ||||
-rw-r--r-- | qmake/generators/win32/mingw_make.cpp | 284 | ||||
-rw-r--r-- | qmake/generators/win32/mingw_make.h | 11 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_dsp.cpp | 238 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_dsp.h | 13 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 315 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.h | 15 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.cpp | 341 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.h | 43 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 686 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.h | 14 | ||||
-rw-r--r-- | qmake/generators/win32/winmakefile.cpp | 121 | ||||
-rw-r--r-- | qmake/generators/win32/winmakefile.h | 10 |
14 files changed, 1745 insertions, 573 deletions
diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index 26eea88..12607cf 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** NmakeMakefileGenerator of BorlandMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -125,144 +123,244 @@ BorlandMakefileGenerator::writeBorlandParts(QTextStream &t) 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 << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << 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; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << 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: .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 << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << " $(TARGET)" << endl << endl; t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + << extraCompilerDeps << 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)" + t << "\n\t-$(DEL_FILE) $(TARGET)" << "\n\t" << "$(LIB) $(TARGET) @&&|" << " \n+" << project->variables()["OBJECTS"].join(" \\\n+") << " \\\n+" << project->variables()["OBJMOC"].join(" \\\n+"); } + t << extraCompilerDeps; 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; + t << "\n\t" << "-$(COPY_FILE) \"$(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) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(t); + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } t << "dist:" << "\n\t" - << "$(ZIP) " << var("PROJECT") << ".zip " << var("PROJECT") << ".pro $(SOURCES) $(HEADERS) $(DIST) $(FORMS)" - << endl << endl; + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:"; + QString uiclean = varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( uiclean.isEmpty() ) { + // Borland make does not like an empty command section + uiclean = "\n\t@cd ."; + } + t << uiclean << 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 ","") - << varGlue("QMAKE_CLEAN","\n\t-del ","\n\t-del ","") - << varGlue("CLEAN_FILES","\n\t-del ","\n\t-del ",""); + t << "mocclean:"; + QString mocclean = varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); + if ( mocclean.isEmpty() ) { + // Borland make does not like an empty command section + mocclean = "\n\t@cd ."; + } + t << mocclean << endl; + + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; - // blasted user defined targets + // user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + 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; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } t << endl << endl; + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; } void BorlandMakefileGenerator::init() { if(init_flag) return; init_flag = TRUE; project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"]; @@ -271,30 +369,41 @@ BorlandMakefileGenerator::init() 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; } + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + 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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } 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"); @@ -347,24 +456,31 @@ BorlandMakefileGenerator::init() } 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("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } 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 { @@ -459,51 +575,87 @@ BorlandMakefileGenerator::init() 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"]; + // Update -lname to name.lib, and -Ldir to + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } 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::Iterator it; + 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); } 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()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += 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 ); } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } } diff --git a/qmake/generators/win32/borland_bmake.h b/qmake/generators/win32/borland_bmake.h index 5ffed58..700e7f7 100644 --- a/qmake/generators/win32/borland_bmake.h +++ b/qmake/generators/win32/borland_bmake.h @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Definition of BorlandMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -25,24 +23,25 @@ ** 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 __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(); diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 7f58a55..c693d6a 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -1,20 +1,20 @@ /****************************************************************************
-** $Id$
**
-** Definition of ________ class.
**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+** Implementation of MingwMakefileGenerator class. **
-** This file is part of the network module of the Qt GUI Toolkit.
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. **
** 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
@@ -38,309 +38,422 @@ #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::findLibraries() // todo - pascal +{ + return TRUE; +} + +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 createLdObjectScriptFile(const QString & fileName, QStringList & objList) +{ + QString filePath = Option::output_dir + QDir::separator() + fileName; + QFile file(filePath); + if (file.open(IO_WriteOnly | IO_Translate )) { + QTextStream t(&file); + t << "INPUT(" << endl; + for (QStringList::Iterator it = objList.begin(); it != objList.end(); ++it ) { + t << *it << endl; + } + t << ");" << endl; + file.close(); + } +} + 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" << "\"" << inc << "\""; }
- t << " -I" << specdir()
- << endl;
+ t << " -I" << "\"" << specdir() << "\"" << endl; if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
t << "LINK = " << var("QMAKE_LINK") << endl;
- t << "LFLAGS = ";
+ t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl; + t << "LIBS = "; 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;
+ t << varGlue("QMAKE_LIBDIR","-L\"","\" -L\"","\"") << " "; + t << 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 << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << 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;
+ QString objectsLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJECTS"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJECT_SCRIPT"), project->variables()["OBJECTS"]); + objectsLinkLine = var("QMAKE_LINK_OBJECT_SCRIPT"); + } else { + objectsLinkLine = "$(OBJECTS)"; + } 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;
+ QString objmocLinkLine; + if (!project->variables()["QMAKE_APP_OR_DLL"].isEmpty() && + project->variables()["OBJMOC"].count() > var("QMAKE_LINK_OBJECT_MAX").toUInt()) { + createLdObjectScriptFile(var("QMAKE_LINK_OBJMOC_SCRIPT"), project->variables()["OBJMOC"]); + objmocLinkLine = var("QMAKE_LINK_OBJMOC_SCRIPT"); + } else { + objmocLinkLine = "$(OBJMOC)"; + } t << "OBJMOC = " << varList("OBJMOC") << endl;
-// t << "OBJMOC = " << varList("OBJMOC").replace(QRegExp("\\.obj"),".o") << endl;
+ QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << 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");
+ << extraCompilerDeps << var("POST_TARGETDEPS"); if(!project->variables()["QMAKE_APP_OR_DLL"].isEmpty()) {
- t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)";
+ t << "\n\t" << "$(LINK) $(LFLAGS) -o $(TARGET) " << objectsLinkLine << " " << objmocLinkLine << " $(LIBS)"; } else {
- t << "\n\t" << "$(LIB) $(TARGET) $(OBJECTS) $(OBJMOC)";
+ t << "\n\t" << "$(LIB) $(TARGET) " << objectsLinkLine << " " << objmocLinkLine; }
-
+ t << extraCompilerDeps; 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;
+ t << "\n\t" << "$(COPY_FILE) \"$(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) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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;
+ << var("QMAKE_RC") << " -i " << var("RC_FILE") << " -o " << var("RC_FILE").replace(QRegExp("\\.rc"),".o") << " --include-dir=" << QFileInfo(var("RC_FILE")).dirPath() << 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;
+ << "@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;
+ << "@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 ","");
+ << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","").replace(QRegExp("\\.obj"),".o") + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << "\n\t-$(DEL_FILE) $(TARGET)" + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ",""); if ( project->isActiveConfig("activeqt")) {
- t << ("\n\t-del tmp\\" + targetfilename + ".*");
- t << "\n\t-del tmp\\dump.*";
+ t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); }
- 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 ", "");
+ t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); - // blasted user defined targets
+ // user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"];
- for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) {
+ + 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 << "\n\n" << targ << ":" << deps << "\n\t"
<< cmd;
}
t << endl << endl;
+ + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << 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;
}
+ if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + 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 (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"];
@@ -354,70 +467,81 @@ MingwMakefileGenerator::init() } 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_QT_ENTRY"] = "-lqaxserver"; + 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"];
}
+ + // QMAKE_LIBS_QT_ENTRY should be first on the link line as it needs qt + project->variables()["QMAKE_LIBS"].remove(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + project->variables()["QMAKE_LIBS"].prepend(project->variables()["QMAKE_LIBS_QT_ENTRY"].first()); + }
}
+ 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 {
@@ -425,100 +549,160 @@ MingwMakefileGenerator::init() 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("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);
+ + // add -L libs to libdir + QStringList &libs = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit = libs.begin(); libit != libs.end(); ) { + if ( (*libit).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit).mid(2); + libit = libs.remove( libit ); + } else { + ++libit; + } + } + 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::Iterator it; + 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);
}
- if ( project->isActiveConfig("dll") )
- project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + project->first("DESTDIR") + "\\lib"+ project->first("TARGET") + ".a");
+ if ( project->isActiveConfig("dll") ) { + QString destDir = ""; + if (!project->first("DESTDIR").isEmpty()) + destDir = project->first("DESTDIR") + Option::dir_sep; + project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,--out-implib,") + + 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"));
+ project->variables()["QMAKE_LFLAGS"].append(QString("-Wl,") + 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"];
+ project->variables()["CLEAN_FILES"] += 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");
}
+ + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } + } }
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);
+ 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 index c00bf1b..d971e3a 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -1,20 +1,20 @@ /****************************************************************************
-** $Id$
**
-** Definition of ________ class.
**
-** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
+** Definition of MingwMakefileGenerator class. **
-** This file is part of the network module of the Qt GUI Toolkit.
+** Copyright (C) 1992-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. **
** 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
@@ -23,36 +23,39 @@ ** 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();
+ virtual bool findLibraries(); + 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 3fa0496..d2abac6 100644 --- a/qmake/generators/win32/msvc_dsp.cpp +++ b/qmake/generators/win32/msvc_dsp.cpp @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Implementation of DspMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -69,111 +67,191 @@ DspMakefileGenerator::writeMakefile(QTextStream &t) return FALSE; } bool DspMakefileGenerator::writeDspParts(QTextStream &t) { QString dspfile; if ( !project->variables()["DSP_TEMPLATE"].isEmpty() ) { dspfile = project->first("DSP_TEMPLATE"); } else { dspfile = project->first("MSVCDSP_TEMPLATE"); } + if (dspfile.startsWith("\"") && dspfile.endsWith("\"")) + dspfile = dspfile.mid(1, dspfile.length() - 2); QString dspfile_loc = findTemplate(dspfile); QFile file(dspfile_loc); if(!file.open(IO_ReadOnly)) { fprintf(stderr, "Cannot open dsp file: %s\n", dspfile.latin1()); return FALSE; } QTextStream dsp(&file); + QString platform = "Win32"; + if ( !project->variables()["QMAKE_PLATFORM"].isEmpty() ) + platform = varGlue("QMAKE_PLATFORM", "", " ", ""); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + QString namePCH = QFileInfo(precompH).fileName(); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + origTarget.replace(QRegExp("-"), "_"); + precompObj = "\"$(IntDir)\\" + origTarget + Option::obj_ext + "\""; + precompPch = "\"$(IntDir)\\" + origTarget + ".pch\""; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Add precompile compiler options + project->variables()["PRECOMPILED_FLAGS_REL"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + project->variables()["PRECOMPILED_FLAGS_DEB"] = "/Yu\"" + namePCH + "\" /FI\"" + namePCH + "\" "; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } int rep; QString line; while ( !dsp.eof() ) { line = dsp.readLine(); while((rep = line.find(QRegExp("\\$\\$[a-zA-Z0-9_-]*"))) != -1) { QString torep = line.mid(rep, line.find(QRegExp("[^\\$a-zA-Z0-9_-]"), rep) - rep); QString variable = torep.right(torep.length()-2); t << line.left(rep); //output the left side line = line.right(line.length() - (rep + torep.length())); //now past the variable if(variable == "MSVCDSP_SOURCES") { if(project->variables()["SOURCES"].isEmpty()) continue; QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; QStringList list = project->variables()["SOURCES"] + project->variables()["DEF_FILE"]; if(!project->isActiveConfig("flat")) list.sort(); QStringList::Iterator it; for( it = list.begin(); it != list.end(); ++it) { beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if (usePCH && (*it).endsWith(".c")) + t << "# SUBTRACT CPP /FI\"" << namePCH << "\" /Yu\"" << namePCH << "\" /Fp" << endl; + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" "\t" + mocpath + findMocSource((*it)) + " -o " + (*it) + "\n\n" "# End Custom Build\n\n"; t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; } t << "# End Source File" << endl; } endGroups(t); } else if(variable == "MSVCDSP_IMAGES") { if(project->variables()["IMAGES"].isEmpty()) continue; t << "# Begin Source File\n\nSOURCE=" << project->first("QMAKE_IMAGE_COLLECTION") << endl; t << "# End Source File" << endl; } else if(variable == "MSVCDSP_HEADERS") { if(project->variables()["HEADERS"].isEmpty()) continue; QStringList list = project->variables()["HEADERS"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { // beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl << endl; - if ( project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { + QString compilePCH; + QStringList customDependencies; + QString createMOC; + QString buildCmdsR, buildCmdsD; + QString buildCmds = "\nBuildCmds= \\\n"; + // Create unique baseID QString base = (*it); + { base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); - + } + if (usePCH && precompH.endsWith(*it)) { + QString basicBuildCmd = QString("\tcl.exe /TP /W3 /FD /c /D \"WIN32\" /Yc /Fp\"%1\" /Fo\"%2\" %3 %4 %5 %6 %7 %8 %9 /D \"") + .arg(precompPch) + .arg(precompObj) + .arg(var("MSVCDSP_INCPATH")) + .arg(var("MSVCDSP_DEFINES")) + .arg(var("MSVCDSP_CXXFLAGS")); + buildCmdsR = basicBuildCmd + .arg("/D \"NDEBUG\"") + .arg(var("QMAKE_CXXFLAGS_RELEASE")) + .arg(var("MSVCDSP_MTDEF")) + .arg(var("MSVCDSP_RELDEFS")); + buildCmdsD = basicBuildCmd + .arg("/D \"_DEBUG\" /Od") + .arg(var("QMAKE_CXXFLAGS_DEBUG")) + .arg(var("MSVCDSP_MTDEFD")) + .arg(var("MSVCDSP_DEBUG_OPT")); + if (project->first("TEMPLATE") == "vcapp") { // App + buildCmdsR += var("MSVCDSP_WINCONDEF"); + buildCmdsD += var("MSVCDSP_WINCONDEF"); + } else if (project->isActiveConfig("dll")) { // Dll + buildCmdsR += "_WINDOWS\" /D \"_USRDLL"; + buildCmdsD += "_WINDOWS\" /D \"_USRDLL"; + } else { // Lib + buildCmdsR += "_LIB"; + buildCmdsD += "_LIB"; + } + buildCmdsR += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + buildCmdsD += "\" /Fd\"$(IntDir)\\\\\" " + (*it) + " \\\n"; + + compilePCH = precompPch + " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + + QStringList &tmp = findDependencies(precompH); + if(!tmp.isEmpty()) // Got Deps for PCH + customDependencies += tmp; + } + if (project->isActiveConfig("moc") && !findMocDestination((*it)).isEmpty()) { QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; + buildCmds += "\t" + mocpath + (*it) + " -o " + findMocDestination((*it)) + " \\\n"; + createMOC = "\"" + findMocDestination((*it)) + "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n $(BuildCmds)\n\n"; + customDependencies += "\"$(QTDIR)\\bin\\moc.exe\""; + } + if (!createMOC.isEmpty() || !compilePCH.isEmpty()) { + bool doMOC = !createMOC.isEmpty(); + bool doPCH = !compilePCH.isEmpty(); + QString build = "\n\n# Begin Custom Build - "+ + QString(doMOC?"Moc'ing ":"") + + QString((doMOC&&doPCH)?" and ":"") + + QString(doPCH?"Creating PCH cpp from ":"") + + (*it) + "...\nInputPath=.\\" + (*it) + "\n\n" + + buildCmds + "%1\n" + + createMOC + + compilePCH + + "# End Custom Build\n\n"; - QString build = "\n\n# Begin Custom Build - Moc'ing " + (*it) + - "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + findMocDestination((*it)) + - "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" - "\t" + mocpath + (*it) + " -o " + - findMocDestination((*it)) + "\n\n" "# End Custom Build\n\n"; - - t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" - << build << "!ENDIF " << endl << endl; + t << "USERDEP_" << base << "=" << valGlue(customDependencies, "\"", "\" \"", "\"") << endl << endl; + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build.arg(buildCmdsR) + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build.arg(buildCmdsD) + << "!ENDIF " << endl << endl; } t << "# End Source File" << endl; } // endGroups(t); } else if(variable == "MSVCDSP_FORMSOURCES" || variable == "MSVCDSP_FORMHEADERS") { if(project->variables()["FORMS"].isEmpty()) continue; QString uiSourcesDir; QString uiHeadersDir; if(!project->variables()["UI_DIR"].isEmpty()) { uiSourcesDir = project->first("UI_DIR"); @@ -243,39 +321,39 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) if ( project->variables()["SRCMOC"].isEmpty()) continue; QString mocpath = var( "QMAKE_MOC" ); mocpath = mocpath.replace( QRegExp( "\\..*$" ), "" ) + " "; QStringList list = project->variables()["SRCMOC"]; if(!project->isActiveConfig("flat")) list.sort(); for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { // beginGroupForFile((*it), t); t << "# Begin Source File\n\nSOURCE=" << (*it) << endl; - if ( project->isActiveConfig("moc") && (*it).endsWith(Option::moc_ext)) { + if ( project->isActiveConfig("moc") && (*it).endsWith(Option::cpp_moc_ext)) { QString base = (*it); base.replace(QRegExp("\\..*$"), "").upper(); base.replace(QRegExp("[^a-zA-Z]"), "_"); QString build = "\n\n# Begin Custom Build - Moc'ing " + findMocSource((*it)) + "...\n" "InputPath=.\\" + (*it) + "\n\n" "\"" + (*it) + "\"" " : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n" "\t" + mocpath + findMocSource((*it)) + " -o " + (*it) + "\n\n" "# End Custom Build\n\n"; t << "USERDEP_" << base << "=\".\\" << findMocSource((*it)) << "\" \"$(QTDIR)\\bin\\moc.exe\"" << endl << endl; - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF " << endl << endl; } t << "# End Source File" << endl; } // endGroups(t); } else if(variable == "MSVCDSP_PICTURES") { if(project->variables()["IMAGES"].isEmpty()) continue; t << "# Begin Group \"Images\"\n" << "# Prop Default_Filter \"png jpeg bmp xpm\"\n"; @@ -378,37 +456,38 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) if ( !project->variables()["UI_HEADERS_DIR"].isEmpty() ) uiHeadersDir = project->first("UI_HEADERS_DIR"); else uiHeadersDir = fpath; } t << "USERDEP_" << base << "=\"$(QTDIR)\\bin\\moc.exe\" \"$(QTDIR)\\bin\\uic.exe\"" << endl << endl; QString build = "\n\n# Begin Custom Build - Uic'ing " + base + "...\n" "InputPath=.\\" + base + "\n\n" "BuildCmds= \\\n\t" + uicpath + base + " -o " + uiHeadersDir + fname + ".h \\\n" "\t" + uicpath + base + " -i " + fname + ".h -o " + uiSourcesDir + fname + ".cpp \\\n" - "\t" + mocpath + uiHeadersDir + fname + ".h -o " + mocFile + "moc_" + fname + ".cpp \\\n"; + "\t" + mocpath + " " + uiHeadersDir + + fname + ".h -o " + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + " \\\n"; build.append("\n\"" + uiHeadersDir + fname + ".h\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n" "\"" + uiSourcesDir + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n" - "\"" + mocFile + "moc_" + fname + ".cpp\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" + "\"" + mocFile + Option::h_moc_mod + fname + Option::h_moc_ext + "\" : \"$(SOURCE)\" \"$(INTDIR)\" \"$(OUTDIR)\"" "\n" "\t$(BuildCmds)\n\n"); build.append("# End Custom Build\n\n"); - t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Release\"" << build - << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - Win32 Debug\"" << build + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Debug\"" << build << "!ENDIF \n\n" << "# End Source File" << endl; } // endGroups(t); t << "\n# End Group\n"; } else if(variable == "MSVCDSP_LEXSOURCES") { if(project->variables()["LEXSOURCES"].isEmpty()) continue; t << "# Begin Group \"Lexables\"\n" << "# Prop Default_Filter \"l\"\n"; QString lexpath = var("QMAKE_LEX") + varGlue("QMAKE_LEXFLAGS", " ", " ", "") + " "; @@ -420,26 +499,26 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) 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 + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " 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"; @@ -456,26 +535,26 @@ DspMakefileGenerator::writeDspParts(QTextStream &t) 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 + t << "!IF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " Release\"" << build + << "!ELSEIF \"$(CFG)\" == \"" << var("MSVCDSP_PROJECT") << " - " << platform << " 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"]; @@ -523,40 +602,47 @@ DspMakefileGenerator::init() } 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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } 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"); @@ -572,24 +658,32 @@ DspMakefileGenerator::init() 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("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } + 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( thread ) @@ -625,24 +719,26 @@ DspMakefileGenerator::init() 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"); + else + project->variables()["MSVCDSP_OBJECTSDIRREL"] = "Release"; 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"]; } @@ -661,38 +757,63 @@ DspMakefileGenerator::init() 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") ) { + 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() ) { 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 { + 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"]; + } + 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(); @@ -723,60 +844,75 @@ DspMakefileGenerator::init() 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"]; + processPrlFiles(); + + // Update -lname to name.lib, + QStringList &libs2 = project->variables()["QMAKE_LIBS"]; + for ( QStringList::Iterator libit2 = libs2.begin(); libit2 != libs2.end(); ++libit2 ) { + if ( (*libit2).startsWith( "-l" ) ) { + (*libit2) = (*libit2).mid( 2 ) + ".lib"; + } else if ( (*libit2).startsWith( "-L" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*libit2).mid(2); + libit2 = libs2.remove( libit2 ); + } + } + 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(); + if (!project->variables()["RES_FILE"].isEmpty()) + project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + 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("\"", ""); + if(inc.endsWith("\\")) // Remove trailing \'s from paths + inc.truncate(inc.length()-1); 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; @@ -811,48 +947,45 @@ DspMakefileGenerator::init() copyDllStep += "\t"; for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { copyDllStep += "copy \"$(TargetPath)\" \"" + *dlldir + "\"\t"; } } 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" ); + project->variables()["MSVCDSP_IDLSOURCES"].append( var("OBJECTS_DIR") + targetfilename + ".idl" ); if ( project->isActiveConfig( "dll" ) ) { 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 -idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"; activeQtStepPostCopyDll += "\t" + idc + " %1 /regserver\n"; 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() + "\\" + targetfilename + ".dll"; activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } else { 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 -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb" + + "\t" + idc + " %2 /tlb " + var("OBJECTS_DIR") + 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); executable = project->variables()["MSVCDSP_TARGETDIRDEB"].first() + "\\" + targetfilename + ".exe"; activeQtStepPreCopyDllDebug = activeQtStepPreCopyDll.arg(executable).arg(executable); activeQtStepPostCopyDllDebug = activeQtStepPostCopyDll.arg(executable); } } @@ -910,49 +1043,52 @@ DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList & } else { MakefileGenerator::processPrlVariable(var, l); } } void DspMakefileGenerator::beginGroupForFile(QString file, QTextStream &t, const QString& filter) { if(project->isActiveConfig("flat")) 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; if(file.isEmpty() || !QDir::isRelativePath(file)) { endGroups(t); return; } - if(file.startsWith(currentGroup)) - file = file.mid(currentGroup.length()); + + QString tempFile = file; + if(tempFile.startsWith(currentGroup)) + tempFile = tempFile.mid(currentGroup.length()); int dirSep = currentGroup.findRev( Option::dir_sep ); - while( !file.startsWith( currentGroup ) && dirSep != -1 ) { + + while( !tempFile.startsWith( currentGroup ) && dirSep != -1 ) { currentGroup.truncate( dirSep ); dirSep = currentGroup.findRev( Option::dir_sep ); - if ( !file.startsWith( currentGroup ) && dirSep != -1 ) + if ( !tempFile.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"; } currentGroup = file; } void DspMakefileGenerator::endGroups(QTextStream &t) { @@ -964,24 +1100,26 @@ DspMakefileGenerator::endGroups(QTextStream &t) 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 = ""; } bool DspMakefileGenerator::openOutput(QFile &file) const { QString outdir; if(!file.name().isEmpty()) { + if(QDir::isRelativePath(file.name())) + file.setName(Option::output_dir + file.name()); //pwd when qmake was run 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("-"), "_"); diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h index 3a7d18e..0e86539 100644 --- a/qmake/generators/win32/msvc_dsp.h +++ b/qmake/generators/win32/msvc_dsp.h @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Definition of DspMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -25,24 +23,25 @@ ** 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 __MSVC_DSP_H__ #define __MSVC_DSP_H__ #include "winmakefile.h" #include <qvaluestack.h> class DspMakefileGenerator : public Win32MakefileGenerator { QString currentGroup; void beginGroupForFile(QString file, QTextStream &, const QString& filter=""); void endGroups(QTextStream &); @@ -53,21 +52,25 @@ class DspMakefileGenerator : public Win32MakefileGenerator 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(); + + QString precompH, + precompObj, precompPch; + bool usePCH; }; inline DspMakefileGenerator::~DspMakefileGenerator() { } inline bool DspMakefileGenerator::findLibraries() { return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); } #endif /* __MSVC_DSP_H__ */ diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index ecef34d..528cb19 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Implementation of NmakeMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -34,94 +32,116 @@ ** 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()) { + { //write the extra unix targets.. + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) + t << *it << " "; + } 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; } +QStringList +&NmakeMakefileGenerator::findDependencies(const QString &file) +{ + QStringList &aList = MakefileGenerator::findDependencies(file); + // Note: The QMAKE_IMAGE_COLLECTION file have all images + // as dependency, so don't add precompiled header then + if (file == project->first("QMAKE_IMAGE_COLLECTION")) + return aList; + for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { + if(file.endsWith(*it)) { + if(!aList.contains(precompH)) + aList += precompH; + break; + } + } + return aList; +} + 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("\"", ""); + if (inc.endsWith("\\")) + inc.truncate(inc.length()-1); 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("\""), ""); + if (lib.endsWith("\\")) + lib.truncate(lib.length()-1); 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") : @@ -129,63 +149,85 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) 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 << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl; + t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << 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; + + QString extraCompilerDeps; + if(!project->isEmpty("QMAKE_EXTRA_WIN_COMPILERS")) { + t << "OBJCOMP = " << varList("OBJCOMP") << endl; + extraCompilerDeps += " $(OBJCOMP) "; + + QStringList &comps = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) { + QStringList &vars = project->variables()[(*compit) + ".variables"]; + for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) { + QStringList vals = project->variables()[(*varit)]; + if(!vals.isEmpty()) + t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << 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: .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 directories[] = { QString("MOC_DIR"), QString("UI_SOURCES_DIR"), QString("UI_DIR"), QString::null }; + for(int y = 0; !directories[y].isNull(); y++) { + QString dirTemp = project->first(directories[y]); + if (dirTemp.endsWith("\\")) + dirTemp.truncate(dirTemp.length()-1); + if(!dirTemp.isEmpty()) + source_directories.insert(dirTemp, (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); } } @@ -197,148 +239,268 @@ NmakeMakefileGenerator::writeNmakeParts(QTextStream &t) 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 << "all: " << fileFixify(Option::output.name()) << " " << varGlue("ALL_DEPS"," "," "," ") << "$(TARGET)" << endl << endl; t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) " - << var("POST_TARGETDEPS"); + << extraCompilerDeps << 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 << extraCompilerDeps; 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; + t << "\n\t" << "-$(COPY_FILE) \"$(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) /idl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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) -dumpidl " + var("OBJECTS_DIR") + targetfilename + ".idl -version " + version); + t << "\n\t" << ("-$(IDL) /nologo " + var("OBJECTS_DIR") + targetfilename + ".idl /tlb " + var("OBJECTS_DIR") + targetfilename + ".tlb"); + t << "\n\t" << ("-$(IDC) $(TARGET) /tlb " + var("OBJECTS_DIR") + 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; + t << "mocables: $(SRCMOC)" << endl + << "uicables: $(UICIMPLS) $(UICDECLS)" << endl << endl; writeMakeQmake(t); + QStringList dist_files = Option::mkfile::project_files; + if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES")) + dist_files += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"]; + if(!project->isEmpty("TRANSLATIONS")) + dist_files << var("TRANSLATIONS"); + if(!project->isEmpty("FORMS")) { + QStringList &forms = project->variables()["FORMS"]; + for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) { + QString ui_h = fileFixify((*formit) + Option::h_ext.first()); + if(QFile::exists(ui_h) ) + dist_files << ui_h; + } + } 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 ",""); + << "$(ZIP) " << var("QMAKE_ORIG_TARGET") << ".zip " << "$(SOURCES) $(HEADERS) $(DIST) $(FORMS) " + << dist_files.join(" ") << " " << var("TRANSLATIONS") << " " << var("IMAGES") << endl << endl; + + t << "uiclean:" + << varGlue("UICDECLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("UICIMPLS" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + t << "mocclean:" + << varGlue("SRCMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("OBJMOC" ,"\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") << endl; + + t << "clean: uiclean mocclean" + << varGlue("OBJECTS","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","") + << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n") + << varGlue("CLEAN_FILES","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ","\n"); if ( project->isActiveConfig("activeqt")) { - t << ("\n\t-del tmp\\" + targetfilename + ".*"); - t << "\n\t-del tmp\\dump.*"; + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".idl"); + t << ("\n\t-$(DEL_FILE) " + var("OBJECTS_DIR") + targetfilename + ".tlb"); } if(!project->isEmpty("IMAGES")) - t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-del ", "\n\t-del ", ""); + t << varGlue("QMAKE_IMAGE_COLLECTION", "\n\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", ""); + t << endl; + + // user defined targets - // blasted user defined targets + QStringList::Iterator it; QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; - for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + 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; } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; t << "\n\n" << targ << ":" << deps << "\n\t" << cmd; } - t << endl << endl; + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + QString tmp_dep = project->variables()[(*it) + ".depends"].join(" "); + QStringList &vars = project->variables()[(*it) + ".variables"]; + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out, cmd = tmp_cmd, deps; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + cmd.replace("${QMAKE_FILE_BASE}", fi.baseName()); + cmd.replace("${QMAKE_FILE_OUT}", out); + cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3) + cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); + if(!tmp_dep.isEmpty()) { + char buff[256]; + QString dep_cmd = tmp_dep; + dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) { + while(!feof(proc)) { + int read_in = int(fread(buff, 1, 255, proc)); + if(!read_in) + break; + int l = 0; + for(int i = 0; i < read_in; i++) { + if(buff[i] == '\n' || buff[i] == ' ') { + deps += " " + QCString(buff+l, (i - l) + 1); + l = i; + } + } + } + fclose(proc); + } + } + t << out << ": " << in << deps << "\n\t" + << cmd << endl << endl; + } + } + } + t << endl; + + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) + t << "FORCE:" << endl << endl; + t << "distclean: clean" - << "\n\t-del $(TARGET)" + << "\n\t-$(DEL_FILE) $(TARGET)" << endl << endl; + + // precompiled header + if(usePCH) { + QString precompRule = QString("-c -Yc -Fp%1 -Fo%2").arg(precompPch).arg(precompObj); + t << precompObj << ": " << precompH << " " << findDependencies(precompH).join(" \\\n\t\t") + << "\n\t" << "$(CXX) " + precompRule +" $(CXXFLAGS) $(INCPATH) -TP " << precompH << endl << endl; + } } +QString +NmakeMakefileGenerator::var(const QString &value) +{ + if (usePCH) { + if ((value == "QMAKE_RUN_CXX_IMP_BATCH" + || value == "QMAKE_RUN_CXX_IMP" + || value == "QMAKE_RUN_CXX")) { + QFileInfo precompHInfo(precompH); + QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") + .arg(precompHInfo.fileName()) + .arg(precompHInfo.fileName()) + .arg(precompPch); + QString p = MakefileGenerator::var(value); + p.replace("-c", precompRule); + // Cannot use -Gm with -FI & -Yu, as this gives an + // internal compiler error, on the newer compilers + p.remove("-Gm"); + return p; + } else if (value == "QMAKE_CXXFLAGS") { + // Remove internal compiler error option + return MakefileGenerator::var(value).remove("-Gm"); + } + } + + // Normal val + return MakefileGenerator::var(value); +} 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; } + if(project->isEmpty("QMAKE_INSTALL_FILE")) + project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)"); + if(project->isEmpty("QMAKE_INSTALL_DIR")) + project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)"); + 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("qtopia") ) { + if(configs.findIndex("qtopialib") == -1) + configs.append("qtopialib"); + if(configs.findIndex("qtopiainc") == -1) + configs.append("qtopiainc"); + } 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() ) @@ -392,24 +554,31 @@ NmakeMakefileGenerator::init() 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("qtopiainc") ) + project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"]; + if ( project->isActiveConfig("qtopialib") ) { + if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA")) + project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QTOPIA"]; + project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"]; + } 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 { @@ -499,28 +668,44 @@ NmakeMakefileGenerator::init() 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"]; + + QStringList &libList = project->variables()["QMAKE_LIBS"]; + for( QStringList::Iterator stIt = libList.begin(); stIt != libList.end(); ) { + QString s = *stIt; + if( s.startsWith( "-l" ) ) { + stIt = libList.remove( stIt ); + stIt = libList.insert( stIt, s.mid( 2 ) + ".lib" ); + } else if( s.startsWith( "-L" ) ) { + stIt = libList.remove( stIt ); + project->variables()["QMAKE_LIBDIR"].append(QDir::convertSeparators(s.mid( 2 ))); + } else { + stIt++; + } + } + 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::Iterator it; + 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); } 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]; @@ -530,33 +715,73 @@ NmakeMakefileGenerator::init() 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()["POST_TARGETDEPS"] += project->variables()["RES_FILE"]; + project->variables()["CLEAN_FILES"] += project->variables()["RES_FILE"]; } if ( !project->variables()["RES_FILE"].isEmpty()) project->variables()["QMAKE_LIBS"] += project->variables()["RES_FILE"]; + // Base class init! MakefileGenerator::init(); + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + // Created files + precompObj = var("OBJECTS_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext; + precompPch = var("OBJECTS_DIR") + project->first("TARGET") + "_pch.pch"; + // Add linking of precompObj (required for whole precompiled classes) + project->variables()["OBJECTS"] += precompObj; + // Add pch file to cleanup + project->variables()["QMAKE_CLEAN"] += precompPch; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + 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") + version + ".exp"); } if(project->isActiveConfig("debug")) { 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"); + project->variables()["QMAKE_CLEAN"].append("vc*.idb"); + } + + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + if(tmp_out.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QFileInfo fi(Option::fixPathToLocalOS((*input))); + QString in = Option::fixPathToTargetOS((*input), FALSE), + out = tmp_out; + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1) + project->variables()["OBJCOMP"] += out; + } + } } } diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 579fc35..f2996cd 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Definition of NmakeMakefileGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -25,35 +23,42 @@ ** 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 __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(); +protected: + QStringList &findDependencies(const QString &file); + QString var(const QString &value); + QString precompH, precompObj, precompPch; + bool usePCH; + public: NmakeMakefileGenerator(QMakeProject *p); ~NmakeMakefileGenerator(); }; inline NmakeMakefileGenerator::~NmakeMakefileGenerator() { } #endif /* __MSVC_NMAKE_H__ */ diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 7ffe4f7..a672c2d 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -1,20 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Implementation of VCProject class. ** -** This file is part of the network module of the Qt GUI Toolkit. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. ** ** 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 @@ -28,39 +28,25 @@ ** 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_objectmodel.h" #include "msvc_vcproj.h" #include <qtextstream.h> #include <qstringlist.h> -#include <quuid.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 +#include <qfileinfo.h> // XML Tags --------------------------------------------------------- const char* _xmlInit = "<?xml version=\"1.0\" encoding = \"Windows-1252\"?>"; const char* _begConfiguration = "\n\t\t<Configuration"; const char* _begConfigurations = "\n\t<Configurations>"; const char* _begFile = "\n\t\t\t<File"; const char* _begFileConfiguration = "\n\t\t\t\t<FileConfiguration"; const char* _begFiles = "\n\t<Files>"; const char* _begFilter = "\n\t\t<Filter"; const char* _begGlobals = "\n\t<Globals>"; const char* _begPlatform = "\n\t\t<Platform"; const char* _begPlatforms = "\n\t<Platforms>"; @@ -272,25 +258,24 @@ struct SPair { const char* name; const QString& value; }; struct XPair { XPair( const char* n, const QStringList& v, const char* s = "," ) : name(n), value(v), sep(s) {}; const char* name; const QStringList& value; const char* sep; }; // void streamSPair( QTextStream &strm, const char *n, const QString &s ) - // Streaming operators for property Pairs --------------------------- QTextStream &operator<<( QTextStream &strm, const TPair &prop ) { switch( prop.value ) { case _False: strm << prop.name << "FALSE\""; break; case _True: strm << prop.name << "TRUE\""; break; case unset: default: @@ -309,148 +294,149 @@ QTextStream &operator<<( QTextStream &strm, const EPair &prop ) 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() << "\""; + strm << prop.name << QString(prop.value).remove("\"") << "\""; 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 ), + BufferSecurityCheck( _False ), CallingConvention( callConventionDefault ), CompileAs( compileAsDefault ), CompileAsManaged( managedDefault ), CompileOnly( unset ), DebugInformationFormat( debugDisabled ), DefaultCharIsUnsigned( unset ), Detect64BitPortabilityProblems( unset ), DisableLanguageExtensions( unset ), EnableFiberSafeOptimizations( unset ), EnableFunctionLevelLinking( unset ), EnableIntrinsicFunctions( unset ), - ExceptionHandling( unset ), + ExceptionHandling( _False ), ExpandAttributedSource( unset ), FavorSizeOrSpeed( favorNone ), ForceConformanceInForLoopScope( unset ), GeneratePreprocessedFile( preprocessNo ), GlobalOptimizations( unset ), IgnoreStandardIncludePath( unset ), ImproveFloatingPointConsistency( unset ), - InlineFunctionExpansion( expandOnlyInline ), + InlineFunctionExpansion( expandDefault ), KeepComments( unset ), MinimalRebuild( unset ), OmitFramePointers( unset ), - Optimization( optimizeDisabled ), + Optimization( optimizeCustom ), OptimizeForProcessor( procOptimizeBlended ), OptimizeForWindowsApplication( unset ), + ProgramDataBaseFileName( "" ), RuntimeLibrary( rtMultiThreaded ), RuntimeTypeInfo( unset ), ShowIncludes( unset ), SmallerTypeCheck( unset ), StringPooling( unset ), StructMemberAlignment( alignNotSet ), SuppressStartupBanner( unset ), TreatWChar_tAsBuiltInType( unset ), TurnOffAssemblyGeneration( unset ), UndefineAllPreprocessorDefinitions( unset ), - UsePrecompiledHeader( pchGenerateAuto ), + UsePrecompiledHeader( pchNone ), 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( _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 ); + if ( tool.DebugInformationFormat != debugUnknown ) 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 ); + if ( tool.GeneratePreprocessedFile != preprocessUnknown)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 ); + if ( tool.InlineFunctionExpansion != expandDefault ) 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.Optimization != optimizeDefault ) 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 ); + if ( !tool.ProgramDataBaseFileName.isNull() ) strm << _ProgramDataBaseFileName << tool.ProgramDataBaseFileName.latin1() << "\""; + if ( tool.RuntimeLibrary != rtUnknown ) 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 ); + if ( tool.WarningLevel != warningLevelUnknown ) 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]; @@ -465,40 +451,47 @@ bool VCCLCompilerTool::parseOption( const char* option ) case '@': qWarning( "Generator: Option '/@': MSVC.NET projects do not support the use of a response file" ); found = FALSE; break; case 'l': qWarning( "Generator: Option '/link': qmake generator does not support passing link options through the compiler tool" ); found = FALSE; break; case 'A': if ( second != 'I' ) { found = FALSE; break; } - AdditionalUsingDirectories += option+2; + AdditionalUsingDirectories += option+3; break; case 'C': KeepComments = _True; break; case 'D': - PreprocessorDefinitions += option+1; + PreprocessorDefinitions += option+2; break; case 'E': if ( second == 'H' ) { - if ( third == 'a' || third == 'c' || third == 's' ) { + if ( third == 'a' + || (third == 'c' && fourth != 's') + || (third == 's' && fourth != 'c') ) { // ExceptionHandling must be false, or it will override // with an /EHsc option ExceptionHandling = _False; AdditionalOptions += option; break; + } else if ( (third == 'c' && fourth == 's') + || (third == 's' && fourth == 'c') ) { + ExceptionHandling = _True; + AdditionalOptions += option; + break; } found = FALSE; break; } GeneratePreprocessedFile = preprocessYes; break; case 'F': if ( second <= '9' && second >= '0' ) { AdditionalOptions += option; break; } else { switch ( second ) { case 'A': @@ -582,24 +575,27 @@ bool VCCLCompilerTool::parseOption( const char* option ) case 'R': RuntimeTypeInfo = _True; if ( third == '-' ) RuntimeTypeInfo = _False; break; case 'S': BufferSecurityCheck = _True; break; case 'T': EnableFiberSafeOptimizations = _True; break; case 'X': + // ExceptionHandling == true will override with + // an /EHsc option, which is correct with /GX + ExceptionHandling = _True; // Fall-through case 'Z': case 'e': case 'h': AdditionalOptions += option; break; case 'd': CallingConvention = callConventionCDecl; break; case 'f': StringPooling = _True; AdditionalOptions += option; break; @@ -945,28 +941,28 @@ bool VCCLCompilerTool::parseOption( const char* option ) return TRUE; } // VCLinkerTool ----------------------------------------------------- VCLinkerTool::VCLinkerTool() : EnableCOMDATFolding( optFoldingDefault ), GenerateDebugInformation( unset ), GenerateMapFile( unset ), HeapCommitSize( -1 ), HeapReserveSize( -1 ), IgnoreAllDefaultLibraries( unset ), IgnoreEmbeddedIDL( unset ), - IgnoreImportLibrary( unset ), + IgnoreImportLibrary( _True ), LargeAddressAware( addrAwareDefault ), LinkDLL( unset ), - LinkIncremental( linkIncrementalYes ), + LinkIncremental( linkIncrementalDefault ), LinkTimeCodeGeneration( unset ), MapExports( unset ), MapLines( unset ), OptimizeForWindows98( optWin98Default ), OptimizeReferences( optReferencesDefault ), RegisterOutput( unset ), ResourceOnlyDLL( unset ), SetChecksum( unset ), ShowProgress( linkProgressNotSet ), StackCommitSize( -1 ), StackReserveSize( -1 ), SubSystem( subSystemNotSet ), @@ -1010,25 +1006,25 @@ QTextStream &operator<<( QTextStream &strm, const VCLinkerTool &tool ) 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 << _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 ); @@ -1698,27 +1694,27 @@ QTextStream &operator<<( QTextStream &strm, const VCLibrarianTool &tool ) // 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 << XPair( _CommandLine4, tool.CommandLine, "\n" ); strm << SPair( _Description4, tool.Description ); - strm << SPair( _Outputs4, tool.Outputs ); + strm << XPair( _Outputs4, tool.Outputs, ";" ); strm << SPair( _ToolPath, tool.ToolPath ); strm << "/>"; return strm; } // VCResourceCompilerTool ------------------------------------------- VCResourceCompilerTool::VCResourceCompilerTool() : Culture( rcUseDefault ), IgnoreStandardIncludePath( unset ), ShowProgress( linkProgressNotSet ) { PreprocessorDefinitions = "NDEBUG"; @@ -1817,61 +1813,57 @@ QTextStream &operator<<( QTextStream &strm, const VCConfiguration &tool ) strm << tool.idl; strm << tool.postBuild; strm << tool.preBuild; strm << tool.preLink; strm << tool.resource; strm << _endConfiguration; return strm; } // VCFilter --------------------------------------------------------- VCFilter::VCFilter() : ParseFiles( unset ) { + useCustomBuildTool = FALSE; + useCompilerTool = FALSE; } -void VCFilter::generateMOC( QTextStream &strm, QString str ) const +void VCFilter::addMOCstage( QTextStream &strm, QString filename ) { - QString mocOutput = Project->findMocDestination( str ); + QString mocOutput = Project->findMocDestination( filename ); QString mocApp = Project->var( "QMAKE_MOC" ); - if( mocOutput.isEmpty() ) { + if( mocOutput.isEmpty() && filename.endsWith(".moc") ) { // 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 ); + mocOutput = filename; + filename = 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; + if (mocOutput.isEmpty()) + return; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + CustomBuildTool.Description = "Moc'ing " + filename + "..."; + CustomBuildTool.CommandLine += (mocApp + " " + + filename + " -o " + mocOutput); + CustomBuildTool.AdditionalDependencies = mocApp; + CustomBuildTool.Outputs += mocOutput; } -void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const +void VCFilter::addUICstage( QTextStream &strm, QString str ) { + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + QString uicApp = Project->var("QMAKE_UIC"); QString mocApp = Project->var( "QMAKE_MOC" ); QString fname = str.section( '\\', -1 ); QString mocDir = Project->var( "MOC_DIR" ); 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() ) { @@ -1886,107 +1878,236 @@ void VCFilter::generateUIC( QTextStream &strm, const QString& str ) const 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 " << 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 << uiHeaders << fname << ".h;" << uiSources << fname << ".cpp;" << mocDir << "moc_" << fname << ".cpp\""; - strm << "/>"; - strm << _endFileConfiguration; + if ( mocDir.isEmpty() ) + mocDir = pname; + + CustomBuildTool.Description = ("Uic'ing " + str + "...\""); + CustomBuildTool.CommandLine += // Create .h from .ui file + uicApp + " " + str + " -o " + uiHeaders + fname + ".h"; + CustomBuildTool.CommandLine += // Create .cpp from .ui file + uicApp + " " + str + " -i " + fname + ".h -o " + uiSources + fname + ".cpp"; + CustomBuildTool.CommandLine += // Moc the headerfile + mocApp + " " + uiHeaders + fname + ".h -o " + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; + + CustomBuildTool.AdditionalDependencies += mocApp; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.Outputs += + uiHeaders + fname + ".h;" + uiSources + fname + ".cpp;" + mocDir + Option::h_moc_mod + fname + Option::h_moc_ext; +} + +void VCFilter::modifyPCHstage( QTextStream &strm, QString str ) +{ + bool isCFile = str.endsWith(".c"); + bool isHFile = (str.endsWith(".h") && str == Project->precompH); + + if (!isCFile && !isHFile) + return; + + CompilerTool = VCCLCompilerTool(); + useCompilerTool = TRUE; + + // Unset some default options + CompilerTool.BufferSecurityCheck = unset; + CompilerTool.DebugInformationFormat = debugUnknown; + CompilerTool.ExceptionHandling = unset; + CompilerTool.GeneratePreprocessedFile = preprocessUnknown; + CompilerTool.Optimization = optimizeDefault; + CompilerTool.ProgramDataBaseFileName = QString::null; + CompilerTool.RuntimeLibrary = rtUnknown; + CompilerTool.WarningLevel = warningLevelUnknown; + + // Setup PCH options + CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); + CompilerTool.PrecompiledHeaderThrough = "$(NOINHERIT)"; + CompilerTool.ForcedIncludeFiles = "$(NOINHERIT)"; } -QTextStream &operator<<( QTextStream &strm, const VCFilter &tool ) +bool VCFilter::addIMGstage( QTextStream &strm, QString str ) +{ + bool isCorH = FALSE; + if (str.endsWith(".c") || str.endsWith(".rc")) + isCorH = TRUE; + QStringList::Iterator it; + for(it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + for(it = Option::h_ext.begin(); it != Option::h_ext.end(); ++it) + if(str.endsWith(*it)) + isCorH = TRUE; + + QString collectionName = Project->project->first("QMAKE_IMAGE_COLLECTION"); + if (str.isEmpty() || isCorH || collectionName.isEmpty()) + return FALSE; + + CustomBuildTool = VCCustomBuildTool(); + useCustomBuildTool = TRUE; + + // Some projects (like designer core) may have too many images to + // call uic directly. Therefor we have to create a temporary + // file, with the image list, and call uic with the -f option. + QString tmpFileCmd = "echo "; + QString tmpImageFilename = ".imgcol"; + QStringList& list = Project->project->variables()["IMAGES"]; + bool firstOutput = TRUE; + it = list.begin(); + while( it!=list.end() ) { + tmpFileCmd += (*it) + " "; + ++it; + if (tmpFileCmd.length()>250 || it==list.end()) { + CustomBuildTool.CommandLine += tmpFileCmd + + (firstOutput?"> ":">> ") + + tmpImageFilename; + tmpFileCmd = "echo "; + firstOutput = FALSE; + } + } + + QString uicApp = Project->var("QMAKE_UIC"); + CustomBuildTool.Description = ("Generate imagecollection"); + CustomBuildTool.CommandLine += + uicApp + " -embed " + Project->project->first("QMAKE_ORIG_TARGET") + + " -f .imgcol -o " + collectionName; + CustomBuildTool.AdditionalDependencies += uicApp; + CustomBuildTool.AdditionalDependencies += list; + CustomBuildTool.Outputs = collectionName; + CustomBuildTool.Outputs += tmpImageFilename; + return TRUE; +} + +QTextStream &operator<<( QTextStream &strm, 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 << ">"; + + bool resourceBuild = FALSE; + int currentLevels = 0; + QStringList currentDirs; for ( QStringList::ConstIterator it = tool.Files.begin(); it != tool.Files.end(); ++it ) { + if ( !tool.flat_files ) { + QStringList newDirs = QStringList::split('\\',(*it)); + newDirs.pop_back(); // Skip the filename + + int newLevels = int(newDirs.count()); + int equalLevels = 0; + for (int i = 0; i<currentLevels; i++, equalLevels++ ) + if (currentDirs[i] != newDirs[i]) + break; + int closeFilters = currentLevels - equalLevels; + int openFilters = newLevels - equalLevels; + + // close previous non-equal filter + while ( closeFilters-- ) + strm << _endFilter; + + // open new non-equal filters + newLevels = 0; + while ( openFilters-- ) { + strm << _begFilter; + strm << SPair( _Name3, newDirs[equalLevels + newLevels] ); + strm << _Filter << "\">"; // Blank filter + ++newLevels; + } + currentDirs = newDirs; + currentLevels = int(newDirs.count()); + } + + tool.useCustomBuildTool = FALSE; + tool.useCompilerTool = FALSE; + // Add UIC, MOC and PCH stages to file + if ( tool.CustomBuild == moc ) + tool.addMOCstage( strm, *it ); + else if ( tool.CustomBuild == uic ) + tool.addUICstage( strm, *it ); + else if ( tool.CustomBuild == resource ) { + if (!resourceBuild) + resourceBuild = tool.addIMGstage(strm, *it); + } + if (tool.Project->usePCH) + tool.modifyPCHstage( strm, *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 ); + // Output custom build and compiler options + // for all configurations + if (tool.useCustomBuildTool || tool.useCompilerTool) { + for ( uint i = 0; i < tool.Config->count(); i++ ) { + strm << _begFileConfiguration; + strm << _Name5; + strm << (*tool.Config)[i].Name; + strm << "\">"; + if (tool.useCustomBuildTool) + strm << tool.CustomBuildTool; + if (tool.useCompilerTool) + strm << tool.CompilerTool; + strm << _endFileConfiguration; + } + } strm << _endFile; } - + // close remaining open filters, in non-flat mode + while ( !tool.flat_files && currentLevels-- ) { + strm << _endFilter; + } strm << _endFilter; return strm; } // VCProject -------------------------------------------------------- VCProject::VCProject() { -#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 + VCConfiguration conf; + Configuration += conf ; // Release + //Configuration += conf ; // Debug added later, after Release init } 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; + for ( uint i = 0; i < tool.Configuration.count(); i++ ) + strm << tool.Configuration[i]; 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 << (VCFilter&)tool.SourceFiles; + strm << (VCFilter&)tool.HeaderFiles; + strm << (VCFilter&)tool.MOCFiles; + strm << (VCFilter&)tool.UICFiles; + strm << (VCFilter&)tool.FormFiles; + strm << (VCFilter&)tool.TranslationFiles; + strm << (VCFilter&)tool.LexYaccFiles; + strm << (VCFilter&)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 1dca68d..9ce38d2 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1,20 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Copyright (C) 2002 Trolltech AS. All rights reserved. +** Definition of VCProject class. ** -** This file is part of the network module of the Qt GUI Toolkit. +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. +** +** This file is part of qmake. ** ** 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 @@ -23,49 +23,51 @@ ** 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 __MSVC_OBJECTMODEL_H__ #define __MSVC_OBJECTMODEL_H__ #include "project.h" #include <qstring.h> #include <qstringlist.h> /* This Object model is of course VERY simplyfied, and does not actually follow the original MSVC object model. However, it fulfilles the basic needs for qmake */ /* If a triState value is 'unset' then the corresponding property is not in the output, forcing the tool to utilize default values. False/True values will be in the output... */ enum customBuildCheck { none, moc, uic, - lexyacc + lexyacc, + resource }; enum triState { unset = -1, _False = 0, _True = 1 }; enum addressAwarenessType { addrAwareDefault, addrAwareNoLarge, addrAwareLarge }; enum asmListingOption { @@ -105,24 +107,25 @@ enum CompileAsOptions{ compileAsDefault, compileAsC, compileAsCPlusPlus }; enum ConfigurationTypes { typeUnknown = 0, typeApplication = 1, typeDynamicLibrary = 2, typeStaticLibrary = 4, typeGeneric = 10 }; enum debugOption { + debugUnknown = -1, debugDisabled, debugOldStyleInfo, debugLineInfoOnly, debugEnabled, debugEditAndContinue }; enum eAppProtectionOption { eAppProtectUnchanged, eAppProtectLow, eAppProtectMedium, eAppProtectHigh }; @@ -231,25 +234,26 @@ enum enumSccEvent { enum favorSizeOrSpeedOption { favorNone, favorSpeed, favorSize }; enum genProxyLanguage { genProxyNative, genProxyManaged }; enum inlineExpansionOption { expandDisable, expandOnlyInline, - expandAnySuitable + expandAnySuitable, + expandDefault // Not useful number, but stops the output }; enum linkIncrementalType { linkIncrementalDefault, linkIncrementalNo, linkIncrementalYes }; enum linkProgressOption { linkProgressNotSet, linkProgressAll, linkProgressLibs }; enum machineTypeOption { @@ -287,58 +291,61 @@ enum midlWarningLevelOption { midlWarningLevel_4 }; enum optFoldingType { optFoldingDefault, optNoFolding, optFolding }; enum optimizeOption { optimizeDisabled, optimizeMinSpace, optimizeMaxSpeed, optimizeFull, - optimizeCustom + optimizeCustom, + optimizeDefault // Not useful number, but stops the output }; enum optRefType { optReferencesDefault, optNoReferences, optReferences }; enum optWin98Type { optWin98Default, optWin98No, optWin98Yes }; enum pchOption { pchNone, pchCreateUsingSpecific, pchGenerateAuto, pchUseUsingSpecific }; enum preprocessOption { + preprocessUnknown = -1, preprocessNo, preprocessYes, preprocessNoLineNumbers }; enum ProcessorOptimizeOption { procOptimizeBlended, procOptimizePentium, procOptimizePentiumProAndAbove }; enum RemoteDebuggerType { DbgLocal, DbgRemote, DbgRemoteTCPIP }; enum runtimeLibraryOption { + rtUnknown = -1, rtMultiThreaded, rtMultiThreadedDebug, rtMultiThreadedDLL, rtMultiThreadedDebugDLL, rtSingleThreaded, rtSingleThreadedDebug }; enum structMemberAlignOption { alignNotSet, alignSingleByte, alignTwoBytes, alignFourBytes, @@ -370,24 +377,25 @@ enum TypeOfDebugger { }; enum useOfATL { useATLNotSet, useATLStatic, useATLDynamic }; enum useOfMfc { useMfcStdWin, useMfcStatic, useMfcDynamic }; enum warningLevelOption { + warningLevelUnknown = -1, warningLevel_0, warningLevel_1, warningLevel_2, warningLevel_3, warningLevel_4 }; class VCToolBase { protected: // Functions VCToolBase(){}; virtual ~VCToolBase(){} @@ -602,27 +610,27 @@ public: }; class VCCustomBuildTool : public VCToolBase { public: // Functions VCCustomBuildTool(); virtual ~VCCustomBuildTool(){} bool parseOption( const char* ){ return FALSE; }; // Variables QStringList AdditionalDependencies; - QString CommandLine; + QStringList CommandLine; QString Description; - QString Outputs; + QStringList Outputs; QString ToolName; QString ToolPath; }; class VCResourceCompilerTool : public VCToolBase { public: // Functions VCResourceCompilerTool(); virtual ~VCResourceCompilerTool(){} bool parseOption( const char* ){ return FALSE; }; @@ -710,64 +718,71 @@ public: VCPreBuildEventTool preBuild; VCPreLinkEventTool preLink; VCResourceCompilerTool resource; }; class VcprojGenerator; class VCFilter { public: // Functions VCFilter(); ~VCFilter(){} - void generateMOC( QTextStream &strm, QString str ) const; - void generateUIC( QTextStream &strm, const QString& str ) const; + void addMOCstage( QTextStream &strm, QString str ); + void addUICstage( QTextStream &strm, QString str ); + bool addIMGstage( QTextStream &strm, QString str ); + void modifyPCHstage( QTextStream &strm, QString str ); // Variables QString Name; QString Filter; triState ParseFiles; QStringList Files; VcprojGenerator* Project; - VCConfiguration* Config; + QValueList<VCConfiguration> *Config; customBuildCheck CustomBuild; + bool useCustomBuildTool; + VCCustomBuildTool CustomBuildTool; + bool useCompilerTool; + VCCLCompilerTool CompilerTool; + bool flat_files; }; class VCProject { public: // Functions VCProject(); ~VCProject(){} // Variables QString Name; QString Version; QString ProjectGUID; QString SccProjectName; QString SccLocalPath; QString PlatformName; // XML sub-parts - VCConfiguration Configuration; + QValueList<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 &, 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 d2cbc31..aa8fe16 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of VcprojGenerator class. ** -** Created : 970521 +** Implementation of VcprojGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -28,69 +26,112 @@ ** 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 "qtmd5.h" // SG's MD5 addon #include <qdir.h> #include <qregexp.h> #include <qdict.h> #include <quuid.h> #include <stdlib.h> +#include <qsettings.h> -#if defined(Q_OS_WIN32) -#include <objbase.h> -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID +//#define DEBUG_SOLUTION_GEN +//#define DEBUG_PROJECT_GEN + +// Registry keys for .NET version detection ------------------------- +const char* _regNet2002 = "Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"; +const char* _regNet2003 = "Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"; + +bool use_net2003_version() { - ulong Data1; - ushort Data2; - ushort Data3; - uchar Data4[8]; -} GUID; -#endif +#ifndef Q_OS_WIN32 + return FALSE; // Always generate 7.0 versions on other platforms +#else + // Only search for the version once + static int current_version = -1; + if (current_version!=-1) + return (current_version==71); + + // Fallback to .NET 2002 + current_version = 70; + + // Get registry entries for both versions + bool ok = false; + QSettings setting; + QString path2002 = setting.readEntry(_regNet2002); + QString path2003 = setting.readEntry(_regNet2003); + + if ( path2002.isNull() || path2003.isNull() ) { + // Only have one MSVC, so use that one + current_version = (path2003.isNull() ? 70 : 71); + } else { + // Have both, so figure out the current + QString paths = getenv("PATH"); + QStringList pathlist = QStringList::split(";", paths.lower()); + + path2003 = path2003.lower(); + QStringList::iterator it; + for(it=pathlist.begin(); it!=pathlist.end(); ++it) { + if ((*it).contains(path2003)) { + current_version = 71; + } else if ((*it).contains(path2002) + && current_version == 71) { + fprintf( stderr, "Both .NET 2002 & .NET 2003 directories for VC found in you PATH variable!\nFallback to .NET 2002 project generation" ); + current_version = 70; + break; + } + } + } + return (current_version==71); #endif +}; // Flatfile Tags ---------------------------------------------------- -const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader70 = "Microsoft Visual Studio Solution File, Format Version 7.00"; +const char* _slnHeader71 = "Microsoft Visual Studio Solution File, Format Version 8.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" +const char* _slnMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"; +const char* _slnProjectBeg = "\nProject(\""; +const char* _slnProjectMid = "\") = "; +const char* _slnProjectEnd = "\nEndProject"; +const char* _slnGlobalBeg = "\nGlobal"; +const char* _slnGlobalEnd = "\nEndGlobal"; +const char* _slnSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" + "\n\t\tConfigName.0 = Debug" + "\n\t\tConfigName.1 = 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" +const char* _slnProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution"; +const char* _slnProjDepEnd = "\n\tEndGlobalSection"; +const char* _slnProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution"; +const char* _slnProjRelConfTag1 = ".Release.ActiveCfg = Release|Win32"; +const char* _slnProjRelConfTag2 = ".Release.Build.0 = Release|Win32"; +const char* _slnProjDbgConfTag1 = ".Debug.ActiveCfg = Debug|Win32"; +const char* _slnProjDbgConfTag2 = ".Debug.Build.0 = Debug|Win32"; +const char* _slnProjConfEnd = "\n\tEndGlobalSection"; +const char* _slnExtSections = "\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 @@ -117,27 +158,57 @@ bool VcprojGenerator::writeMakefile(QTextStream &t) 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; + bool debugBuild; QStringList dependencies; }; +QUuid VcprojGenerator::getProjectUUID(const QString &filename) +{ + bool validUUID = true; + + // Read GUID from variable-space + QUuid uuid = project->first("GUID"); + + // If none, create one based on the MD5 of absolute project path + if (uuid.isNull() || !filename.isNull()) { + QString abspath = filename.isNull()?project->first("QMAKE_MAKEFILE"):filename; + qtMD5(abspath.utf8(), (unsigned char*)(&uuid)); + validUUID = !uuid.isNull(); + uuid.data4[0] = (uuid.data4[0] & 0x3F) | 0x80; // UV_DCE variant + uuid.data3 = (uuid.data3 & 0x0FFF) | (QUuid::Name<<12); + } + + // If still not valid, generate new one, and suggest adding to .pro + if (uuid.isNull() || !validUUID) { + uuid = QUuid::createUuid(); + fprintf(stderr, + "qmake couldn't create a GUID based on filepath, and we couldn't\nfind a valid GUID in the .pro file (Consider adding\n'GUID = %s' to the .pro file)\n", + uuid.toString().upper().latin1()); + } + + // Store GUID in variable-space + project->values("GUID") = uuid.toString().upper(); + return uuid; +} + 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]; @@ -154,159 +225,173 @@ QUuid VcprojGenerator::increaseUUID( const QUuid &id ) result.data4[7] = uchar( dataLast & 0xff); return result; } void VcprojGenerator::writeSubDirs(QTextStream &t) { if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); Win32MakefileGenerator::writeSubDirs(t); return; } - 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 - + t << (use_net2003_version() ? _slnHeader71 : _slnHeader70); 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; + subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]); } 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() ); + warn_msg(WarnLogic, "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->target = tmp_proj.first("MSVCPROJ_TARGET").section(Option::dir_sep, -1); newDep->targetType = tmp_vcproj.projectTarget; - { - static QUuid uuid = solutionGUID; - uuid = increaseUUID( uuid ); - newDep->uuid = uuid.toString().upper(); - } + newDep->debugBuild = tmp_proj.isActiveConfig("debug"); + newDep->uuid = getProjectUUID(Option::fixPathToLocalOS(QDir::currentDirPath() + QDir::separator() + vcproj)).toString().upper(); + + // We want to store it as the .lib name. if(newDep->target.endsWith(".dll")) newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; + + // All projects using Forms are dependent on uic.exe if(!tmp_proj.isEmpty("FORMS")) newDep->dependencies << "uic.exe"; - { + + // Add all unknown libs to the deps 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 + if(!opt.startsWith("/") && // Not a switch + opt != newDep->target && // Not self + opt != "opengl32.lib" && // We don't care about these libs + opt != "glu32.lib" && // to make depgen alittle faster + opt != "kernel32.lib" && + opt != "user32.lib" && + opt != "gdi32.lib" && + opt != "comdlg32.lib" && + opt != "advapi32.lib" && + opt != "shell32.lib" && + opt != "ole32.lib" && + opt != "oleaut32.lib" && + opt != "uuid.lib" && + opt != "imm32.lib" && + opt != "winmm.lib" && + opt != "wsock32.lib" && + opt != "winspool.lib" && + opt != "delayimp.lib" ) + { newDep->dependencies << opt.section(Option::dir_sep, -1); } } } +#ifdef DEBUG_SOLUTION_GEN + qDebug( "Deps for %20s: [%s]", newDep->target.latin1(), newDep->dependencies.join(" :: " ).latin1() ); +#endif 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 + t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile << "\", \"" << newDep->uuid << "\""; - t << _snlProjectEnd; + t << _slnProjectEnd; } } nextfile: QDir::setCurrent(oldpwd); } } } - t << _snlGlobalBeg; - t << _snlSolutionConf; - t << _snlProjDepBeg; + t << _slnGlobalBeg; + t << _slnSolutionConf; + t << _slnProjDepBeg; + + // Figure out dependencies for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { + if(solution_cleanup.current()->targetType == StaticLib) + continue; // Shortcut, Static libs are not dep. int cnt = 0; for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); dit != solution_cleanup.current()->dependencies.end(); - ++dit) { - VcsolutionDepend *vc; - if((vc=solution_depends[*dit])) { - if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) + ++dit) + { + VcsolutionDepend *vc = solution_depends[*dit]; + if(vc) t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; } } - } - t << _snlProjDepEnd; - t << _snlProjConfBeg; + t << _slnProjDepEnd; + t << _slnProjConfBeg; 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 << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag2; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag1; + t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag2; } - t << _snlProjConfEnd; - t << _snlExtSections; - t << _snlGlobalEnd; + t << _slnProjConfEnd; + t << _slnExtSections; + t << _slnGlobalEnd; } // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ void VcprojGenerator::init() { if( init_flag ) return; if(project->first("TEMPLATE") == "vcsubdirs") { //too much work for subdirs init_flag = TRUE; return; @@ -360,390 +445,546 @@ void VcprojGenerator::init() */ 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; } + + // Setup PCH variables + precompH = project->first("PRECOMPILED_HEADER"); + usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + if (usePCH) { + precompHFilename = QFileInfo(precompH).fileName(); + // Created files + QString origTarget = project->first("QMAKE_ORIG_TARGET"); + precompObj = origTarget + Option::obj_ext; + precompPch = origTarget + ".pch"; + // Add PRECOMPILED_HEADER to HEADERS + if (!project->variables()["HEADERS"].contains(precompH)) + project->variables()["HEADERS"] += precompH; + // Return to variable pool + project->variables()["PRECOMPILED_OBJECT"] = precompObj; + project->variables()["PRECOMPILED_PCH"] = precompPch; + } + 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" ); + vcProject.Version = use_net2003_version() ? "7.10" : "7.00"; + vcProject.ProjectGUID = getProjectUUID().toString().upper(); + vcProject.PlatformName = ( vcProject.Configuration[0].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; + vcProject.Configuration[0].ConfigurationType = typeDynamicLibrary; break; case StaticLib: - vcProject.Configuration.ConfigurationType = typeStaticLibrary; + vcProject.Configuration[0].ConfigurationType = typeStaticLibrary; break; case Application: default: - vcProject.Configuration.ConfigurationType = typeApplication; + vcProject.Configuration[0].ConfigurationType = typeApplication; break; } - 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() ? (short)unset : temp.toShort() ); + + // Release version of the Configuration --------------- + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.Name = "Release"; + RConf.Name += ( RConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + RConf.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True ); + RConf.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() ); temp = project->first("CharacterSet"); - 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; + RConf.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() ); + RConf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean"); + RConf.ImportLibrary = RConf.linker.ImportLibrary; + RConf.IntermediateDirectory = project->first("OBJECTS_DIR"); + RConf.OutputDirectory = "."; + RConf.PrimaryOutput = project->first("PrimaryOutput"); + RConf.WholeProgramOptimization = RConf.compiler.WholeProgramOptimization; temp = project->first("UseOfATL"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfATL = useOfATL( temp.toShort() ); + RConf.UseOfATL = useOfATL( temp.toShort() ); temp = project->first("UseOfMfc"); if ( !temp.isEmpty() ) - vcProject.Configuration.UseOfMfc = useOfMfc( temp.toShort() ); + RConf.UseOfMfc = useOfMfc( temp.toShort() ); // Configuration does not need parameters from // these sub XML items; initCustomBuildTool(); initPreBuildEventTools(); initPostBuildEventTools(); initPreLinkEventTools(); + + // Debug version of the Configuration ----------------- + VCConfiguration DConf = vcProject.Configuration[0]; // Create copy configuration for debug + DConf.Name = "Debug"; + DConf.Name += ( DConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" ); + + // Set definite values in both configurations + DConf.compiler.PreprocessorDefinitions.remove("NDEBUG"); + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; + RConf.linker.GenerateDebugInformation = _False; + DConf.linker.GenerateDebugInformation = _True; + + // Modify configurations, based on Qt build + if ( project->isActiveConfig("debug") ) { + RConf.IntermediateDirectory = + RConf.compiler.AssemblerListingLocation = + RConf.compiler.ObjectFile = "Release\\"; + RConf.librarian.OutputFile = + RConf.linker.OutputFile = RConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + RConf.linker.parseOptions(project->variables()["QMAKE_LFLAGS_RELEASE"]); + RConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_RELEASE"]); + } else { + DConf.IntermediateDirectory = + DConf.compiler.AssemblerListingLocation = + DConf.compiler.ObjectFile = "Debug\\"; + DConf.librarian.OutputFile = + DConf.linker.OutputFile = DConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET"); + DConf.linker.DelayLoadDLLs.clear(); + DConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_DEBUG"]); + } + + // Add Debug configuration to project + vcProject.Configuration += DConf; } void VcprojGenerator::initCompilerTool() { QString placement = project->first("OBJECTS_DIR"); if ( placement.isEmpty() ) 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"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.compiler.AssemblerListingLocation = placement ; + RConf.compiler.ProgramDataBaseFileName = ".\\" ; + RConf.compiler.ObjectFile = placement ; + // PCH + if ( usePCH ) { + RConf.compiler.UsePrecompiledHeader = pchUseUsingSpecific; + RConf.compiler.PrecompiledHeaderFile = "$(IntDir)\\" + precompPch; + RConf.compiler.PrecompiledHeaderThrough = precompHFilename; + RConf.compiler.ForcedIncludeFiles = precompHFilename; + // Minimal build option triggers an Internal Compiler Error + // when used in conjunction with /FI and /Yu, so remove it + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CFLAGS_DEBUG"].remove("/Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("-Gm"); + project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("/Gm"); + } if ( project->isActiveConfig("debug") ){ // Debug version - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.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"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST_DBG"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_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"; + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] ); + RConf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; + RConf.compiler.PreprocessorDefinitions += "NDEBUG"; if ( project->isActiveConfig("thread") ) { if ( (projectTarget == Application) || (projectTarget == StaticLib) ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); else - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] ); } else { - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_ST"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] ); } } // Common for both release and debug if ( project->isActiveConfig("warn_off") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] ); else if ( project->isActiveConfig("warn_on") ) - vcProject.Configuration.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); + RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] ); if ( project->isActiveConfig("windows") ) - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"]; + RConf.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"; + RConf.compiler.PreprocessorDefinitions += "_WINDOWS"; + + RConf.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; + RConf.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; + QStringList::iterator it; + for(it=RConf.compiler.PreprocessorDefinitions.begin(); + it!=RConf.compiler.PreprocessorDefinitions.end(); + ++it) + (*it).replace('\"', """); - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["DEFINES"]; - vcProject.Configuration.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"]; - vcProject.Configuration.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] ); + RConf.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 = ".\\"; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.librarian.OutputFile = project->first( "DESTDIR" ); + if( RConf.librarian.OutputFile.isEmpty() ) + RConf.librarian.OutputFile = ".\\"; - if( !vcProject.Configuration.librarian.OutputFile.endsWith("\\") ) - vcProject.Configuration.librarian.OutputFile += '\\'; + if( !RConf.librarian.OutputFile.endsWith("\\") ) + RConf.librarian.OutputFile += '\\'; - vcProject.Configuration.librarian.OutputFile += project->first("MSVCPROJ_TARGET"); + RConf.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"]; + VCConfiguration &RConf = vcProject.Configuration[0]; + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] ); + RConf.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"]; switch ( projectTarget ) { case Application: - vcProject.Configuration.linker.OutputFile = project->first( "DESTDIR" ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; case SharedLib: - vcProject.Configuration.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); - vcProject.Configuration.linker.OutputFile = project->first( "DLLDESTDIR" ); + RConf.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] ); + RConf.linker.OutputFile = project->first( "DESTDIR" ); break; case StaticLib: //unhandled - added to remove warnings.. break; } - if( vcProject.Configuration.linker.OutputFile.isEmpty() ) - vcProject.Configuration.linker.OutputFile = ".\\"; + if( RConf.linker.OutputFile.isEmpty() ) + RConf.linker.OutputFile = ".\\"; - if( !vcProject.Configuration.linker.OutputFile.endsWith("\\") ) - vcProject.Configuration.linker.OutputFile += '\\'; + if( !RConf.linker.OutputFile.endsWith("\\") ) + RConf.linker.OutputFile += '\\'; - vcProject.Configuration.linker.OutputFile += project->first("MSVCPROJ_TARGET"); - vcProject.Configuration.linker.ProgramDatabaseFile = project->first("OBJECTS_DIR") + project->first("QMAKE_ORIG_TARGET") + ".pdb"; + RConf.linker.OutputFile += project->first("MSVCPROJ_TARGET"); if ( project->isActiveConfig("debug") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] ); } if ( project->isActiveConfig("dll") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] ); } if ( project->isActiveConfig("console") ){ - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); + RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] ); } else { - vcProject.Configuration.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] ); + RConf.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; - - 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() { + VCConfiguration &RConf = vcProject.Configuration[0]; if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) { - vcProject.Configuration.postBuild.Description = var("QMAKE_POST_LINK"); - vcProject.Configuration.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description = var("QMAKE_POST_LINK"); + RConf.postBuild.CommandLine = var("QMAKE_POST_LINK"); + RConf.postBuild.Description.replace(" && ", " && "); + RConf.postBuild.CommandLine.replace(" && ", " && "); + } + if ( !project->variables()["MSVCPROJ_COPY_DLL"].isEmpty() ) { + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; + RConf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC"); + RConf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL"); } 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 += " && "; + RConf.postBuild.Description = "Finalizing ActiveQt server..."; + if ( !RConf.postBuild.CommandLine.isEmpty() ) + RConf.postBuild.CommandLine += " && "; if( project->isActiveConfig( "dll" ) ) { // In process - vcProject.Configuration.postBuild.CommandLine += + RConf.postBuild.CommandLine += // call idc to generate .idl file from .dll - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " -idl " + objdir + name + ".idl -version 1.0 && " + + idc + " "$(TargetPath)" -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 && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // register server - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /regserver"; + idc + " "$(TargetPath)" /regserver"; } else { // out of process - vcProject.Configuration.postBuild.CommandLine = + RConf.postBuild.CommandLine = // call application to dump idl - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -dumpidl " + objdir + name + ".idl -version 1.0 && " + + ""$(TargetPath)" -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 && " + + project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb && " + // call idc to replace tlb... - idc + " " + vcProject.Configuration.OutputDirectory + "\\" + nameext + " /tlb " + objdir + name + ".tlb && " + + idc + " "$(TargetPath)" /tlb " + objdir + name + ".tlb && " + // call app to register - vcProject.Configuration.OutputDirectory + "\\" + nameext + " -regserver"; + ""$(TargetPath)" -regserver"; } } } void VcprojGenerator::initPreLinkEventTools() { } + +// ------------------------------------------------------------------ +// Helper functions to do proper sorting of the +// qstringlists, for both flat and non-flat modes. +inline bool XLessThanY( QString &x, QString &y, bool flat_mode ) +{ + if ( flat_mode ) { + QString subX = x.mid( x.findRev('\\')+1 ); + QString subY = y.mid( y.findRev('\\')+1 ); + return QString::compare(subX, subY) < 0; + } + + int xPos = 0; + int yPos = 0; + int xSlashPos; + int ySlashPos; + for (;;) { + xSlashPos = x.find('\\', xPos); + ySlashPos = y.find('\\', yPos); + + if (xSlashPos == -1 && ySlashPos != -1) { + return false; + } else if (xSlashPos != -1 && ySlashPos == -1) { + return true; + } else if (xSlashPos == -1 /* && yySlashPos == -1 */) { + QString subX = x.mid(xPos); + QString subY = y.mid(yPos); + return QString::compare(subX, subY) < 0; + } else { + QString subX = x.mid(xPos, xSlashPos - xPos); + QString subY = y.mid(yPos, ySlashPos - yPos); + int cmp = QString::compare(subX, subY); + if (cmp != 0) + return cmp < 0; + } + xPos = xSlashPos + 1; + yPos = ySlashPos + 1; + } + return false; +} +void nonflatDir_BubbleSort( QStringList& list, bool flat_mode ) +{ + QStringList::Iterator b = list.begin(); + QStringList::Iterator e = list.end(); + QStringList::Iterator last = e; + --last; // goto last + if ( last == b ) // shortcut + return; + while( b != last ) {// sort them + bool swapped = FALSE; + QStringList::Iterator swap_pos = b; + QStringList::Iterator x = e; + QStringList::Iterator y = x; + --y; + QString swap_str; + do { + --x; + --y; + if ( XLessThanY(*x,*y, flat_mode) ) { + swapped = TRUE; + swap_str = (*x); // Swap ------- + (*x) = (*y); + (*y) = swap_str; // ------------ + swap_pos = y; + } + } while( y != b ); + if ( !swapped ) + return; + b = swap_pos; + ++b; + } +} +// ------------------------------------------------------------------ + void VcprojGenerator::initSourceFiles() { + vcProject.SourceFiles.flat_files = project->isActiveConfig("flat"); 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(); + nonflatDir_BubbleSort( vcProject.SourceFiles.Files, + vcProject.SourceFiles.flat_files ); vcProject.SourceFiles.Project = this; vcProject.SourceFiles.Config = &(vcProject.Configuration); vcProject.SourceFiles.CustomBuild = none; } void VcprojGenerator::initHeaderFiles() { + vcProject.HeaderFiles.flat_files = project->isActiveConfig("flat"); vcProject.HeaderFiles.Name = "Header Files"; vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl"; vcProject.HeaderFiles.Files += project->variables()["HEADERS"]; - vcProject.HeaderFiles.Files.sort(); + if (usePCH) { // Generated PCH cpp file + if (!vcProject.HeaderFiles.Files.contains(precompH)) + vcProject.HeaderFiles.Files += precompH; + } + nonflatDir_BubbleSort( vcProject.HeaderFiles.Files, + vcProject.HeaderFiles.flat_files ); vcProject.HeaderFiles.Project = this; vcProject.HeaderFiles.Config = &(vcProject.Configuration); vcProject.HeaderFiles.CustomBuild = moc; } void VcprojGenerator::initMOCFiles() { + vcProject.MOCFiles.flat_files = project->isActiveConfig("flat"); vcProject.MOCFiles.Name = "Generated MOC Files"; vcProject.MOCFiles.Filter = "cpp;c;cxx;moc"; vcProject.MOCFiles.Files += project->variables()["SRCMOC"]; - vcProject.MOCFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.MOCFiles.Files, + vcProject.MOCFiles.flat_files ); vcProject.MOCFiles.Project = this; vcProject.MOCFiles.Config = &(vcProject.Configuration); vcProject.MOCFiles.CustomBuild = moc; } void VcprojGenerator::initUICFiles() { - vcProject.UICFiles.Name = "Generated UI Files"; + vcProject.UICFiles.flat_files = project->isActiveConfig("flat"); + vcProject.UICFiles.Name = "Generated Form 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(); + nonflatDir_BubbleSort( vcProject.UICFiles.Files, + vcProject.UICFiles.flat_files ); vcProject.UICFiles.Config = &(vcProject.Configuration); vcProject.UICFiles.CustomBuild = none; } void VcprojGenerator::initFormsFiles() { + vcProject.FormFiles.flat_files = project->isActiveConfig("flat"); vcProject.FormFiles.Name = "Forms"; vcProject.FormFiles.ParseFiles = _False; vcProject.FormFiles.Filter = "ui"; vcProject.FormFiles.Files += project->variables()["FORMS"]; - vcProject.FormFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.FormFiles.Files, + vcProject.FormFiles.flat_files ); vcProject.FormFiles.Project = this; vcProject.FormFiles.Config = &(vcProject.Configuration); vcProject.FormFiles.CustomBuild = uic; } void VcprojGenerator::initTranslationFiles() { + vcProject.TranslationFiles.flat_files = project->isActiveConfig("flat"); vcProject.TranslationFiles.Name = "Translations Files"; vcProject.TranslationFiles.ParseFiles = _False; vcProject.TranslationFiles.Filter = "ts"; vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"]; - vcProject.TranslationFiles.Files.sort(); + nonflatDir_BubbleSort( vcProject.TranslationFiles.Files, + vcProject.TranslationFiles.flat_files ); vcProject.TranslationFiles.Project = this; vcProject.TranslationFiles.Config = &(vcProject.Configuration); vcProject.TranslationFiles.CustomBuild = none; } void VcprojGenerator::initLexYaccFiles() { + vcProject.LexYaccFiles.flat_files = project->isActiveConfig("flat"); 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(); + nonflatDir_BubbleSort( vcProject.LexYaccFiles.Files, + vcProject.LexYaccFiles.flat_files ); vcProject.LexYaccFiles.Project = this; + vcProject.LexYaccFiles.Config = &(vcProject.Configuration); vcProject.LexYaccFiles.CustomBuild = lexyacc; } void VcprojGenerator::initResourceFiles() { + vcProject.ResourceFiles.flat_files = project->isActiveConfig("flat"); 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(); + nonflatDir_BubbleSort( vcProject.ResourceFiles.Files, + vcProject.ResourceFiles.flat_files ); vcProject.ResourceFiles.Project = this; - vcProject.ResourceFiles.CustomBuild = none; + vcProject.ResourceFiles.Config = &(vcProject.Configuration); + vcProject.ResourceFiles.CustomBuild = resource; } /* \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; @@ -856,25 +1097,24 @@ void VcprojGenerator::initOld() 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 @@ -930,34 +1170,44 @@ void VcprojGenerator::initOld() // INCREMENTAL:NO ------------------------------------------------ if(!project->isActiveConfig("incremental")) { 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); + // /VERSION:x.yz ------------------------------------------------- + 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 ); + } 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" ) ) { + project->variables()["QMAKE_LIBDIR"] += (*it).mid(2); 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)]; @@ -1041,100 +1291,98 @@ void VcprojGenerator::initOld() 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"); Option::fixPathToTargetOS(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"] = dest; - if ( project->isActiveConfig("dll") ) { - 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; - } // 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="; + QString copydll(""); + QStringList::Iterator dlldir; + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { + if ( !copydll.isEmpty() ) + copydll += " && "; + copydll += "copy "$(TargetPath)" "" + *dlldir + """; + } - for ( QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) { - copydll += "copy \"" + dest + "\" \"" + *dlldir + "\"\t"; + QString deststr( "Copy " + dest + " to " ); + for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ) { + deststr += *dlldir; + ++dlldir; + if ( dlldir != dlldirs.end() ) + deststr += ", "; } - copydll += "\n# End Special Build Tool"; - project->variables()["MSVCPROJ_COPY_DLL_REL"].append( copydll ); - project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( copydll ); + project->variables()["MSVCPROJ_COPY_DLL"].append( copydll ); + project->variables()["MSVCPROJ_COPY_DLL_DESC"].append( deststr ); } // 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" ); + QString objdir = project->first( "OBJECTS_DIR" ); + project->variables()["MSVCPROJ_IDLSOURCES"].append( objdir + targetfilename + ".idl" ); 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" + idc + " %1 -idl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + + "\t" + idc + " %1 /tlb " + objdir + 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" + "%1 -dumpidl " + objdir + targetfilename + ".idl -version " + version + + "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" + "\t" + idc + " %1 /tlb " + objdir + 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) ); } - } + if ( !project->variables()["DEF_FILE"].isEmpty() ) + project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE")); + // 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(); } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 69e0c02..d1ca666 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -1,22 +1,21 @@ + /**************************************************************************** -** $Id$ ** -** Definition of VcprojGenerator class. ** -** Created : 970521 +** Definition of VcprojGenerator class. ** -** 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 is part of qmake. ** ** 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 @@ -25,24 +24,25 @@ ** 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 __MSVC_VCPROJ_H__ #define __MSVC_VCPROJ_H__ #include "winmakefile.h" #include "msvc_objectmodel.h" enum target { Application, SharedLib, StaticLib }; @@ -54,24 +54,27 @@ class VcprojGenerator : public Win32MakefileGenerator 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 + QString precompH, precompHFilename, + precompObj, precompPch; + bool usePCH; 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(); @@ -86,24 +89,25 @@ protected: void initHeaderFiles(); void initMOCFiles(); void initUICFiles(); void initFormsFiles(); void initTranslationFiles(); void initLexYaccFiles(); void initResourceFiles(); VCProject vcProject; target projectTarget; private: + QUuid getProjectUUID(const QString &filename=QString::null); QUuid increaseUUID(const QUuid &id); friend class VCFilter; }; inline VcprojGenerator::~VcprojGenerator() { } inline QString VcprojGenerator::defaultMakefile() const { return project->first("TARGET") + project->first("VCPROJ_EXTENSION"); } 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,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Implementation of Win32MakefileGenerator class. ** -** Copyright (C) 1992-2000 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 is part of qmake. ** ** 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 @@ -29,24 +27,25 @@ ** 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 "meta.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) { } @@ -88,43 +87,40 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) 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 << "MAKEFILE = " << (project->isEmpty("MAKEFILE") ? QString("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; + t << "all: $(MAKEFILE) $(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(); 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; @@ -136,24 +132,34 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) t << "\n\t" << "cd " << (*it)->directory; t << "\n\t" << "$(MAKE)"; 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->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; + } + 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"; @@ -166,85 +172,152 @@ Win32MakefileGenerator::writeSubDirs(QTextStream &t) << " " << 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 ", ""); + QStringList targs; + targs << "clean" << "install_subdirs" << "mocables" << "uicables" << "uiclean" << "mocclean"; + targs += project->values("SUBDIR_TARGETS"); + for(QStringList::Iterator targ_it = targs.begin(); targ_it != targs.end(); ++targ_it) { + t << (*targ_it) << ": qmake_all"; + QString targ = (*targ_it); + if(targ == "install_subdirs") + targ = "install"; + else if(targ == "uninstall_subdirs") + targ = "uninstall"; + if(targ == "clean") + t << varGlue("QMAKE_CLEAN","\n\t-$(DEL_FILE) ","\n\t-$(DEL_FILE) ", ""); 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 = " -f " + (*it)->makefile; - t << "\n\t" << "$(MAKE) " << in_file << " " << targs[x]; + t << "\n\t" << "$(MAKE) " << in_file << " " << targ; 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; } + //installations + project->variables()["INSTALLDEPS"] += "install_subdirs"; + project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs"; + writeInstalls(t, "INSTALLS"); + + // user defined targets + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator sit = qut.begin(); sit != qut.end(); ++sit) { + QString targ = var((*sit) + ".target"), + cmd = var((*sit) + ".commands"), deps; + if(targ.isEmpty()) + targ = (*sit); + QStringList &deplist = project->variables()[(*sit) + ".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; + } + if(!project->variables()["QMAKE_NOFORCE"].isEmpty() && + project->variables()[(*sit) + ".CONFIG"].findIndex("phony") != -1) + deps += QString(" ") + "FORCE"; + t << "\n\n" << targ << ":" << deps << "\n\t" + << cmd; + } + if(project->variables()["QMAKE_NOFORCE"].isEmpty()) t << "FORCE:" << endl << endl; } int Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem) { 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(); QDir dir(bd); int biggest=-1; QStringList entries = dir.entryList(); 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) == 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()); - } + QMakeMetaInfo libinfo; + if(libinfo.readLib(bd + dllStem)) { + if(!libinfo.isEmpty("QMAKE_PRL_VERSION")) + biggest = QMAX(biggest, libinfo.first("QMAKE_PRL_VERSION").replace(".", "").toInt()); } return biggest; } +QString +Win32MakefileGenerator::findDependency(const QString &dep) +{ + { + QStringList &qut = project->variables()["QMAKE_EXTRA_WIN_TARGETS"]; + for(QStringList::Iterator it = qut.begin(); it != qut.end(); ++it) { + QString targ = var((*it) + ".target"); + if(targ.isEmpty()) + targ = (*it); + if(targ.endsWith(dep)) + return targ; + } + } + { + QStringList &quc = project->variables()["QMAKE_EXTRA_WIN_COMPILERS"]; + for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) { + QString tmp_out = project->variables()[(*it) + ".output"].first(); + QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" "); + if(tmp_out.isEmpty() || tmp_cmd.isEmpty()) + continue; + QStringList &tmp = project->variables()[(*it) + ".input"]; + for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) { + QStringList &inputs = project->variables()[(*it2)]; + for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) { + QString out = tmp_out; + QFileInfo fi(Option::fixPathToLocalOS((*input))); + out.replace("${QMAKE_FILE_BASE}", fi.baseName()); + out.replace("${QMAKE_FILE_NAME}", fi.fileName()); + if(out.endsWith(dep)) + return out; + } + } + } + } + return MakefileGenerator::findDependency(dep); +} 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); @@ -269,49 +342,50 @@ Win32MakefileGenerator::findLibraries(const QString &where) dirs.append(new MakefileDependDir(r.replace("\"",""), l.replace("\"",""))); 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) extension += QString::number(ver); extension += ".lib"; - if(QFile::exists(mdd->local_dir + Option::dir_sep + lib + Option::prl_ext) || + if(QMakeMetaInfo::libExists(mdd->local_dir + Option::dir_sep + lib) || 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; //just eat it since we cannot find one.. } else { modified_opt = TRUE; (*it) = out; } } else if(!QFile::exists(Option::fixPathToLocalOS(opt))) { QPtrList<MakefileDependDir> lib_dirs; QString file = opt; int slsh = file.findRev(Option::dir_sep); if(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()) { if(file.endsWith(".lib")) { file = file.left(file.length() - 4); if(!file.at(file.length()-1).isNumber()) { 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) { if(ver) lib_tmpl = lib_tmpl.arg(ver); else lib_tmpl = lib_tmpl.arg(""); if(slsh != -1) { @@ -319,24 +393,25 @@ Win32MakefileGenerator::findLibraries(const QString &where) if(!dir.endsWith(Option::dir_sep)) dir += Option::dir_sep; lib_tmpl.prepend(dir); } modified_opt = TRUE; (*it) = lib_tmpl; break; } } } } } + } if(remove) { it = l.remove(it); } else { if(!quote.isNull() && modified_opt) (*it) = quote + (*it) + quote; ++it; } } return TRUE; } void diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 75ba0e0..dac4a99 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -1,22 +1,20 @@ /**************************************************************************** -** $Id$ ** -** Definition of ________ class. ** -** Created : 970521 +** Definition of Win32MakefileGenerator class. ** -** Copyright (C) 1992-2000 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 is part of qmake. ** ** 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 @@ -25,43 +23,45 @@ ** 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 __WINMAKEFILE_H__ #define __WINMAKEFILE_H__ #include "makefile.h" // In the Qt evaluation and educational version, we have a postfix in the // library name (e.g. qtmteval301.dll). QTDLL_POSTFIX is used for this. // A script modifies these lines when building eval/edu version, so be careful // when changing them. #ifndef QTDLL_POSTFIX #define QTDLL_POSTFIX "" #endif class Win32MakefileGenerator : public MakefileGenerator { protected: virtual void writeSubDirs(QTextStream &t); int findHighestVersion(const QString &dir, const QString &stem); bool findLibraries(const QString &); + QString findDependency(const QString &); virtual bool findLibraries(); virtual void processPrlFiles(); public: Win32MakefileGenerator(QMakeProject *p); ~Win32MakefileGenerator(); }; inline Win32MakefileGenerator::~Win32MakefileGenerator() { } inline bool Win32MakefileGenerator::findLibraries() |