?? vcprojprocess.cpp
字號:
/////////////////////////////////////////////////////////////////////////////////
//
// vcprojprocess class implementation
//
// S.Rodriguez - Sept 2002
//
//
// purpose : convert a .vcproj file format to a .dsp file format
// (a .vcproj file is the makefile of a VisualStudio 7 C++ project)
//
//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <atlbase.h> // CComPtr
#include <comutil.h> // _variant_t
#pragma comment(lib, "comsupp.lib")
#include <msxml2.h>
#include "slnprocess.h"
#include "vcprojconfiguration.h"
#include "symbols.h"
#include "vcprojprocess.h"
// Constructor
vcprojprocess::vcprojprocess()
{
::CoInitialize(NULL);
}
vcprojprocess::~vcprojprocess()
{
::CoUninitialize();
}
// Methods
void vcprojprocess::process(CString &szSolutionName, PROJECTPARAM *p)
{
m_szSolutionName = szSolutionName;
m_cpPrj = p; // copy ptr
if (!m_cpPrj) return; // good bye!
CString szVcprojPath = m_cpPrj->szProjectPath;
if ( !isFullPath(szVcprojPath) )
{
long i = m_szSolutionName.ReverseFind(0, '\\');
CString szDirectory = m_szSolutionName.Left(i+1);
szVcprojPath = szDirectory + szVcprojPath;
}
HRESULT hr;
IXMLDOMDocument *pXMLDoc=NULL;
hr = ::CoCreateInstance(CLSID_DOMDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument,
(void**)&pXMLDoc);
if (FAILED(hr))
{
printf ("Cannot instantiate msxml2.dll\n");
printf ("Please download the MSXML run-time (url below)\n");
printf ("http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/001/766/msdncompositedoc.xml\n");
return;
}
VARIANT_BOOL vtbool;
_variant_t bstrFilepath(szVcprojPath);
pXMLDoc->put_async( VARIANT_BOOL(FALSE) );
hr = pXMLDoc->load(bstrFilepath,&vtbool);
if (FAILED(hr) || vtbool==VARIANT_FALSE)
{
printf ("Could not open %s.\n", szVcprojPath);
pXMLDoc->Release();
return;
}
// ok, now the vcproj file is read
// let's translate the content to the .dsp file
//
CString szDspFilename = szVcprojPath.Left( szVcprojPath.GetLength()-strlen(".vcproj") ) + ".dsp";
// create empty .dsp file
//
BOOL bResult = m_outputFile.Open(szDspFilename,CFile::modeCreate|CFile::modeWrite);
if (!bResult)
{
printf("Couldn't create %s\n.",szDspFilename);
pXMLDoc->Release();
return;
}
// now process the content
//
extractHeader( pXMLDoc );
extractConfigurations( pXMLDoc );
writeDspHeader();
writeDspConfigurations( pXMLDoc );
writeDspFiles( pXMLDoc );
writeDspFooter();
pXMLDoc->Release();
}
// extractHeader()
//
// purpose : extract key data from the .vcproj file content
//
void vcprojprocess::extractHeader(IXMLDOMDocument *pDoc)
{
if (!pDoc) return;
m_bIsConsoleApp = FALSE;
// begin with the <VisualStudioProject> element
//
CComPtr<IXMLDOMNodeList> pRootNode;
pDoc->getElementsByTagName( _bstr_t(XMLNODE_VISUALSTUDIOPROJECT), &pRootNode);
if (pRootNode)
{
long nb = 0;
pRootNode->get_length(&nb);
if (nb==1)
{
CComPtr<IXMLDOMNode> pNode;
pRootNode->get_item(0,&pNode);
if (pNode)
{
CComQIPtr<IXMLDOMElement> pElem( pNode );
getAttribValue(pElem,XMLATTRIB_NAME,m_szProjname);
getAttribValue(pElem,XMLATTRIB_SCCPROJECTNAME,m_szSccProjectName);
getAttribValue(pElem,XMLATTRIB_SCCPROJECTPATH,m_szSccLocalPath);
}
} // end if (nb==1)
} // end if (pRootNode)
// now get the list of project configurations, <Configuration> elements
//
CComPtr<IXMLDOMNodeList> pConfigs;
pDoc->getElementsByTagName( _bstr_t(XMLNODE_CONFIGURATION), &pConfigs);
if (pConfigs)
{
long nb = 0;
pConfigs->get_length(&nb);
for (long i=0; i<nb; i++)
{
CComPtr<IXMLDOMNode> pNode;
pConfigs->get_item(i,&pNode);
if (pNode)
{
CComQIPtr<IXMLDOMElement> pElem( pNode );
if (i==0) // retrieve target type
{
getAttribValue(pElem,XMLATTRIB_TARGETTYPE,m_szTargetType);
if ( m_szTargetType.Compare("1") ) // check if the application is also a console app
{
CComPtr<IXMLDOMNodeList> pResult;
HRESULT hr = pElem->selectNodes(_bstr_t("Tool[@Name='VCLinkerTool']"), &pResult);
if (pResult)
{
long nbResult = 0;
pResult->get_length(&nbResult);
if (nbResult>0)
{
CComPtr<IXMLDOMNode> pResult0;
pResult->get_item(0,&pResult0);
if (pResult0)
{
CComQIPtr<IXMLDOMElement> pElem0( pResult0 );
CString szPreProcDefs;
getAttribValue(pElem0,XMLATTRIB_SUBSYSTEM,szPreProcDefs);
m_bIsConsoleApp = szPreProcDefs.CompareNoCase("1"); // console app if = 1
}
}
} // end if (pResult)
}
} // if (i==0)
// get configuration name
CString szConfigName;
getAttribValue(pElem,XMLATTRIB_NAME,szConfigName);
if ( !szConfigName.IsEmpty() )
m_arrConfigurationNames.Add( szConfigName );
} // end if pNode
} // end for
} // end if (pConfigs)
}
// extractConfigurations()
//
// purpose : extract configuration data from the .vcproj file content
//
void vcprojprocess::extractConfigurations(IXMLDOMDocument *pDoc)
{
if (!pDoc) return; // good bye!
CComPtr<IXMLDOMNodeList> pConfigs;
pDoc->getElementsByTagName( _bstr_t(XMLNODE_CONFIGURATION), &pConfigs);
if (pConfigs)
{
long nb = 0;
pConfigs->get_length(&nb);
for (long i=0; i<nb; i++)
{
CComPtr<IXMLDOMNode> pNode;
pConfigs->get_item(i,&pNode);
if (pNode)
{
CComQIPtr<IXMLDOMElement> pConfiguration( pNode );
// create a container in memory, and fill it with the configuration data
//
vcprojconfiguration *pVCConfig = new vcprojconfiguration();
if (pVCConfig)
{
m_arrConfigs.Add( pVCConfig );
pVCConfig->fill( pConfiguration );
}
}
} // end for all configurations
} // end if (pConfigs)
}
// extractFileConfigurations()
//
// purpose : extract configuration data from the a custom file content
//
void vcprojprocess::extractFileConfigurations(IXMLDOMElement *pFileElement, ConfigurationArray &arrFileConfigs)
{
if (!pFileElement) return; // good bye!
CComPtr<IXMLDOMNodeList> pConfigs;
pFileElement->getElementsByTagName( _bstr_t(XMLNODE_FILECONFIGURATION), &pConfigs);
if (pConfigs)
{
long nb = 0;
pConfigs->get_length(&nb);
for (long i=0; i<nb; i++)
{
CComPtr<IXMLDOMNode> pNode;
pConfigs->get_item(i,&pNode);
if (pNode)
{
CComQIPtr<IXMLDOMElement> pConfiguration( pNode );
// create a container in memory, and fill it with the configuration data
//
vcprojconfiguration *pVCConfig = new vcprojconfiguration();
if (pVCConfig)
{
arrFileConfigs.Add( pVCConfig );
pVCConfig->fill( pConfiguration );
}
}
} // end for all configurations
} // end if (pConfigs)
}
void vcprojprocess::writeDspHeader()
{
if (m_szProjname.IsEmpty() || m_arrConfigurationNames.GetSize()==0) return;
// Win32 (x86) Dynamic-Link Library
// Win32 (x86) Application
// Win32 (x86) Console Application
// Win32 (x86) Static Library
// Win32 (x86) External Target = makefile project
CString szFriendlyTargetType;
CString szHexaTargetType;
if (m_szTargetType.Compare("1"))
{
szFriendlyTargetType = m_bIsConsoleApp ? " (x86) Console Application" : " (x86) Application";
szHexaTargetType = m_bIsConsoleApp ? "0x0103" : "0x0101";
}
else if (m_szTargetType.Compare("2"))
{
szFriendlyTargetType = " (x86) Dynamic-Link Library";
szHexaTargetType = "0x0102";
}
else if (m_szTargetType.Compare("4"))
{
szFriendlyTargetType = " (x86) Static Library";
szHexaTargetType = "0x0104";
}
else if (m_szTargetType.Compare("0"))
{
szFriendlyTargetType = " (x86) External Target"; // makefile project
szHexaTargetType = "0x0106";
}
else
{
szFriendlyTargetType = " (x86) Unknown Target"; // not likely to happen, though
szHexaTargetType = "0x0100";
}
CString szPlatform = ExtractPlatform( m_arrConfigurationNames.GetAt(0) ); // usually it is Win32
szFriendlyTargetType = szPlatform + szFriendlyTargetType;
CString s = "# Microsoft Developer Studio Project File - Name=\"";
s += m_szProjname;
s += "\" - Package Owner=<4>\r\n";
m_outputFile.Write(s);
s = "# Microsoft Developer Studio Generated Build File, Format Version 6.00\r\n";
m_outputFile.Write(s);
s = "# ** DO NOT EDIT **\r\n\r\n";
m_outputFile.Write(s);
s = "# TARGTYPE \"" + szFriendlyTargetType + "\" " + szHexaTargetType + "\r\n\r\n";
m_outputFile.Write(s);
s = "CFG=" + TranslateConfigurationName( m_arrConfigurationNames.GetAt(0) ) + "\r\n";
m_outputFile.Write(s);
s = "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r\n";
m_outputFile.Write(s);
s = "!MESSAGE use the Export Makefile command and run\r\n";
m_outputFile.Write(s);
s = "!MESSAGE \r\n";
m_outputFile.Write(s);
s = "!MESSAGE NMAKE /f \"" + m_szProjname + ".mak\".\r\n";
m_outputFile.Write(s);
s = "!MESSAGE \r\n";
m_outputFile.Write(s);
s = "!MESSAGE You can specify a configuration when running NMAKE\r\n";
m_outputFile.Write(s);
s = "!MESSAGE by defining the macro CFG on the command line. For example:\r\n";
m_outputFile.Write(s);
s = "!MESSAGE \r\n";
m_outputFile.Write(s);
s = "!MESSAGE NMAKE /f \"" + m_szProjname + ".mak\" CFG=\"";
s += TranslateConfigurationName( m_arrConfigurationNames.GetAt(0) );
s += "\"\r\n";
m_outputFile.Write(s);
s = "!MESSAGE \r\n";
m_outputFile.Write(s);
s = "!MESSAGE Possible choices for configuration are:\r\n";
m_outputFile.Write(s);
s = "!MESSAGE \r\n";
m_outputFile.Write(s);
// all configs
long nConfigNb = m_arrConfigurationNames.GetSize();
for (long i=0; i<nConfigNb; i++)
{
s = "!MESSAGE \"";
s += TranslateConfigurationName( m_arrConfigurationNames.GetAt(i) );
s += "\" (based on \"";
s += szFriendlyTargetType;
s += "\")\r\n";
m_outputFile.Write(s);
}
s = "!MESSAGE \r\n\r\n";
m_outputFile.Write(s);
s = "# Begin Project\r\n";
m_outputFile.Write(s);
s = "# PROP AllowPerConfigDependencies 0\r\n";
m_outputFile.Write(s);
s = "# PROP Scc_ProjName \"" + m_szSccProjectName + "\"\r\n";
m_outputFile.Write(s);
s = "# PROP Scc_LocalPath \"" + m_szSccLocalPath + "\"\r\n";
m_outputFile.Write(s);
s = "CPP=cl.exe\r\n";
m_outputFile.Write(s);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -