Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

msvc_vcproj.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** 
00003 **
00004 ** Implementation of VcprojGenerator class.
00005 **
00006 ** Copyright (C) 1992-2003 Trolltech AS.  All rights reserved.
00007 **
00008 ** This file is part of qmake.
00009 **
00010 ** This file may be distributed under the terms of the Q Public License
00011 ** as defined by Trolltech AS of Norway and appearing in the file
00012 ** LICENSE.QPL included in the packaging of this file.
00013 **
00014 ** This file may be distributed and/or modified under the terms of the
00015 ** GNU General Public License version 2 as published by the Free Software
00016 ** Foundation and appearing in the file LICENSE.GPL included in the
00017 ** packaging of this file.
00018 **
00019 ** Licensees holding valid Qt Enterprise Edition licenses may use this
00020 ** file in accordance with the Qt Commercial License Agreement provided
00021 ** with the Software.
00022 **
00023 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00024 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00025 **
00026 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00027 **   information about Qt Commercial License Agreements.
00028 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00029 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00030 **
00031 ** Contact info@trolltech.com if any conditions of this licensing are
00032 ** not clear to you.
00033 **
00034 **********************************************************************/
00035 
00036 #include "msvc_vcproj.h"
00037 #include "option.h"
00038 #include "qtmd5.h" // SG's MD5 addon
00039 #include <qdir.h>
00040 #include <qregexp.h>
00041 #include <qdict.h>
00042 #include <quuid.h>
00043 #include <stdlib.h>
00044 #include <qsettings.h>
00045 
00046 //#define DEBUG_SOLUTION_GEN
00047 //#define DEBUG_PROJECT_GEN
00048 
00049 // Registry keys for .NET version detection -------------------------
00050 const char* _regNet2002         = "Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir";
00051 const char* _regNet2003         = "Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir";
00052 
00053 bool use_net2003_version()
00054 {
00055 #ifndef Q_OS_WIN32
00056     return FALSE; // Always generate 7.0 versions on other platforms
00057 #else
00058     // Only search for the version once
00059     static int current_version = -1;
00060     if (current_version!=-1)
00061         return (current_version==71);
00062 
00063     // Fallback to .NET 2002
00064     current_version = 70;
00065 
00066     // Get registry entries for both versions
00067     bool ok = false;
00068     QSettings setting;
00069     QString path2002 = setting.readEntry(_regNet2002);
00070     QString path2003 = setting.readEntry(_regNet2003);
00071 
00072     if ( path2002.isNull() || path2003.isNull() ) {
00073         // Only have one MSVC, so use that one
00074         current_version = (path2003.isNull() ? 70 : 71);
00075     } else {
00076         // Have both, so figure out the current
00077         QString paths = getenv("PATH");
00078         QStringList pathlist = QStringList::split(";", paths.lower());
00079 
00080         path2003 = path2003.lower();
00081         QStringList::iterator it;
00082         for(it=pathlist.begin(); it!=pathlist.end(); ++it) {
00083             if ((*it).contains(path2003)) {
00084                 current_version = 71;
00085             } else if ((*it).contains(path2002)
00086                        && current_version == 71) {
00087                 fprintf( stderr, "Both .NET 2002 & .NET 2003 directories for VC found in you PATH variable!\nFallback to .NET 2002 project generation" );
00088                 current_version = 70;
00089                 break;
00090             }
00091         }
00092     }
00093     return (current_version==71);
00094 #endif
00095 };
00096 
00097 // Flatfile Tags ----------------------------------------------------
00098 const char* _slnHeader70        = "Microsoft Visual Studio Solution File, Format Version 7.00";
00099 const char* _slnHeader71        = "Microsoft Visual Studio Solution File, Format Version 8.00";
00100                                   // The following UUID _may_ change for later servicepacks...
00101                                   // If so we need to search through the registry at
00102                                   // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects
00103                                   // to find the subkey that contains a "PossibleProjectExtension"
00104                                   // containing "vcproj"...
00105                                   // Use the hardcoded value for now so projects generated on other
00106                                   // platforms are actually usable.
00107 const char* _slnMSVCvcprojGUID  = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
00108 const char* _slnProjectBeg      = "\nProject(\"";
00109 const char* _slnProjectMid      = "\") = ";
00110 const char* _slnProjectEnd      = "\nEndProject";
00111 const char* _slnGlobalBeg       = "\nGlobal";
00112 const char* _slnGlobalEnd       = "\nEndGlobal";
00113 const char* _slnSolutionConf    = "\n\tGlobalSection(SolutionConfiguration) = preSolution"
00114                                   "\n\t\tConfigName.0 = Debug"
00115                                   "\n\t\tConfigName.1 = Release"
00116                                   "\n\tEndGlobalSection";
00117 const char* _slnProjDepBeg      = "\n\tGlobalSection(ProjectDependencies) = postSolution";
00118 const char* _slnProjDepEnd      = "\n\tEndGlobalSection";
00119 const char* _slnProjConfBeg     = "\n\tGlobalSection(ProjectConfiguration) = postSolution";
00120 const char* _slnProjRelConfTag1 = ".Release.ActiveCfg = Release|Win32";
00121 const char* _slnProjRelConfTag2 = ".Release.Build.0 = Release|Win32";
00122 const char* _slnProjDbgConfTag1 = ".Debug.ActiveCfg = Debug|Win32";
00123 const char* _slnProjDbgConfTag2 = ".Debug.Build.0 = Debug|Win32";
00124 const char* _slnProjConfEnd     = "\n\tEndGlobalSection";
00125 const char* _slnExtSections     = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution"
00126                                   "\n\tEndGlobalSection"
00127                                   "\n\tGlobalSection(ExtensibilityAddIns) = postSolution"
00128                                   "\n\tEndGlobalSection";
00129 // ------------------------------------------------------------------
00130 
00131 VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE)
00132 {
00133 }
00134 
00135 /* \internal
00136     Generates a project file for the given profile.
00137     Options are either a Visual Studio projectfiles, or
00138     solutionfiles by parsing recursive projectdirectories.
00139 */
00140 bool VcprojGenerator::writeMakefile(QTextStream &t)
00141 {
00142     // Check if all requirements are fullfilled
00143     if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
00144         fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n",
00145                 var("QMAKE_FAILED_REQUIREMENTS").latin1());
00146         return TRUE;
00147     }
00148 
00149     // Generate project file
00150     if(project->first("TEMPLATE") == "vcapp" ||
00151        project->first("TEMPLATE") == "vclib") {
00152         debug_msg(1, "Generator: MSVC.NET: Writing project file" );
00153         t << vcProject;
00154         return TRUE;
00155     }
00156     // Generate solution file
00157     else if(project->first("TEMPLATE") == "vcsubdirs") {
00158         debug_msg(1, "Generator: MSVC.NET: Writing solution file" );
00159         writeSubDirs(t);
00160         return TRUE;
00161     }
00162     return FALSE;
00163 
00164 }
00165 
00166 struct VcsolutionDepend {
00167     QString uuid;
00168     QString vcprojFile, orig_target, target;
00169     ::target targetType;
00170     bool debugBuild;
00171     QStringList dependencies;
00172 };
00173 
00174 QUuid VcprojGenerator::getProjectUUID(const QString &filename)
00175 {
00176     bool validUUID = true;
00177 
00178     // Read GUID from variable-space
00179     QUuid uuid = project->first("GUID");
00180 
00181     // If none, create one based on the MD5 of absolute project path
00182     if (uuid.isNull() || !filename.isNull()) {
00183         QString abspath = filename.isNull()?project->first("QMAKE_MAKEFILE"):filename;
00184         qtMD5(abspath.utf8(), (unsigned char*)(&uuid));
00185         validUUID = !uuid.isNull();
00186         uuid.data4[0] = (uuid.data4[0] & 0x3F) | 0x80; // UV_DCE variant
00187         uuid.data3 = (uuid.data3 & 0x0FFF) | (QUuid::Name<<12);
00188     }
00189 
00190     // If still not valid, generate new one, and suggest adding to .pro
00191     if (uuid.isNull() || !validUUID) {
00192         uuid = QUuid::createUuid();
00193         fprintf(stderr, 
00194                 "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", 
00195                 uuid.toString().upper().latin1());
00196     }
00197 
00198     // Store GUID in variable-space
00199     project->values("GUID") = uuid.toString().upper();
00200     return uuid;
00201 }
00202 
00203 QUuid VcprojGenerator::increaseUUID( const QUuid &id )
00204 {
00205     QUuid result( id );
00206     Q_LONG dataFirst = (result.data4[0] << 24) +
00207                        (result.data4[1] << 16) +
00208                        (result.data4[2] << 8) +
00209                         result.data4[3];
00210     Q_LONG dataLast =  (result.data4[4] << 24) +
00211                        (result.data4[5] << 16) +
00212                        (result.data4[6] <<  8) +
00213                         result.data4[7];
00214 
00215     if ( !(dataLast++) )
00216         dataFirst++;
00217 
00218     result.data4[0] = uchar((dataFirst >> 24) & 0xff);
00219     result.data4[1] = uchar((dataFirst >> 16) & 0xff);
00220     result.data4[2] = uchar((dataFirst >>  8) & 0xff);
00221     result.data4[3] = uchar( dataFirst        & 0xff);
00222     result.data4[4] = uchar((dataLast  >> 24) & 0xff);
00223     result.data4[5] = uchar((dataLast  >> 16) & 0xff);
00224     result.data4[6] = uchar((dataLast  >>  8) & 0xff);
00225     result.data4[7] = uchar( dataLast         & 0xff);
00226     return result;
00227 }
00228 
00229 void VcprojGenerator::writeSubDirs(QTextStream &t)
00230 {
00231     if(project->first("TEMPLATE") == "subdirs") {
00232         writeHeader(t);
00233         Win32MakefileGenerator::writeSubDirs(t);
00234         return;
00235     }
00236 
00237     t << (use_net2003_version() ? _slnHeader71 : _slnHeader70);
00238 
00239     QDict<VcsolutionDepend> solution_depends;
00240 
00241     QPtrList<VcsolutionDepend> solution_cleanup;
00242     solution_cleanup.setAutoDelete(TRUE);
00243 
00244     
00245     QStringList subdirs = project->variables()["SUBDIRS"];
00246     QString oldpwd = QDir::currentDirPath();
00247 
00248     for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) {
00249         QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE));
00250         if(fi.exists()) {
00251             if(fi.isDir()) {
00252                 QString profile = (*it);
00253                 if(!profile.endsWith(Option::dir_sep))
00254                     profile += Option::dir_sep;
00255                 profile += fi.baseName() + ".pro";
00256                 subdirs.append(profile);
00257             } else {
00258                 QMakeProject tmp_proj;
00259                 QString dir = fi.dirPath(), fn = fi.fileName();
00260                 if(!dir.isEmpty()) {
00261                     if(!QDir::setCurrent(dir))
00262                         fprintf(stderr, "Cannot find directory: %s\n", dir.latin1());
00263                 }
00264                 if(tmp_proj.read(fn, oldpwd)) {
00265                     if(tmp_proj.first("TEMPLATE") == "vcsubdirs") {
00266                         subdirs += fileFixify(tmp_proj.variables()["SUBDIRS"]);
00267                     } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") {
00268                         // Initialize a 'fake' project to get the correct variables
00269                         // and to be able to extract all the dependencies
00270                         VcprojGenerator tmp_vcproj(&tmp_proj);
00271                         tmp_vcproj.setNoIO(TRUE);
00272                         tmp_vcproj.init();
00273                         if(Option::debug_level) {
00274                             QMap<QString, QStringList> &vars = tmp_proj.variables();
00275                             for(QMap<QString, QStringList>::Iterator it = vars.begin();
00276                                 it != vars.end(); ++it) {
00277                                 if(it.key().left(1) != "." && !it.data().isEmpty())
00278                                     debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(),
00279                                                 it.data().join(" :: ").latin1());
00280                             }
00281                         }
00282 
00283                         // We assume project filename is [QMAKE_ORIG_TARGET].vcproj
00284                         QString vcproj = fixFilename(tmp_vcproj.project->first("QMAKE_ORIG_TARGET")) + project->first("VCPROJ_EXTENSION");
00285 
00286                         // If file doesn't exsist, then maybe the users configuration
00287                         // doesn't allow it to be created. Skip to next...
00288                         if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) {
00289                             warn_msg(WarnLogic, "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() );
00290                             goto nextfile; // # Dirty!
00291                         }
00292 
00293                         VcsolutionDepend *newDep = new VcsolutionDepend;
00294                         newDep->vcprojFile = fileFixify(vcproj);
00295                         newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET");
00296                         newDep->target = tmp_proj.first("MSVCPROJ_TARGET").section(Option::dir_sep, -1);
00297                         newDep->targetType = tmp_vcproj.projectTarget;
00298                         newDep->debugBuild = tmp_proj.isActiveConfig("debug");
00299                         newDep->uuid = getProjectUUID(Option::fixPathToLocalOS(QDir::currentDirPath() + QDir::separator() + vcproj)).toString().upper();
00300 
00301                         // We want to store it as the .lib name.
00302                         if(newDep->target.endsWith(".dll"))
00303                             newDep->target = newDep->target.left(newDep->target.length()-3) + "lib";
00304 
00305                         // All projects using Forms are dependent on uic.exe
00306                         if(!tmp_proj.isEmpty("FORMS"))
00307                             newDep->dependencies << "uic.exe";
00308 
00309                         // Add all unknown libs to the deps
00310                         QStringList where("QMAKE_LIBS");
00311                         if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
00312                             where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"];
00313                         for(QStringList::iterator wit = where.begin();
00314                             wit != where.end(); ++wit) {
00315                             QStringList &l = tmp_proj.variables()[(*wit)];
00316                             for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
00317                                 QString opt = (*it);
00318                                 if(!opt.startsWith("/") &&   // Not a switch
00319                                     opt != newDep->target && // Not self
00320                                     opt != "opengl32.lib" && // We don't care about these libs
00321                                     opt != "glu32.lib" &&    // to make depgen alittle faster
00322                                     opt != "kernel32.lib" &&
00323                                     opt != "user32.lib" &&
00324                                     opt != "gdi32.lib" &&
00325                                     opt != "comdlg32.lib" &&
00326                                     opt != "advapi32.lib" &&
00327                                     opt != "shell32.lib" &&
00328                                     opt != "ole32.lib" &&
00329                                     opt != "oleaut32.lib" &&
00330                                     opt != "uuid.lib" &&
00331                                     opt != "imm32.lib" &&
00332                                     opt != "winmm.lib" &&
00333                                     opt != "wsock32.lib" &&
00334                                     opt != "winspool.lib" &&
00335                                     opt != "delayimp.lib" )
00336                                 {
00337                                     newDep->dependencies << opt.section(Option::dir_sep, -1);
00338                                 }
00339                             }
00340                         }
00341 #ifdef DEBUG_SOLUTION_GEN
00342                         qDebug( "Deps for %20s: [%s]", newDep->target.latin1(), newDep->dependencies.join(" :: " ).latin1() );
00343 #endif
00344                         solution_cleanup.append(newDep);
00345                         solution_depends.insert(newDep->target, newDep);
00346                         t << _slnProjectBeg << _slnMSVCvcprojGUID << _slnProjectMid
00347                             << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile
00348                             << "\", \"" << newDep->uuid << "\"";
00349                         t << _slnProjectEnd;
00350                     }
00351                 }
00352 nextfile:
00353                 QDir::setCurrent(oldpwd);
00354             }
00355         }
00356     }
00357     t << _slnGlobalBeg;
00358     t << _slnSolutionConf;
00359     t << _slnProjDepBeg;
00360 
00361     // Figure out dependencies 
00362     for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) {
00363         if(solution_cleanup.current()->targetType == StaticLib)
00364             continue; // Shortcut, Static libs are not dep.
00365         int cnt = 0;
00366         for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin();
00367             dit != solution_cleanup.current()->dependencies.end();
00368             ++dit)
00369         {
00370             VcsolutionDepend *vc = solution_depends[*dit];
00371             if(vc)
00372                 t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid;
00373         }
00374     }
00375     t << _slnProjDepEnd;
00376     t << _slnProjConfBeg;
00377     for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) {
00378         t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag1;
00379         t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjDbgConfTag2;
00380         t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag1;
00381         t << "\n\t\t" << solution_cleanup.current()->uuid << _slnProjRelConfTag2;
00382     }
00383     t << _slnProjConfEnd;
00384     t << _slnExtSections;
00385     t << _slnGlobalEnd;
00386 }
00387 
00388 // ------------------------------------------------------------------------------------------------
00389 // ------------------------------------------------------------------------------------------------
00390 
00391 void VcprojGenerator::init()
00392 {
00393     if( init_flag )
00394         return;
00395     if(project->first("TEMPLATE") == "vcsubdirs") { //too much work for subdirs
00396         init_flag = TRUE;
00397         return;
00398     }
00399 
00400     debug_msg(1, "Generator: MSVC.NET: Initializing variables" );
00401 
00402 /*
00403     // Once to be nice and clean code...
00404     // Wouldn't life be great?
00405 
00406     // Are we building Qt?
00407     bool is_qt =
00408         ( project->first("TARGET") == "qt"QTDLL_POSTFIX ||
00409           project->first("TARGET") == "qt-mt"QTDLL_POSTFIX );
00410 
00411     // Are we using Qt?
00412     bool isQtActive = project->isActiveConfig("qt");
00413 
00414     if ( isQtActive ) {
00415         project->variables()["CONFIG"] += "moc";
00416         project->variables()["CONFIG"] += "windows";
00417         project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
00418         project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
00419 
00420         if( projectTarget == SharedLib )
00421             project->variables()["DEFINES"] += "QT_DLL";
00422 
00423         if( project->isActiveConfig("accessibility" ) )
00424             project->variables()["DEFINES"] += "QT_ACCESSIBILITY_SUPPORT";
00425 
00426         if ( project->isActiveConfig("plugin")) {
00427             project->variables()["DEFINES"] += "QT_PLUGIN";
00428             project->variables()["CONFIG"] += "dll";
00429         }
00430 
00431         if( project->isActiveConfig("thread") ) {
00432             project->variables()["DEFINES"] += "QT_THREAD_SUPPORT";
00433             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
00434         } else {
00435             project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
00436         }
00437     }
00438 
00439     if ( project->isActiveConfig("opengl") ) {
00440         project->variables()["CONFIG"] += "windows"; // <-- Also in 'qt' above
00441         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
00442         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
00443 
00444     }
00445 */
00446     initOld();     // Currently calling old DSP code to set variables. CLEAN UP!
00447 
00448     // Figure out what we're trying to build
00449     if ( project->first("TEMPLATE") == "vcapp" ) {
00450         projectTarget = Application;
00451     } else if ( project->first("TEMPLATE") == "vclib") {
00452         if ( project->isActiveConfig( "staticlib" ) )
00453             projectTarget = StaticLib;
00454         else
00455             projectTarget = SharedLib;
00456     }
00457 
00458     // Setup PCH variables
00459     precompH = project->first("PRECOMPILED_HEADER");
00460     usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header");
00461     if (usePCH) {
00462         precompHFilename = QFileInfo(precompH).fileName();
00463         // Created files
00464         QString origTarget = project->first("QMAKE_ORIG_TARGET");
00465         precompObj = origTarget + Option::obj_ext;
00466         precompPch = origTarget + ".pch";
00467         // Add PRECOMPILED_HEADER to HEADERS
00468         if (!project->variables()["HEADERS"].contains(precompH))
00469             project->variables()["HEADERS"] += precompH;
00470         // Return to variable pool
00471         project->variables()["PRECOMPILED_OBJECT"] = precompObj;
00472         project->variables()["PRECOMPILED_PCH"]    = precompPch;
00473     }
00474 
00475     initProject(); // Fills the whole project with proper data
00476 }
00477 
00478 void VcprojGenerator::initProject()
00479 {
00480     // Initialize XML sub elements
00481     // - Do this first since project elements may need
00482     // - to know of certain configuration options
00483     initConfiguration();
00484     initSourceFiles();
00485     initHeaderFiles();
00486     initMOCFiles();
00487     initUICFiles();
00488     initFormsFiles();
00489     initTranslationFiles();
00490     initLexYaccFiles();
00491     initResourceFiles();
00492 
00493     // Own elements -----------------------------
00494     vcProject.Name = project->first("QMAKE_ORIG_TARGET");
00495     vcProject.Version = use_net2003_version() ? "7.10" : "7.00";
00496     vcProject.ProjectGUID = getProjectUUID().toString().upper();
00497     vcProject.PlatformName = ( vcProject.Configuration[0].idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32" );
00498     // These are not used by Qt, but may be used by customers
00499     vcProject.SccProjectName = project->first("SCCPROJECTNAME");
00500     vcProject.SccLocalPath = project->first("SCCLOCALPATH");
00501 }
00502 
00503 void VcprojGenerator::initConfiguration()
00504 {
00505     // Initialize XML sub elements
00506     // - Do this first since main configuration elements may need
00507     // - to know of certain compiler/linker options
00508     initCompilerTool();
00509     if ( projectTarget == StaticLib )
00510         initLibrarianTool();
00511     else
00512         initLinkerTool();
00513     initIDLTool();
00514 
00515     // Own elements -----------------------------
00516     QString temp = project->first("BuildBrowserInformation");
00517     switch ( projectTarget ) {
00518     case SharedLib:
00519         vcProject.Configuration[0].ConfigurationType = typeDynamicLibrary;
00520         break;
00521     case StaticLib:
00522         vcProject.Configuration[0].ConfigurationType = typeStaticLibrary;
00523         break;
00524     case Application:
00525     default:
00526         vcProject.Configuration[0].ConfigurationType = typeApplication;
00527         break;
00528     }
00529 
00530     // Release version of the Configuration ---------------
00531     VCConfiguration &RConf = vcProject.Configuration[0];
00532     RConf.Name = "Release";
00533     RConf.Name += ( RConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" );
00534     RConf.ATLMinimizesCRunTimeLibraryUsage = ( project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True );
00535     RConf.BuildBrowserInformation = triState( temp.isEmpty() ? (short)unset : temp.toShort() );
00536     temp = project->first("CharacterSet");
00537     RConf.CharacterSet = charSet( temp.isEmpty() ? (short)charSetNotSet : temp.toShort() );
00538     RConf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean");
00539     RConf.ImportLibrary = RConf.linker.ImportLibrary;
00540     RConf.IntermediateDirectory = project->first("OBJECTS_DIR");
00541     RConf.OutputDirectory = ".";
00542     RConf.PrimaryOutput = project->first("PrimaryOutput");
00543     RConf.WholeProgramOptimization = RConf.compiler.WholeProgramOptimization;
00544     temp = project->first("UseOfATL");
00545     if ( !temp.isEmpty() )
00546         RConf.UseOfATL = useOfATL( temp.toShort() );
00547     temp = project->first("UseOfMfc");
00548     if ( !temp.isEmpty() )
00549         RConf.UseOfMfc = useOfMfc( temp.toShort() );
00550 
00551     // Configuration does not need parameters from
00552     // these sub XML items;
00553     initCustomBuildTool();
00554     initPreBuildEventTools();
00555     initPostBuildEventTools();
00556     initPreLinkEventTools();
00557 
00558     // Debug version of the Configuration -----------------
00559     VCConfiguration DConf = vcProject.Configuration[0]; // Create copy configuration for debug
00560     DConf.Name = "Debug";
00561     DConf.Name += ( DConf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32" );
00562 
00563     // Set definite values in both configurations
00564     DConf.compiler.PreprocessorDefinitions.remove("NDEBUG");
00565     RConf.compiler.PreprocessorDefinitions += "NDEBUG";
00566     RConf.linker.GenerateDebugInformation = _False;
00567     DConf.linker.GenerateDebugInformation = _True;
00568 
00569     // Modify configurations, based on Qt build
00570     if ( project->isActiveConfig("debug") ) {
00571         RConf.IntermediateDirectory =
00572         RConf.compiler.AssemblerListingLocation =
00573         RConf.compiler.ObjectFile = "Release\\";
00574         RConf.librarian.OutputFile = 
00575         RConf.linker.OutputFile = RConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET");
00576         RConf.linker.parseOptions(project->variables()["QMAKE_LFLAGS_RELEASE"]);
00577         RConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_RELEASE"]);
00578     } else {
00579         DConf.IntermediateDirectory =
00580         DConf.compiler.AssemblerListingLocation =
00581         DConf.compiler.ObjectFile = "Debug\\";
00582         DConf.librarian.OutputFile = 
00583         DConf.linker.OutputFile = DConf.IntermediateDirectory + "\\" + project->first("MSVCPROJ_TARGET");
00584         DConf.linker.DelayLoadDLLs.clear();
00585         DConf.compiler.parseOptions(project->variables()["QMAKE_CFLAGS_DEBUG"]);
00586     }
00587 
00588     // Add Debug configuration to project
00589     vcProject.Configuration += DConf;
00590 }
00591 
00592 void VcprojGenerator::initCompilerTool()
00593 {
00594     QString placement = project->first("OBJECTS_DIR");
00595     if ( placement.isEmpty() )
00596         placement = ".\\";
00597 
00598     VCConfiguration &RConf = vcProject.Configuration[0];
00599     RConf.compiler.AssemblerListingLocation = placement ;
00600     RConf.compiler.ProgramDataBaseFileName = ".\\" ;
00601     RConf.compiler.ObjectFile = placement ;
00602     // PCH
00603     if ( usePCH ) {
00604         RConf.compiler.UsePrecompiledHeader     = pchUseUsingSpecific;
00605         RConf.compiler.PrecompiledHeaderFile    = "$(IntDir)\\" + precompPch;
00606         RConf.compiler.PrecompiledHeaderThrough = precompHFilename;
00607         RConf.compiler.ForcedIncludeFiles       = precompHFilename;
00608         // Minimal build option triggers an Internal Compiler Error
00609         // when used in conjunction with /FI and /Yu, so remove it
00610         project->variables()["QMAKE_CFLAGS_DEBUG"].remove("-Gm");
00611         project->variables()["QMAKE_CFLAGS_DEBUG"].remove("/Gm");
00612         project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("-Gm");
00613         project->variables()["QMAKE_CXXFLAGS_DEBUG"].remove("/Gm");
00614     }
00615 
00616     if ( project->isActiveConfig("debug") ){
00617         // Debug version
00618         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] );
00619         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_DEBUG"] );
00620         if ( project->isActiveConfig("thread") ) {
00621             if ( (projectTarget == Application) || (projectTarget == StaticLib) )
00622                 RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] );
00623             else
00624                 RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLLDBG"] );
00625         } else {
00626             RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DBG"] );
00627         }
00628     } else {
00629         // Release version
00630         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS"] );
00631         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_RELEASE"] );
00632         RConf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
00633         RConf.compiler.PreprocessorDefinitions += "NDEBUG";
00634         if ( project->isActiveConfig("thread") ) {
00635             if ( (projectTarget == Application) || (projectTarget == StaticLib) )
00636                 RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] );
00637             else
00638                 RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT_DLL"] );
00639         } else {
00640             RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_MT"] );
00641         }
00642     }
00643 
00644     // Common for both release and debug
00645     if ( project->isActiveConfig("warn_off") )
00646         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_OFF"] );
00647     else if ( project->isActiveConfig("warn_on") )
00648         RConf.compiler.parseOptions( project->variables()["QMAKE_CXXFLAGS_WARN_ON"] );
00649     if ( project->isActiveConfig("windows") )
00650         RConf.compiler.PreprocessorDefinitions += project->variables()["MSVCPROJ_WINCONDEF"];
00651 
00652     // Can this be set for ALL configs?
00653     // If so, use qmake.conf!
00654     if ( projectTarget == SharedLib )
00655         RConf.compiler.PreprocessorDefinitions += "_WINDOWS";
00656 
00657     RConf.compiler.PreprocessorDefinitions += project->variables()["DEFINES"];
00658     RConf.compiler.PreprocessorDefinitions += project->variables()["PRL_EXPORT_DEFINES"];
00659     QStringList::iterator it;
00660     for(it=RConf.compiler.PreprocessorDefinitions.begin(); 
00661         it!=RConf.compiler.PreprocessorDefinitions.end(); 
00662         ++it)
00663         (*it).replace('\"', "&quot;");
00664     
00665     RConf.compiler.parseOptions( project->variables()["MSVCPROJ_INCPATH"] );
00666 }
00667 
00668 void VcprojGenerator::initLibrarianTool()
00669 {
00670     VCConfiguration &RConf = vcProject.Configuration[0];
00671     RConf.librarian.OutputFile = project->first( "DESTDIR" );
00672     if( RConf.librarian.OutputFile.isEmpty() )
00673         RConf.librarian.OutputFile = ".\\";
00674 
00675     if( !RConf.librarian.OutputFile.endsWith("\\") )
00676         RConf.librarian.OutputFile += '\\';
00677 
00678     RConf.librarian.OutputFile += project->first("MSVCPROJ_TARGET");
00679 }
00680 
00681 void VcprojGenerator::initLinkerTool()
00682 {
00683     VCConfiguration &RConf = vcProject.Configuration[0];
00684     RConf.linker.parseOptions( project->variables()["MSVCPROJ_LFLAGS"] );
00685     RConf.linker.AdditionalDependencies += project->variables()["MSVCPROJ_LIBS"];
00686 
00687     switch ( projectTarget ) {
00688     case Application:
00689         RConf.linker.OutputFile = project->first( "DESTDIR" );
00690         break;
00691     case SharedLib:
00692         RConf.linker.parseOptions( project->variables()["MSVCPROJ_LIBOPTIONS"] );
00693         RConf.linker.OutputFile = project->first( "DESTDIR" );
00694         break;
00695     case StaticLib: //unhandled - added to remove warnings..
00696         break;
00697     }
00698 
00699     if( RConf.linker.OutputFile.isEmpty() )
00700         RConf.linker.OutputFile = ".\\";
00701 
00702     if( !RConf.linker.OutputFile.endsWith("\\") )
00703         RConf.linker.OutputFile += '\\';
00704 
00705     RConf.linker.OutputFile += project->first("MSVCPROJ_TARGET");
00706 
00707     if ( project->isActiveConfig("debug") ){
00708         RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_DEBUG"] );
00709     } else {
00710         RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_RELEASE"] );
00711     }
00712 
00713     if ( project->isActiveConfig("dll") ){
00714         RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_QT_DLL"] );
00715     }
00716 
00717     if ( project->isActiveConfig("console") ){
00718         RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_CONSOLE"] );
00719     } else {
00720         RConf.linker.parseOptions( project->variables()["QMAKE_LFLAGS_WINDOWS"] );
00721     }
00722 
00723 }
00724 
00725 void VcprojGenerator::initIDLTool()
00726 {
00727 }
00728 
00729 void VcprojGenerator::initCustomBuildTool()
00730 {
00731 }
00732 
00733 void VcprojGenerator::initPreBuildEventTools()
00734 {
00735 }
00736 
00737 void VcprojGenerator::initPostBuildEventTools()
00738 {
00739     VCConfiguration &RConf = vcProject.Configuration[0];
00740     if ( !project->variables()["QMAKE_POST_LINK"].isEmpty() ) {
00741         RConf.postBuild.Description = var("QMAKE_POST_LINK");
00742         RConf.postBuild.CommandLine = var("QMAKE_POST_LINK");
00743         RConf.postBuild.Description.replace(" && ", " &amp;&amp; ");
00744         RConf.postBuild.CommandLine.replace(" && ", " &amp;&amp; ");
00745     }
00746     if ( !project->variables()["MSVCPROJ_COPY_DLL"].isEmpty() ) {
00747         if ( !RConf.postBuild.CommandLine.isEmpty() )
00748             RConf.postBuild.CommandLine += " &amp;&amp; ";
00749         RConf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC");
00750         RConf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL");
00751     }
00752     if( project->isActiveConfig( "activeqt" ) ) {
00753         QString name = project->first( "QMAKE_ORIG_TARGET" );
00754         QString nameext = project->first( "TARGET" );
00755         QString objdir = project->first( "OBJECTS_DIR" );
00756         QString idc = project->first( "QMAKE_IDC" );
00757 
00758         RConf.postBuild.Description = "Finalizing ActiveQt server...";
00759         if ( !RConf.postBuild.CommandLine.isEmpty() )
00760             RConf.postBuild.CommandLine += " &amp;&amp; ";
00761 
00762         if( project->isActiveConfig( "dll" ) ) { // In process
00763             RConf.postBuild.CommandLine +=
00764                 // call idc to generate .idl file from .dll
00765                 idc + " &quot;$(TargetPath)&quot; -idl " + objdir + name + ".idl -version 1.0 &amp;&amp; " +
00766                 // call midl to create implementations of the .idl file
00767                 project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb &amp;&amp; " +
00768                 // call idc to replace tlb...
00769                 idc + " &quot;$(TargetPath)&quot; /tlb " + objdir + name + ".tlb &amp;&amp; " +
00770                 // register server
00771                 idc + " &quot;$(TargetPath)&quot; /regserver";
00772         } else { // out of process
00773             RConf.postBuild.CommandLine =
00774                 // call application to dump idl
00775                 "&quot;$(TargetPath)&quot; -dumpidl " + objdir + name + ".idl -version 1.0 &amp;&amp; " +
00776                 // call midl to create implementations of the .idl file
00777                 project->first( "QMAKE_IDL" ) + " /nologo " + objdir + name + ".idl /tlb " + objdir + name + ".tlb &amp;&amp; " +
00778                 // call idc to replace tlb...
00779                 idc + " &quot;$(TargetPath)&quot; /tlb " + objdir + name + ".tlb &amp;&amp; " +
00780                 // call app to register
00781                 "&quot;$(TargetPath)&quot; -regserver";
00782         }
00783     }
00784 }
00785 
00786 void VcprojGenerator::initPreLinkEventTools()
00787 {
00788 }
00789 
00790 
00791 // ------------------------------------------------------------------
00792 // Helper functions to do proper sorting of the
00793 // qstringlists, for both flat and non-flat modes.
00794 inline bool XLessThanY( QString &x, QString &y, bool flat_mode )
00795 {
00796     if ( flat_mode ) {
00797         QString subX = x.mid( x.findRev('\\')+1 );
00798         QString subY = y.mid( y.findRev('\\')+1 );
00799         return QString::compare(subX, subY) < 0;
00800     }
00801 
00802     int xPos = 0;
00803     int yPos = 0;
00804     int xSlashPos;
00805     int ySlashPos;
00806     for (;;) {
00807         xSlashPos = x.find('\\', xPos);
00808         ySlashPos = y.find('\\', yPos);
00809 
00810         if (xSlashPos == -1 && ySlashPos != -1) {
00811             return false;
00812         } else if (xSlashPos != -1 && ySlashPos == -1) {
00813             return true;
00814         } else if (xSlashPos == -1 /* && yySlashPos == -1 */) {
00815             QString subX = x.mid(xPos);
00816             QString subY = y.mid(yPos);
00817             return QString::compare(subX, subY) < 0;
00818         } else {
00819             QString subX = x.mid(xPos, xSlashPos - xPos);
00820             QString subY = y.mid(yPos, ySlashPos - yPos);
00821             int cmp = QString::compare(subX, subY);
00822             if (cmp != 0)
00823                 return cmp < 0;
00824         }
00825         xPos = xSlashPos + 1;
00826         yPos = ySlashPos + 1;
00827     }
00828     return false;
00829 }
00830 void nonflatDir_BubbleSort( QStringList& list, bool flat_mode )
00831 {
00832     QStringList::Iterator b = list.begin();
00833     QStringList::Iterator e = list.end();
00834     QStringList::Iterator last = e;
00835     --last;             // goto last
00836     if ( last == b )    // shortcut
00837         return;
00838     while( b != last ) {// sort them
00839         bool swapped = FALSE;
00840         QStringList::Iterator swap_pos = b;
00841         QStringList::Iterator x = e;
00842         QStringList::Iterator y = x;
00843         --y;
00844         QString swap_str;
00845         do {
00846             --x;
00847             --y;
00848             if ( XLessThanY(*x,*y, flat_mode) ) {
00849                 swapped = TRUE;
00850                 swap_str = (*x); // Swap -------
00851                 (*x) = (*y);
00852                 (*y) = swap_str; // ------------
00853                 swap_pos = y;
00854             }
00855         } while( y != b );
00856         if ( !swapped )
00857             return;
00858         b = swap_pos;
00859         ++b;
00860     }
00861 }
00862 // ------------------------------------------------------------------
00863 
00864 void VcprojGenerator::initSourceFiles()
00865 {
00866     vcProject.SourceFiles.flat_files = project->isActiveConfig("flat");
00867     vcProject.SourceFiles.Name = "Source Files";
00868     vcProject.SourceFiles.Filter = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat";
00869     vcProject.SourceFiles.Files += project->variables()["SOURCES"];
00870     nonflatDir_BubbleSort( vcProject.SourceFiles.Files,
00871                            vcProject.SourceFiles.flat_files );
00872     vcProject.SourceFiles.Project = this;
00873     vcProject.SourceFiles.Config = &(vcProject.Configuration);
00874     vcProject.SourceFiles.CustomBuild = none;
00875 }
00876 
00877 void VcprojGenerator::initHeaderFiles()
00878 {
00879     vcProject.HeaderFiles.flat_files = project->isActiveConfig("flat");
00880     vcProject.HeaderFiles.Name = "Header Files";
00881     vcProject.HeaderFiles.Filter = "h;hpp;hxx;hm;inl";
00882     vcProject.HeaderFiles.Files += project->variables()["HEADERS"];
00883     if (usePCH) { // Generated PCH cpp file
00884         if (!vcProject.HeaderFiles.Files.contains(precompH))
00885             vcProject.HeaderFiles.Files += precompH;
00886     }
00887     nonflatDir_BubbleSort( vcProject.HeaderFiles.Files,
00888                            vcProject.HeaderFiles.flat_files );
00889     vcProject.HeaderFiles.Project = this;
00890     vcProject.HeaderFiles.Config = &(vcProject.Configuration);
00891     vcProject.HeaderFiles.CustomBuild = moc;
00892 }
00893 
00894 void VcprojGenerator::initMOCFiles()
00895 {
00896     vcProject.MOCFiles.flat_files = project->isActiveConfig("flat");
00897     vcProject.MOCFiles.Name = "Generated MOC Files";
00898     vcProject.MOCFiles.Filter = "cpp;c;cxx;moc";
00899     vcProject.MOCFiles.Files += project->variables()["SRCMOC"];
00900     nonflatDir_BubbleSort( vcProject.MOCFiles.Files,
00901                            vcProject.MOCFiles.flat_files );
00902     vcProject.MOCFiles.Project = this;
00903     vcProject.MOCFiles.Config = &(vcProject.Configuration);
00904     vcProject.MOCFiles.CustomBuild = moc;
00905 }
00906 
00907 void VcprojGenerator::initUICFiles()
00908 {
00909     vcProject.UICFiles.flat_files = project->isActiveConfig("flat");
00910     vcProject.UICFiles.Name = "Generated Form Files";
00911     vcProject.UICFiles.Filter = "cpp;c;cxx;h;hpp;hxx;";
00912     vcProject.UICFiles.Project = this;
00913     vcProject.UICFiles.Files += project->variables()["UICDECLS"];
00914     vcProject.UICFiles.Files += project->variables()["UICIMPLS"];
00915     nonflatDir_BubbleSort( vcProject.UICFiles.Files,
00916                            vcProject.UICFiles.flat_files );
00917     vcProject.UICFiles.Config = &(vcProject.Configuration);
00918     vcProject.UICFiles.CustomBuild = none;
00919 }
00920 
00921 void VcprojGenerator::initFormsFiles()
00922 {
00923     vcProject.FormFiles.flat_files = project->isActiveConfig("flat");
00924     vcProject.FormFiles.Name = "Forms";
00925     vcProject.FormFiles.ParseFiles = _False;
00926     vcProject.FormFiles.Filter = "ui";
00927     vcProject.FormFiles.Files += project->variables()["FORMS"];
00928     nonflatDir_BubbleSort( vcProject.FormFiles.Files,
00929                            vcProject.FormFiles.flat_files );
00930     vcProject.FormFiles.Project = this;
00931     vcProject.FormFiles.Config = &(vcProject.Configuration);
00932     vcProject.FormFiles.CustomBuild = uic;
00933 }
00934 
00935 void VcprojGenerator::initTranslationFiles()
00936 {
00937     vcProject.TranslationFiles.flat_files = project->isActiveConfig("flat");
00938     vcProject.TranslationFiles.Name = "Translations Files";
00939     vcProject.TranslationFiles.ParseFiles = _False;
00940     vcProject.TranslationFiles.Filter = "ts";
00941     vcProject.TranslationFiles.Files += project->variables()["TRANSLATIONS"];
00942     nonflatDir_BubbleSort( vcProject.TranslationFiles.Files,
00943                            vcProject.TranslationFiles.flat_files );
00944     vcProject.TranslationFiles.Project = this;
00945     vcProject.TranslationFiles.Config = &(vcProject.Configuration);
00946     vcProject.TranslationFiles.CustomBuild = none;
00947 }
00948 
00949 void VcprojGenerator::initLexYaccFiles()
00950 {
00951     vcProject.LexYaccFiles.flat_files = project->isActiveConfig("flat");
00952     vcProject.LexYaccFiles.Name = "Lex / Yacc Files";
00953     vcProject.LexYaccFiles.ParseFiles = _False;
00954     vcProject.LexYaccFiles.Filter = "l;y";
00955     vcProject.LexYaccFiles.Files += project->variables()["LEXSOURCES"];
00956     vcProject.LexYaccFiles.Files += project->variables()["YACCSOURCES"];
00957     nonflatDir_BubbleSort( vcProject.LexYaccFiles.Files,
00958                            vcProject.LexYaccFiles.flat_files );
00959     vcProject.LexYaccFiles.Project = this;
00960     vcProject.LexYaccFiles.Config = &(vcProject.Configuration);
00961     vcProject.LexYaccFiles.CustomBuild = lexyacc;
00962 }
00963 
00964 void VcprojGenerator::initResourceFiles()
00965 {
00966     vcProject.ResourceFiles.flat_files = project->isActiveConfig("flat");
00967     vcProject.ResourceFiles.Name = "Resources";
00968     vcProject.ResourceFiles.ParseFiles = _False;
00969     vcProject.ResourceFiles.Filter = "cpp;ico;png;jpg;jpeg;gif;xpm;bmp;rc;ts";
00970     vcProject.ResourceFiles.Files += project->variables()["RC_FILE"];
00971     vcProject.ResourceFiles.Files += project->variables()["QMAKE_IMAGE_COLLECTION"];
00972     vcProject.ResourceFiles.Files += project->variables()["IMAGES"];
00973     vcProject.ResourceFiles.Files += project->variables()["IDLSOURCES"];
00974     nonflatDir_BubbleSort( vcProject.ResourceFiles.Files,
00975                            vcProject.ResourceFiles.flat_files );
00976     vcProject.ResourceFiles.Project = this;
00977     vcProject.ResourceFiles.Config = &(vcProject.Configuration);
00978     vcProject.ResourceFiles.CustomBuild = resource;
00979 }
00980 
00981 /* \internal
00982     Sets up all needed variables from the environment and all the different caches and .conf files
00983 */
00984 
00985 void VcprojGenerator::initOld()
00986 {
00987     if( init_flag )
00988         return;
00989 
00990     init_flag = TRUE;
00991     QStringList::Iterator it;
00992 
00993     if ( project->isActiveConfig("stl") ) {
00994         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_ON"];
00995         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_ON"];
00996     } else {
00997         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_STL_OFF"];
00998         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_STL_OFF"];
00999     }
01000     if ( project->isActiveConfig("exceptions") ) {
01001         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_ON"];
01002         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_ON"];
01003     } else {
01004         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_EXCEPTIONS_OFF"];
01005         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_EXCEPTIONS_OFF"];
01006     }
01007     if ( project->isActiveConfig("rtti") ) {
01008         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_ON"];
01009         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_ON"];
01010     } else {
01011         project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RTTI_OFF"];
01012         project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RTTI_OFF"];
01013     }
01014 
01015     // this should probably not be here, but I'm using it to wrap the .t files
01016     if(project->first("TEMPLATE") == "vcapp" )
01017         project->variables()["QMAKE_APP_FLAG"].append("1");
01018     else if(project->first("TEMPLATE") == "vclib")
01019         project->variables()["QMAKE_LIB_FLAG"].append("1");
01020     if ( project->variables()["QMAKESPEC"].isEmpty() )
01021         project->variables()["QMAKESPEC"].append( getenv("QMAKESPEC") );
01022 
01023     bool is_qt =
01024         ( project->first("TARGET") == "qt"QTDLL_POSTFIX ||
01025           project->first("TARGET") == "qt-mt"QTDLL_POSTFIX );
01026 
01027    QStringList &configs = project->variables()["CONFIG"];
01028 
01029     if ( project->isActiveConfig( "shared" ) )
01030         project->variables()["DEFINES"].append( "QT_DLL" );
01031 
01032     if ( project->isActiveConfig( "qt_dll" ) &&
01033          configs.findIndex("qt") == -1 )
01034             configs.append("qt");
01035 
01036     if ( project->isActiveConfig( "qt" ) ) {
01037         if ( project->isActiveConfig( "plugin" ) ) {
01038             project->variables()["CONFIG"].append( "dll" );
01039             project->variables()["DEFINES"].append( "QT_PLUGIN" );
01040         }
01041         if ( ( project->variables()["DEFINES"].findIndex( "QT_NODLL" )   == -1 ) &&
01042             (( project->variables()["DEFINES"].findIndex( "QT_MAKEDLL" ) != -1   ||
01043                project->variables()["DEFINES"].findIndex( "QT_DLL" )     != -1 ) ||
01044              ( getenv( "QT_DLL" ) && !getenv( "QT_NODLL" ))) ) {
01045             project->variables()["QMAKE_QT_DLL"].append( "1" );
01046             if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() )
01047                 project->variables()["CONFIG"].append( "dll" );
01048         }
01049     }
01050 
01051     // If we are a dll, then we cannot be a staticlib at the same time...
01052     if ( project->isActiveConfig( "dll" ) || !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
01053         project->variables()["CONFIG"].remove( "staticlib" );
01054         project->variables()["QMAKE_APP_OR_DLL"].append( "1" );
01055     } else {
01056         project->variables()["CONFIG"].append( "staticlib" );
01057     }
01058 
01059     // If we need 'qt' and/or 'opengl', then we need windows and not console
01060     if ( project->isActiveConfig( "qt" ) || project->isActiveConfig( "opengl" ) ) {
01061         project->variables()["CONFIG"].append( "windows" );
01062     }
01063 
01064     // Decode version, and add it to $$MSVCPROJ_VERSION --------------
01065     if ( !project->variables()["VERSION"].isEmpty() ) {
01066         QString version = project->variables()["VERSION"][0];
01067         int firstDot = version.find( "." );
01068         QString major = version.left( firstDot );
01069         QString minor = version.right( version.length() - firstDot - 1 );
01070         minor.replace( QRegExp( "\\." ), "" );
01071         project->variables()["MSVCPROJ_VERSION"].append( "/VERSION:" + major + "." + minor );
01072     }
01073 
01074     // QT ------------------------------------------------------------
01075     if ( project->isActiveConfig("qt") ) {
01076         project->variables()["CONFIG"].append("moc");
01077         project->variables()["INCLUDEPATH"] +=  project->variables()["QMAKE_INCDIR_QT"];
01078         project->variables()["QMAKE_LIBDIR"] += project->variables()["QMAKE_LIBDIR_QT"];
01079 
01080         if ( is_qt && !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
01081             if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
01082                 project->variables()["DEFINES"].append("QT_MAKEDLL");
01083                 project->variables()["QMAKE_LFLAGS"].append("/BASE:0x39D00000");
01084             }
01085         } else {
01086             if(project->isActiveConfig("thread"))
01087                 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
01088             else
01089                 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
01090             if ( !project->variables()["QMAKE_QT_DLL"].isEmpty() ) {
01091                 int hver = findHighestVersion(project->first("QMAKE_LIBDIR_QT"), "qt");
01092                 if( hver==-1 ) {
01093                     hver = findHighestVersion( project->first("QMAKE_LIBDIR_QT"), "qt-mt" );
01094                 }
01095 
01096                 if(hver != -1) {
01097                     QString ver;
01098                     ver.sprintf("qt%s" QTDLL_POSTFIX "%d.lib", (project->isActiveConfig("thread") ? "-mt" : ""), hver);
01099                     QStringList &libs = project->variables()["QMAKE_LIBS"];
01100                     for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit)
01101                         (*libit).replace(QRegExp("qt(-mt)?\\.lib"), ver);
01102                 }
01103             }
01104             if ( project->isActiveConfig( "activeqt" ) ) {
01105                 project->variables().remove("QMAKE_LIBS_QT_ENTRY");
01106                 project->variables()["QMAKE_LIBS_QT_ENTRY"] = "qaxserver.lib";
01107                 if ( project->isActiveConfig( "dll" ) ) {
01108                     project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_ENTRY"];
01109                 }
01110             }
01111             if ( !project->isActiveConfig("dll") && !project->isActiveConfig("plugin") ) {
01112                 project->variables()["QMAKE_LIBS"] +=project->variables()["QMAKE_LIBS_QT_ENTRY"];
01113             }
01114         }
01115     }
01116 
01117     // Set target directories ----------------------------------------
01118  //   if ( !project->first("OBJECTS_DIR").isEmpty() )
01119         //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->first("OBJECTS_DIR");
01120  //   else
01121         //project->variables()["MSVCPROJ_OBJECTSDIR"] = project->isActiveConfig( "release" )?"Release":"Debug";
01122  //   if ( !project->first("DESTDIR").isEmpty() )
01123         //project->variables()["MSVCPROJ_TARGETDIR"] = project->first("DESTDIR");
01124  //   else
01125         //project->variables()["MSVCPROJ_TARGETDIR"] = project->isActiveConfig( "release" )?"Release":"Debug";
01126 
01127     // OPENGL --------------------------------------------------------
01128     if ( project->isActiveConfig("opengl") ) {
01129         project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
01130         project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_OPENGL"];
01131     }
01132 
01133     // THREAD --------------------------------------------------------
01134     if ( project->isActiveConfig("thread") ) {
01135         if(project->isActiveConfig("qt"))
01136             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT" );
01137         if ( !project->variables()["DEFINES"].contains("QT_DLL") && is_qt
01138              && project->first("TARGET") != "qtmain" )
01139             project->variables()["QMAKE_LFLAGS"].append("/NODEFAULTLIB:libc");
01140     }
01141 
01142     // ACCESSIBILITY -------------------------------------------------
01143     if(project->isActiveConfig("qt")) {
01144         if ( project->isActiveConfig("accessibility" ) )
01145             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
01146         if ( project->isActiveConfig("tablet") )
01147             project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
01148     }
01149 
01150     // DLL -----------------------------------------------------------
01151     if ( project->isActiveConfig("dll") ) {
01152         if ( !project->variables()["QMAKE_LIB_FLAG"].isEmpty() ) {
01153             QString ver_xyz(project->first("VERSION"));
01154             ver_xyz.replace(QRegExp("\\."), "");
01155             project->variables()["TARGET_EXT"].append(ver_xyz + ".dll");
01156         } else {
01157             project->variables()["TARGET_EXT"].append(".dll");
01158         }
01159     }
01160     // EXE / LIB -----------------------------------------------------
01161     else {
01162         if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() )
01163             project->variables()["TARGET_EXT"].append(".exe");
01164         else
01165             project->variables()["TARGET_EXT"].append(".lib");
01166     }
01167 
01168     project->variables()["MSVCPROJ_VER"] = "7.00";
01169     project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /ZI";
01170 
01171     // INCREMENTAL:NO ------------------------------------------------
01172     if(!project->isActiveConfig("incremental")) {
01173         project->variables()["QMAKE_LFLAGS"].append(QString("/INCREMENTAL:no"));
01174         if ( is_qt )
01175             project->variables()["MSVCPROJ_DEBUG_OPT"] = "/GZ /Zi";
01176     }
01177 
01178     // MOC -----------------------------------------------------------
01179     if ( project->isActiveConfig("moc") )
01180         setMocAware(TRUE);
01181 
01182     // /VERSION:x.yz -------------------------------------------------
01183     if ( !project->variables()["VERSION"].isEmpty() ) {
01184         QString version = project->variables()["VERSION"][0];
01185         int firstDot = version.find( "." );
01186         QString major = version.left( firstDot );
01187         QString minor = version.right( version.length() - firstDot - 1 );
01188         minor.replace( ".", "" );
01189         project->variables()["QMAKE_LFLAGS"].append( "/VERSION:" + major + "." + minor );
01190     }
01191 
01192     project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
01193     // Update -lname to name.lib, and -Ldir to
01194     QStringList &libList = project->variables()["QMAKE_LIBS"];
01195     for( it = libList.begin(); it != libList.end(); ) {
01196         QString s = *it;
01197         if( s.startsWith( "-l" ) ) {
01198             it = libList.remove( it );
01199             it = libList.insert( it, s.mid( 2 ) + ".lib" );
01200         } else if( s.startsWith( "-L" ) ) {
01201             project->variables()["QMAKE_LIBDIR"] += (*it).mid(2);
01202             it = libList.remove( it );
01203         } else {
01204             it++;
01205         }
01206     }
01207 
01208     // Run through all variables containing filepaths, and -----------
01209     // slash-slosh them correctly depending on current OS  -----------
01210     project->variables()["QMAKE_FILETAGS"] += QStringList::split(' ', "HEADERS SOURCES DEF_FILE RC_FILE TARGET QMAKE_LIBS DESTDIR DLLDESTDIR INCLUDEPATH");
01211     QStringList &l = project->variables()["QMAKE_FILETAGS"];
01212     for(it = l.begin(); it != l.end(); ++it) {
01213         QStringList &gdmf = project->variables()[(*it)];
01214         for(QStringList::Iterator inner = gdmf.begin(); inner != gdmf.end(); ++inner)
01215             (*inner) = Option::fixPathToTargetOS((*inner), FALSE);
01216     }
01217 
01218      // Get filename w/o extention -----------------------------------
01219     QString msvcproj_project = "";
01220     QString targetfilename = "";
01221     if ( project->variables()["TARGET"].count() ) {
01222         msvcproj_project = project->variables()["TARGET"].first();
01223         targetfilename = msvcproj_project;
01224     }
01225 
01226     // Save filename w/o extention in $$QMAKE_ORIG_TARGET ------------
01227     project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
01228 
01229     // TARGET (add extention to $$TARGET)
01230     //project->variables()["MSVCPROJ_DEFINES"].append(varGlue(".first() += project->first("TARGET_EXT");
01231 
01232     // Init base class too -------------------------------------------
01233     MakefileGenerator::init();
01234 
01235 
01236     if ( msvcproj_project.isEmpty() )
01237         msvcproj_project = Option::output.name();
01238 
01239     msvcproj_project = msvcproj_project.right( msvcproj_project.length() - msvcproj_project.findRev( "\\" ) - 1 );
01240     msvcproj_project = msvcproj_project.left( msvcproj_project.findRev( "." ) );
01241     msvcproj_project.replace(QRegExp("-"), "");
01242 
01243     project->variables()["MSVCPROJ_PROJECT"].append(msvcproj_project);
01244     QStringList &proj = project->variables()["MSVCPROJ_PROJECT"];
01245 
01246     for(it = proj.begin(); it != proj.end(); ++it)
01247         (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), "");
01248 
01249     // SUBSYSTEM -----------------------------------------------------
01250     if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
01251             project->variables()["MSVCPROJ_TEMPLATE"].append("win32app" + project->first( "VCPROJ_EXTENSION" ) );
01252             if ( project->isActiveConfig("console") ) {
01253                 project->variables()["MSVCPROJ_CONSOLE"].append("CONSOLE");
01254                 project->variables()["MSVCPROJ_WINCONDEF"].append("_CONSOLE");
01255                 project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0103");
01256                 project->variables()["MSVCPROJ_SUBSYSTEM"].append("CONSOLE");
01257             } else {
01258                 project->variables()["MSVCPROJ_CONSOLE"].clear();
01259                 project->variables()["MSVCPROJ_WINCONDEF"].append("_WINDOWS");
01260                 project->variables()["MSVCPROJ_VCPROJTYPE"].append("0x0101");
01261                 project->variables()["MSVCPROJ_SUBSYSTEM"].append("WINDOWS");
01262             }
01263     } else {
01264         if ( project->isActiveConfig("dll") ) {
01265             project->variables()["MSVCPROJ_TEMPLATE"].append("win32dll" + project->first( "VCPROJ_EXTENSION" ) );
01266         } else {
01267             project->variables()["MSVCPROJ_TEMPLATE"].append("win32lib" + project->first( "VCPROJ_EXTENSION" ) );
01268         }
01269     }
01270 
01271     // $$QMAKE.. -> $$MSVCPROJ.. -------------------------------------
01272     project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS"];
01273     project->variables()["MSVCPROJ_LIBS"] += project->variables()["QMAKE_LIBS_WINDOWS"];
01274     project->variables()["MSVCPROJ_LFLAGS" ] += project->variables()["QMAKE_LFLAGS"];
01275     if ( !project->variables()["QMAKE_LIBDIR"].isEmpty() ) {
01276         QStringList strl = project->variables()["QMAKE_LIBDIR"];
01277         QStringList::iterator stri;
01278         for ( stri = strl.begin(); stri != strl.end(); ++stri ) {
01279             if ( !(*stri).startsWith("/LIBPATH:") )
01280                 (*stri).prepend( "/LIBPATH:" );
01281         }
01282         project->variables()["MSVCPROJ_LFLAGS"] += strl;
01283     }
01284     project->variables()["MSVCPROJ_CXXFLAGS" ] += project->variables()["QMAKE_CXXFLAGS"];
01285     // We don't use this... Direct manipulation of compiler object
01286     //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("DEFINES","/D ","" " /D ",""));
01287     //project->variables()["MSVCPROJ_DEFINES"].append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ",""));
01288     QStringList &incs = project->variables()["INCLUDEPATH"];
01289     for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
01290         QString inc = (*incit);
01291         inc.replace(QRegExp("\""), "");
01292         project->variables()["MSVCPROJ_INCPATH"].append("/I" + inc );
01293     }
01294     project->variables()["MSVCPROJ_INCPATH"].append("/I" + specdir());
01295 
01296     QString dest;
01297     project->variables()["MSVCPROJ_TARGET"] = project->first("TARGET");
01298     Option::fixPathToTargetOS(project->first("TARGET"));
01299     dest = project->first("TARGET") + project->first( "TARGET_EXT" );
01300     if ( project->first("TARGET").startsWith("$(QTDIR)") )
01301         dest.replace( QRegExp("\\$\\(QTDIR\\)"), getenv("QTDIR") );
01302     project->variables()["MSVCPROJ_TARGET"] = dest;
01303 
01304     // DLL COPY ------------------------------------------------------
01305     if ( project->isActiveConfig("dll") && !project->variables()["DLLDESTDIR"].isEmpty() ) {
01306         QStringList dlldirs = project->variables()["DLLDESTDIR"];
01307         QString copydll("");
01308         QStringList::Iterator dlldir;
01309         for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir ) {
01310             if ( !copydll.isEmpty() )
01311                 copydll += " && ";
01312             copydll += "copy  &quot;$(TargetPath)&quot; &quot;" + *dlldir + "&quot;";
01313         }
01314 
01315         QString deststr( "Copy " + dest + " to " );
01316         for ( dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ) {
01317             deststr += *dlldir;
01318             ++dlldir;
01319             if ( dlldir != dlldirs.end() )
01320                 deststr += ", ";
01321         }
01322 
01323         project->variables()["MSVCPROJ_COPY_DLL"].append( copydll );
01324         project->variables()["MSVCPROJ_COPY_DLL_DESC"].append( deststr );
01325     }
01326 
01327     // ACTIVEQT ------------------------------------------------------
01328     if ( project->isActiveConfig("activeqt") ) {
01329         QString idl = project->variables()["QMAKE_IDL"].first();
01330         QString idc = project->variables()["QMAKE_IDC"].first();
01331         QString version = project->variables()["VERSION"].first();
01332         if ( version.isEmpty() )
01333             version = "1.0";
01334 
01335         QString objdir = project->first( "OBJECTS_DIR" );
01336         project->variables()["MSVCPROJ_IDLSOURCES"].append( objdir + targetfilename + ".idl" );
01337         if ( project->isActiveConfig( "dll" ) ) {
01338             QString regcmd = "# Begin Special Build Tool\n"
01339                             "TargetPath=" + targetfilename + "\n"
01340                             "SOURCE=$(InputPath)\n"
01341                             "PostBuild_Desc=Finalizing ActiveQt server...\n"
01342                             "PostBuild_Cmds=" +
01343                             idc + " %1 -idl " + objdir + targetfilename + ".idl -version " + version +
01344                             "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb" +
01345                             "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb"
01346                             "\tregsvr32 /s %1\n"
01347                             "# End Special Build Tool";
01348 
01349             QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
01350             project->variables()["MSVCPROJ_COPY_DLL_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
01351 
01352             executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
01353             project->variables()["MSVCPROJ_COPY_DLL_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
01354         } else {
01355             QString regcmd = "# Begin Special Build Tool\n"
01356                             "TargetPath=" + targetfilename + "\n"
01357                             "SOURCE=$(InputPath)\n"
01358                             "PostBuild_Desc=Finalizing ActiveQt server...\n"
01359                             "PostBuild_Cmds="
01360                             "%1 -dumpidl " + objdir + targetfilename + ".idl -version " + version +
01361                             "\t" + idl + " /nologo " + objdir + targetfilename + ".idl /tlb " + objdir + targetfilename + ".tlb"
01362                             "\t" + idc + " %1 /tlb " + objdir + targetfilename + ".tlb"
01363                             "\t%1 -regserver\n"
01364                             "# End Special Build Tool";
01365 
01366             QString executable = project->variables()["MSVCPROJ_TARGETDIRREL"].first() + "\\" + project->variables()["TARGET"].first();
01367             project->variables()["MSVCPROJ_REGSVR_REL"].append( regcmd.arg(executable).arg(executable).arg(executable) );
01368 
01369             executable = project->variables()["MSVCPROJ_TARGETDIRDEB"].first() + "\\" + project->variables()["TARGET"].first();
01370             project->variables()["MSVCPROJ_REGSVR_DBG"].append( regcmd.arg(executable).arg(executable).arg(executable) );
01371         }
01372     }
01373 
01374     if ( !project->variables()["DEF_FILE"].isEmpty() )
01375         project->variables()["MSVCPROJ_LFLAGS"].append("/DEF:"+project->first("DEF_FILE"));
01376 
01377     // FORMS ---------------------------------------------------------
01378     QStringList &list = project->variables()["FORMS"];
01379     for( it = list.begin(); it != list.end(); ++it ) {
01380         if ( QFile::exists( *it + ".h" ) )
01381             project->variables()["SOURCES"].append( *it + ".h" );
01382     }
01383 
01384     project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "MSVCPROJ_LFLAGS" << "MSVCPROJ_LIBS";
01385 
01386     // Verbose output if "-d -d"...
01387     outputVariables();
01388 }
01389 
01390 // ------------------------------------------------------------------------------------------------
01391 // ------------------------------------------------------------------------------------------------
01392 
01393 bool VcprojGenerator::openOutput(QFile &file) const
01394 {
01395     QString outdir;
01396     if(!file.name().isEmpty()) {
01397         QFileInfo fi(file);
01398         if(fi.isDir())
01399             outdir = file.name() + QDir::separator();
01400     }
01401     if(!outdir.isEmpty() || file.name().isEmpty()) {
01402         QString ext = project->first("VCPROJ_EXTENSION");
01403         if(project->first("TEMPLATE") == "vcsubdirs")
01404             ext = project->first("VCSOLUTION_EXTENSION");
01405         file.setName(outdir + project->first("TARGET") + ext);
01406     }
01407     if(QDir::isRelativePath(file.name())) {
01408         file.setName( Option::fixPathToLocalOS(QDir::currentDirPath() + Option::dir_sep + fixFilename(file.name())) );
01409     }
01410     return Win32MakefileGenerator::openOutput(file);
01411 }
01412 
01413 QString VcprojGenerator::fixFilename(QString ofile) const
01414 {
01415     int slashfind = ofile.findRev('\\');
01416     if (slashfind == -1) {
01417         ofile = ofile.replace('-', '_');
01418     } else {
01419         int hypenfind = ofile.find('-', slashfind);
01420         while (hypenfind != -1 && slashfind < hypenfind) {
01421             ofile = ofile.replace(hypenfind, 1, '_');
01422             hypenfind = ofile.find('-', hypenfind + 1);
01423         }
01424     }
01425     return ofile;
01426 }
01427 
01428 QString VcprojGenerator::findTemplate(QString file)
01429 {
01430     QString ret;
01431     if(!QFile::exists((ret = file)) &&
01432        !QFile::exists((ret = QString(Option::mkfile::qmakespec + "/" + file))) &&
01433        !QFile::exists((ret = QString(getenv("QTDIR")) + "/mkspecs/win32-msvc.net/" + file)) &&
01434        !QFile::exists((ret = (QString(getenv("HOME")) + "/.tmake/" + file))))
01435         return "";
01436     debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.latin1() );
01437     return ret;
01438 }
01439 
01440 
01441 void VcprojGenerator::processPrlVariable(const QString &var, const QStringList &l)
01442 {
01443     if(var == "QMAKE_PRL_DEFINES") {
01444         QStringList &out = project->variables()["MSVCPROJ_DEFINES"];
01445         for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
01446             if(out.findIndex((*it)) == -1)
01447                 out.append((" /D " + *it ));
01448         }
01449     } else {
01450         MakefileGenerator::processPrlVariable(var, l);
01451     }
01452 }
01453 
01454 void VcprojGenerator::outputVariables()
01455 {
01456 #if 0
01457     qDebug( "Generator: MSVC.NET: List of current variables:" );
01458     for ( QMap<QString, QStringList>::ConstIterator it = project->variables().begin(); it != project->variables().end(); ++it) {
01459         qDebug( "Generator: MSVC.NET: %s => %s", it.key().latin1(), it.data().join(" | ").latin1() );
01460     }
01461 #endif
01462 }

Generated on Sat Nov 5 16:18:22 2005 for OPIE by  doxygen 1.4.2