📄 msvc_vcproj.cpp
字号:
/****************************************************************************** $Id: qt/msvc_vcproj.cpp 3.1.1 edited Dec 4 14:29 $**** Definition of VcprojGenerator class.**** Created : 970521**** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.**** This file is part of the network module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition licenses may use this** file in accordance with the Qt Commercial License Agreement provided** with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "msvc_vcproj.h"#include "option.h"#include <qdir.h>#include <qregexp.h>#include <qdict.h>#include <quuid.h>#include <stdlib.h>#if defined(Q_OS_WIN32)#include <objbase.h>#ifndef GUID_DEFINED#define GUID_DEFINEDtypedef struct _GUID{ ulong Data1; ushort Data2; ushort Data3; uchar Data4[8];} GUID;#endif#endif// Flatfile Tags ----------------------------------------------------const char* _snlHeader = "Microsoft Visual Studio Solution File, Format Version 7.00"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects // to find the subkey that contains a "PossibleProjectExtension" // containing "vcproj"... // Use the hardcoded value for now so projects generated on other // platforms are actually usable.const char* _snlMSVCvcprojGUID = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";const char* _snlProjectBeg = "\nProject(\"";const char* _snlProjectMid = "\") = ";const char* _snlProjectEnd = "\nEndProject";const char* _snlGlobalBeg = "\nGlobal";const char* _snlGlobalEnd = "\nEndGlobal";const char* _snlSolutionConf = "\n\tGlobalSection(SolutionConfiguration) = preSolution" "\n\t\tConfigName.0 = Release" "\n\tEndGlobalSection";const char* _snlProjDepBeg = "\n\tGlobalSection(ProjectDependencies) = postSolution";const char* _snlProjDepEnd = "\n\tEndGlobalSection";const char* _snlProjConfBeg = "\n\tGlobalSection(ProjectConfiguration) = postSolution";const char* _snlProjConfTag1 = ".Release.ActiveCfg = Release|Win32";const char* _snlProjConfTag2 = ".Release.Build.0 = Release|Win32";const char* _snlProjConfEnd = "\n\tEndGlobalSection";const char* _snlExtSections = "\n\tGlobalSection(ExtensibilityGlobals) = postSolution" "\n\tEndGlobalSection" "\n\tGlobalSection(ExtensibilityAddIns) = postSolution" "\n\tEndGlobalSection";// ------------------------------------------------------------------VcprojGenerator::VcprojGenerator(QMakeProject *p) : Win32MakefileGenerator(p), init_flag(FALSE){}/* \internal Generates a project file for the given profile. Options are either a Visual Studio projectfiles, or solutionfiles by parsing recursive projectdirectories.*/bool VcprojGenerator::writeMakefile(QTextStream &t){ // Check if all requirements are fullfilled if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", var("QMAKE_FAILED_REQUIREMENTS").latin1()); return TRUE; } // Generate project file if(project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { debug_msg(1, "Generator: MSVC.NET: Writing project file" ); t << vcProject; return TRUE; } // Generate solution file else if(project->first("TEMPLATE") == "vcsubdirs") { debug_msg(1, "Generator: MSVC.NET: Writing solution file" ); writeSubDirs(t); return TRUE; } return FALSE;}struct VcsolutionDepend { QString uuid; QString vcprojFile, orig_target, target; ::target targetType; QStringList dependencies;};QUuid VcprojGenerator::increaseUUID( const QUuid &id ){ QUuid result( id ); Q_LONG dataFirst = (result.data4[0] << 24) + (result.data4[1] << 16) + (result.data4[2] << 8) + result.data4[3]; Q_LONG dataLast = (result.data4[4] << 24) + (result.data4[5] << 16) + (result.data4[6] << 8) + result.data4[7]; if ( !(dataLast++) ) dataFirst++; result.data4[0] = uchar((dataFirst >> 24) & 0xff); result.data4[1] = uchar((dataFirst >> 16) & 0xff); result.data4[2] = uchar((dataFirst >> 8) & 0xff); result.data4[3] = uchar( dataFirst & 0xff); result.data4[4] = uchar((dataLast >> 24) & 0xff); result.data4[5] = uchar((dataLast >> 16) & 0xff); result.data4[6] = uchar((dataLast >> 8) & 0xff); result.data4[7] = uchar( dataLast & 0xff); return result;}void VcprojGenerator::writeSubDirs(QTextStream &t){ if(project->first("TEMPLATE") == "subdirs") { writeHeader(t); Win32MakefileGenerator::writeSubDirs(t); return; } t << _snlHeader; QUuid solutionGUID;#if defined(Q_WS_WIN32) GUID guid; HRESULT h = CoCreateGuid( &guid ); if ( h == S_OK ) solutionGUID = QUuid( guid );#else // Qt doesn't support GUID on other platforms yet, // so we use the all-zero uuid, and increase that.#endif QDict<VcsolutionDepend> solution_depends; QPtrList<VcsolutionDepend> solution_cleanup; solution_cleanup.setAutoDelete(TRUE); QStringList subdirs = project->variables()["SUBDIRS"]; QString oldpwd = QDir::currentDirPath(); for(QStringList::Iterator it = subdirs.begin(); it != subdirs.end(); ++it) { QFileInfo fi(Option::fixPathToLocalOS((*it), TRUE)); if(fi.exists()) { if(fi.isDir()) { QString profile = (*it); if(!profile.endsWith(Option::dir_sep)) profile += Option::dir_sep; profile += fi.baseName() + ".pro"; subdirs.append(profile); } else { QMakeProject tmp_proj; QString dir = fi.dirPath(), fn = fi.fileName(); if(!dir.isEmpty()) { if(!QDir::setCurrent(dir)) fprintf(stderr, "Cannot find directory: %s\n", dir.latin1()); } if(tmp_proj.read(fn, oldpwd)) { if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { QStringList tmp_subdirs = fileFixify(tmp_proj.variables()["SUBDIRS"]); subdirs += tmp_subdirs; } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { // Initialize a 'fake' project to get the correct variables // and to be able to extract all the dependencies VcprojGenerator tmp_vcproj(&tmp_proj); tmp_vcproj.setNoIO(TRUE); tmp_vcproj.init(); if(Option::debug_level) { QMap<QString, QStringList> &vars = tmp_proj.variables(); for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) { if(it.key().left(1) != "." && !it.data().isEmpty()) debug_msg(1, "%s: %s === %s", fn.latin1(), it.key().latin1(), it.data().join(" :: ").latin1()); } } // We assume project filename is [QMAKE_ORIG_TARGET].vcproj QString vcproj = fixFilename(tmp_vcproj.project->first("QMAKE_ORIG_TARGET")) + project->first("VCPROJ_EXTENSION"); // If file doesn't exsist, then maybe the users configuration // doesn't allow it to be created. Skip to next... if(!QFile::exists(QDir::currentDirPath() + Option::dir_sep + vcproj)) { qDebug( "Ignored (not found) '%s'", QString(QDir::currentDirPath() + Option::dir_sep + vcproj).latin1() ); goto nextfile; // # Dirty! } VcsolutionDepend *newDep = new VcsolutionDepend; newDep->vcprojFile = fileFixify(vcproj); newDep->orig_target = tmp_proj.first("QMAKE_ORIG_TARGET"); newDep->target = tmp_proj.first("TARGET").section(Option::dir_sep, -1); newDep->targetType = tmp_vcproj.projectTarget; { static QUuid uuid = solutionGUID; uuid = increaseUUID( uuid ); newDep->uuid = uuid.toString().upper(); } if(newDep->target.endsWith(".dll")) newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; if(!tmp_proj.isEmpty("FORMS")) newDep->dependencies << "uic.exe"; { QStringList where("QMAKE_LIBS"); if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; for(QStringList::iterator wit = where.begin(); wit != where.end(); ++wit) { QStringList &l = tmp_proj.variables()[(*wit)]; for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { QString opt = (*it); if(!opt.startsWith("/")) //Not a switch newDep->dependencies << opt.section(Option::dir_sep, -1); } } } solution_cleanup.append(newDep); solution_depends.insert(newDep->target, newDep); { QRegExp libVersion("[0-9]{3,3}\\.lib$"); if(libVersion.search(newDep->target) != -1) solution_depends.insert(newDep->target.left(newDep->target.length() - libVersion.matchedLength()) + ".lib", newDep); } t << _snlProjectBeg << _snlMSVCvcprojGUID << _snlProjectMid << "\"" << newDep->orig_target << "\", \"" << newDep->vcprojFile << "\", \"" << newDep->uuid << "\""; t << _snlProjectEnd; } }nextfile: QDir::setCurrent(oldpwd); } } } t << _snlGlobalBeg; t << _snlSolutionConf; t << _snlProjDepBeg; for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { int cnt = 0; for(QStringList::iterator dit = solution_cleanup.current()->dependencies.begin(); dit != solution_cleanup.current()->dependencies.end(); ++dit) { VcsolutionDepend *vc; if((vc=solution_depends[*dit])) { if(solution_cleanup.current()->targetType != StaticLib || vc->targetType == Application) t << "\n\t\t" << solution_cleanup.current()->uuid << "." << cnt++ << " = " << vc->uuid; } } } t << _snlProjDepEnd; t << _snlProjConfBeg; for(solution_cleanup.first(); solution_cleanup.current(); solution_cleanup.next()) { t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag1; t << "\n\t\t" << solution_cleanup.current()->uuid << _snlProjConfTag2; } t << _snlProjConfEnd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -