This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions
+296
View File
@@ -0,0 +1,296 @@
# Make command to use for dependencies
SHELL=/bin/sh
RM:=rm
MKDIR:=mkdir
OS:=$(shell uname)
EXE_POSTFIX:=""
# ---------------------------------------------------------------- #
# Figure out if we're building in the Steam tree or not.
# ---------------------------------------------------------------- #
SRCROOT:=../..
-include $(SRCROOT)/devtools/steam_def.mak
# ---------------------------------------------------------------- #
# Set paths to gcc.
# ---------------------------------------------------------------- #
CC:=gcc -m32
CXX:=g++ -m32
ifeq ($(OS),Darwin)
CC:=clang -m32
CXX:=clang++ -m32
EXE_POSTFIX:=_osx
endif
ifeq ($(OS),Linux)
CC=/valve/bin/gcc -m32
CXX=/valve/bin/g++ -m32
EXE_POSTFIX=_linux
endif
ifneq ($(CC_OVERRIDE),)
CC:=$(CC_OVERRIDE)
CXX:=$(CPP_OVERRIDE)
endif
# ---------------------------------------------------------------- #
# Lists of files.
# ---------------------------------------------------------------- #
VPC_SRC:= \
exprsimplifier.cpp \
groupscript.cpp \
conditionals.cpp \
macros.cpp \
projectscript.cpp \
scriptsource.cpp \
baseprojectdatacollector.cpp \
configuration.cpp \
dependencies.cpp \
main.cpp \
projectgenerator_makefile.cpp \
projectgenerator_xcode.cpp \
solutiongenerator_makefile.cpp \
solutiongenerator_xcode.cpp \
sys_utils.cpp \
../vpccrccheck/crccheck_shared.cpp
TIER0_SRC:= \
../../tier0/assert_dialog.cpp \
../../tier0/cpu_posix.cpp \
../../tier0/cpu.cpp \
../../tier0/dbg.cpp \
../../tier0/fasttimer.cpp \
../../tier0/mem.cpp \
../../tier0/mem_helpers.cpp \
../../tier0/memdbg.cpp \
../../tier0/memstd.cpp \
../../tier0/memvalidate.cpp \
../../tier0/minidump.cpp \
../../tier0/pch_tier0.cpp \
../../tier0/threadtools.cpp \
../../tier0/valobject.cpp \
../../tier0/vprof.cpp
TIER1_SRC:= \
../../tier1/keyvalues.cpp \
../../tier1/checksum_crc.cpp \
../../tier1/checksum_md5.cpp \
../../tier1/convar.cpp \
../../tier1/generichash.cpp \
../../tier1/interface.cpp \
../../tier1/mempool.cpp \
../../tier1/memstack.cpp \
../../tier1/stringpool.cpp \
../../tier1/utlbuffer.cpp \
../../tier1/utlsymbol.cpp
VSTDLIB_SRC:= \
../../vstdlib/cvar.cpp \
../../vstdlib/vstrtools.cpp \
../../vstdlib/random.cpp
ifeq "$(STEAM_BRANCH)" "1"
TIER0_SRC+= \
../../tier0/tier0.cpp \
../../tier0/platform_posix.cpp \
../../tier0/validator.cpp \
../../tier0/thread.cpp \
../../tier0/pmelib.cpp \
../../tier0/pme_posix.cpp \
../../tier0/testthread.cpp \
../../tier0/cpu_posix.cpp \
../../tier0/memblockhdr.cpp
VSTDLIB_SRC+= \
../../vstdlib/keyvaluessystem.cpp \
../../vstdlib/qsort_s.cpp \
../../vstdlib/strtools.cpp \
../../vstdlib/stringnormalize.cpp \
../../vstdlib/splitstring.cpp \
../../vstdlib/commandline.cpp
INTERFACES_SRC=
BINLAUNCH_SRC =
else
TIER0_SRC+= \
../../tier0/platform_posix.cpp \
../../tier0/pme_posix.cpp \
../../tier0/commandline.cpp \
../../tier0/win32consoleio.cpp \
../../tier0/logging.cpp \
../../tier0/tier0_strtools.cpp
TIER1_SRC+= \
../../tier1/utlstring.cpp \
../../tier1/tier1.cpp \
../../tier1/characterset.cpp \
../../tier1/splitstring.cpp \
../../tier1/strtools.cpp \
../../tier1/exprevaluator.cpp \
VSTDLIB_SRC+= \
../../vstdlib/keyvaluessystem.cpp
INTERFACES_SRC= \
../../interfaces/interfaces.cpp
BINLAUNCH_SRC = \
endif
SRC:=$(VPC_SRC) $(TIER0_SRC) $(TIER1_SRC) $(VSTDLIB_SRC) $(INTERFACES_SRC) $(BINLAUNCH_SRC)
# -----Begin user-editable area-----
# -----End user-editable area-----
# If no configuration is specified, "Debug" will be used
ifndef "CFG"
CFG:=Release
endif
#
# Configuration: Debug
#
ifeq "$(CFG)" "Debug"
OUTDIR:=obj/$(OS)/debug
CONFIG_DEPENDENT_FLAGS:=-O0
ifeq ($(OS),Linux)
CONFIG_DEPENDENT_FLAGS+=-g3 -ggdb -fpermissive
endif
else
OUTDIR:=obj/$(OS)/release
CONFIG_DEPENDENT_FLAGS:=-O3
ifeq ($(OS),Linux)
CONFIG_DEPENDENT_FLAGS+=-g3 -ggdb -fpermissive
endif
endif
OBJS:=$(addprefix $(OUTDIR)/, $(subst ../../, ,$(SRC:.cpp=.o)))
OUTFILE:=$(OUTDIR)/vpc
CFG_INC:=-I../../public -I../../common -I../../public/tier0 \
-I../../public/tier1 -I../../public/tier2 -I../../public/vstdlib
CFLAGS=-D_POSIX -DPOSIX -DGNUC -DNDEBUG $(CONFIG_DEPENDENT_FLAGS) -msse -mmmx -pipe -w -fPIC $(CFG_INC)
ifeq "$(STEAM_BRANCH)" "1"
CFLAGS+= -DSTEAM
endif
ifeq "$(OS)" "Darwin"
CFLAGS+=-I/usr/include/malloc
CFLAGS+= -DOSX -D_OSX
CFLAGS+= -arch i386 -fasm-blocks
endif
ifeq "$(OS)" "Linux"
CFLAGS+= -DPLATFORM_LINUX -D_LINUX -DLINUX
endif
ifeq ($(CYGWIN),1)
CFLAGS+=-D_CYGWIN -DCYGWIN -D_CYGWIN_WINDOWS_TARGET
endif
CFLAGS+= -DCOMPILER_GCC
# the sed magic here adds the dependency file to the list of things that depend on the computed dependency
# set, so if any of them change, the dependencies are re-made
MAKEDEPEND=$(CXX) -M -MT $@ -MM $(CFLAGS) $< | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $(@:.o=.d)
COMPILE=$(CXX) -c $(CFLAGS) -o $@ $<
LINK=$(CXX) $(CONFIG_DEPENDENT_FLAGS) -ldl -lpthread -o "$(OUTFILE)" $(OBJS)
ifeq "$(OS)" "Darwin"
LINK+=-liconv -framework Foundation
endif
ifeq "$(OS)" "Darwin"
LINK+= -arch i386
endif
# Build rules
all: $(OUTFILE) ../../devtools/bin/vpc$(EXE_POSTFIX)
../../devtools/bin/vpc$(EXE_POSTFIX) : $(OUTFILE)
cp "$(OUTFILE)" ../../devtools/bin/vpc$(EXE_POSTFIX)
$(OUTFILE): Makefile $(OBJS)
$(LINK)
# Rebuild this project
rebuild: cleanall all
# Clean this project
clean:
$(RM) -f $(OUTFILE)
$(RM) -f $(OBJS)
$(RM) -f $(OBJS:.o=.d)
$(RM) -f ../../devtools/bin/vpc$(EXE_POSTFIX)
# Clean this project and all dependencies
cleanall: clean
# magic rules - tread with caution
-include $(OBJS:.o=.d)
# Pattern rules
$(OUTDIR)/%.o : %.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/tier0/%.o : ../../tier0/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/tier1/%.o : ../../tier1/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/vstdlib/%.o : ../../vstdlib/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/interfaces/%.o : ../../interfaces/%.cpp
if [ ! -d $(@D) ]; then $(MKDIR) $(@D); fi
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/utils/binlaunch/%.o : ../binlaunch/%.cpp
if [ ! -d $(@D) ]; then $(MKDIR) $(@D); fi
@$(MAKEDEPEND);
$(COMPILE)
# the tags file) seems like more work than it's worth. feel free to fix that up
# if it bugs you.
TAGS:
@find . -name '*.cpp' -print0 | xargs -0 etags --declarations --ignore-indentation
@find . -name '*.h' -print0 | xargs -0 etags --language=c++ --declarations --ignore-indentation --append
@find . -name '*.c' -print0 | xargs -0 etags --declarations --ignore-indentation --append
+337
View File
@@ -0,0 +1,337 @@
//====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "baseprojectdatacollector.h"
#include "tier1/utlstack.h"
#include "p4lib/ip4.h"
// ------------------------------------------------------------------------------------------------ //
// CSpecificConfig implementation.
// ------------------------------------------------------------------------------------------------ //
CSpecificConfig::CSpecificConfig( CSpecificConfig *pParentConfig )
: m_pParentConfig( pParentConfig )
{
m_pKV = new KeyValues( "" );
m_bFileExcluded = false;
m_bIsSchema = false;
}
CSpecificConfig::~CSpecificConfig()
{
m_pKV->deleteThis();
}
const char* CSpecificConfig::GetConfigName()
{
return m_pKV->GetName();
}
const char* CSpecificConfig::GetOption( const char *pOptionName )
{
const char *pRet = m_pKV->GetString( pOptionName, NULL );
if ( pRet )
return pRet;
if ( m_pParentConfig )
return m_pParentConfig->m_pKV->GetString( pOptionName, NULL );
return NULL;
}
// ------------------------------------------------------------------------------------------------ //
// CFileConfig implementation.
// ------------------------------------------------------------------------------------------------ //
CFileConfig::~CFileConfig()
{
Term();
}
void CFileConfig::Term()
{
m_Configurations.PurgeAndDeleteElements();
}
const char* CFileConfig::GetName()
{
return m_Filename.String();
}
CSpecificConfig* CFileConfig::GetConfig( const char *pConfigName )
{
int i = m_Configurations.Find( pConfigName );
if ( i == m_Configurations.InvalidIndex() )
return NULL;
else
return m_Configurations[i];
}
CSpecificConfig* CFileConfig::GetOrCreateConfig( const char *pConfigName, CSpecificConfig *pParentConfig )
{
int i = m_Configurations.Find( pConfigName );
if ( i == m_Configurations.InvalidIndex() )
{
CSpecificConfig *pConfig = new CSpecificConfig( pParentConfig );
i = m_Configurations.Insert( pConfigName, pConfig );
}
return m_Configurations[i];
}
bool CFileConfig::IsExcludedFrom( const char *pConfigName )
{
CSpecificConfig *pSpecificConfig = GetConfig( pConfigName );
if ( pSpecificConfig )
return pSpecificConfig->m_bFileExcluded;
else
return false;
}
// ------------------------------------------------------------------------------------------------ //
// CBaseProjectDataCollector implementation.
// ------------------------------------------------------------------------------------------------ //
CBaseProjectDataCollector::CBaseProjectDataCollector( CRelevantPropertyNames *pNames ) : m_Files( k_eDictCompareTypeFilenames )
{
m_RelevantPropertyNames.m_nNames = 0;
m_RelevantPropertyNames.m_pNames = NULL;
if ( pNames )
{
m_RelevantPropertyNames = *pNames;
}
}
CBaseProjectDataCollector::~CBaseProjectDataCollector()
{
Term();
}
void CBaseProjectDataCollector::StartProject()
{
m_ProjectName = "UNNAMED";
m_CurFileConfig.Push( &m_BaseConfigData );
m_CurSpecificConfig.Push( NULL );
}
void CBaseProjectDataCollector::EndProject()
{
}
void CBaseProjectDataCollector::Term()
{
m_BaseConfigData.Term();
m_Files.PurgeAndDeleteElements();
m_CurFileConfig.Purge();
m_CurSpecificConfig.Purge();
}
CUtlString CBaseProjectDataCollector::GetProjectName()
{
return m_ProjectName;
}
void CBaseProjectDataCollector::SetProjectName( const char *pProjectName )
{
char tmpBuf[MAX_PATH];
V_strncpy( tmpBuf, pProjectName, sizeof( tmpBuf ) );
Q_strlower( tmpBuf );
m_ProjectName = tmpBuf;
}
// Get a list of all configurations.
void CBaseProjectDataCollector::GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames )
{
configurationNames.Purge();
for ( int i=m_BaseConfigData.m_Configurations.First(); i != m_BaseConfigData.m_Configurations.InvalidIndex(); i=m_BaseConfigData.m_Configurations.Next(i) )
{
configurationNames.AddToTail( m_BaseConfigData.m_Configurations.GetElementName(i) );
}
}
void CBaseProjectDataCollector::StartConfigurationBlock( const char *pConfigName, bool bFileSpecific )
{
CFileConfig *pFileConfig = m_CurFileConfig.Top();
// Find or add a new config block.
char sLowerCaseConfigName[MAX_PATH];
V_strncpy( sLowerCaseConfigName, pConfigName, sizeof( sLowerCaseConfigName ) );
V_strlower( sLowerCaseConfigName );
int index = pFileConfig->m_Configurations.Find( sLowerCaseConfigName );
if ( index == -1 )
{
CSpecificConfig *pParent = ( pFileConfig==&m_BaseConfigData ? NULL : m_BaseConfigData.GetOrCreateConfig( sLowerCaseConfigName, NULL ) );
CSpecificConfig *pConfig = new CSpecificConfig( pParent );
pConfig->m_bFileExcluded = false;
pConfig->m_pKV->SetName( sLowerCaseConfigName );
index = pFileConfig->m_Configurations.Insert( sLowerCaseConfigName, pConfig );
}
// Remember what the current config is.
m_CurSpecificConfig.Push( pFileConfig->m_Configurations[index] );
}
void CBaseProjectDataCollector::EndConfigurationBlock()
{
m_CurSpecificConfig.Pop();
}
bool CBaseProjectDataCollector::StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip )
{
return true;
}
void CBaseProjectDataCollector::HandleProperty( const char *pProperty, const char *pCustomScriptData )
{
int i;
for ( i=0; i < m_RelevantPropertyNames.m_nNames; i++ )
{
if ( V_stricmp( m_RelevantPropertyNames.m_pNames[i], pProperty ) == 0 )
break;
}
if ( i == m_RelevantPropertyNames.m_nNames )
{
// not found
return;
}
if ( pCustomScriptData )
{
g_pVPC->GetScript().PushScript( "HandleProperty( custom script data )", pCustomScriptData );
}
const char *pNextToken = g_pVPC->GetScript().PeekNextToken( false );
if ( pNextToken && pNextToken[0] != 0 )
{
// Pass in the previous value so the $base substitution works.
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
const char *pBaseString = pConfig->m_pKV->GetString( pProperty );
char buff[MAX_SYSTOKENCHARS];
if ( g_pVPC->GetScript().ParsePropertyValue( pBaseString, buff, sizeof( buff ) ) )
{
pConfig->m_pKV->SetString( pProperty, buff );
}
}
if ( pCustomScriptData )
{
// Restore prior script state
g_pVPC->GetScript().PopScript();
}
}
void CBaseProjectDataCollector::EndPropertySection( configKeyword_e keyword )
{
}
void CBaseProjectDataCollector::StartFolder( const char *pFolderName )
{
}
void CBaseProjectDataCollector::EndFolder()
{
}
bool CBaseProjectDataCollector::StartFile( const char *pFilename, bool bWarnIfAlreadyExists )
{
CFileConfig *pFileConfig = new CFileConfig;
pFileConfig->m_Filename = pFilename;
m_Files.Insert( pFilename, pFileConfig );
m_CurFileConfig.Push( pFileConfig );
m_CurSpecificConfig.Push( NULL );
char szFullPath[MAX_PATH];
V_GetCurrentDirectory( szFullPath, sizeof( szFullPath ) );
V_AppendSlash( szFullPath, sizeof( szFullPath ) );
V_strncat( szFullPath, pFilename, sizeof( szFullPath ) );
V_RemoveDotSlashes( szFullPath );
#if 0
// Add file to Perforce if it isn't there already
if ( Sys_Exists( szFullPath ) )
{
if ( m_bP4AutoAdd && p4 && !p4->IsFileInPerforce( szFullPath ) )
{
p4->OpenFileForAdd( szFullPath );
VPCStatus( "%s automatically opened for add in default changelist.", szFullPath );
}
}
else
{
// g_pVPC->Warning( "%s not found on disk at location specified in project script.", szFullPath );
}
#endif
return true;
}
void CBaseProjectDataCollector::EndFile()
{
m_CurFileConfig.Pop();
m_CurSpecificConfig.Pop();
}
// This is actually just per-file configuration data.
void CBaseProjectDataCollector::FileExcludedFromBuild( bool bExcluded )
{
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
pConfig->m_bFileExcluded = bExcluded;
}
void CBaseProjectDataCollector::FileIsSchema( bool bIsSchema )
{
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
pConfig->m_bIsSchema = bIsSchema;
}
bool CBaseProjectDataCollector::RemoveFile( const char *pFilename )
{
bool bRet = false;
int i = m_Files.Find( pFilename );
if ( i != m_Files.InvalidIndex() )
{
delete m_Files[i];
m_Files.RemoveAt( i );
bRet = true;
}
return bRet;
}
void CBaseProjectDataCollector::DoStandardVisualStudioReplacements( const char *pStartString, const char *pFullInputFilename, char *pOut, int outLen )
{
// Decompose the input filename.
char sInputDir[MAX_PATH], sFileBase[MAX_PATH];
if ( !V_ExtractFilePath( pFullInputFilename, sInputDir, sizeof( sInputDir ) ) )
g_pVPC->VPCError( "V_ExtractFilePath failed on %s.", pFullInputFilename );
V_FileBase( pFullInputFilename, sFileBase, sizeof( sFileBase ) );
// Handle $(InputPath), $(InputDir), $(InputName)
char *strings[2] =
{
(char*)stackalloc( outLen ),
(char*)stackalloc( outLen )
};
V_StrSubst( pStartString, "$(InputPath)", pFullInputFilename, strings[0], outLen );
V_StrSubst( strings[0], "$(InputDir)", sInputDir, strings[1], outLen );
V_StrSubst( strings[1], "$(InputName)", sFileBase, strings[0], outLen );
V_StrSubst( strings[0], "$(IntDir)", "$(OBJ_DIR)", strings[1], outLen );
V_StrSubst( strings[1], "$(InputFileName)", pFullInputFilename + Q_strlen(sInputDir), strings[0], outLen );
V_strncpy( pOut, strings[0], outLen );
V_FixSlashes( pOut, '/' );
}
+130
View File
@@ -0,0 +1,130 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
//
//=============================================================================
#ifndef BASEPROJECTDATACOLLECTOR_H
#define BASEPROJECTDATACOLLECTOR_H
#ifdef _WIN32
#pragma once
#endif
#ifdef STEAM
#include "tier1/keyvalues.h"
#else
#include "tier1/keyvalues.h"
#endif
#include "tier1/utlstack.h"
class CSpecificConfig
{
public:
CSpecificConfig( CSpecificConfig *pParentConfig );
~CSpecificConfig();
const char *GetConfigName();
const char *GetOption( const char *pOptionName );
public:
CSpecificConfig *m_pParentConfig;
KeyValues *m_pKV;
bool m_bFileExcluded; // Is the file that holds this config excluded from the build?
bool m_bIsSchema; // Is this a schema file?
};
class CFileConfig
{
public:
~CFileConfig();
void Term();
const char *GetName();
CSpecificConfig *GetConfig( const char *pConfigName );
CSpecificConfig *GetOrCreateConfig( const char *pConfigName, CSpecificConfig *pParentConfig );
bool IsExcludedFrom( const char *pConfigName );
public:
CUtlDict< CSpecificConfig*, int > m_Configurations;
CUtlString m_Filename; // "" if this is the config data for the whole project.
};
// This just holds the list of property names that we're supposed to scan for.
class CRelevantPropertyNames
{
public:
const char **m_pNames;
int m_nNames;
};
//
// This class is shared by the makefile and SlickEdit project file generator.
// It just collects interesting file properties into KeyValues and then the project file generator
// is responsible for using that data to write out a project file.
//
class CBaseProjectDataCollector : public IBaseProjectGenerator
{
// IBaseProjectGenerator implementation.
public:
CBaseProjectDataCollector( CRelevantPropertyNames *pNames );
~CBaseProjectDataCollector();
// Called before doing anything in a project (in g_pVPC->GetOutputFilename()).
virtual void StartProject();
virtual void EndProject();
// Access the project name.
virtual CUtlString GetProjectName();
virtual void SetProjectName( const char *pProjectName );
// Get a list of all configurations.
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames );
// Configuration data is specified in between these calls and inside BeginPropertySection/EndPropertySection.
// If bFileSpecific is set, then the configuration data only applies to the last file added.
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific );
virtual void EndConfigurationBlock();
// These functions are called when it enters a section like $Compiler, $Linker, etc.
// In between the BeginPropertySection/EndPropertySection, it'll call HandleProperty for any properties inside that section.
//
// If you pass pCustomScriptData to HandleProperty, it won't touch the global parsing state -
// it'll parse the platform filters and property value from pCustomScriptData instead.
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip = NULL );
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData = NULL );
virtual void EndPropertySection( configKeyword_e keyword );
// Files go in folders. The generator should maintain a stack of folders as they're added.
virtual void StartFolder( const char *pFolderName );
virtual void EndFolder();
// Add files. Any config blocks/properties between StartFile/EndFile apply to this file only.
// It will only ever have one active file.
virtual bool StartFile( const char *pFilename, bool bWarnIfAlreadyExists );
virtual void EndFile();
// This is actually just per-file configuration data.
virtual void FileExcludedFromBuild( bool bExcluded );
virtual void FileIsSchema( bool bIsSchema );
// Remove the specified file.
virtual bool RemoveFile( const char *pFilename ); // returns ture if a file was removed
public:
// This is called in EndProject if bAutoCleanupAfterProject is set.
void Term();
static void DoStandardVisualStudioReplacements( const char *pStartString, const char *pFullInputFilename, char *pOut, int outLen );
public:
CUtlString m_ProjectName;
CUtlDict< CFileConfig *, int > m_Files;
CFileConfig m_BaseConfigData;
CUtlStack< CFileConfig* > m_CurFileConfig; // Either m_BaseConfigData or one of the files.
CUtlStack< CSpecificConfig* > m_CurSpecificConfig; // Debug, release?
CRelevantPropertyNames m_RelevantPropertyNames;
};
#endif // BASEPROJECTDATACOLLECTOR_H
+244
View File
@@ -0,0 +1,244 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CVPC::SetupDefaultConditionals()
{
//
// PLATFORM Conditionals
//
{
FindOrCreateConditional( "WIN32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "WIN64", true, CONDITIONAL_PLATFORM );
// LINUX is the platform but the VPC scripts use $LINUX and $DEDICATED
// (which we automatically create later).
FindOrCreateConditional( "LINUX32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUX64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "CYGWIN", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "OSX32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "OSX64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "X360", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "PS3", true, CONDITIONAL_PLATFORM );
}
//
// CUSTOM conditionals
//
{
// setup default custom conditionals
FindOrCreateConditional( "PROFILE", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "RETAIL", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "CALLCAP", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "FASTCAP", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "CERT", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "MEMTEST", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "NOFPO", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "POSIX", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "LV", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "DEMO", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "NO_STEAM", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "DVDEMU", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "QTDEBUG", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "NO_CEG", true, CONDITIONAL_CUSTOM );
FindOrCreateConditional( "UPLOAD_CEG", true, CONDITIONAL_CUSTOM );
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CVPC::GetTargetPlatformName()
{
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
conditional_t *pConditional = &m_Conditionals[i];
if ( pConditional->type == CONDITIONAL_PLATFORM && pConditional->m_bDefined )
{
return pConditional->name.String();
}
}
// fatal - should have already been default set
Assert( 0 );
VPCError( "Unspecified platform." );
return NULL;
}
//-----------------------------------------------------------------------------
// Case Insensitive. Returns true if platform conditional has been marked
// as defined.
//-----------------------------------------------------------------------------
bool CVPC::IsPlatformDefined( const char *pName )
{
for ( int i=0; i<m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i].type == CONDITIONAL_PLATFORM && !V_stricmp( pName, m_Conditionals[i].name.String() ) )
{
return m_Conditionals[i].m_bDefined;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Case Insensitive
//-----------------------------------------------------------------------------
conditional_t *CVPC::FindOrCreateConditional( const char *pName, bool bCreate, conditionalType_e type )
{
for (int i=0; i<m_Conditionals.Count(); i++)
{
if ( !V_stricmp( pName, m_Conditionals[i].name.String() ) )
{
// found
return &m_Conditionals[i];
}
}
if ( !bCreate )
{
return NULL;
}
int index = m_Conditionals.AddToTail();
char tempName[256];
V_strncpy( tempName, pName, sizeof( tempName ) );
// primary internal use as lower case, but spewed to user as upper for style consistency
m_Conditionals[index].name = V_strlower( tempName );
m_Conditionals[index].upperCaseName = V_strupr( tempName );
m_Conditionals[index].type = type;
return &m_Conditionals[index];
}
void CVPC::SetConditional( const char *pString, bool bSet )
{
VPCStatus( false, "Set Conditional: $%s = %s", pString, ( bSet ? "1" : "0" ) );
conditional_t *pConditional = FindOrCreateConditional( pString, true, CONDITIONAL_CUSTOM );
if ( !pConditional )
{
VPCError( "Failed to find or create $%s conditional", pString );
}
pConditional->m_bDefined = bSet;
}
//-----------------------------------------------------------------------------
// Returns true if string has a conditional of the specified type
//-----------------------------------------------------------------------------
bool CVPC::ConditionHasDefinedType( const char* pCondition, conditionalType_e type )
{
char symbol[MAX_SYSTOKENCHARS];
for ( int i=0; i<m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i].type != type )
continue;
sprintf( symbol, "$%s", m_Conditionals[i].name.String() );
if ( V_stristr( pCondition, symbol ) )
{
// a define of expected type occurs in the conditional expression
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
bool CVPC::ResolveConditionalSymbol( const char *pSymbol )
{
int offset = 0;
if ( !V_stricmp( pSymbol, "$0" ) || !V_stricmp( pSymbol, "0" ) )
{
return false;
}
else if ( !V_stricmp( pSymbol, "$1" ) || !V_stricmp( pSymbol, "1" ) )
{
return true;
}
if ( pSymbol[0] == '$' )
{
offset = 1;
}
conditional_t *pConditional = FindOrCreateConditional( (char*)pSymbol+offset, false, CONDITIONAL_NULL );
if ( pConditional )
{
// game conditionals only resolve true when they are 'defined' and 'active'
// only one game conditional is expected to be active at a time
if ( pConditional->type == CONDITIONAL_GAME )
{
if ( !pConditional->m_bDefined )
{
return false;
}
pConditional->m_bGameConditionActive;
}
// all other type of conditions are gated by their 'defined' state
return pConditional->m_bDefined;
}
// unknown conditional, defaults to false
return false;
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
static bool ResolveSymbol( const char *pSymbol )
{
return g_pVPC->ResolveConditionalSymbol( pSymbol );
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
static void SymbolSyntaxError( const char *pReason )
{
// invoke internal syntax error hndling which spews script stack as well
g_pVPC->VPCSyntaxError( pReason );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CVPC::EvaluateConditionalExpression( const char *pExpression )
{
char conditionalBuffer[MAX_SYSTOKENCHARS];
ResolveMacrosInString( pExpression, conditionalBuffer, sizeof( conditionalBuffer ) );
if ( !conditionalBuffer[0] )
{
// empty string, same as not having a conditional
return true;
}
bool bResult = false;
CExpressionEvaluator ExpressionHandler;
bool bValid = ExpressionHandler.Evaluate( bResult, conditionalBuffer, ::ResolveSymbol, ::SymbolSyntaxError );
if ( !bValid )
{
g_pVPC->VPCSyntaxError( "VPC Conditional Evaluation Error" );
}
return bResult;
}
+317
View File
@@ -0,0 +1,317 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
static KeywordName_t s_KeywordNameTable[] =
{
{"$General", KEYWORD_GENERAL},
{"$Debugging", KEYWORD_DEBUGGING},
{"$Compiler", KEYWORD_COMPILER},
{"$SNCCompiler", KEYWORD_PS3_SNCCOMPILER},
{"$GCCCompiler", KEYWORD_PS3_GCCCOMPILER},
{"$Librarian", KEYWORD_LIBRARIAN},
{"$Linker", KEYWORD_LINKER},
{"$SNCLinker", KEYWORD_PS3_SNCLINKER},
{"$GCCLinker", KEYWORD_PS3_GCCLINKER},
{"$ManifestTool", KEYWORD_MANIFEST},
{"$XMLDocumentGenerator", KEYWORD_XMLDOCGEN},
{"$BrowseInformation", KEYWORD_BROWSEINFO},
{"$Resources", KEYWORD_RESOURCES},
{"$PreBuildEvent", KEYWORD_PREBUILDEVENT},
{"$PreLinkEvent", KEYWORD_PRELINKEVENT},
{"$PostBuildEvent", KEYWORD_POSTBUILDEVENT},
{"$CustomBuildStep", KEYWORD_CUSTOMBUILDSTEP},
{"$Xbox360ImageConversion", KEYWORD_XBOXIMAGE},
{"$ConsoleDeployment", KEYWORD_XBOXDEPLOYMENT},
};
const char *CVPC::KeywordToName( configKeyword_e keyword )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_KeywordNameTable ) == KEYWORD_MAX );
if ( keyword == KEYWORD_UNKNOWN )
{
return "???";
}
return s_KeywordNameTable[keyword].m_pName;
}
configKeyword_e CVPC::NameToKeyword( const char *pKeywordName )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_KeywordNameTable ) == KEYWORD_MAX );
for ( int i = 0; i < ARRAYSIZE( s_KeywordNameTable ); i++ )
{
if ( !V_stricmp( pKeywordName, s_KeywordNameTable[i].m_pName ) )
{
return s_KeywordNameTable[i].m_Keyword;
}
}
return KEYWORD_UNKNOWN;
}
//-----------------------------------------------------------------------------
// VPC_Config_Keyword
//
//-----------------------------------------------------------------------------
void VPC_Config_Keyword( configKeyword_e keyword, const char *pkeywordToken )
{
const char *pToken;
bool bShouldSkip = false;
if ( !g_pVPC->GetProjectGenerator()->StartPropertySection( keyword, &bShouldSkip ) )
{
g_pVPC->VPCSyntaxError( "Unsupported Keyword: %s for target platform", pkeywordToken );
}
if ( bShouldSkip )
{
pToken = g_pVPC->GetScript().PeekNextToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
g_pVPC->VPCSyntaxError();
g_pVPC->GetScript().SkipBracedSection();
}
else
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
break;
if ( !V_stricmp( pToken, "}" ) )
{
// end of section
break;
}
// Copy off the token name so HandleProperty() doesn't have to (or else the parser will overwrite it on the next token).
char tempTokenName[MAX_PATH];
V_strncpy( tempTokenName, pToken, sizeof( tempTokenName ) );
g_pVPC->GetProjectGenerator()->HandleProperty( tempTokenName );
}
}
g_pVPC->GetProjectGenerator()->EndPropertySection( keyword );
}
//-----------------------------------------------------------------------------
// VPC_Keyword_Configuration
//
//-----------------------------------------------------------------------------
void VPC_Keyword_Configuration()
{
const char *pToken;
char szConfigName[MAX_PATH];
bool bAllowNextLine = false;
int i;
CUtlVector<CUtlString> configs;
char buff[MAX_SYSTOKENCHARS];
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( bAllowNextLine );
if ( !pToken || !pToken[0] )
break;
if ( !V_stricmp( pToken, "\\" ) )
{
bAllowNextLine = true;
continue;
}
else
{
bAllowNextLine = false;
}
int index = configs.AddToTail();
configs[index] = pToken;
// check for another optional config
pToken = g_pVPC->GetScript().PeekNextToken( bAllowNextLine );
if ( !pToken || !pToken[0] || !V_stricmp( pToken, "{" ) || !V_stricmp( pToken, "}" ) || (pToken[0] == '$') )
break;
}
// no configuration specified, use all known
if ( !configs.Count() )
{
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configs );
if ( !configs.Count() )
{
g_pVPC->VPCError( "Trying to parse a configuration block and no configs have been defined yet.\n[%s line:%d]", g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetLine() );
}
}
// save parser state
CScriptSource scriptSource = g_pVPC->GetScript().GetCurrentScript();
for ( i=0; i<configs.Count(); i++ )
{
// restore parser state
g_pVPC->GetScript().RestoreScript( scriptSource );
V_strncpy( szConfigName, configs[i].String(), sizeof( szConfigName ) );
// get access objects
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( szConfigName, false );
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
{
g_pVPC->VPCSyntaxError();
}
while ( 1 )
{
g_pVPC->GetScript().SkipToValidToken();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, buff, sizeof( buff ) ) )
{
g_pVPC->GetScript().SkipBracedSection();
continue;
}
if ( !V_stricmp( buff, "}" ) )
{
// end of section
break;
}
configKeyword_e keyword = g_pVPC->NameToKeyword( buff );
if ( keyword == KEYWORD_UNKNOWN )
{
g_pVPC->VPCSyntaxError();
}
else
{
VPC_Config_Keyword( keyword, buff );
}
}
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
//-----------------------------------------------------------------------------
// VPC_Keyword_FileConfiguration
//
//-----------------------------------------------------------------------------
void VPC_Keyword_FileConfiguration()
{
const char *pToken;
char szConfigName[MAX_PATH];
bool bAllowNextLine = false;
char buff[MAX_SYSTOKENCHARS];
CUtlVector< CUtlString > configurationNames;
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( bAllowNextLine );
if ( !pToken || !pToken[0] )
break;
if ( !V_stricmp( pToken, "\\" ) )
{
bAllowNextLine = true;
continue;
}
else
{
bAllowNextLine = false;
}
strcpy( szConfigName, pToken );
configurationNames.AddToTail( pToken );
// check for another optional config
pToken = g_pVPC->GetScript().PeekNextToken( bAllowNextLine );
if ( !pToken || !pToken[0] || !V_stricmp( pToken, "{" ) || !V_stricmp( pToken, "}" ) || (pToken[0] == '$') )
break;
}
// no configuration specified, use all known
if ( configurationNames.Count() == 0 )
{
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configurationNames );
}
// save parser state
CScriptSource scriptSource = g_pVPC->GetScript().GetCurrentScript();
for ( int i=0; i < configurationNames.Count(); i++ )
{
// restore parser state
g_pVPC->GetScript().RestoreScript( scriptSource );
// Tell the generator we're about to feed it configuration data for this file.
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( configurationNames[i].String(), true );
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
{
g_pVPC->VPCSyntaxError();
}
while ( 1 )
{
g_pVPC->GetScript().SkipToValidToken();
pToken = g_pVPC->GetScript().PeekNextToken( true );
if ( pToken && pToken[0] && !V_stricmp( pToken, "$ExcludedFromBuild" ) )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
char buff[MAX_SYSTOKENCHARS];
if ( g_pVPC->GetScript().ParsePropertyValue( NULL, buff, sizeof( buff ) ) )
{
g_pVPC->GetProjectGenerator()->FileExcludedFromBuild( Sys_StringToBool( buff ) );
}
continue;
}
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, buff, sizeof( buff ) ) )
{
g_pVPC->GetScript().SkipBracedSection();
continue;
}
if ( !V_stricmp( buff, "}" ) )
{
// end of section
break;
}
configKeyword_e keyword = g_pVPC->NameToKeyword( buff );
switch ( keyword )
{
case KEYWORD_COMPILER:
case KEYWORD_PS3_SNCCOMPILER:
case KEYWORD_PS3_GCCCOMPILER:
case KEYWORD_RESOURCES:
case KEYWORD_CUSTOMBUILDSTEP:
VPC_Config_Keyword( keyword, buff );
break;
default:
g_pVPC->VPCSyntaxError();
}
}
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
File diff suppressed because it is too large Load Diff
+197
View File
@@ -0,0 +1,197 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef DEPENDENCIES_H
#define DEPENDENCIES_H
#ifdef _WIN32
#pragma once
#endif
enum EDependencyType
{
k_eDependencyType_SourceFile, // .cpp, .cxx, .h, .hxx
k_eDependencyType_Project, // this is a project file WITHOUT the target-specific extension (.mak, .vpj, .vcproj).
k_eDependencyType_Library, // this is a library file
k_eDependencyType_Unknown // Unrecognized file extension (probably .ico or .rc2 or somesuch).
};
class CProjectDependencyGraph;
enum k_EDependsOnFlags
{
k_EDependsOnFlagCheckNormalDependencies = 0x01,
k_EDependsOnFlagCheckAdditionalDependencies = 0x02,
k_EDependsOnFlagRecurse = 0x04,
k_EDependsOnFlagTraversePastLibs = 0x08
};
// Flags to CProjectDependencyGraph::BuildProjectDependencies.
#define BUILDPROJDEPS_FULL_DEPENDENCY_SET 0x01 // This tells it to build a graph of all projects in the source tree _including_ all games.
#define BUILDPROJDEPS_CHECK_ALL_PROJECTS 0x02 // If this is set, then it reads all .vpc files.
// If this is not set, then it only includes the files from the command line with the "vpc +tier0 *bitmap +client /tf" syntax
class CDependency
{
friend class CProjectDependencyGraph;
friend class CSingleProjectScanner;
public:
CDependency( CProjectDependencyGraph *pDependencyGraph );
virtual ~CDependency();
// Flags are a combination of k_EDependsOnFlags.
bool DependsOn( CDependency *pTest, int flags=k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse );
const char* GetName() const;
// Returns true if the absolute filename of this thing (CDependency::m_Filename) matches the absolute path specified.
bool CompareAbsoluteFilename( const char *pAbsPath ) const;
private:
bool FindDependency_Internal( CUtlVector<CUtlBuffer> &callTreeOutputStack, CDependency *pTest, int flags, int depth );
void Mark();
bool HasBeenMarked();
public:
CUtlString m_Filename; // Full paths (slashes are platform dependent).
// This is the VPC filename for a project (use CDependency_Project::m_ProjectFilename for the VCPROJ/VPJ filename).
EDependencyType m_Type;
// Files that this guy depends on.
CUtlVector<CDependency*> m_Dependencies;
// Files added by $AdditionalProjectDependencies. This is in a separate list because we don't
// always want DependsOn() to check this.
CUtlVector<CDependency*> m_AdditionalDependencies;
private:
CProjectDependencyGraph *m_pDependencyGraph;
unsigned int m_iDependencyMark;
bool m_bCheckedIncludes; // Set to true when we have checked all the includes for this.
// Cache info.
int64 m_nCacheFileSize;
int64 m_nCacheModificationTime;
// Used by the cache.
bool m_bCacheDirty; // File size or modification time don't match.
};
// This represents a project (.vcproj) file, NOT a project like a projectIndex_t.
// There can be separate .vcproj files (and thus separate CDependency_Project) for each game and platform of a projectIndex_t.
// If m_Type == k_eDependencyType_Project, then you can cast to this.
class CDependency_Project : public CDependency
{
public:
typedef CDependency BaseClass;
CDependency_Project( CProjectDependencyGraph *pDependencyGraph );
// These functions read/write g_pVPC->GetOutputFilename() and such (all the m_xxStoredXXXX vars below).
void StoreProjectParameters( const char *szScriptName );
void ExportProjectParameters();
// Does a case-insensitive string compare against m_ProjectName.
// Returns -1 if not found or the index into projects.
static int FindByProjectName( CUtlVector<CDependency_Project*> &projects, const char *pTestName );
public:
// Include directories for the project.
CUtlVector<CUtlString> m_IncludeDirectories;
// Straight out of the $AdditionalProjectDependencies key (split on semicolons).
CUtlVector<CUtlString> m_AdditionalProjectDependencies;
// Straight out of the $AdditionalOutputFiles key (split on semicolons).
CUtlVector<CUtlString> m_AdditionalOutputFiles;
CUtlString m_ProjectName; // This comes from the $Project key in the .vpc file.
CUtlString m_ProjectFilename; // Absolute path to the VCPROJ file (g_pVPC->GetOutputFilename() - see CDependency::m_Filename for the VPC filename).
CUtlString m_ImportLibrary;
// Note that there can be multiple CDependency_Projects with the same m_iProjectIndex.
projectIndex_t m_iProjectIndex;
// This is used by /p4sln. It uses this to call into VPC_ParseProjectScript. These are the values of g_pVPC->GetOutputFilename(), szScriptName,
// and the defines at the time of building this project.
CUtlString m_StoredOutputFilename;
char m_szStoredScriptName[MAX_PATH];
char m_szStoredCurrentDirectory[MAX_PATH];
CUtlVector<bool> m_StoredConditionalsActive;
};
// This class builds a graph of all dependencies, starting at the projects.
class CProjectDependencyGraph : public IProjectIterator
{
friend class CDependency;
public:
CProjectDependencyGraph();
// This is the main function to generate dependencies.
// nBuildProjectDepsFlags is a combination of BUILDPROJDEPS_ flags.
void BuildProjectDependencies( int nBuildProjectDepsFlags );
bool HasGeneratedDependencies() const;
CDependency* FindDependency( const char *pFilename );
CDependency* FindOrCreateDependency( const char *pFilename );
// Look for all projects (that we've scanned during BuildProjectDependencies) that depend on the specified project.
// If bDownwards is true, then it adds iProject and all projects that _it depends on_.
// If bDownwards is false, then it adds iProject and all projects that _depend on it_.
void GetProjectDependencyTree( projectIndex_t iProject, CUtlVector<projectIndex_t> &dependentProjects, bool bDownwards );
// This solves the central mismatch between the way VPC references projects and the way the CDependency stuff does.
//
// - VPC uses projectIndex_t, but a single projectIndex_t can turn into multiple games (server_tf, server_episodic, etc) in VPC_IterateTargetProjects.
// - The dependency code has a separate CDependency_Project for each game.
//
// This takes a bunch of project indices (usually m_targetProjects, which comes from the command line's "+this -that *theother" syntax),
// which are game-agnostic, and based on what games were specified on the command line, it builds the list of CDependency_Project*s.
void TranslateProjectIndicesToDependencyProjects( CUtlVector<projectIndex_t> &projectList, CUtlVector<CDependency_Project*> &out );
// IProjectIterator overrides.
protected:
virtual bool VisitProject( projectIndex_t iProject, const char *szProjectName );
private:
void ClearAllDependencyMarks();
// Functions for the vpc.cache file management.
bool LoadCache( const char *pFilename );
bool SaveCache( const char *pFilename );
void WriteString( FILE *fp, CUtlString &utlString );
CUtlString ReadString( FILE *fp );
void CheckCacheEntries();
void RemoveDirtyCacheEntries();
void MarkAllCacheEntriesValid();
void ResolveAdditionalProjectDependencies();
public:
// Projects and everything they depend on.
CUtlVector<CDependency_Project*> m_Projects;
CUtlDict<CDependency*,int> m_AllFiles; // All files go in here. They should never be duplicated. These are indexed by the full filename (except .lib files, which have that stripped off).
bool m_bFullDependencySet; // See bFullDepedencySet passed into BuildProjectDependencies.
int m_nFilesParsedForIncludes;
private:
// Used when sweeping the dependency graph to prevent looping around forever.
unsigned int m_iDependencyMark;
bool m_bHasGeneratedDependencies; // Set to true after finishing BuildProjectDependencies.
};
bool IsLibraryFile( const char *pFilename );
bool IsSharedLibraryFile( const char *pFilename );
#endif // DEPENDENCIES_H
+324
View File
@@ -0,0 +1,324 @@
//===== Copyright (c) 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: ExprSimplifier builds a binary tree from an infix expression (in the
// form of a character array).
//
//===========================================================================//
#include "vpc.h"
static ExprTree mExprTree; // Tree representation of the expression
static char mCurToken; // Current token read from the input expression
static const char *mExpression; // Array of the expression characters
static int mCurPosition; // Current position in the input expression
static char mIdentifier[MAX_IDENTIFIER_LEN]; // Stores the identifier string
static GetSymbolProc_t g_pGetSymbolProc;
//-----------------------------------------------------------------------------
// Sets mCurToken to the next token in the input string. Skips all whitespace.
//-----------------------------------------------------------------------------
static char GetNextToken( void )
{
// while whitespace, Increment CurrentPosition
while( mExpression[mCurPosition] == ' ' )
++mCurPosition;
// CurrentToken = Expression[CurrentPosition]
mCurToken = mExpression[mCurPosition++];
return mCurToken;
}
//-----------------------------------------------------------------------------
// Utility funcs
//-----------------------------------------------------------------------------
static void FreeNode( ExprNode *node )
{
delete node;
}
static ExprNode *AllocateNode( void )
{
return new ExprNode;
}
static void FreeTree( ExprTree& node )
{
if(!node)
return;
FreeTree(node->left);
FreeTree(node->right);
FreeNode(node);
node = 0;
}
static bool IsConditional( const char token )
{
char nextchar = ' ';
if ( token == OR_OP || token == AND_OP )
{
nextchar = mExpression[mCurPosition++];
if ( (token & nextchar) == token )
{
return true;
}
else
g_pVPC->VPCSyntaxError( "Bad expression token: %c %c", token, nextchar );
}
return false;
}
static bool IsNotOp( const char token )
{
if ( token == NOT_OP )
return true;
else
return false;
}
static bool IsIdentifierOrConstant( const char token )
{
bool success = false;
if ( token == '$' )
{
// store the entire identifier
int i = 0;
mIdentifier[i++] = token;
while( (V_isalnum( mExpression[mCurPosition] ) || mExpression[mCurPosition] == '_') && i < MAX_IDENTIFIER_LEN )
{
mIdentifier[i] = mExpression[mCurPosition];
++mCurPosition;
++i;
}
if ( i < MAX_IDENTIFIER_LEN - 1 )
{
mIdentifier[i] = '\0';
success = true;
}
}
else
{
if ( V_isdigit( token ) )
{
int i = 0;
mIdentifier[i++] = token;
while( V_isdigit( mExpression[mCurPosition] ) && ( i < MAX_IDENTIFIER_LEN ) )
{
mIdentifier[i] = mExpression[mCurPosition];
++mCurPosition;
++i;
}
if ( i < MAX_IDENTIFIER_LEN - 1 )
{
mIdentifier[i] = '\0';
success = true;
}
}
}
return success;
}
static void MakeExprNode( ExprTree &tree, char token, Kind kind, ExprTree left, ExprTree right )
{
tree = AllocateNode();
tree->left = left;
tree->right = right;
tree->kind = kind;
switch ( kind )
{
case CONDITIONAL:
tree->data.cond = token;
break;
case LITERAL:
if ( V_isdigit( mIdentifier[0] ) )
{
tree->data.value = atoi( mIdentifier ) != 0;
}
else
{
tree->data.value = g_pGetSymbolProc( mIdentifier );
}
break;
case NOT:
break;
default:
g_pVPC->VPCError( "Error in ExpTree" );
}
}
static void MakeExpression( ExprTree& tree );
//-----------------------------------------------------------------------------
// Makes a factor :: { <expression> } | <identifier>.
//-----------------------------------------------------------------------------
static void MakeFactor( ExprTree& tree )
{
if ( mCurToken == '(' )
{
// Get the next token
GetNextToken();
// Make an expression, setting Tree to point to it
MakeExpression( tree );
}
else if ( IsIdentifierOrConstant( mCurToken ) )
{
// Make a literal node, set Tree to point to it, set left/right children to NULL.
MakeExprNode( tree, mCurToken, LITERAL, NULL, NULL );
}
else if ( IsNotOp( mCurToken ) )
{
// do nothing
return;
}
else
{
// This must be a bad token
g_pVPC->VPCSyntaxError( "Bad expression token: %c", mCurToken );
}
// Get the next token
GetNextToken();
}
//-----------------------------------------------------------------------------
// Makes a term :: <factor> { <not> }.
//-----------------------------------------------------------------------------
static void MakeTerm( ExprTree& tree )
{
// Make a factor, setting Tree to point to it
MakeFactor( tree );
// while the next token is !
while( IsNotOp( mCurToken ) )
{
// Make an operator node, setting left child to Tree and right to NULL. (Tree points to new node)
MakeExprNode( tree, mCurToken, NOT, tree, NULL );
// Get the next token.
GetNextToken();
// Make a factor, setting the right child of Tree to point to it.
MakeFactor(tree->right);
}
}
//-----------------------------------------------------------------------------
// Makes a complete expression :: <term> { <cond> <term> }.
//-----------------------------------------------------------------------------
static void MakeExpression( ExprTree& tree )
{
// Make a term, setting Tree to point to it
MakeTerm( tree );
// while the next token is a conditional
while ( IsConditional( mCurToken ) )
{
// Make a conditional node, setting left child to Tree and right to NULL. (Tree points to new node)
MakeExprNode( tree, mCurToken, CONDITIONAL, tree, NULL );
// Get the next token.
GetNextToken();
// Make a term, setting the right child of Tree to point to it.
MakeTerm( tree->right );
}
}
//-----------------------------------------------------------------------------
// returns true for success, false for failure
//-----------------------------------------------------------------------------
static bool BuildExpression( void )
{
// Get the first token, and build the tree.
GetNextToken();
MakeExpression( mExprTree );
return true;
}
//-----------------------------------------------------------------------------
// returns the value of the node after resolving all children
//-----------------------------------------------------------------------------
static bool SimplifyNode( ExprTree& node )
{
if( !node )
return false;
// Simplify the left and right children of this node
bool leftVal = SimplifyNode(node->left);
bool rightVal = SimplifyNode(node->right);
// Simplify this node
switch( node->kind )
{
case NOT:
// the child of '!' is always to the right
node->data.value = !rightVal;
break;
case CONDITIONAL:
if ( node->data.cond == AND_OP )
{
node->data.value = leftVal && rightVal;
}
else // OR_OP
{
node->data.value = leftVal || rightVal;
}
break;
default: // LITERAL
break;
}
// This node has beed resolved
node->kind = LITERAL;
return node->data.value;
}
//-----------------------------------------------------------------------------
// Interface to solve a conditional expression. Returns false on failure.
//-----------------------------------------------------------------------------
bool EvaluateExpression( bool &result, const char *InfixExpression, GetSymbolProc_t pGetSymbolProc )
{
if ( !InfixExpression )
return false;
g_pGetSymbolProc = pGetSymbolProc;
bool success = false;
mExpression = InfixExpression;
mExprTree = 0;
mCurPosition = 0;
// Building the expression tree will fail on bad syntax
if ( BuildExpression() )
{
success = true;
result = SimplifyNode( mExprTree );
}
FreeTree( mExprTree );
return success;
}
+353
View File
@@ -0,0 +1,353 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
//
//=====================================================================================//
#include "vpc.h"
CGeneratorDefinition::CGeneratorDefinition()
{
Clear();
}
void CGeneratorDefinition::Clear()
{
m_pPropertyNames = NULL;
m_ScriptName.Clear();
m_NameString.Clear();
m_VersionString.Clear();
m_Tools.Purge();
m_ScriptCRC = 0;
}
void CGeneratorDefinition::IterateAttributesKey( ToolProperty_t *pProperty, KeyValues *pAttributesKV )
{
const char *pAttributeName = pAttributesKV->GetName();
const char *pValue = pAttributesKV->GetString( "" );
//Msg( "Attribute name: %s\n", pAttributeName );
if ( !V_stricmp( pAttributeName, "type" ) )
{
if ( !V_stricmp( pValue, "bool" ) || !V_stricmp( pValue, "boolean" ) )
{
pProperty->m_nType = PT_BOOLEAN;
}
else if ( !V_stricmp( pValue, "string" ) )
{
pProperty->m_nType = PT_STRING;
}
else if ( !V_stricmp( pValue, "list" ) )
{
pProperty->m_nType = PT_LIST;
}
else if ( !V_stricmp( pValue, "int" ) || !V_stricmp( pValue, "integer" ) )
{
pProperty->m_nType = PT_INTEGER;
}
else if ( !V_stricmp( pValue, "ignore" ) || !V_stricmp( pValue, "none" ) )
{
pProperty->m_nType = PT_IGNORE;
}
else if ( !V_stricmp( pValue, "deprecated" ) || !V_stricmp( pValue, "donotuse" ) )
{
pProperty->m_nType = PT_DEPRECATED;
}
else
{
// unknown
g_pVPC->VPCError( "Unknown type '%s' in '%s'", pValue, pProperty->m_ParseString.Get() );
}
}
else if ( !V_stricmp( pAttributeName, "alias" ) )
{
pProperty->m_AliasString = pValue;
}
else if ( !V_stricmp( pAttributeName, "legacy" ) )
{
pProperty->m_LegacyString = pValue;
}
else if ( !V_stricmp( pAttributeName, "InvertOutput" ) )
{
pProperty->m_bInvertOutput = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "output" ) )
{
pProperty->m_OutputString = pValue;
}
else if ( !V_stricmp( pAttributeName, "fixslashes" ) )
{
pProperty->m_bFixSlashes = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "PreferSemicolonNoComma" ) )
{
pProperty->m_bPreferSemicolonNoComma = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "PreferSemicolonNoSpace" ) )
{
pProperty->m_bPreferSemicolonNoSpace = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "AppendSlash" ) )
{
pProperty->m_bAppendSlash = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "GlobalProperty" ) )
{
pProperty->m_bEmitAsGlobalProperty = pAttributesKV->GetBool();
}
else if ( !V_stricmp( pAttributeName, "ordinals" ) )
{
if ( pProperty->m_nType == PT_UNKNOWN )
{
pProperty->m_nType = PT_LIST;
}
for ( KeyValues *pKV = pAttributesKV->GetFirstSubKey(); pKV; pKV = pKV->GetNextKey() )
{
const char *pOrdinalName = pKV->GetName();
const char *pOrdinalValue = pKV->GetString();
if ( !pOrdinalValue[0] )
{
g_pVPC->VPCError( "Unknown ordinal value for name '%s' in '%s'", pOrdinalName, pProperty->m_ParseString.Get() );
}
int iIndex = pProperty->m_Ordinals.AddToTail();
pProperty->m_Ordinals[iIndex].m_ParseString = pOrdinalName;
pProperty->m_Ordinals[iIndex].m_ValueString = pOrdinalValue;
}
}
else
{
g_pVPC->VPCError( "Unknown attribute '%s' in '%s'", pAttributeName, pProperty->m_ParseString.Get() );
}
}
void CGeneratorDefinition::IteratePropertyKey( GeneratorTool_t *pTool, KeyValues *pPropertyKV )
{
//Msg( "Property Key name: %s\n", pPropertyKV->GetName() );
int iIndex = pTool->m_Properties.AddToTail();
ToolProperty_t *pProperty = &pTool->m_Properties[iIndex];
pProperty->m_ParseString = pPropertyKV->GetName();
KeyValues *pKV = pPropertyKV->GetFirstSubKey();
if ( !pKV )
return;
for ( ;pKV; pKV = pKV->GetNextKey() )
{
IterateAttributesKey( pProperty, pKV );
}
}
void CGeneratorDefinition::IterateToolKey( KeyValues *pToolKV )
{
//Msg( "Tool Key name: %s\n", pToolKV->GetName() );
// find or create
GeneratorTool_t *pTool = NULL;
for ( int i = 0; i < m_Tools.Count(); i++ )
{
if ( !V_stricmp( pToolKV->GetName(), m_Tools[i].m_ParseString ) )
{
pTool = &m_Tools[i];
break;
}
}
if ( !pTool )
{
int iIndex = m_Tools.AddToTail();
pTool = &m_Tools[iIndex];
}
pTool->m_ParseString = pToolKV->GetName();
KeyValues *pKV = pToolKV->GetFirstSubKey();
if ( !pKV )
return;
for ( ;pKV; pKV = pKV->GetNextKey() )
{
IteratePropertyKey( pTool, pKV );
}
}
void CGeneratorDefinition::AssignIdentifiers()
{
CUtlVector< bool > usedPropertyNames;
int nTotalPropertyNames = 0;
while ( m_pPropertyNames[nTotalPropertyNames].m_nPropertyId >= 0 )
{
nTotalPropertyNames++;
}
usedPropertyNames.SetCount( nTotalPropertyNames );
// assign property identifiers
for ( int i = 0; i < m_Tools.Count(); i++ )
{
GeneratorTool_t *pTool = &m_Tools[i];
// assign the tool keyword
configKeyword_e keyword = g_pVPC->NameToKeyword( pTool->m_ParseString.Get() );
if ( keyword == KEYWORD_UNKNOWN )
{
g_pVPC->VPCError( "Unknown Tool Keyword '%s' in '%s'", pTool->m_ParseString.Get(), m_ScriptName.Get() );
}
pTool->m_nKeyword = keyword;
const char *pPrefix = m_NameString.Get();
const char *pToolName = pTool->m_ParseString.Get();
if ( pToolName[0] == '$' )
{
pToolName++;
}
for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
{
ToolProperty_t *pProperty = &pTool->m_Properties[j];
if ( pProperty->m_nType == PT_IGNORE || pProperty->m_nType == PT_DEPRECATED )
{
continue;
}
const char *pPropertyName = pProperty->m_AliasString.Get();
if ( !pPropertyName[0] )
{
pPropertyName = pProperty->m_ParseString.Get();
}
if ( pPropertyName[0] == '$' )
{
pPropertyName++;
}
CUtlString prefixString = CFmtStr( "%s_%s", pPrefix, pToolName );
bool bFound = false;
for ( int k = 0; k < nTotalPropertyNames && !bFound; k++ )
{
if ( !V_stricmp( prefixString.Get(), m_pPropertyNames[k].m_pPrefixName ) )
{
if ( !V_stricmp( pPropertyName, m_pPropertyNames[k].m_pPropertyName ) )
{
pProperty->m_nPropertyId = m_pPropertyNames[k].m_nPropertyId;
bFound = true;
usedPropertyNames[k] = true;
}
}
}
if ( !bFound )
{
g_pVPC->VPCError( "Could not find PROPERTYNAME( %s, %s ) for %s", prefixString.Get(), pPropertyName, m_ScriptName.Get() );
}
}
}
if ( g_pVPC->IsVerbose() )
{
for ( int i = 0; i < usedPropertyNames.Count(); i++ )
{
if ( !usedPropertyNames[i] )
{
g_pVPC->VPCWarning( "Unused PROPERTYNAME( %s, %s ) in %s", m_pPropertyNames[i].m_pPrefixName, m_pPropertyNames[i].m_pPropertyName, m_ScriptName.Get() );
}
}
}
}
void CGeneratorDefinition::LoadDefinition( const char *pDefnitionName, PropertyName_t *pPropertyNames )
{
Clear();
m_pPropertyNames = pPropertyNames;
g_pVPC->GetScript().PushScript( CFmtStr( "vpc_scripts\\definitions\\%s", pDefnitionName ) );
// project definitions are KV format
KeyValues *pScriptKV = new KeyValues( g_pVPC->GetScript().GetName() );
pScriptKV->LoadFromBuffer( g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetData() );
m_ScriptName = g_pVPC->GetScript().GetName();
m_ScriptCRC = CRC32_ProcessSingleBuffer( g_pVPC->GetScript().GetData(), strlen( g_pVPC->GetScript().GetData() ) );
m_NameString = pScriptKV->GetName();
KeyValues *pKV = pScriptKV->GetFirstSubKey();
for ( ;pKV; pKV = pKV->GetNextKey() )
{
const char *pKeyName = pKV->GetName();
if ( !V_stricmp( pKeyName, "version" ) )
{
m_VersionString = pKV->GetString();
}
else
{
IterateToolKey( pKV );
}
}
g_pVPC->GetScript().PopScript();
pScriptKV->deleteThis();
g_pVPC->VPCStatus( false, "Definition: '%s' Version: %s", m_NameString.Get(), m_VersionString.Get() );
AssignIdentifiers();
}
const char *CGeneratorDefinition::GetScriptName( CRC32_t *pCRC )
{
if ( pCRC )
{
*pCRC = m_ScriptCRC;
}
return m_ScriptName.Get();
}
ToolProperty_t *CGeneratorDefinition::GetProperty( configKeyword_e keyword, const char *pPropertyName )
{
for ( int i = 0; i < m_Tools.Count(); i++ )
{
GeneratorTool_t *pTool = &m_Tools[i];
if ( pTool->m_nKeyword != keyword )
continue;
for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
{
ToolProperty_t *pToolProperty = &pTool->m_Properties[j];
if ( !V_stricmp( pToolProperty->m_ParseString.Get(), pPropertyName ) )
{
// found
return pToolProperty;
}
if ( !pToolProperty->m_LegacyString.IsEmpty() && !V_stricmp( pToolProperty->m_LegacyString.Get(), pPropertyName ) )
{
// found
return pToolProperty;
}
}
}
// not found
return NULL;
}
+130
View File
@@ -0,0 +1,130 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
//
//==================================================================================================
#ifndef GENERATORDEFINITION_H
#define GENERATORDEFINITION_H
#ifdef _WIN32
#pragma once
#endif
struct PropertyName_t
{
int m_nPropertyId;
const char *m_pPrefixName;
const char *m_pPropertyName;
};
enum configKeyword_e
{
KEYWORD_UNKNOWN = -1,
KEYWORD_GENERAL,
KEYWORD_DEBUGGING,
KEYWORD_COMPILER,
KEYWORD_PS3_SNCCOMPILER,
KEYWORD_PS3_GCCCOMPILER,
KEYWORD_LIBRARIAN,
KEYWORD_LINKER,
KEYWORD_PS3_SNCLINKER,
KEYWORD_PS3_GCCLINKER,
KEYWORD_MANIFEST,
KEYWORD_XMLDOCGEN,
KEYWORD_BROWSEINFO,
KEYWORD_RESOURCES,
KEYWORD_PREBUILDEVENT,
KEYWORD_PRELINKEVENT,
KEYWORD_POSTBUILDEVENT,
KEYWORD_CUSTOMBUILDSTEP,
KEYWORD_XBOXIMAGE,
KEYWORD_XBOXDEPLOYMENT,
KEYWORD_MAX,
};
enum PropertyType_e
{
PT_UNKNOWN = 0,
PT_BOOLEAN,
PT_STRING,
PT_INTEGER,
PT_LIST,
PT_IGNORE,
PT_DEPRECATED,
};
struct PropertyOrdinal_t
{
CUtlString m_ParseString;
CUtlString m_ValueString;
};
struct ToolProperty_t
{
ToolProperty_t()
{
m_nPropertyId = -1;
m_nType = PT_UNKNOWN;
m_bFixSlashes = false;
m_bEmitAsGlobalProperty = false;
m_bInvertOutput = false;
m_bAppendSlash = false;
m_bPreferSemicolonNoComma = false;
m_bPreferSemicolonNoSpace = false;
}
CUtlString m_ParseString;
CUtlString m_AliasString;
CUtlString m_LegacyString;
CUtlString m_OutputString;
CUtlVector< PropertyOrdinal_t > m_Ordinals;
int m_nPropertyId;
PropertyType_e m_nType;
bool m_bFixSlashes;
bool m_bEmitAsGlobalProperty;
bool m_bInvertOutput;
bool m_bAppendSlash;
bool m_bPreferSemicolonNoComma;
bool m_bPreferSemicolonNoSpace;
};
struct GeneratorTool_t
{
GeneratorTool_t()
{
m_nKeyword = KEYWORD_UNKNOWN;
}
CUtlString m_ParseString;
CUtlVector< ToolProperty_t > m_Properties;
configKeyword_e m_nKeyword;
};
class CGeneratorDefinition
{
public:
CGeneratorDefinition();
void LoadDefinition( const char *pDefinitionName, PropertyName_t *pPropertyNames );
ToolProperty_t *GetProperty( configKeyword_e keyword, const char *pPropertyName );
const char *GetScriptName( CRC32_t *pCRC );
private:
void AssignIdentifiers();
void IterateToolKey( KeyValues *pToolKV );
void IteratePropertyKey( GeneratorTool_t *pTool, KeyValues *pPropertyKV );
void IterateAttributesKey( ToolProperty_t *pProperty, KeyValues *pAttributesKV );
void Clear();
PropertyName_t *m_pPropertyNames;
CUtlString m_ScriptName;
CUtlString m_NameString;
CUtlString m_VersionString;
CUtlVector< GeneratorTool_t > m_Tools;
CRC32_t m_ScriptCRC;
};
#endif // GENERATORDEFINITION_H
+360
View File
@@ -0,0 +1,360 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateProject
//
//-----------------------------------------------------------------------------
projectIndex_t VPC_Group_FindOrCreateProject( const char *pName, bool bCreate )
{
for ( int i = 0; i < g_pVPC->m_Projects.Count(); i++ )
{
if ( !V_stricmp( pName, g_pVPC->m_Projects[i].name.String() ) )
{
return i;
}
}
if ( !bCreate )
return INVALID_INDEX;
int index = g_pVPC->m_Projects.AddToTail();
g_pVPC->m_Projects[index].name = pName;
return index;
}
//-----------------------------------------------------------------------------
// VPC_Group_CreateGroup
//
//-----------------------------------------------------------------------------
groupIndex_t VPC_Group_CreateGroup()
{
groupIndex_t index = g_pVPC->m_Groups.AddToTail();
return index;
}
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateGroupTag
//
//-----------------------------------------------------------------------------
groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate )
{
for (int i=0; i<g_pVPC->m_GroupTags.Count(); i++)
{
if ( !V_stricmp( pName, g_pVPC->m_GroupTags[i].name.String() ) )
return i;
}
if ( !bCreate )
return INVALID_INDEX;
groupTagIndex_t index = g_pVPC->m_GroupTags.AddToTail();
g_pVPC->m_GroupTags[index].name = pName;
return index;
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Games
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Games()
{
const char *pToken;
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) )
{
// end of section
break;
}
else
{
g_pVPC->FindOrCreateConditional( pToken, true, CONDITIONAL_GAME );
}
}
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Group
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Group()
{
const char *pToken;
bool bFirstToken = true;
groupIndex_t groupIndex;
projectIndex_t projectIndex;
groupIndex = VPC_Group_CreateGroup();
while ( 1 )
{
if ( !bFirstToken )
{
pToken = g_pVPC->GetScript().PeekNextToken( false );
if ( !pToken || !pToken[0] )
break;
}
else
{
bFirstToken = false;
}
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
// specified tag now builds this group
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
}
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) )
{
// end of section
break;
}
else
{
projectIndex = VPC_Group_FindOrCreateProject( pToken, false );
if ( projectIndex != INVALID_INDEX )
{
int index = g_pVPC->m_Groups[groupIndex].projects.AddToTail();
g_pVPC->m_Groups[groupIndex].projects[index] = projectIndex;
}
else
{
g_pVPC->VPCWarning( "No Project %s defined, ignoring.", pToken );
continue;
}
}
}
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Project
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Project()
{
const char *pToken;
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( VPC_Group_FindOrCreateProject( pToken, false ) != INVALID_INDEX )
{
// already defined
g_pVPC->VPCWarning( "project %s already defined", pToken );
g_pVPC->VPCSyntaxError();
}
projectIndex_t projectIndex = VPC_Group_FindOrCreateProject( pToken, true );
// create a default group that contains just this project
groupIndex_t groupIndex = VPC_Group_CreateGroup();
g_pVPC->m_Groups[groupIndex].projects.AddToTail( projectIndex );
// create a default tag that matches the project name
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
g_pVPC->m_GroupTags[groupTagIndex].bSameAsProject = true;
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) )
{
// end of section
break;
}
else
{
scriptIndex_t scriptIndex = g_pVPC->m_Projects[projectIndex].scripts.AddToTail();
g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].name = pToken;
pToken = g_pVPC->GetScript().PeekNextToken( false );
if ( pToken && pToken[0] )
{
pToken = g_pVPC->GetScript().GetToken( false );
g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].m_condition = pToken;
}
}
}
}
//-----------------------------------------------------------------------------
// VPC_ParseGroupScript
//
//-----------------------------------------------------------------------------
void VPC_ParseGroupScript( const char *pScriptName )
{
char szScriptName[MAX_PATH];
const char *pToken;
// caller's pointer is aliased
strcpy( szScriptName, pScriptName );
V_FixSlashes( szScriptName );
g_pVPC->VPCStatus( false, "Parsing: %s", szScriptName );
g_pVPC->GetScript().PushScript( szScriptName );
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
{
// end of file
break;
}
if ( !V_stricmp( pToken, "$include" ) )
{
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
{
// end of file
g_pVPC->VPCSyntaxError();
}
// recurse into and run
VPC_ParseGroupScript( pToken );
}
else if ( !V_stricmp( pToken, "$games" ) )
{
VPC_GroupKeyword_Games();
}
else if ( !V_stricmp( pToken, "$group" ) )
{
VPC_GroupKeyword_Group();
}
else if ( !V_stricmp( pToken, "$project" ) )
{
VPC_GroupKeyword_Project();
}
else
{
g_pVPC->VPCSyntaxError();
}
}
g_pVPC->GetScript().PopScript();
}
//-----------------------------------------------------------------------------
// Collect all the +XXX, remove all the -XXX
// This allows removal to be the expected trumping operation.
//-----------------------------------------------------------------------------
void CVPC::GenerateBuildSet( CProjectDependencyGraph &dependencyGraph )
{
// process +XXX commands
for ( int i = 0; i < m_BuildCommands.Count(); i++ )
{
const char *pCommand = m_BuildCommands[i].Get();
if ( pCommand[0] == '-' )
continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
if ( groupTagIndex == INVALID_INDEX )
continue;
groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
CUtlVector<projectIndex_t> projectsToAdd;
for ( int j=0; j<pGroupTag->groups.Count(); j++ )
{
group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
for ( int k=0; k<pGroup->projects.Count(); k++ )
{
projectIndex_t targetProject = pGroup->projects[k];
if ( pCommand[0] == '*' )
{
// Add this project and any projects that depend on it.
if ( !dependencyGraph.HasGeneratedDependencies() )
dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, false );
}
else if ( pCommand[0] == '@' )
{
// Add this project and any projects that it depends on.
if ( !dependencyGraph.HasGeneratedDependencies() )
dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, true );
}
else
{
projectsToAdd.AddToTail( targetProject );
}
}
}
// Add all the projects in the list.
for ( int j=0; j < projectsToAdd.Count(); j++ )
{
projectIndex_t targetProject = projectsToAdd[j];
if ( g_pVPC->m_TargetProjects.Find( targetProject ) == -1 )
{
g_pVPC->m_TargetProjects.AddToTail( targetProject );
}
}
}
// process -XXX commands, explicitly remove tagge projects
for ( int i=0; i<m_BuildCommands.Count(); i++ )
{
const char *pCommand = m_BuildCommands[i].Get();
if ( pCommand[0] == '+' || pCommand[0] == '*' || pCommand[0] == '@' )
continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
if ( groupTagIndex == INVALID_INDEX )
continue;
groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
for ( int j=0; j<pGroupTag->groups.Count(); j++ )
{
group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
for ( int k=0; k<pGroup->projects.Count(); k++ )
{
g_pVPC->m_TargetProjects.FindAndRemove( pGroup->projects[k] );
}
}
}
}
+74
View File
@@ -0,0 +1,74 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef IBASEPROJECTGENERATOR_H
#define IBASEPROJECTGENERATOR_H
#ifdef _WIN32
#pragma once
#endif
//
// Usage:
//
// StartProject
// StartConfigurationBlock
// StartPropertySection
// HandleProperty...
// EndPropertySection
// EndConfigurationBlock
//
// AddFile...
// [inside each file it can do another configuration block as above]
// [also, files can be put in folders with StartFolder/AddFolder]
// EndProject
//
class IBaseProjectGenerator
{
public:
// What file extension does this use? (vcproj, mak, vpj).
virtual const char* GetProjectFileExtension() = 0;
// Called before doing anything in a project (in g_pVPC->GetOutputFilename()).
virtual void StartProject() = 0;
virtual void EndProject() = 0;
// Access the project name.
virtual CUtlString GetProjectName() = 0;
virtual void SetProjectName( const char *pProjectName ) = 0;
// Get a list of all configurations.
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames ) = 0;
// Configuration data is specified in between these calls and inside BeginPropertySection/EndPropertySection.
// If bFileSpecific is set, then the configuration data only applies to the last file added.
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific ) = 0;
virtual void EndConfigurationBlock() = 0;
// These functions are called when it enters a section like $Compiler, $Linker, etc.
// In between the BeginPropertySection/EndPropertySection, it'll call HandleProperty for any properties inside that section.
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip = NULL ) = 0;
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData=NULL ) = 0;
virtual void EndPropertySection( configKeyword_e keyword ) = 0;
// Files go in folders. The generator should maintain a stack of folders as they're added.
virtual void StartFolder( const char *pFolderName ) = 0;
virtual void EndFolder() = 0;
// Add files. Any config blocks/properties between StartFile/EndFile apply to this file only.
// It will only ever have one active file.
virtual bool StartFile( const char *pFilename, bool bWarnIfAlreadyExists ) = 0;
virtual void EndFile() = 0;
// This is actually just per-file configuration data.
virtual void FileExcludedFromBuild( bool bExcluded ) = 0;
virtual void FileIsSchema( bool bIsSchema ) = 0; // Mark the current file as schema.
// Remove the specified file. return true if success
virtual bool RemoveFile( const char *pFilename ) = 0;
};
#endif // IBASEPROJECTGENERATOR_H
+24
View File
@@ -0,0 +1,24 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef IBASESOLUTIONGENERATOR_H
#define IBASESOLUTIONGENERATOR_H
#ifdef _WIN32
#pragma once
#endif
#include "dependencies.h"
class IBaseSolutionGenerator
{
public:
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects ) = 0;
};
#endif // IBASESOLUTIONGENERATOR_H
+120
View File
@@ -0,0 +1,120 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
void CVPC::SetMacro( const char *pName, const char *pValue, bool bSetupDefineInProjectFile )
{
// Setup the macro.
VPCStatus( false, "Set Macro: $%s = %s", pName, pValue );
macro_t *pMacro = FindOrCreateMacro( pName, true, pValue );
pMacro->m_bSetupDefineInProjectFile = bSetupDefineInProjectFile;
pMacro->m_bInternalCreatedMacro = true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
macro_t *CVPC::FindOrCreateMacro( const char *pName, bool bCreate, const char *pValue )
{
for ( int i = 0; i < m_Macros.Count(); i++ )
{
if ( !V_stricmp( pName, m_Macros[i].name.String() ) )
{
if ( pValue && V_stricmp( pValue, m_Macros[i].value.String() ) )
{
// update
m_Macros[i].value = pValue;
}
return &m_Macros[i];
}
}
if ( !bCreate )
{
return NULL;
}
int index = m_Macros.AddToTail();
m_Macros[index].name = pName;
m_Macros[index].value = pValue;
return &m_Macros[index];
}
int CVPC::GetMacrosMarkedForCompilerDefines( CUtlVector< macro_t* > &macroDefines )
{
macroDefines.Purge();
for ( int i = 0; i < m_Macros.Count(); i++ )
{
if ( m_Macros[i].m_bSetupDefineInProjectFile )
{
macroDefines.AddToTail( &m_Macros[i] );
}
}
return macroDefines.Count();
}
void CVPC::ResolveMacrosInString( char const *pString, char *pOutBuff, int outBuffSize )
{
char macroName[MAX_SYSTOKENCHARS];
char buffer1[MAX_SYSTOKENCHARS];
char buffer2[MAX_SYSTOKENCHARS];
int i;
// iterate and resolve user macros until all macros resolved
strcpy( buffer1, pString );
bool bDone;
do
{
bDone = true;
for ( i=0; i<m_Macros.Count(); i++ )
{
sprintf( macroName, "$%s", m_Macros[i].name.String() );
if ( Sys_ReplaceString( buffer1, macroName, m_Macros[i].value.String(), buffer2, sizeof( buffer2 ) ) )
{
bDone = false;
}
strcpy( buffer1, buffer2 );
}
}
while ( !bDone );
int len = strlen( buffer1 );
if ( outBuffSize < len )
len = outBuffSize;
memcpy( pOutBuff, buffer1, len );
pOutBuff[len] = '\0';
}
void CVPC::RemoveScriptCreatedMacros()
{
for ( int i=0; i < m_Macros.Count(); i++ )
{
if ( !m_Macros[i].m_bInternalCreatedMacro )
{
m_Macros.Remove( i );
--i;
}
}
}
const char *CVPC::GetMacroValue( const char *pName )
{
for ( int i = 0; i < m_Macros.Count(); i++ )
{
if ( !V_stricmp( pName, m_Macros[i].name.String() ) )
{
return m_Macros[i].value.String();
}
}
// not found
return "";
}
+2270
View File
File diff suppressed because it is too large Load Diff
+240
View File
@@ -0,0 +1,240 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "p4lib/ip4.h"
// fix filenames that have double backslashes at the start
// (Perforce will return this if the root of a clientspec is e.g. "D:\")
static const char* FixPerforceFilename( const char *filename )
{
if ( filename && Q_strlen( filename ) > 2 && !Q_strnicmp( filename + 1, ":\\\\", 3 ) )
{
// strip out the first backslash
static char newFilename[MAX_PATH];
Q_snprintf( newFilename, sizeof(newFilename), "%c:%s",
filename[0],
&filename[3]
);
return newFilename;
}
return filename;
}
static void GetChangelistFilenames( CUtlVector<int> &changelists, CUtlVector<CUtlString> &changelistFilenames )
{
// P4 interface didn't initalize in main - abort
if ( !p4 )
{
g_pVPC->VPCWarning( "P4SLN: Perforce interface not available. Unable to generate solution from the given Perforce changelist." );
return;
}
CUtlVector<P4File_t> fileList;
int changeListIndex = 0;
if ( changelists.Count() )
{
changeListIndex = changelists[0];
}
if ( changeListIndex == -1 )
{
p4->GetOpenedFileList( fileList, false );
}
else if ( changeListIndex == 0 )
{
p4->GetOpenedFileList( fileList, true );
}
else
{
CUtlVector<P4File_t> partialFileList;
FOR_EACH_VEC( changelists, i )
{
p4->GetFileListInChangelist( changelists[i], partialFileList );
FOR_EACH_VEC( partialFileList, j )
{
fileList.AddToTail( partialFileList[j] );
}
}
}
// If -1 is in the changelist index, then include all.
bool bIncludeAllChangelists = ( changelists.Find( -1 ) != changelists.InvalidIndex() );
for ( int i=0; i < fileList.Count(); i++ )
{
if ( bIncludeAllChangelists || changelists.Find( fileList[i].m_iChangelist ) != changelists.InvalidIndex() )
{
const char *pFilename = p4->String( fileList[i].m_sLocalFile );
const char *pNewFilename = FixPerforceFilename( pFilename );
changelistFilenames.AddToTail( pNewFilename );
}
}
}
static void AddAdditionalDependencies( CUtlVector<CDependency_Project*> &projects, CUtlVector<CDependency_Project*> &allProjects )
{
for ( int nProject=0; nProject < projects.Count(); nProject++ )
{
CDependency_Project *pCurProject = projects[nProject];
// Look at all the $AdditionalProjectDependencies projects for this one.
for ( int nDependency=0; nDependency < pCurProject->m_AdditionalProjectDependencies.Count(); nDependency++ )
{
const char *pLookingFor = pCurProject->m_AdditionalProjectDependencies[nDependency].String();
// Search for a match in allProjects.
int nFound = CDependency_Project::FindByProjectName( allProjects, pLookingFor );
if ( nFound == -1 )
{
g_pVPC->VPCError( "P4SLN: Project %s lists '%s' in its $AdditionalProjectDependencies, but there is no project by that name.", pCurProject->GetName(), pLookingFor );
}
else
{
// Got a match.
CDependency_Project *pFound = allProjects[nFound];
int nTest = projects.Find( pFound );
if ( nTest == projects.InvalidIndex() )
{
projects.AddToTail( pFound );
}
}
}
}
}
static void GetProjectsDependingOnFiles( CProjectDependencyGraph &dependencyGraph, CUtlVector<CUtlString> &filenames, CUtlVector<CDependency_Project*> &projects )
{
// Now figure out the projects that depend on each of these files.
for ( int iFile=0; iFile < filenames.Count(); iFile++ )
{
CDependency *pFile = dependencyGraph.FindDependency( filenames[iFile].String() );
if ( !pFile )
{
char szRelative[MAX_PATH];
if ( !V_MakeRelativePath( filenames[iFile].String(), g_pVPC->GetSourcePath(), szRelative, sizeof( szRelative ) ) )
{
V_strncpy( szRelative, filenames[iFile].String(), sizeof( szRelative ) );
}
// This probably means their build commands on the command line didn't include
// any projects that included this file.
g_pVPC->VPCWarning( "%s is not found in the projects searched.", szRelative );
continue;
}
// Now see which projects depend on this file.
for ( int iProject=0; iProject < dependencyGraph.m_Projects.Count(); iProject++ )
{
CDependency_Project *pProject = dependencyGraph.m_Projects[iProject];
if ( pProject->DependsOn( pFile, k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse | k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagCheckAdditionalDependencies ) )
{
if ( projects.Find( pProject ) == -1 )
projects.AddToTail( pProject );
}
}
}
//
// Make sure that each of the dependent projects are members of the "everything" group
//
// Find the everything group
groupTagIndex_t everythingIndex = VPC_Group_FindOrCreateGroupTag( "everything", false );
if ( everythingIndex != INVALID_INDEX )
{
CUtlVector<int> doomedProjectIndices;
CUtlVector<int> everythingProjectsIndices;
FOR_EACH_VEC( g_pVPC->m_GroupTags[everythingIndex].groups, m )
{
FOR_EACH_VEC( g_pVPC->m_Groups[g_pVPC->m_GroupTags[everythingIndex].groups[m]].projects, n )
{
everythingProjectsIndices.AddToTail( g_pVPC->m_Groups[g_pVPC->m_GroupTags[everythingIndex].groups[m]].projects[n] );
}
}
// Search for each dependency project in the everything group
FOR_EACH_VEC( projects, j )
{
// If it wasn't in the everything group then mark it for removal
if ( everythingProjectsIndices.InvalidIndex() == everythingProjectsIndices.Find( projects[j]->m_iProjectIndex ) )
{
doomedProjectIndices.AddToHead( j );
}
}
// Remove the projects that aren't in the everything solution
FOR_EACH_VEC( doomedProjectIndices, p )
{
projects.Remove( doomedProjectIndices[p] );
}
}
}
static void UpdateProjects( CUtlVector<CDependency_Project*> &projects )
{
for ( int iProject=0; iProject < projects.Count(); iProject++ )
{
Log_Msg( LOG_VPC, "\n" );
CDependency_Project *pDependency = projects[iProject];
pDependency->ExportProjectParameters();
if ( g_pVPC->IsForceGenerate() || !g_pVPC->IsProjectCurrent( g_pVPC->GetOutputFilename() ) )
{
project_t *pProject = &g_pVPC->m_Projects[ pDependency->m_iProjectIndex ];
g_pVPC->SetProjectName( pProject->name.String() );
g_pVPC->SetLoadAddressName( pProject->name.String() );
g_pVPC->ParseProjectScript( pDependency->m_szStoredScriptName, 0, false, true );
}
}
}
void GenerateSolutionForPerforceChangelist( CProjectDependencyGraph &dependencyGraph, CUtlVector<int> &changelists, IBaseSolutionGenerator *pGenerator, const char *pSolutionFilename )
{
// We want to check against ALL projects in projects.vgc.
int nDepFlags = BUILDPROJDEPS_FULL_DEPENDENCY_SET | BUILDPROJDEPS_CHECK_ALL_PROJECTS;
dependencyGraph.BuildProjectDependencies( nDepFlags );
// Get the list of files from Perforce.
CUtlVector<CUtlString> filenames;
GetChangelistFilenames( changelists, filenames );
// Get the list of projects that depend on these files.
CUtlVector<CDependency_Project*> projects;
GetProjectsDependingOnFiles( dependencyGraph, filenames, projects );
// Add g_targetProjects, which will include any other projects that they added on the command line with +tier0 *engine syntax.
CUtlVector<CDependency_Project*> commandLineProjects;
dependencyGraph.TranslateProjectIndicesToDependencyProjects( g_pVPC->m_TargetProjects, commandLineProjects );
for ( int i=0; i < commandLineProjects.Count(); i++ )
{
if ( projects.Find( commandLineProjects[i] ) == projects.InvalidIndex() )
projects.AddToTail( commandLineProjects[i] );
}
// Make sure the latest .vcproj files are generated.
UpdateProjects( projects );
// List the projects.
Msg( "Dependent projects: \n\n" );
for ( int i=0; i < projects.Count(); i++ )
Msg( "%s\n", projects[i]->GetName() );
// Write the solution file.
pGenerator->GenerateSolutionFile( pSolutionFilename, projects );
}
+17
View File
@@ -0,0 +1,17 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef P4SLN_H
#define P4SLN_H
#ifdef _WIN32
#pragma once
#endif
void GenerateSolutionForPerforceChangelist( CProjectDependencyGraph &dependencyGraph, CUtlVector<int> &changelists, IBaseSolutionGenerator *pGenerator, const char *pSolutionFilename );
#endif // P4SLN_H
+706
View File
@@ -0,0 +1,706 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "baseprojectdatacollector.h"
#include "tier1/utlstack.h"
#include "projectgenerator_xcode.h"
extern bool g_bForceGenerate;
static const char *g_pOption_OptimizerLevel = "$OptimizerLevel";
static const char *g_pOption_GameOutputFile = "$GameOutputFile";
static const char *g_pOption_SymbolVisibility = "$SymbolVisibility";
static const char *g_pOption_ConfigurationType = "$ConfigurationType";
static const char *g_pOption_PrecompiledHeader = "$Create/UsePrecompiledHeader";
static const char *g_pOption_UsePCHThroughFile = "$Create/UsePCHThroughFile";
static const char *g_pOption_PrecompiledHeaderFile = "$PrecompiledHeaderFile";
static const char *g_pOption_SystemLibraries = "$SystemLibraries";
static const char *g_pOption_SystemFrameworks = "$SystemFrameworks";
static const char *g_pOption_LocalFrameworks = "$LocalFrameworks";
static const char *g_pOption_ExtraCompilerFlags = "$GCC_ExtraCompilerFlags";
static const char *g_pOption_ExtraLinkerFlags = "$GCC_ExtraLinkerFlags";
static const char *g_pOption_ForceInclude = "$ForceIncludes";
static const char *g_pOption_LowerCaseFileNames = "$LowerCaseFileNames";
static const char *g_pOption_PostBuildEvent = "$PostBuildEvent";
static const char *g_pOption_CommandLine = "$CommandLine";
static const char *g_pOption_Description = "$Description";
static const char *g_pOption_Outputs = "$Outputs";
static const char *k_pszBase_Makefile = "$(SRCROOT)/devtools/makefile_base_posix.mak";
// These are the only properties we care about for makefiles.
static const char *g_pRelevantProperties[] =
{
g_pOption_AdditionalIncludeDirectories,
g_pOption_OptimizerLevel,
g_pOption_OutputFile,
g_pOption_GameOutputFile,
g_pOption_SymbolVisibility,
g_pOption_PreprocessorDefinitions,
g_pOption_ConfigurationType,
g_pOption_ImportLibrary,
g_pOption_PrecompiledHeader,
g_pOption_UsePCHThroughFile,
g_pOption_PrecompiledHeaderFile,
g_pOption_CommandLine,
g_pOption_Outputs,
g_pOption_Description,
g_pOption_SystemLibraries,
g_pOption_SystemFrameworks,
g_pOption_LocalFrameworks,
g_pOption_ExtraCompilerFlags,
g_pOption_ExtraLinkerFlags,
g_pOption_ForceInclude,
};
CRelevantPropertyNames g_RelevantPropertyNames =
{
g_pRelevantProperties,
Q_ARRAYSIZE( g_pRelevantProperties )
};
void MakeFriendlyProjectName( char *pchProject );
void V_MakeAbsoluteCygwinPath( char *pOut, int outLen, const char *pRelativePath )
{
// While generating makefiles under Win32, we must translate drive letters like c:\
// to Cygwin-style paths like /cygdrive/c/
#ifdef _WIN32
char tmp[MAX_PATH];
V_MakeAbsolutePath( tmp, sizeof( tmp ), pRelativePath );
V_FixSlashes( tmp, '/' );
if ( tmp[0] != 0 && tmp[1] == ':' && tmp[2] == '/' )
{
// Ok, this is an absolute path
V_snprintf( pOut, outLen, "/cygdrive/%c/", tmp[0] );
V_strncat( pOut, &tmp[3], outLen );
}
else
#endif // _WIN32
{
V_MakeAbsolutePath( pOut, outLen, pRelativePath );
V_RemoveDotSlashes( pOut );
}
}
static const char* UsePOSIXSlashes( const char *pStr )
{
static char str[2048];
V_strncpy( str, pStr, sizeof( str ) );
V_FixSlashes( str, '/' );
return str;
}
// pExt should be the bare extension without the . in front. i.e. "h", "cpp", "lib".
static inline bool CheckExtension( const char *pFilename, const char *pExt )
{
Assert( pExt[0] != '.' );
int nFilenameLen = V_strlen( pFilename );
int nExtensionLen = V_strlen( pExt );
return (nFilenameLen > nExtensionLen && pFilename[nFilenameLen-nExtensionLen-1] == '.' && V_stricmp( &pFilename[nFilenameLen-nExtensionLen], pExt ) == 0 );
}
static bool CheckExtensions( const char *pFilename, const char **ppExtensions )
{
for ( int i=0; ppExtensions[i] != NULL; i++ )
{
if ( CheckExtension( pFilename, ppExtensions[i] ) )
return true;
}
return false;
}
static void GetObjFilenameForFile( const char *pConfigName, const char *pFilename, char *pOut, int maxLen )
{
char sBaseFilename[MAX_PATH];
V_FileBase( pFilename, sBaseFilename, sizeof( sBaseFilename ) );
//V_strlower( sBaseFilename );
const char *pObjExtension = (CheckExtension( pFilename, "cxx" ) ? "oxx" : "o");
V_snprintf( pOut, maxLen, "$(OBJ_DIR)/%s.%s", sBaseFilename, pObjExtension );
}
// This class drastically accelerates looking up which file creates which precompiled header.
class CPrecompiledHeaderAccel
{
public:
void Setup( CUtlDict<CFileConfig*,int> &files, CFileConfig *pBaseConfig )
{
for ( int i=files.First(); i != files.InvalidIndex(); i=files.Next( i ) )
{
CFileConfig *pFile = files[i];
for ( int iSpecific=pFile->m_Configurations.First(); iSpecific != pFile->m_Configurations.InvalidIndex(); iSpecific=pFile->m_Configurations.Next( iSpecific ) )
{
CSpecificConfig *pSpecific = pFile->m_Configurations[iSpecific];
if ( pSpecific->m_bFileExcluded )
continue;
// Does this file create a precompiled header?
const char *pPrecompiledHeaderOption = pSpecific->GetOption( g_pOption_PrecompiledHeader );
if ( pPrecompiledHeaderOption && V_stristr( pPrecompiledHeaderOption, "Create" ) )
{
// Ok, which header do we scan through?
const char *pUsePCHThroughFile = pSpecific->GetOption( g_pOption_UsePCHThroughFile );
if ( !pUsePCHThroughFile )
{
g_pVPC->VPCError( "File %s creates a precompiled header in config %s but no UsePCHThroughFile option specified.", pFile->m_Filename.String(), pSpecific->GetConfigName() );
}
char sLookup[1024];
V_snprintf( sLookup, sizeof( sLookup ), "%s__%s", pSpecific->GetConfigName(), pUsePCHThroughFile );
if ( m_Lookup.Find( sLookup ) != m_Lookup.InvalidIndex() )
{
g_pVPC->VPCError( "File %s has UsePCHThroughFile of %s but another file already does.", pFile->m_Filename.String(), pUsePCHThroughFile );
}
m_Lookup.Insert( sLookup, pFile );
}
}
}
}
CFileConfig* FindFileThatCreatesPrecompiledHeader( const char *pConfigName, const char *pUsePCHThroughFile )
{
char sLookup[1024];
V_snprintf( sLookup, sizeof( sLookup ), "%s__%s", pConfigName, pUsePCHThroughFile );
int i = m_Lookup.Find( sLookup );
if ( i == m_Lookup.InvalidIndex() )
return NULL;
else
return m_Lookup[i];
}
private:
// This indexes whatever file creates a certain precompiled header for a certain config.
// These are indexed as <config name>_<pchthroughfile>.
// So an entry might look like release_cbase.h
CUtlDict<CFileConfig*,int> m_Lookup;
};
class CProjectGenerator_Makefile : public CBaseProjectDataCollector
{
public:
typedef CBaseProjectDataCollector BaseClass;
CProjectGenerator_Makefile() : BaseClass( &g_RelevantPropertyNames )
{
}
virtual void Setup()
{
}
virtual const char* GetProjectFileExtension()
{
return "mak";
}
virtual void EndProject()
{
const char *pMakefileFilename = g_pVPC->GetOutputFilename();
CUtlString strProjectName = GetProjectName();
bool bProjectIsCurrent = g_pVPC->IsProjectCurrent( pMakefileFilename );
if ( g_pVPC->IsForceGenerate() || !bProjectIsCurrent )
{
g_pVPC->VPCStatus( true, "Saving makefile project for: '%s' File: '%s'", strProjectName.String(), g_pVPC->GetOutputFilename() );
WriteMakefile( pMakefileFilename );
}
const char *pTargetPlatformName = g_pVPC->GetTargetPlatformName();
if ( !pTargetPlatformName )
g_pVPC->VPCError( "GetTargetPlatformName failed." );
if ( !V_stricmp( pTargetPlatformName, "OSX32" ) || !V_stricmp( pTargetPlatformName, "OSX64" ) )
{
if ( g_pVPC->IsForceGenerate() || !bProjectIsCurrent )
{
// Write a XCode project as well.
char sFilename[MAX_PATH];
V_StripExtension( g_pVPC->GetOutputFilename(), sFilename, sizeof( sFilename ) );
CProjectGenerator_XCode xcodeGenerator;
xcodeGenerator.GenerateXCodeProject( this, sFilename, pMakefileFilename );
}
extern CUtlVector<CBaseProjectDataCollector*> g_vecPGenerators;
g_vecPGenerators.AddToTail( this );
extern IBaseProjectGenerator *g_pGenerator;
g_pVPC->SetProjectGenerator( new CProjectGenerator_Makefile() );
}
else
{
Term();
}
}
void WriteSourceFilesList( FILE *fp, const char *pListName, const char **pExtensions, const char *pConfigName )
{
fprintf( fp, "%s= \\\n", pListName );
for ( int i=m_Files.First(); i != m_Files.InvalidIndex(); i=m_Files.Next(i) )
{
CFileConfig *pFileConfig = m_Files[i];
if ( pFileConfig->IsExcludedFrom( pConfigName ) )
continue;
const char *pFilename = m_Files[i]->m_Filename.String();
if ( CheckExtensions( pFilename, pExtensions ) )
{
fprintf( fp, " %s \\\n", UsePOSIXSlashes( pFilename ) );
}
}
fprintf( fp, "\n\n" );
}
void WriteNonConfigSpecificStuff( FILE *fp )
{
// NAME
char szName[256];
V_strncpy( szName, m_ProjectName.String(), sizeof(szName) );
MakeFriendlyProjectName( szName );
fprintf( fp, "NAME=%s\n", szName );
// SRCDIR
char sSrcRootRelative[MAX_PATH];
g_pVPC->ResolveMacrosInString( "$SRCDIR", sSrcRootRelative, sizeof( sSrcRootRelative ) );
fprintf( fp, "SRCROOT=%s\n", UsePOSIXSlashes( sSrcRootRelative ) );
// TargetPlatformName
const char *pTargetPlatformName = g_pVPC->GetTargetPlatformName();
if ( !pTargetPlatformName )
g_pVPC->VPCError( "GetTargetPlatformName failed." );
fprintf( fp, "TARGET_PLATFORM=%s\n", pTargetPlatformName );
fprintf( fp, "PWD:=$(shell pwd)\n" );
// Select debug config if no config is specified.
fprintf( fp, "# If no configuration is specified, \"release\" will be used.\n" );
fprintf( fp, "ifeq \"$(CFG)\" \"\"\n" );
fprintf( fp, "CFG=release\n" );
fprintf( fp, "endif\n\n" );
}
void WriteConfigSpecificStuff( CSpecificConfig *pConfig, FILE *fp, CPrecompiledHeaderAccel *pAccel )
{
KeyValues *pKV = pConfig->m_pKV;
fprintf( fp, "#\n#\n# CFG=%s\n#\n#\n\n", pConfig->GetConfigName() );
fprintf( fp, "ifeq \"$(CFG)\" \"%s\"\n\n", pConfig->GetConfigName() );
// GCC_ExtraCompilerFlags
// Hopefully, they don't ever need to use backslashes because we're turning them into forward slashes here.
// If that does become a problem, we can put some token around the pathnames we need to be fixed up and leave the rest alone.
fprintf( fp, "GCC_ExtraCompilerFlags=%s\n", UsePOSIXSlashes( pKV->GetString( g_pOption_ExtraCompilerFlags, "" ) ) );
// GCC_ExtraLinkerFlags
fprintf( fp, "GCC_ExtraLinkerFlags=%s\n", pKV->GetString( g_pOption_ExtraLinkerFlags, "" ) );
// SymbolVisibility
fprintf( fp, "SymbolVisibility=%s\n", pKV->GetString( g_pOption_SymbolVisibility, "hidden" ) );
// OptimizerLevel
fprintf( fp, "OptimizerLevel=%s\n", pKV->GetString( g_pOption_OptimizerLevel, "$(SAFE_OPTFLAGS_GCC_422)" ) );
// system libraries
{
fprintf( fp, "SystemLibraries=" );
{
CSplitString libs( pKV->GetString( g_pOption_SystemLibraries ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
for ( int i=0; i < libs.Count(); i++ )
{
fprintf( fp, "-l%s ", libs[i] );
}
}
if ( !V_stricmp( g_pVPC->GetTargetPlatformName(), "OSX32" ) || !V_stricmp( g_pVPC->GetTargetPlatformName(), "OSX64" ) )
{
char rgchFrameworkCompilerFlags[1024]; rgchFrameworkCompilerFlags[0] = '\0';
CSplitString systemFrameworks( pKV->GetString( g_pOption_SystemFrameworks ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
for ( int i=0; i < systemFrameworks.Count(); i++ )
{
fprintf( fp, "-framework %s ", systemFrameworks[i] );
}
CSplitString localFrameworks( pKV->GetString( g_pOption_LocalFrameworks ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
for ( int i=0; i < localFrameworks.Count(); i++ )
{
char rgchFrameworkName[MAX_PATH];
V_StripExtension( V_UnqualifiedFileName( localFrameworks[i] ), rgchFrameworkName, sizeof( rgchFrameworkName ) );
V_StripFilename( localFrameworks[i] );
fprintf( fp, "-F%s ", localFrameworks[i] );
fprintf( fp, "-framework %s ", rgchFrameworkName );
strcat( rgchFrameworkCompilerFlags, "-F" );
strcat( rgchFrameworkCompilerFlags, localFrameworks[i] );
}
fprintf( fp, "\n" );
if ( rgchFrameworkCompilerFlags[0] )
// the colon here is important - and should probably get percolated to more places in our generated
// makefiles - it means to perform the assignment once, rather than at evaluation time
fprintf( fp, "GCC_ExtraCompilerFlags:=$(GCC_ExtraCompilerFlags) %s\n", rgchFrameworkCompilerFlags );
}
else
fprintf( fp, "\n" );
}
macro_t *pMacro = g_pVPC->FindOrCreateMacro( "_DLL_EXT", false, NULL );
if ( pMacro )
fprintf( fp, "DLL_EXT=%s\n", pMacro->value.String() );
pMacro = g_pVPC->FindOrCreateMacro( "_SYM_EXT", false, NULL );
if ( pMacro )
fprintf( fp, "SYM_EXT=%s\n", pMacro->value.String() );
// ForceIncludes
{
CSplitString outStrings( pKV->GetString( g_pOption_ForceInclude ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
fprintf( fp, "FORCEINCLUDES= " );
for ( int i=0; i < outStrings.Count(); i++ )
{
if ( V_strlen( outStrings[i] ) > 2 )
fprintf( fp, "-include %s ", UsePOSIXSlashes( outStrings[i] ) );
}
}
fprintf( fp, "\n" );
// DEFINES
{
CSplitString outStrings( pKV->GetString( g_pOption_PreprocessorDefinitions ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
fprintf( fp, "DEFINES= " );
for ( int i=0; i < outStrings.Count(); i++ )
{
fprintf( fp, "-D%s ", outStrings[i] );
}
}
// Add VPC macros marked to become defines.
CUtlVector< macro_t* > macroDefines;
g_pVPC->GetMacrosMarkedForCompilerDefines( macroDefines );
for ( int i=0; i < macroDefines.Count(); i++ )
{
macro_t *pMacro = macroDefines[i];
fprintf( fp, "-D%s=%s ", pMacro->name.String(), pMacro->value.String() );
}
fprintf( fp, "\n" );
// INCLUDEDIRS
{
CSplitString outStrings( pKV->GetString( g_pOption_AdditionalIncludeDirectories ), (const char**)g_IncludeSeparators, Q_ARRAYSIZE(g_IncludeSeparators) );
fprintf( fp, "INCLUDEDIRS= " );
for ( int i=0; i < outStrings.Count(); i++ )
{
char sDir[MAX_PATH];
V_strncpy( sDir, outStrings[i], sizeof( sDir ) );
if ( !V_stricmp( sDir, "$(IntDir)" ) )
V_strncpy( sDir, "$(OBJ_DIR)", sizeof( sDir ) );
V_FixSlashes( sDir, '/' );
fprintf( fp, "%s ", sDir );
}
fprintf( fp, "\n" );
}
// CONFTYPE
if ( V_stristr( pKV->GetString( g_pOption_ConfigurationType ), "dll" ) )
{
fprintf( fp, "CONFTYPE=dll\n" );
// Write ImportLibrary for dll (so) builds.
const char *pRelative = pKV->GetString( g_pOption_ImportLibrary, "" );
fprintf( fp, "IMPORTLIBRARY=%s\n", UsePOSIXSlashes( pRelative ) );
// GameOutputFile is where it copies OutputFile to.
fprintf( fp, "GAMEOUTPUTFILE=%s\n", UsePOSIXSlashes( pKV->GetString( g_pOption_GameOutputFile, "" ) ) );
}
else if ( V_stristr( pKV->GetString( g_pOption_ConfigurationType ), "lib" ) )
{
fprintf( fp, "CONFTYPE=lib\n" );
}
else if ( V_stristr( pKV->GetString( g_pOption_ConfigurationType ), "exe" ) )
{
fprintf( fp, "CONFTYPE=exe\n" );
}
else
{
fprintf( fp, "CONFTYPE=***UNKNOWN***\n" );
}
// OutputFile is where it builds to.
char szFixedOutputFile[MAX_PATH];
V_strncpy( szFixedOutputFile, pKV->GetString( g_pOption_OutputFile ), sizeof( szFixedOutputFile ) );
V_FixSlashes( szFixedOutputFile, '/' );
fprintf( fp, "OUTPUTFILE=%s\n", szFixedOutputFile );
fprintf( fp, "\n\n" );
// post build event
char rgchPostBuildCommand[2048]; rgchPostBuildCommand[0] = '\0';
if ( pKV->GetString( g_pOption_CommandLine, NULL ) )
{
V_strncpy( rgchPostBuildCommand, pKV->GetString( g_pOption_CommandLine, NULL ), sizeof( rgchPostBuildCommand ) );
// V_StripPrecedingAndTrailingWhitespace( rgchPostBuildCommand );
}
if ( Q_strlen( rgchPostBuildCommand ) )
fprintf( fp, "POSTBUILDCOMMAND=%s\n", rgchPostBuildCommand );
else
fprintf( fp, "POSTBUILDCOMMAND=true\n" );
fprintf( fp, "\n\n" );
// Write all the filenames.
const char *sSourceFileExtensions[] = {"cpp","cxx","cc","c","mm","cc",NULL};
fprintf( fp, "\n" );
WriteSourceFilesList( fp, "CPPFILES", (const char**)sSourceFileExtensions, pConfig->GetConfigName() );
// LIBFILES
char sImportLibraryFile[MAX_PATH];
const char *pRelative = pKV->GetString( g_pOption_ImportLibrary, "" );
V_strncpy( sImportLibraryFile, UsePOSIXSlashes( pRelative ), sizeof( sImportLibraryFile ) );
V_RemoveDotSlashes( sImportLibraryFile );
fprintf( fp, "LIBFILES = \\\n" );
for ( int i=m_Files.First(); i != m_Files.InvalidIndex(); i=m_Files.Next(i) )
{
CFileConfig *pFileConfig = m_Files[i];
if ( pFileConfig->IsExcludedFrom( pConfig->GetConfigName() ) )
continue;
char szFilename[MAX_PATH];
V_strncpy( szFilename, UsePOSIXSlashes( pFileConfig->m_Filename.String() ), sizeof( szFilename ) );
const char *pFilename = szFilename;
if ( IsLibraryFile( pFilename ) )
{
char *pchFileName = (char*)Q_strrchr( pFilename, '/' ) + 1;
if ( !sImportLibraryFile[0] || Q_stricmp( sImportLibraryFile, pFilename ) ) // only link this as a library if it isn't our own output!
{
char szExt[32];
Q_ExtractFileExtension( pFilename, szExt, sizeof(szExt) );
if ( IsLibraryFile( pFilename ) && (pchFileName-1) && pchFileName[0] == 'l' && pchFileName[1] == 'i' && pchFileName[2] == 'b'
&& szExt[0] != 'a' ) // its a lib ext but not an archive file, link like a library
{
*(pchFileName-1) = 0;
// Cygwin import libraries use ".dll.a", so get rid of any file extensions here.
char *pExt;
while ( 1 )
{
pExt = (char*)Q_strrchr( pchFileName, '.' );
if ( !pExt || Q_strrchr( pchFileName, '/' ) > pExt || Q_strrchr( pchFileName, '\\' ) > pExt )
break;
*pExt = 0;
}
fprintf( fp, " -L%s -l%s \\\n", pFilename, pchFileName + 3 ); // +3 to dodge the lib ext
}
else
{
fprintf( fp, " %s \\\n", pFilename );
}
}
}
}
fprintf( fp, "\n\n" );
fprintf( fp, "LIBFILENAMES = \\\n" );
for ( int i=m_Files.First(); i != m_Files.InvalidIndex(); i=m_Files.Next(i) )
{
CFileConfig *pFileConfig = m_Files[i];
if ( pFileConfig->IsExcludedFrom( pConfig->GetConfigName() ) )
continue;
const char *pFilename = pFileConfig->m_Filename.String();
if ( IsLibraryFile( pFilename ) )
{
if ( !sImportLibraryFile[0] || Q_stricmp( sImportLibraryFile, pFilename ) ) // only link this as a library if it isn't our own output!
{
fprintf( fp, " %s \\\n", UsePOSIXSlashes( pFilename ) );
}
}
}
fprintf( fp, "\n\n" );
// Include the base makefile before the rules to build the .o files.
fprintf( fp, "# Include the base makefile now.\n" );
if ( g_pVPC->FindOrCreateConditional( "POSIX", false, CONDITIONAL_NULL ) )
{
fprintf( fp, "include %s\n\n\n", k_pszBase_Makefile );
}
CUtlVector< CUtlString > otherDependencies;
// Scan the list of files for any generated dependencies so we can pull them up front
for ( int i=m_Files.First(); i != m_Files.InvalidIndex(); i=m_Files.Next(i) )
{
CFileConfig *pFileConfig = m_Files[i];
CSpecificConfig *pFileSpecificData = pFileConfig->GetOrCreateConfig( pConfig->GetConfigName(), pConfig );
if ( pFileConfig->IsExcludedFrom( pConfig->GetConfigName() ) )
{
continue;
}
const char *pCustomBuildCommandLine = pFileSpecificData->GetOption( g_pOption_CommandLine );
const char *pOutputFile = pFileSpecificData->GetOption( g_pOption_Outputs );
if ( pOutputFile && pCustomBuildCommandLine && V_strlen( pCustomBuildCommandLine ) > 0 )
{
char szTempFilename[MAX_PATH];
V_strncpy( szTempFilename, UsePOSIXSlashes( pFileConfig->m_Filename.String() ), sizeof( szTempFilename ) );
const char *pFilename = szTempFilename;
// This file uses a custom build step.
char sFormattedOutputFile[MAX_PATH];
char szAbsPath[MAX_PATH];
V_MakeAbsolutePath( szAbsPath, sizeof(szAbsPath), pFilename );
DoStandardVisualStudioReplacements( pOutputFile, szAbsPath, sFormattedOutputFile, sizeof( sFormattedOutputFile ) );
CSplitString outFiles( sFormattedOutputFile, ";" );
for ( int i = 0; i < outFiles.Count(); i ++ )
{
// Remember this as a dependency so the executable will depend on it.
if ( otherDependencies.Find( outFiles[i] ) == otherDependencies.InvalidIndex() )
otherDependencies.AddToTail( outFiles[i] );
}
}
}
WriteOtherDependencies( fp, otherDependencies );
fprintf( fp, "\n\n" );
// Now write the rules to build the .o files.
// .o files go in [project dir]/obj/[config]/[base filename]
for ( int i=m_Files.First(); i != m_Files.InvalidIndex(); i=m_Files.Next(i) )
{
CFileConfig *pFileConfig = m_Files[i];
CSpecificConfig *pFileSpecificData = pFileConfig->GetOrCreateConfig( pConfig->GetConfigName(), pConfig );
if ( pFileConfig->IsExcludedFrom( pConfig->GetConfigName() ) )
{
continue;
}
char szTempFilename[MAX_PATH];
V_strncpy( szTempFilename, UsePOSIXSlashes( pFileConfig->m_Filename.String() ), sizeof( szTempFilename ) );
const char *pFilename = szTempFilename;
char sAbsFilename[MAX_PATH];
V_strncpy( sAbsFilename, pFilename, sizeof( sAbsFilename ) );
// Custom build steps??
const char *pCustomBuildCommandLine = pFileSpecificData->GetOption( g_pOption_CommandLine );
const char *pOutputFile = pFileSpecificData->GetOption( g_pOption_Outputs );
if ( pOutputFile && pCustomBuildCommandLine && V_strlen( pCustomBuildCommandLine ) > 0 )
{
// This file uses a custom build step.
char sFormattedOutputFile[MAX_PATH];
char sFormattedCommandLine[8192];
char szAbsPath[MAX_PATH];
V_MakeAbsolutePath( szAbsPath, sizeof(szAbsPath), sAbsFilename );
DoStandardVisualStudioReplacements( pCustomBuildCommandLine, szAbsPath, sFormattedCommandLine, sizeof( sFormattedCommandLine ) );
DoStandardVisualStudioReplacements( pOutputFile, szAbsPath, sFormattedOutputFile, sizeof( sFormattedOutputFile ) );
CSplitString outFiles( sFormattedOutputFile, ";" );
for ( int i = 0; i < outFiles.Count(); i ++ )
{
fprintf( fp, "%s ", outFiles[i] );
}
fprintf( fp, ": %s\n", UsePOSIXSlashes( szAbsPath ) );
const char *pDescription = pFileSpecificData->GetOption( g_pOption_Description );
DoStandardVisualStudioReplacements( pDescription, szAbsPath, sFormattedOutputFile, sizeof( sFormattedOutputFile ) );
fprintf( fp, "\t @echo \"%s\";mkdir -p $(OBJ_DIR) 2> /dev/null;%s\n\n", sFormattedOutputFile, sFormattedCommandLine );
}
else if ( CheckExtensions( pFilename, (const char**)sSourceFileExtensions ) )
{
//V_strlower( sAbsFilename );
char sObjFilename[MAX_PATH];
GetObjFilenameForFile( pConfig->GetConfigName(), pFilename, sObjFilename, sizeof( sObjFilename ) );
// Get the base obj filename for the .P file.
char sPFileBase[MAX_PATH];
V_StripExtension( sObjFilename, sPFileBase, sizeof( sPFileBase ) );
// include the .P file which will include dependency information.
fprintf( fp, "ifneq (clean, $(findstring clean, $(MAKECMDGOALS)))\n" );
fprintf( fp, "\n%s.P: %s $(PWD)/%s %s $(OTHER_DEPENDENCIES)\n", sPFileBase, UsePOSIXSlashes( sAbsFilename ), g_pVPC->GetOutputFilename(),
g_pVPC->FindOrCreateConditional( "POSIX", false, CONDITIONAL_NULL ) == NULL ? "" : k_pszBase_Makefile );
fprintf( fp, "\t$(GEN_DEP_FILE)\n");
fprintf( fp, "\n-include %s.P\n", sPFileBase );
fprintf( fp, "endif\n" );
fprintf( fp, "\n%s : $(PWD)/%s $(PWD)/%s %s\n", sObjFilename, sAbsFilename, g_pVPC->GetOutputFilename(),
g_pVPC->FindOrCreateConditional( "POSIX", false, CONDITIONAL_NULL ) == NULL ? "" : k_pszBase_Makefile );
fprintf( fp, "\t$(PRE_COMPILE_FILE)\n" );
fprintf( fp, "\t$(COMPILE_FILE) $(POST_COMPILE_FILE)\n" );
}
}
fprintf( fp, "\n\nendif # (CFG=%s)\n\n", pConfig->GetConfigName() );
fprintf( fp, "\n\n" );
}
void WriteOtherDependencies( FILE *fp, CUtlVector< CUtlString > &otherDependencies )
{
fprintf( fp, "\nOTHER_DEPENDENCIES = \\\n" );
for ( int i=0; i < otherDependencies.Count(); i++ )
{
fprintf( fp, "\t%s%s\n", otherDependencies[i].String(),
(i == otherDependencies.Count()-1) ? "" : " \\" );
}
fprintf( fp, "\n\n" );
}
void WriteMakefile( const char *pFilename )
{
FILE *fp = fopen( pFilename, "wt" );
CPrecompiledHeaderAccel accel;
accel.Setup( m_Files, &m_BaseConfigData );
// Write all the non-config-specific stuff.
WriteNonConfigSpecificStuff( fp );
// Write each config out.
for ( int i=m_BaseConfigData.m_Configurations.First(); i != m_BaseConfigData.m_Configurations.InvalidIndex(); i=m_BaseConfigData.m_Configurations.Next( i ) )
{
CSpecificConfig *pConfig = m_BaseConfigData.m_Configurations[i];
WriteConfigSpecificStuff( pConfig, fp, &accel );
}
fclose( fp );
}
bool m_bForceLowerCaseFileName;
};
static CProjectGenerator_Makefile g_ProjectGenerator_Makefile;
IBaseProjectGenerator* GetMakefileProjectGenerator()
{
return &g_ProjectGenerator_Makefile;
}
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_PS3_H
#define PROJECTGENERATOR_PS3_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum PS3Properties_e
{
#include "projectgenerator_ps3.inc"
};
class CProjectGenerator_PS3 : public IVCProjWriter
{
public:
CProjectGenerator_PS3();
IBaseProjectGenerator *GetProjectGenerator() { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WritePreBuildEventTool( CPreBuildEventTool *pPreBuildEventTool );
bool WriteCustomBuildTool( CCustomBuildTool *pCustomBuildTool );
bool WriteSNCCompilerTool( CCompilerTool *pCompilerTool );
bool WriteGCCCompilerTool( CCompilerTool *pCompilerTool );
bool WriteSNCLinkerTool( CLinkerTool *pLinkerTool );
bool WriteGCCLinkerTool( CLinkerTool *pLinkerTool );
bool WritePreLinkEventTool( CPreLinkEventTool *pPreLinkEventTool );
bool WriteLibrarianTool( CLibrarianTool *pLibrarianTool );
bool WritePostBuildEventTool( CPostBuildEventTool *pPostBuildEventTool );
const char *BoolStringToTrueFalseString( const char *pValue );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_PS3_H
+138
View File
@@ -0,0 +1,138 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( PS3_GENERAL, ConfigurationType )
PROPERTYNAME( PS3_GENERAL, ExcludedFromBuild )
PROPERTYNAME( PS3_GENERAL, OutputDirectory )
PROPERTYNAME( PS3_GENERAL, IntermediateDirectory )
PROPERTYNAME( PS3_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( PS3_GENERAL, BuildLogFile )
PROPERTYNAME( PS3_GENERAL, SystemIncludeDependencies )
PROPERTYNAME( PS3_GENERAL, SaveDebuggerPropertiesInProject )
// GCC Compiler
PROPERTYNAME( PS3_GCCCOMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( PS3_GCCCOMPILER, PreprocessorDefinitions )
PROPERTYNAME( PS3_GCCCOMPILER, ForceIncludes )
PROPERTYNAME( PS3_GCCCOMPILER, GenerateDebugInformation )
PROPERTYNAME( PS3_GCCCOMPILER, Warnings )
PROPERTYNAME( PS3_GCCCOMPILER, ExtraWarnings )
PROPERTYNAME( PS3_GCCCOMPILER, WarnLoadHitStores )
PROPERTYNAME( PS3_GCCCOMPILER, WarnMicrocodedInstruction )
PROPERTYNAME( PS3_GCCCOMPILER, TreatWarningsAsErrors )
PROPERTYNAME( PS3_GCCCOMPILER, ObjectFileName )
PROPERTYNAME( PS3_GCCCOMPILER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_GCCCOMPILER, SPURSUsage )
PROPERTYNAME( PS3_GCCCOMPILER, OptimizationLevel )
PROPERTYNAME( PS3_GCCCOMPILER, FastMath )
PROPERTYNAME( PS3_GCCCOMPILER, NoStrictAliasing )
PROPERTYNAME( PS3_GCCCOMPILER, UnrollLoops )
PROPERTYNAME( PS3_GCCCOMPILER, InlineFunctionSizeLimit )
PROPERTYNAME( PS3_GCCCOMPILER, TOCUsage )
PROPERTYNAME( PS3_GCCCOMPILER, SaveRestoreFunctions )
PROPERTYNAME( PS3_GCCCOMPILER, GenerateMicrocodedInstructions )
PROPERTYNAME( PS3_GCCCOMPILER, PositionIndependentCode )
PROPERTYNAME( PS3_GCCCOMPILER, FunctionSections )
PROPERTYNAME( PS3_GCCCOMPILER, DataSections )
PROPERTYNAME( PS3_GCCCOMPILER, StackCheck )
PROPERTYNAME( PS3_GCCCOMPILER, CPPExceptionsAndRTTIUsage )
PROPERTYNAME( PS3_GCCCOMPILER, CheckANSICompliance )
PROPERTYNAME( PS3_GCCCOMPILER, DefaultCharSigned )
PROPERTYNAME( PS3_GCCCOMPILER, Permissive )
PROPERTYNAME( PS3_GCCCOMPILER, EnableMSExtensions )
PROPERTYNAME( PS3_GCCCOMPILER, RelaxCPPCompliance )
PROPERTYNAME( PS3_GCCCOMPILER, AdditionalOptions )
// Librarian
PROPERTYNAME( PS3_LIBRARIAN, OutputFile )
PROPERTYNAME( PS3_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( PS3_LIBRARIAN, WholeArchive )
PROPERTYNAME( PS3_LIBRARIAN, LinkLibraryDependencies )
// GCC Linker
PROPERTYNAME( PS3_GCCLINKER, OutputFile )
PROPERTYNAME( PS3_GCCLINKER, AdditionalDependencies )
PROPERTYNAME( PS3_GCCLINKER, AdditionalLibraryDirectories )
PROPERTYNAME( PS3_GCCLINKER, ImportLibrary )
PROPERTYNAME( PS3_GCCLINKER, SPURSUsage )
PROPERTYNAME( PS3_GCCLINKER, PositionIndependentCode )
PROPERTYNAME( PS3_GCCLINKER, EmitRelocations )
PROPERTYNAME( PS3_GCCLINKER, GarbageCollection )
PROPERTYNAME( PS3_GCCLINKER, GenerateMapFile )
PROPERTYNAME( PS3_GCCLINKER, MapFileName )
PROPERTYNAME( PS3_GCCLINKER, LinkLibraryDependencies )
PROPERTYNAME( PS3_GCCLINKER, AdditionalOptions )
// SNC Compiler
PROPERTYNAME( PS3_SNCCOMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( PS3_SNCCOMPILER, PreprocessorDefinitions )
PROPERTYNAME( PS3_SNCCOMPILER, ForceIncludes )
PROPERTYNAME( PS3_SNCCOMPILER, ForcedUsingFiles )
PROPERTYNAME( PS3_SNCCOMPILER, GenerateDebugInformation )
PROPERTYNAME( PS3_SNCCOMPILER, Warnings )
PROPERTYNAME( PS3_SNCCOMPILER, TreatMessagesAsErrors )
PROPERTYNAME( PS3_SNCCOMPILER, DisableSpecificWarnings )
PROPERTYNAME( PS3_SNCCOMPILER, ObjectFileName )
PROPERTYNAME( PS3_SNCCOMPILER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_SNCCOMPILER, OptimizationLevel )
PROPERTYNAME( PS3_SNCCOMPILER, FastMath )
PROPERTYNAME( PS3_SNCCOMPILER, RelaxAliasChecking )
PROPERTYNAME( PS3_SNCCOMPILER, BranchlessCompares )
PROPERTYNAME( PS3_SNCCOMPILER, UnrollLoops )
PROPERTYNAME( PS3_SNCCOMPILER, AssumeAlignedPointers )
PROPERTYNAME( PS3_SNCCOMPILER, AssumeCorrectSign )
PROPERTYNAME( PS3_SNCCOMPILER, TOCPointerPreservation )
PROPERTYNAME( PS3_SNCCOMPILER, InitializedDataPlacement )
PROPERTYNAME( PS3_SNCCOMPILER, PromoteFPConstantsToDoubles )
PROPERTYNAME( PS3_SNCCOMPILER, CCPPDialect )
PROPERTYNAME( PS3_SNCCOMPILER, CPPExceptionsAndRTTIUsage )
PROPERTYNAME( PS3_SNCCOMPILER, DefaultCharUnsigned )
PROPERTYNAME( PS3_SNCCOMPILER, DefaultFPConstantsAsTypeFloat )
PROPERTYNAME( PS3_SNCCOMPILER, BuiltInDefinitionForWCHAR_TType )
PROPERTYNAME( PS3_SNCCOMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( PS3_SNCCOMPILER, PrecompiledHeaderFile )
PROPERTYNAME( PS3_SNCCOMPILER, AdditionalOptions )
// SNC Linker
PROPERTYNAME( PS3_SNCLINKER, OutputFile )
PROPERTYNAME( PS3_SNCLINKER, OutputFormat )
PROPERTYNAME( PS3_SNCLINKER, AdditionalDependencies )
PROPERTYNAME( PS3_SNCLINKER, AdditionalLibraryDirectories )
PROPERTYNAME( PS3_SNCLINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( PS3_SNCLINKER, UsingExceptionHandling )
PROPERTYNAME( PS3_SNCLINKER, TOCPointerElimination )
PROPERTYNAME( PS3_SNCLINKER, ForceSymbolReferences )
PROPERTYNAME( PS3_SNCLINKER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_SNCLINKER, DebugInfoAndSymbolStripping )
PROPERTYNAME( PS3_SNCLINKER, UnusedFunctionAndDataStripping )
PROPERTYNAME( PS3_SNCLINKER, ImportLibrary )
PROPERTYNAME( PS3_SNCLINKER, GenerateMapFile )
PROPERTYNAME( PS3_SNCLINKER, MapFileName )
PROPERTYNAME( PS3_SNCLINKER, LinkLibraryDependencies )
PROPERTYNAME( PS3_SNCLINKER, AdditionalOptions )
// Pre Build
PROPERTYNAME( PS3_PREBUILDEVENT, CommandLine )
PROPERTYNAME( PS3_PREBUILDEVENT, Description )
PROPERTYNAME( PS3_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( PS3_PRELINKEVENT, CommandLine )
PROPERTYNAME( PS3_PRELINKEVENT, Description )
PROPERTYNAME( PS3_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( PS3_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( PS3_POSTBUILDEVENT, Description )
PROPERTYNAME( PS3_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, AdditionalDependencies )
File diff suppressed because it is too large Load Diff
+379
View File
@@ -0,0 +1,379 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef VCPROJGENERATOR_H
#define VCPROJGENERATOR_H
#ifdef _WIN32
#pragma once
#endif
class CProjectConfiguration;
class CVCProjGenerator;
class CProjectTool;
struct PropertyState_t
{
ToolProperty_t *m_pToolProperty;
CUtlString m_OrdinalString;
CUtlString m_StringValue;
};
// ps3 visual studio integration
enum PS3VSIType_e
{
PS3_VSI_TYPE_UNDEFINED = -1,
PS3_VSI_TYPE_SNC = 0,
PS3_VSI_TYPE_GCC = 1,
};
class CProjectFile
{
public:
CProjectFile( CVCProjGenerator *pGenerator, const char *pFilename );
~CProjectFile();
bool GetConfiguration( const char *pConfigName, CProjectConfiguration **ppConfig );
bool AddConfiguration( const char *pConfigName, CProjectConfiguration **ppConfig );
bool RemoveConfiguration( CProjectConfiguration *pConfig );
CUtlString m_Name;
CVCProjGenerator *m_pGenerator;
CUtlVector< CProjectConfiguration* > m_Configs;
};
class CProjectFolder
{
public:
CProjectFolder( CVCProjGenerator *pGenerator, const char *pFolderName );
~CProjectFolder();
bool GetFolder( const char *pFolderName, CProjectFolder **pFolder );
bool AddFolder( const char *pFolderName, CProjectFolder **pFolder );
void AddFile( const char *pFilename, CProjectFile **ppFile );
bool FindFile( const char *pFilename );
bool RemoveFile( const char *pFilename );
CUtlString m_Name;
CVCProjGenerator *m_pGenerator;
CUtlLinkedList< CProjectFolder* > m_Folders;
CUtlLinkedList< CProjectFile* > m_Files;
};
class CPropertyStateLessFunc
{
public:
bool Less( const int& lhs, const int& rhs, void *pContext );
};
class CPropertyStates
{
public:
CPropertyStates();
bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, bool bEnabled );
PropertyState_t *GetProperty( int nPropertyId );
PropertyState_t *GetProperty( const char *pPropertyName );
CUtlVector< PropertyState_t > m_Properties;
CUtlSortVector< int, CPropertyStateLessFunc > m_PropertiesInOutputOrder;
private:
bool SetStringProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetListProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool, bool bEnabled );
bool SetIntegerProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
};
class CProjectTool
{
public:
CProjectTool( CVCProjGenerator *pGenerator )
{
m_pGenerator = pGenerator;
}
CVCProjGenerator *GetGenerator() { return m_pGenerator; }
// when the property belongs to the root tool (i.e. linker), no root tool is passed in
// when the property is for the file's specific configuration tool, (i.e. compiler/debug), the root tool must be supplied
virtual bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
CPropertyStates m_PropertyStates;
private:
CVCProjGenerator *m_pGenerator;
};
class CDebuggingTool : public CProjectTool
{
public:
CDebuggingTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CCompilerTool : public CProjectTool
{
public:
CCompilerTool( CVCProjGenerator *pGenerator, const char *pConfigName, bool bIsFileConfig ) : CProjectTool( pGenerator )
{
m_ConfigName = pConfigName;
m_bIsFileConfig = bIsFileConfig;
}
bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
private:
CUtlString m_ConfigName;
bool m_bIsFileConfig;
};
class CLibrarianTool : public CProjectTool
{
public:
CLibrarianTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CLinkerTool : public CProjectTool
{
public:
CLinkerTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CManifestTool : public CProjectTool
{
public:
CManifestTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CXMLDocGenTool : public CProjectTool
{
public:
CXMLDocGenTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CBrowseInfoTool : public CProjectTool
{
public:
CBrowseInfoTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CResourcesTool : public CProjectTool
{
public:
CResourcesTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CPreBuildEventTool : public CProjectTool
{
public:
CPreBuildEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CPreLinkEventTool : public CProjectTool
{
public:
CPreLinkEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CPostBuildEventTool : public CProjectTool
{
public:
CPostBuildEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CCustomBuildTool : public CProjectTool
{
public:
CCustomBuildTool( CVCProjGenerator *pGenerator, const char *pConfigName, bool bIsFileConfig ) : CProjectTool( pGenerator )
{
m_ConfigName = pConfigName;
m_bIsFileConfig = bIsFileConfig;
}
bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
private:
CUtlString m_ConfigName;
bool m_bIsFileConfig;
};
class CXboxImageTool : public CProjectTool
{
public:
CXboxImageTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CXboxDeploymentTool : public CProjectTool
{
public:
CXboxDeploymentTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CProjectConfiguration
{
public:
CProjectConfiguration( CVCProjGenerator *pGenerator, const char *pConfigName, const char *pFilename );
~CProjectConfiguration();
CDebuggingTool *GetDebuggingTool() { return m_pDebuggingTool; }
CCompilerTool *GetCompilerTool() { return m_pCompilerTool; }
CLibrarianTool *GetLibrarianTool() { return m_pLibrarianTool; }
CLinkerTool *GetLinkerTool() { return m_pLinkerTool; }
CManifestTool *GetManifestTool() { return m_pManifestTool; }
CXMLDocGenTool *GetXMLDocGenTool() { return m_pXMLDocGenTool; }
CBrowseInfoTool *GetBrowseInfoTool() { return m_pBrowseInfoTool; }
CResourcesTool *GetResourcesTool() { return m_pResourcesTool; }
CPreBuildEventTool *GetPreBuildEventTool() { return m_pPreBuildEventTool; }
CPreLinkEventTool *GetPreLinkEventTool() { return m_pPreLinkEventTool; }
CPostBuildEventTool *GetPostBuildEventTool() { return m_pPostBuildEventTool; }
CCustomBuildTool *GetCustomBuildTool() { return m_pCustomBuildTool; }
CXboxImageTool *GetXboxImageTool() { return m_pXboxImageTool; }
CXboxDeploymentTool *GetXboxDeploymentTool() { return m_pXboxDeploymentTool; }
bool IsEmpty();
bool SetProperty( ToolProperty_t *pToolProperty );
CVCProjGenerator *m_pGenerator;
// type of config, and config's properties
bool m_bIsFileConfig;
CUtlString m_Name;
CPropertyStates m_PropertyStates;
private:
// the config's tools
CDebuggingTool *m_pDebuggingTool;
CCompilerTool *m_pCompilerTool;
CLibrarianTool *m_pLibrarianTool;
CLinkerTool *m_pLinkerTool;
CManifestTool *m_pManifestTool;
CXMLDocGenTool *m_pXMLDocGenTool;
CBrowseInfoTool *m_pBrowseInfoTool;
CResourcesTool *m_pResourcesTool;
CPreBuildEventTool *m_pPreBuildEventTool;
CPreLinkEventTool *m_pPreLinkEventTool;
CPostBuildEventTool *m_pPostBuildEventTool;
CCustomBuildTool *m_pCustomBuildTool;
CXboxImageTool *m_pXboxImageTool;
CXboxDeploymentTool *m_pXboxDeploymentTool;
};
class IVCProjWriter
{
public:
virtual bool Save( const char *pOutputFilename ) = 0;
};
class CVCProjGenerator : public CBaseProjectDataCollector
{
public:
typedef CBaseProjectDataCollector BaseClass;
CVCProjGenerator();
virtual const char *GetProjectFileExtension();
virtual void StartProject();
virtual void EndProject();
virtual CUtlString GetProjectName();
virtual void SetProjectName( const char *pProjectName );
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames );
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific );
virtual void EndConfigurationBlock();
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip );
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData );
virtual void EndPropertySection( configKeyword_e keyword );
virtual void StartFolder( const char *pFolderName );
virtual void EndFolder();
virtual bool StartFile( const char *pFilename, bool bWarnIfAlreadyExists );
virtual void EndFile();
virtual void FileExcludedFromBuild( bool bExcluded );
virtual bool RemoveFile( const char *pFilename );
CGeneratorDefinition *GetGeneratorDefinition() { return m_pGeneratorDefinition; }
void SetupGeneratorDefinition( IVCProjWriter *pVCProjWriter, const char *pDefinitionName, PropertyName_t *pPropertyNames );
PS3VSIType_e GetVSIType() { return m_VSIType; }
CUtlString GetGUIDString() { return m_GUIDString; }
bool GetRootConfiguration( const char *pConfigName, CProjectConfiguration **pConfig );
CProjectFolder *GetRootFolder() { return m_pRootFolder; }
private:
void Clear();
bool Config_GetConfigurations( const char *pszConfigName );
// returns true if found, false otherwise
bool GetFolder( const char *pFolderName, CProjectFolder *pParentFolder, CProjectFolder **pOutFolder );
// returns true if added, false otherwise (duplicate)
bool AddFolder( const char *pFolderName, CProjectFolder *pParentFolder, CProjectFolder **pOutFolder );
// returns true if found, false otherwise
bool FindFile( const char *pFilename, CProjectFile **pFile );
void AddFileToFolder( const char *pFilename, CProjectFolder *pFolder, bool bWarnIfExists, CProjectFile **pFile );
// returns true if removed, false otherwise (not found)
bool RemoveFileFromFolder( const char *pFilename, CProjectFolder *pFolder );
bool IsConfigurationNameValid( const char *pConfigName );
void SetGUID( const char *pOutputFilename );
configKeyword_e SetPS3VisualStudioIntegrationType( configKeyword_e eKeyword );
void ApplyInternalPreprocessorDefinitions();
private:
configKeyword_e m_nActivePropertySection;
CGeneratorDefinition *m_pGeneratorDefinition;
CDebuggingTool *m_pDebuggingTool;
CCompilerTool *m_pCompilerTool;
CLibrarianTool *m_pLibrarianTool;
CLinkerTool *m_pLinkerTool;
CManifestTool *m_pManifestTool;
CXMLDocGenTool *m_pXMLDocGenTool;
CBrowseInfoTool *m_pBrowseInfoTool;
CResourcesTool *m_pResourcesTool;
CPreBuildEventTool *m_pPreBuildEventTool;
CPreLinkEventTool *m_pPreLinkEventTool;
CPostBuildEventTool *m_pPostBuildEventTool;
CCustomBuildTool *m_pCustomBuildTool;
CXboxImageTool *m_pXboxImageTool;
CXboxDeploymentTool *m_pXboxDeploymentTool;
CProjectConfiguration *m_pConfig;
CProjectConfiguration *m_pFileConfig;
CProjectFile *m_pProjectFile;
CSimplePointerStack< CProjectFolder*, CProjectFolder*, 128 > m_spFolderStack;
CSimplePointerStack< CCompilerTool*, CCompilerTool*, 128 > m_spCompilerStack;
CSimplePointerStack< CCustomBuildTool*, CCustomBuildTool*, 128 > m_spCustomBuildToolStack;
CUtlString m_ProjectName;
CUtlString m_OutputFilename;
CProjectFolder *m_pRootFolder;
CUtlVector< CProjectConfiguration* > m_RootConfigurations;
// primary file dictionary
CUtlRBTree< CProjectFile*, int > m_FileDictionary;
CUtlString m_GUIDString;
IVCProjWriter *m_pVCProjWriter;
// ps3 visual studio integration
PS3VSIType_e m_VSIType;
};
#endif // VCPROJGENERATOR_H
+345
View File
@@ -0,0 +1,345 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Win32PropertyNames[] =
{
#include "projectgenerator_win32.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetWin32ProjectGenerator()
{
static CProjectGenerator_Win32 *s_pProjectGenerator = NULL;
if ( !s_pProjectGenerator )
{
s_pProjectGenerator = new CProjectGenerator_Win32();
}
return s_pProjectGenerator->GetProjectGenerator();
}
CProjectGenerator_Win32::CProjectGenerator_Win32()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( this, "win32_2005.def", s_Win32PropertyNames );
}
bool CProjectGenerator_Win32::WriteFile( CProjectFile *pFile )
{
m_XMLWriter.PushNode( "File" );
m_XMLWriter.Write( CFmtStrMax( "RelativePath=\"%s\"", pFile->m_Name.Get() ) );
m_XMLWriter.Write( ">" );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Win32::WriteFolder( CProjectFolder *pFolder )
{
m_XMLWriter.PushNode( "Filter" );
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", pFolder->m_Name.Get() ) );
m_XMLWriter.Write( ">" );
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex] ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex] ) )
return false;
}
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Win32::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "FileConfiguration" );
}
else
{
m_XMLWriter.PushNode( "Configuration" );
}
const char *pOutputName = "???";
if ( !V_stricmp( pConfig->m_Name.Get(), "debug" ) )
{
pOutputName = "Debug|Win32";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "release" ) )
{
pOutputName = "Release|Win32";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "profile" ) )
{
pOutputName = "Profile|Win32";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "retail" ) )
{
pOutputName = "Retail|Win32";
}
else
{
return false;
}
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", pOutputName ) );
// write configuration properties
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] );
}
m_XMLWriter.Write( ">" );
if ( !WriteTool( "VCPreBuildEventTool", pConfig->GetPreBuildEventTool() ) )
return false;
if ( !WriteTool( "VCCustomBuildTool", pConfig->GetCustomBuildTool() ) )
return false;
if ( !WriteNULLTool( "VCXMLDataGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebServiceProxyGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCMIDLTool", pConfig ) )
return false;
if ( !WriteTool( "VCCLCompilerTool", pConfig->GetCompilerTool() ) )
return false;
if ( !WriteNULLTool( "VCManagedResourceCompilerTool", pConfig ) )
return false;
if ( !WriteTool( "VCResourceCompilerTool", pConfig->GetResourcesTool() ) )
return false;
if ( !WriteTool( "VCPreLinkEventTool", pConfig->GetPreLinkEventTool() ) )
return false;
if ( !WriteTool( "VCLinkerTool", pConfig->GetLinkerTool() ) )
return false;
if ( !WriteTool( "VCLibrarianTool", pConfig->GetLibrarianTool() ) )
return false;
if ( !WriteNULLTool( "VCALinkTool", pConfig ) )
return false;
if ( !WriteTool( "VCManifestTool", pConfig->GetManifestTool() ) )
return false;
if ( !WriteTool( "VCXDCMakeTool", pConfig->GetXMLDocGenTool() ) )
return false;
if ( !WriteTool( "VCBscMakeTool", pConfig->GetBrowseInfoTool() ) )
return false;
if ( !WriteNULLTool( "VCFxCopTool", pConfig ) )
return false;
if ( !pConfig->GetLibrarianTool() )
{
if ( !WriteNULLTool( "VCAppVerifierTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebDeploymentTool", pConfig ) )
return false;
}
if ( !WriteTool( "VCPostBuildEventTool", pConfig->GetPostBuildEventTool() ) )
return false;
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Win32::WriteToXML()
{
m_XMLWriter.PushNode( "VisualStudioProject" );
m_XMLWriter.Write( "ProjectType=\"Visual C++\"" );
m_XMLWriter.Write( "Version=\"8.00\"" );
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", m_pVCProjGenerator->GetProjectName().Get() ) );
m_XMLWriter.Write( CFmtStrMax( "ProjectGUID=\"%s\"", m_pVCProjGenerator->GetGUIDString().Get() ) );
m_XMLWriter.Write( ">" );
m_XMLWriter.PushNode( "Platforms" );
m_XMLWriter.PushNode( "Platform" );
m_XMLWriter.Write( "Name=\"Win32\"" );
m_XMLWriter.PopNode( false );
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "ToolFiles" );
m_XMLWriter.PopNode( true );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
// write the root configurations
m_XMLWriter.PushNode( "Configurations" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "References" );
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "Files" );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pRootFolder->m_Folders[iIndex] ) )
return false;
}
for ( int iIndex = pRootFolder->m_Files.Head(); iIndex != pRootFolder->m_Files.InvalidIndex(); iIndex = pRootFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pRootFolder->m_Files[iIndex] ) )
return false;
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Win32::Save( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename ) )
return false;
bool bValid = WriteToXML();
m_XMLWriter.Close();
return bValid;
}
bool CProjectGenerator_Win32::WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
return true;
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.Write( CFmtStr( "Name=\"%s\"", pToolName ) );
m_XMLWriter.PopNode( false );
return true;
}
bool CProjectGenerator_Win32::WriteTool( const char *pToolName, const CProjectTool *pProjectTool )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.Write( CFmtStr( "Name=\"%s\"", pToolName ) );
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] );
}
m_XMLWriter.PopNode( false );
return true;
}
bool CProjectGenerator_Win32::WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, pOutputValue ) );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
if ( pPropertyState )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, bEnabled ? "true" : "false" ) );
}
break;
case PT_STRING:
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ) ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, pPropertyState->m_StringValue.Get() ) );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Win32: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
+41
View File
@@ -0,0 +1,41 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_WIN32_H
#define PROJECTGENERATOR_WIN32_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Win32Properties_e
{
#include "projectgenerator_win32.inc"
};
class CProjectGenerator_Win32 : public IVCProjWriter
{
public:
CProjectGenerator_Win32();
IBaseProjectGenerator *GetProjectGenerator() { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_WIN32_H
+252
View File
@@ -0,0 +1,252 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( WIN32_GENERAL, ExcludedFromBuild )
PROPERTYNAME( WIN32_GENERAL, OutputDirectory )
PROPERTYNAME( WIN32_GENERAL, IntermediateDirectory )
PROPERTYNAME( WIN32_GENERAL, ConfigurationType )
PROPERTYNAME( WIN32_GENERAL, CharacterSet )
PROPERTYNAME( WIN32_GENERAL, WholeProgramOptimization )
PROPERTYNAME( WIN32_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( WIN32_GENERAL, BuildLogFile )
PROPERTYNAME( WIN32_GENERAL, InheritedProjectPropertySheets )
PROPERTYNAME( WIN32_GENERAL, UseOfMFC )
PROPERTYNAME( WIN32_GENERAL, UseOfATL )
PROPERTYNAME( WIN32_GENERAL, MinimizeCRTUseInATL )
// Debugging
PROPERTYNAME( WIN32_DEBUGGING, Command )
PROPERTYNAME( WIN32_DEBUGGING, CommandArguments )
PROPERTYNAME( WIN32_DEBUGGING, RemoteMachine )
PROPERTYNAME( WIN32_DEBUGGING, WorkingDirectory )
PROPERTYNAME( WIN32_DEBUGGING, Attach )
PROPERTYNAME( WIN32_DEBUGGING, DebuggerType )
PROPERTYNAME( WIN32_DEBUGGING, Environment )
PROPERTYNAME( WIN32_DEBUGGING, MergeEnvironment )
PROPERTYNAME( WIN32_DEBUGGING, SQLDebugging )
// Compiler
PROPERTYNAME( WIN32_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_COMPILER, AdditionalOptions )
PROPERTYNAME( WIN32_COMPILER, Optimization )
PROPERTYNAME( WIN32_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( WIN32_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( WIN32_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( WIN32_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( WIN32_COMPILER, WholeProgramOptimization )
PROPERTYNAME( WIN32_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( WIN32_COMPILER, KeepComments )
PROPERTYNAME( WIN32_COMPILER, EnableStringPooling )
PROPERTYNAME( WIN32_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( WIN32_COMPILER, EnableCPPExceptions )
PROPERTYNAME( WIN32_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( WIN32_COMPILER, SmallerTypeCheck )
PROPERTYNAME( WIN32_COMPILER, RuntimeLibrary )
PROPERTYNAME( WIN32_COMPILER, StructMemberAlignment )
PROPERTYNAME( WIN32_COMPILER, BufferSecurityCheck )
PROPERTYNAME( WIN32_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( WIN32_COMPILER, EnableEnhancedInstructionSet )
PROPERTYNAME( WIN32_COMPILER, FloatingPointModel )
PROPERTYNAME( WIN32_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( WIN32_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( WIN32_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( WIN32_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( WIN32_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( WIN32_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( WIN32_COMPILER, OpenMPSupport )
PROPERTYNAME( WIN32_COMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( WIN32_COMPILER, CreateUsePCHThroughFile )
PROPERTYNAME( WIN32_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( WIN32_COMPILER, ExpandAttributedSource )
PROPERTYNAME( WIN32_COMPILER, AssemblerOutput )
PROPERTYNAME( WIN32_COMPILER, ASMListLocation )
PROPERTYNAME( WIN32_COMPILER, ObjectFileName )
PROPERTYNAME( WIN32_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( WIN32_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( WIN32_COMPILER, EnableBrowseInformation )
PROPERTYNAME( WIN32_COMPILER, BrowseFile )
PROPERTYNAME( WIN32_COMPILER, WarningLevel )
PROPERTYNAME( WIN32_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( WIN32_COMPILER, Detect64bitPortabilityIssues )
PROPERTYNAME( WIN32_COMPILER, SuppressStartupBanner )
PROPERTYNAME( WIN32_COMPILER, DebugInformationFormat )
PROPERTYNAME( WIN32_COMPILER, CompileAs )
PROPERTYNAME( WIN32_COMPILER, ForceIncludes )
PROPERTYNAME( WIN32_COMPILER, ShowIncludes )
PROPERTYNAME( WIN32_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, UseFullPaths )
PROPERTYNAME( WIN32_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( WIN32_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( WIN32_COMPILER, PreschedulingOptimization )
PROPERTYNAME( WIN32_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( WIN32_COMPILER, RegisterReservation )
PROPERTYNAME( WIN32_COMPILER, Stalls )
PROPERTYNAME( WIN32_COMPILER, CallAttributedProfiling )
PROPERTYNAME( WIN32_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( WIN32_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( WIN32_COMPILER, ResolveUsingReferences )
PROPERTYNAME( WIN32_COMPILER, OmitFramePointers )
PROPERTYNAME( WIN32_COMPILER, CallingConvention )
PROPERTYNAME( WIN32_COMPILER, ForceUsing )
PROPERTYNAME( WIN32_COMPILER, ErrorReporting )
// Librarian
PROPERTYNAME( WIN32_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( WIN32_LIBRARIAN, OutputFile )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( WIN32_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( WIN32_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( WIN32_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( WIN32_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( WIN32_LINKER, IgnoreImportLibrary )
PROPERTYNAME( WIN32_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_LINKER, AdditionalOptions )
PROPERTYNAME( WIN32_LINKER, AdditionalDependencies )
PROPERTYNAME( WIN32_LINKER, ShowProgress )
PROPERTYNAME( WIN32_LINKER, OutputFile )
PROPERTYNAME( WIN32_LINKER, Version )
PROPERTYNAME( WIN32_LINKER, EnableIncrementalLinking )
PROPERTYNAME( WIN32_LINKER, SuppressStartupBanner )
PROPERTYNAME( WIN32_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_LINKER, GenerateManifest )
PROPERTYNAME( WIN32_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_LINKER, ModuleDefinitionFile )
PROPERTYNAME( WIN32_LINKER, GenerateDebugInfo )
PROPERTYNAME( WIN32_LINKER, DebuggableAssembly )
PROPERTYNAME( WIN32_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( WIN32_LINKER, GenerateMapFile )
PROPERTYNAME( WIN32_LINKER, MapFileName )
PROPERTYNAME( WIN32_LINKER, SubSystem )
PROPERTYNAME( WIN32_LINKER, EnableLargeAddresses )
PROPERTYNAME( WIN32_LINKER, MapExports )
PROPERTYNAME( WIN32_LINKER, StackReserveSize )
PROPERTYNAME( WIN32_LINKER, StackCommitSize )
PROPERTYNAME( WIN32_LINKER, References )
PROPERTYNAME( WIN32_LINKER, EnableCOMDATFolding )
PROPERTYNAME( WIN32_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( WIN32_LINKER, EntryPoint )
PROPERTYNAME( WIN32_LINKER, NoEntryPoint )
PROPERTYNAME( WIN32_LINKER, SetChecksum )
PROPERTYNAME( WIN32_LINKER, BaseAddress )
PROPERTYNAME( WIN32_LINKER, ImportLibrary )
PROPERTYNAME( WIN32_LINKER, TargetMachine )
PROPERTYNAME( WIN32_LINKER, FixedBaseAddress )
PROPERTYNAME( WIN32_LINKER, ErrorReporting )
PROPERTYNAME( WIN32_LINKER, FunctionOrder )
PROPERTYNAME( WIN32_LINKER, LinkLibraryDependencies )
PROPERTYNAME( WIN32_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( WIN32_LINKER, ForceSymbolReferences )
PROPERTYNAME( WIN32_LINKER, StripPrivateSymbols )
PROPERTYNAME( WIN32_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( WIN32_LINKER, MergeSections )
PROPERTYNAME( WIN32_LINKER, RegisterOutput )
PROPERTYNAME( WIN32_LINKER, AddModuleToAssembly )
PROPERTYNAME( WIN32_LINKER, EmbedManagedResourceFile )
PROPERTYNAME( WIN32_LINKER, DelayLoadedDLLs )
PROPERTYNAME( WIN32_LINKER, AssemblyLinkResource )
PROPERTYNAME( WIN32_LINKER, ManifestFile )
PROPERTYNAME( WIN32_LINKER, AdditionalManifestDependencies )
PROPERTYNAME( WIN32_LINKER, AllowIsolation )
PROPERTYNAME( WIN32_LINKER, HeapReserveSize )
PROPERTYNAME( WIN32_LINKER, HeapCommitSize )
PROPERTYNAME( WIN32_LINKER, TerminalServer )
PROPERTYNAME( WIN32_LINKER, SwapRunFromCD )
PROPERTYNAME( WIN32_LINKER, SwapRunFromNetwork )
PROPERTYNAME( WIN32_LINKER, Driver )
PROPERTYNAME( WIN32_LINKER, OptimizeForWindows98 )
PROPERTYNAME( WIN32_LINKER, MIDLCommands )
PROPERTYNAME( WIN32_LINKER, IgnoreEmbeddedIDL )
PROPERTYNAME( WIN32_LINKER, MergeIDLBaseFileName )
PROPERTYNAME( WIN32_LINKER, TypeLibrary )
PROPERTYNAME( WIN32_LINKER, TypeLibResourceID )
PROPERTYNAME( WIN32_LINKER, TurnOffAssemblyGeneration )
PROPERTYNAME( WIN32_LINKER, DelayLoadedDLL )
PROPERTYNAME( WIN32_LINKER, Profile )
PROPERTYNAME( WIN32_LINKER, CLRThreadAttribute )
PROPERTYNAME( WIN32_LINKER, CLRImageType )
PROPERTYNAME( WIN32_LINKER, KeyFile )
PROPERTYNAME( WIN32_LINKER, KeyContainer )
PROPERTYNAME( WIN32_LINKER, DelaySign )
PROPERTYNAME( WIN32_LINKER, CLRUnmanagedCodeCheck )
// Manifest
PROPERTYNAME( WIN32_MANIFESTTOOL, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, SuppressStartupBanner )
PROPERTYNAME( WIN32_MANIFESTTOOL, VerboseOutput )
PROPERTYNAME( WIN32_MANIFESTTOOL, AssemblyIdentity )
PROPERTYNAME( WIN32_MANIFESTTOOL, UseFAT32WorkAround )
PROPERTYNAME( WIN32_MANIFESTTOOL, AdditionalManifestFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, InputResourceManifests )
PROPERTYNAME( WIN32_MANIFESTTOOL, EmbedManifest )
PROPERTYNAME( WIN32_MANIFESTTOOL, OutputManifestFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, ManifestResourceFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, GenerateCatalogFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, DependencyInformationFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, TypeLibraryFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, RegistrarScriptFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, ComponentFileName )
PROPERTYNAME( WIN32_MANIFESTTOOL, ReplacementsFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, UpdateFileHashes )
PROPERTYNAME( WIN32_MANIFESTTOOL, UpdateFileHashesSearchPath )
PROPERTYNAME( WIN32_MANIFESTTOOL, AdditionalOptions )
// XML Document Generator
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, SuppressStartupBanner )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, ValidateIntelliSense )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, AdditionalDocumentFiles )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, OutputDocumentFile )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, DocumentLibraryDependencies )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, AdditionalOptions )
// Browse Information
PROPERTYNAME( WIN32_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( WIN32_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( WIN32_BROWSEINFORMATION, AdditionalOptions )
// Resources
PROPERTYNAME( WIN32_RESOURCES, PreprocessorDefinitions )
PROPERTYNAME( WIN32_RESOURCES, Culture )
PROPERTYNAME( WIN32_RESOURCES, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_RESOURCES, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_RESOURCES, ShowProgress )
PROPERTYNAME( WIN32_RESOURCES, ResourceFileName )
PROPERTYNAME( WIN32_RESOURCES, AdditionalOptions )
// Pre Build
PROPERTYNAME( WIN32_PREBUILDEVENT, Description )
PROPERTYNAME( WIN32_PREBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( WIN32_PRELINKEVENT, Description )
PROPERTYNAME( WIN32_PRELINKEVENT, CommandLine )
PROPERTYNAME( WIN32_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( WIN32_POSTBUILDEVENT, Description )
PROPERTYNAME( WIN32_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, Outputs )
+604
View File
@@ -0,0 +1,604 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Win32PropertyNames_2010[] =
{
#include "projectgenerator_win32_2010.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetWin32ProjectGenerator_2010()
{
static CProjectGenerator_Win32_2010 *s_pProjectGenerator = NULL;
if ( !s_pProjectGenerator )
{
s_pProjectGenerator = new CProjectGenerator_Win32_2010();
}
return s_pProjectGenerator->GetProjectGenerator();
}
CProjectGenerator_Win32_2010::CProjectGenerator_Win32_2010()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( this, "win32_2010.def", s_Win32PropertyNames_2010 );
}
enum TypeKeyNames_e
{
TKN_LIBRARY = 0,
TKN_INCLUDE,
TKN_COMPILE,
TKN_RESOURCECOMPILE,
TKN_CUSTOMBUILD,
TKN_NONE,
TKN_MAX_COUNT,
};
static const char *s_TypeKeyNames[] =
{
"Library",
"ClInclude",
"ClCompile",
"ResourceCompile",
"CustomBuild",
"None"
};
const char *CProjectGenerator_Win32_2010::GetKeyNameForFile( CProjectFile *pFile )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_TypeKeyNames ) == TKN_MAX_COUNT );
const char *pExtension = V_GetFileExtension( pFile->m_Name.Get() );
const char *pKeyName = s_TypeKeyNames[TKN_NONE];
if ( pExtension )
{
if ( !V_stricmp( pExtension, "cpp" ) || !V_stricmp( pExtension, "cxx" ) || !V_stricmp( pExtension, "c" ) || !V_stricmp( pExtension, "cc" ) )
{
pKeyName = s_TypeKeyNames[TKN_COMPILE];
}
else if ( !V_stricmp( pExtension, "h" ) || !V_stricmp( pExtension, "hxx" ) )
{
pKeyName = s_TypeKeyNames[TKN_INCLUDE];
}
else if ( !V_stricmp( pExtension, "lib" ) )
{
pKeyName = s_TypeKeyNames[TKN_LIBRARY];
}
else if ( !V_stricmp( pExtension, "rc" ) )
{
pKeyName = s_TypeKeyNames[TKN_RESOURCECOMPILE];
}
else
{
if ( pFile->m_Configs.Count() && pFile->m_Configs[0]->GetCustomBuildTool() )
{
pKeyName = s_TypeKeyNames[TKN_CUSTOMBUILD];
}
}
}
return pKeyName;
}
bool CProjectGenerator_Win32_2010::WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration )
{
if ( !pProjectTool )
return true;
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFile( CProjectFile *pFile, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( !pFile->m_Configs.Count() )
{
m_XMLWriter.Write( CFmtStrMax( "<%s Include=\"%s\" />", pKeyName, pFile->m_Name.Get() ) );
}
else
{
m_XMLWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth )
{
if ( !nDepth )
{
m_XMLWriter.PushNode( "ItemGroup" );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex], pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex], pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( !pConfig->m_bIsFileConfig )
{
const char *pTargetPlatformName = g_pVPC->IsPlatformDefined( "win64" ) ? "x64" : "Win32";
m_XMLWriter.PushNode( "PropertyGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"Configuration\"", pConfig->m_Name.Get(), pTargetPlatformName ) );
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( pConfig->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
m_XMLWriter.PopNode( true );
}
else
{
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteTools( CProjectConfiguration *pConfig )
{
const char *pTargetPlatformName = g_pVPC->IsPlatformDefined( "win64" ) ? "x64" : "Win32";
m_XMLWriter.PushNode( "ItemDefinitionGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\"", pConfig->m_Name.Get(), pTargetPlatformName ) );
if ( !WriteTool( "PreBuildEvent", pConfig->GetPreBuildEventTool(), pConfig ) )
return false;
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "ResourceCompile", pConfig->GetResourcesTool(), pConfig ) )
return false;
if ( !WriteTool( "PreLinkEvent", pConfig->GetPreLinkEventTool(), pConfig ) )
return false;
if ( !WriteTool( "Link", pConfig->GetLinkerTool(), pConfig ) )
return false;
if ( !WriteTool( "Lib", pConfig->GetLibrarianTool(), pConfig ) )
return false;
if ( !WriteTool( "Manifest", pConfig->GetManifestTool(), pConfig ) )
return false;
if ( !WriteTool( "Xdcmake", pConfig->GetXMLDocGenTool(), pConfig ) )
return false;
if ( !WriteTool( "Bscmake", pConfig->GetBrowseInfoTool(), pConfig ) )
return false;
if ( !WriteTool( "PostBuildEvent", pConfig->GetPostBuildEventTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Win32_2010::WritePrimaryXML( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename, true ) )
return false;
const char *pTargetPlatformName = g_pVPC->IsPlatformDefined( "win64" ) ? "x64" : "Win32";
m_XMLWriter.PushNode( "Project", "DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
m_XMLWriter.PushNode( "ItemGroup", "Label=\"ProjectConfigurations\"" );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
const char *pPlatformString = "Win32";
if ( g_pVPC->IsPlatformDefined( "WIN64" ) )
pPlatformString = "x64";
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ProjectConfiguration", CFmtStr( "Include=\"%s|%s\"", configurationNames[i].Get(), pTargetPlatformName ) );
m_XMLWriter.WriteLineNode( "Configuration", "", configurationNames[i].Get() );
m_XMLWriter.WriteLineNode( "Platform", "", CFmtStr( "%s", pTargetPlatformName ) );
m_XMLWriter.PopNode( true );
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"Globals\"" );
m_XMLWriter.WriteLineNode( "ProjectName", "", m_pVCProjGenerator->GetProjectName().Get() );
m_XMLWriter.WriteLineNode( "ProjectGuid", "", m_pVCProjGenerator->GetGUIDString().Get() );
m_XMLWriter.PopNode( true );
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />" );
// write the root configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />" );
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionSettings\"" );
m_XMLWriter.PopNode( true );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ImportGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"PropertySheets\"", configurationNames[i].Get(), pTargetPlatformName ) );
m_XMLWriter.Write( "<Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />" );
m_XMLWriter.PopNode( true );
}
m_XMLWriter.Write( "<PropertyGroup Label=\"UserMacros\" />" );
m_XMLWriter.PushNode( "PropertyGroup" );
m_XMLWriter.WriteLineNode( "_ProjectFileVersion", "", "10.0.30319.1" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
for ( int j = 0; j < pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder.Count(); j++ )
{
int sortedIndex = pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder[j];
if ( !pConfiguration->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfiguration->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
if ( !WritePropertyGroupTool( pConfiguration->GetPreBuildEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPreLinkEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLinkerTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLibrarianTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPostBuildEventTool(), pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode( true );
// write the tool configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteTools( pConfiguration ) )
return false;
}
}
// write root folders
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolder( m_pVCProjGenerator->GetRootFolder(), s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />" );
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionTargets\"" );
m_XMLWriter.PopNode( true );
m_XMLWriter.PopNode( true );
m_XMLWriter.Close();
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath )
{
CUtlString parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
MD5Context_t ctx;
unsigned char digest[MD5_DIGEST_LENGTH];
V_memset( &ctx, 0, sizeof( ctx ) );
V_memset( digest, 0, sizeof( digest ) );
MD5Init( &ctx );
MD5Update( &ctx, (unsigned char *)parentPath.Get(), strlen( parentPath.Get() ) );
MD5Final( digest, &ctx );
char szMD5[64];
V_binarytohex( digest, MD5_DIGEST_LENGTH, szMD5, sizeof( szMD5 ) );
V_strupr( szMD5 );
char szGUID[MAX_PATH];
V_snprintf( szGUID, sizeof( szGUID ), "{%8.8s-%4.4s-%4.4s-%4.4s-%12.12s}", szMD5, &szMD5[8], &szMD5[12], &szMD5[16], &szMD5[20] );
m_XMLFilterWriter.PushNode( "Filter", CFmtStr( "Include=\"%s\"", parentPath.Get() ) );
m_XMLFilterWriter.WriteLineNode( "UniqueIdentifier", "", szGUID );
m_XMLFilterWriter.PopNode( true );
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( pParentPath )
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.WriteLineNode( "Filter", "", pParentPath );
m_XMLFilterWriter.PopNode( true );
}
else
{
m_XMLFilterWriter.Write( CFmtStr( "<%s Include=\"%s\" />", pKeyName, pFile->m_Name.Get() ) );
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth )
{
CUtlString parentPath;
if ( pParentPath )
{
parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
}
if ( !nDepth )
{
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFileToSecondaryXML( pFolder->m_Files[iIndex], parentPath.Get(), pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderContentsToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get(), pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLFilterWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteSecondaryXML( const char *pOutputFilename )
{
if ( !m_XMLFilterWriter.Open( pOutputFilename, true ) )
return false;
m_XMLFilterWriter.PushNode( "Project", "ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
// write the root folders
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pRootFolder->m_Folders[iIndex], "" ) )
return false;
}
m_XMLFilterWriter.PopNode( true );
// write folder contents
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolderContentsToSecondaryXML( pRootFolder, NULL, s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLFilterWriter.PopNode( true );
m_XMLFilterWriter.Close();
return true;
}
bool CProjectGenerator_Win32_2010::WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( pToolName, NULL );
}
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pConfig->m_bIsFileConfig )
{
if ( pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
else
{
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration, const char *pConfigName, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.WriteLineNode( pOutputName, "", pOutputValue );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
const char *pCondition = "";
CUtlString conditionString;
if ( bEmitConfiguration )
{
const char *pTargetPlatformName = g_pVPC->IsPlatformDefined( "win64" ) ? "x64" : "Win32";
conditionString = CFmtStr( " Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\"", pConfigName, pTargetPlatformName );
pCondition = conditionString.Get();
}
if ( pPropertyState )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.WriteLineNode( pOutputName, pCondition, bEnabled ? "true" : "false" );
}
break;
case PT_STRING:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, pPropertyState->m_StringValue.Get() );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Win32_2010: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
bool CProjectGenerator_Win32_2010::Save( const char *pOutputFilename )
{
bool bValid = WritePrimaryXML( pOutputFilename );
if ( bValid )
{
bValid = WriteSecondaryXML( CFmtStr( "%s.filters", pOutputFilename ) );
if ( !bValid )
{
g_pVPC->VPCError( "Cannot save to the specified project '%s'", pOutputFilename );
}
}
return bValid;
}
+54
View File
@@ -0,0 +1,54 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_WIN32_2010_H
#define PROJECTGENERATOR_WIN32_2010_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Win32_2010_Properties_e
{
#include "projectgenerator_win32_2010.inc"
};
class CProjectGenerator_Win32_2010 : public IVCProjWriter
{
public:
CProjectGenerator_Win32_2010();
IBaseProjectGenerator *GetProjectGenerator() { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
// primary XML - foo.vcxproj
bool WritePrimaryXML( const char *pOutputFilename );
bool WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth );
bool WriteFile( CProjectFile *pFile, const char *pFileTypeName );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteTools( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration = false, const char *pConfigurationName = NULL, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
bool WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration );
bool WritePropertyGroup();
// secondary XML - foo.vcxproj.filters
bool WriteSecondaryXML( const char *pOutputFilename );
bool WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath );
bool WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth );
bool WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName );
const char *GetKeyNameForFile( CProjectFile *pFile );
CXMLWriter m_XMLWriter;
CXMLWriter m_XMLFilterWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_WIN32_2010_H
+299
View File
@@ -0,0 +1,299 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( WIN32_2010_GENERAL, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_GENERAL, OutputDirectory )
PROPERTYNAME( WIN32_2010_GENERAL, IntermediateDirectory )
PROPERTYNAME( WIN32_2010_GENERAL, ConfigurationType )
PROPERTYNAME( WIN32_2010_GENERAL, CharacterSet )
PROPERTYNAME( WIN32_2010_GENERAL, WholeProgramOptimization )
PROPERTYNAME( WIN32_2010_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( WIN32_2010_GENERAL, BuildLogFile )
PROPERTYNAME( WIN32_2010_GENERAL, InheritedProjectPropertySheets )
PROPERTYNAME( WIN32_2010_GENERAL, UseOfMFC )
PROPERTYNAME( WIN32_2010_GENERAL, UseOfATL )
PROPERTYNAME( WIN32_2010_GENERAL, MinimizeCRTUseInATL )
PROPERTYNAME( WIN32_2010_GENERAL, TargetName )
PROPERTYNAME( WIN32_2010_GENERAL, TargetExtension )
PROPERTYNAME( WIN32_2010_GENERAL, PlatformToolset )
PROPERTYNAME( WIN32_2010_GENERAL, PreferredToolArchitecture )
PROPERTYNAME( WIN32_2010_GENERAL, ExecutableDirectories )
// Debugging
PROPERTYNAME( WIN32_2010_DEBUGGING, Command )
PROPERTYNAME( WIN32_2010_DEBUGGING, CommandArguments )
PROPERTYNAME( WIN32_2010_DEBUGGING, RemoteMachine )
PROPERTYNAME( WIN32_2010_DEBUGGING, WorkingDirectory )
PROPERTYNAME( WIN32_2010_DEBUGGING, Attach )
PROPERTYNAME( WIN32_2010_DEBUGGING, DebuggerType )
PROPERTYNAME( WIN32_2010_DEBUGGING, Environment )
PROPERTYNAME( WIN32_2010_DEBUGGING, MergeEnvironment )
PROPERTYNAME( WIN32_2010_DEBUGGING, SQLDebugging )
// Compiler
PROPERTYNAME( WIN32_2010_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_COMPILER, AdditionalOptions )
PROPERTYNAME( WIN32_2010_COMPILER, Optimization )
PROPERTYNAME( WIN32_2010_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( WIN32_2010_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( WIN32_2010_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( WIN32_2010_COMPILER, WholeProgramOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_2010_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( WIN32_2010_COMPILER, KeepComments )
PROPERTYNAME( WIN32_2010_COMPILER, EnableStringPooling )
PROPERTYNAME( WIN32_2010_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( WIN32_2010_COMPILER, EnableCPPExceptions )
PROPERTYNAME( WIN32_2010_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( WIN32_2010_COMPILER, SmallerTypeCheck )
PROPERTYNAME( WIN32_2010_COMPILER, RuntimeLibrary )
PROPERTYNAME( WIN32_2010_COMPILER, StructMemberAlignment )
PROPERTYNAME( WIN32_2010_COMPILER, BufferSecurityCheck )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( WIN32_2010_COMPILER, EnableEnhancedInstructionSet )
PROPERTYNAME( WIN32_2010_COMPILER, FloatingPointModel )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( WIN32_2010_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( WIN32_2010_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( WIN32_2010_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( WIN32_2010_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( WIN32_2010_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( WIN32_2010_COMPILER, OpenMPSupport )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeader )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeaderOutputFile )
PROPERTYNAME( WIN32_2010_COMPILER, ExpandAttributedSource )
PROPERTYNAME( WIN32_2010_COMPILER, AssemblerOutput )
PROPERTYNAME( WIN32_2010_COMPILER, ASMListLocation )
PROPERTYNAME( WIN32_2010_COMPILER, ObjectFileName )
PROPERTYNAME( WIN32_2010_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( WIN32_2010_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( WIN32_2010_COMPILER, EnableBrowseInformation )
PROPERTYNAME( WIN32_2010_COMPILER, BrowseFile )
PROPERTYNAME( WIN32_2010_COMPILER, WarningLevel )
PROPERTYNAME( WIN32_2010_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( WIN32_2010_COMPILER, Detect64bitPortabilityIssues )
PROPERTYNAME( WIN32_2010_COMPILER, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_COMPILER, DebugInformationFormat )
PROPERTYNAME( WIN32_2010_COMPILER, CompileAs )
PROPERTYNAME( WIN32_2010_COMPILER, ForceIncludes )
PROPERTYNAME( WIN32_2010_COMPILER, ShowIncludes )
PROPERTYNAME( WIN32_2010_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, UseFullPaths )
PROPERTYNAME( WIN32_2010_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( WIN32_2010_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, PreschedulingOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, RegisterReservation )
PROPERTYNAME( WIN32_2010_COMPILER, Stalls )
PROPERTYNAME( WIN32_2010_COMPILER, CallAttributedProfiling )
PROPERTYNAME( WIN32_2010_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( WIN32_2010_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( WIN32_2010_COMPILER, ResolveUsingReferences )
PROPERTYNAME( WIN32_2010_COMPILER, OmitFramePointers )
PROPERTYNAME( WIN32_2010_COMPILER, CallingConvention )
PROPERTYNAME( WIN32_2010_COMPILER, ForceUsing )
PROPERTYNAME( WIN32_2010_COMPILER, ErrorReporting )
PROPERTYNAME( WIN32_2010_COMPILER, CommonLanguageRuntimeSupport )
PROPERTYNAME( WIN32_2010_COMPILER, MultiProcessorCompilation )
PROPERTYNAME( WIN32_2010_COMPILER, UseUnicodeForAssemblerListing )
PROPERTYNAME( WIN32_2010_COMPILER, IgnoreStandardIncludePaths )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessToAFile )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessSuppressLineNumbers )
PROPERTYNAME( WIN32_2010_COMPILER, CreateHotpatchableImage )
PROPERTYNAME( WIN32_2010_COMPILER, BrowseInformationFile )
PROPERTYNAME( WIN32_2010_COMPILER, ForcedIncludeFile )
PROPERTYNAME( WIN32_2010_COMPILER, ForcedUsingFile )
PROPERTYNAME( WIN32_2010_COMPILER, OmitDefaultLibraryName )
PROPERTYNAME( WIN32_2010_COMPILER, InternalCompilerErrorReporting )
PROPERTYNAME( WIN32_2010_COMPILER, TreatSpecificWarningsAsErrors )
// Librarian
PROPERTYNAME( WIN32_2010_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_LIBRARIAN, OutputFile )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_2010_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( WIN32_2010_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_2010_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( WIN32_2010_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( WIN32_2010_LINKER, IgnoreImportLibrary )
PROPERTYNAME( WIN32_2010_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalOptions )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_LINKER, ShowProgress )
PROPERTYNAME( WIN32_2010_LINKER, OutputFile )
PROPERTYNAME( WIN32_2010_LINKER, Version )
PROPERTYNAME( WIN32_2010_LINKER, EnableIncrementalLinking )
PROPERTYNAME( WIN32_2010_LINKER, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( WIN32_2010_LINKER, GenerateManifest )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_2010_LINKER, ModuleDefinitionFile )
PROPERTYNAME( WIN32_2010_LINKER, GenerateDebugInfo )
PROPERTYNAME( WIN32_2010_LINKER, DebuggableAssembly )
PROPERTYNAME( WIN32_2010_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( WIN32_2010_LINKER, GenerateMapFile )
PROPERTYNAME( WIN32_2010_LINKER, MapFileName )
PROPERTYNAME( WIN32_2010_LINKER, SubSystem )
PROPERTYNAME( WIN32_2010_LINKER, EnableLargeAddresses )
PROPERTYNAME( WIN32_2010_LINKER, MapExports )
PROPERTYNAME( WIN32_2010_LINKER, StackReserveSize )
PROPERTYNAME( WIN32_2010_LINKER, StackCommitSize )
PROPERTYNAME( WIN32_2010_LINKER, References )
PROPERTYNAME( WIN32_2010_LINKER, EnableCOMDATFolding )
PROPERTYNAME( WIN32_2010_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( WIN32_2010_LINKER, EntryPoint )
PROPERTYNAME( WIN32_2010_LINKER, NoEntryPoint )
PROPERTYNAME( WIN32_2010_LINKER, SetChecksum )
PROPERTYNAME( WIN32_2010_LINKER, BaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, ImportLibrary )
PROPERTYNAME( WIN32_2010_LINKER, TargetMachine )
PROPERTYNAME( WIN32_2010_LINKER, FixedBaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, ErrorReporting )
PROPERTYNAME( WIN32_2010_LINKER, FunctionOrder )
PROPERTYNAME( WIN32_2010_LINKER, LinkLibraryDependencies )
PROPERTYNAME( WIN32_2010_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( WIN32_2010_LINKER, ForceSymbolReferences )
PROPERTYNAME( WIN32_2010_LINKER, StripPrivateSymbols )
PROPERTYNAME( WIN32_2010_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( WIN32_2010_LINKER, MergeSections )
PROPERTYNAME( WIN32_2010_LINKER, RegisterOutput )
PROPERTYNAME( WIN32_2010_LINKER, AddModuleToAssembly )
PROPERTYNAME( WIN32_2010_LINKER, EmbedManagedResourceFile )
PROPERTYNAME( WIN32_2010_LINKER, DelayLoadedDLLs )
PROPERTYNAME( WIN32_2010_LINKER, AssemblyLinkResource )
PROPERTYNAME( WIN32_2010_LINKER, ManifestFile )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalManifestDependencies )
PROPERTYNAME( WIN32_2010_LINKER, AllowIsolation )
PROPERTYNAME( WIN32_2010_LINKER, HeapReserveSize )
PROPERTYNAME( WIN32_2010_LINKER, HeapCommitSize )
PROPERTYNAME( WIN32_2010_LINKER, TerminalServer )
PROPERTYNAME( WIN32_2010_LINKER, SwapRunFromCD )
PROPERTYNAME( WIN32_2010_LINKER, SwapRunFromNetwork )
PROPERTYNAME( WIN32_2010_LINKER, Driver )
PROPERTYNAME( WIN32_2010_LINKER, OptimizeForWindows98 )
PROPERTYNAME( WIN32_2010_LINKER, MIDLCommands )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreEmbeddedIDL )
PROPERTYNAME( WIN32_2010_LINKER, MergeIDLBaseFileName )
PROPERTYNAME( WIN32_2010_LINKER, TypeLibrary )
PROPERTYNAME( WIN32_2010_LINKER, TypeLibResourceID )
PROPERTYNAME( WIN32_2010_LINKER, TurnOffAssemblyGeneration )
PROPERTYNAME( WIN32_2010_LINKER, DelayLoadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, Profile )
PROPERTYNAME( WIN32_2010_LINKER, CLRThreadAttribute )
PROPERTYNAME( WIN32_2010_LINKER, CLRImageType )
PROPERTYNAME( WIN32_2010_LINKER, KeyFile )
PROPERTYNAME( WIN32_2010_LINKER, KeyContainer )
PROPERTYNAME( WIN32_2010_LINKER, DelaySign )
PROPERTYNAME( WIN32_2010_LINKER, CLRUnmanagedCodeCheck )
PROPERTYNAME( WIN32_2010_LINKER, PerUserRedirection )
PROPERTYNAME( WIN32_2010_LINKER, LinkStatus )
PROPERTYNAME( WIN32_2010_LINKER, PreventDllBinding )
PROPERTYNAME( WIN32_2010_LINKER, TreatLinkerWarningsAsErrors )
PROPERTYNAME( WIN32_2010_LINKER, ForceFileOutput )
PROPERTYNAME( WIN32_2010_LINKER, CreateHotpatchableImage )
PROPERTYNAME( WIN32_2010_LINKER, SpecifySectionAttributes )
PROPERTYNAME( WIN32_2010_LINKER, EnableUserAccountControl )
PROPERTYNAME( WIN32_2010_LINKER, UACExecutionLevel )
PROPERTYNAME( WIN32_2010_LINKER, UACBypassUIProtection )
PROPERTYNAME( WIN32_2010_LINKER, MinimumRequiredVersion )
PROPERTYNAME( WIN32_2010_LINKER, RandomizedBaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, DataExecutionPrevention )
PROPERTYNAME( WIN32_2010_LINKER, UnloaddelayloadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, NobinddelayloadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, SectionAlignment )
PROPERTYNAME( WIN32_2010_LINKER, PreserveLastErrorCodeforPInvokeCalls )
PROPERTYNAME( WIN32_2010_LINKER, ImageHasSafeExceptionHandlers )
// Manifest
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, VerboseOutput )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AssemblyIdentity )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UseFAT32WorkAround )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AdditionalManifestFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, InputResourceManifests )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, EmbedManifest )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, OutputManifestFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ManifestResourceFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateCatalogFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, DependencyInformationFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, TypeLibraryFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, RegistrarScriptFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ComponentFileName )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ReplacementsFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UpdateFileHashes )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UpdateFileHashesSearchPath )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AdditionalOptions )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateManifestFromManagedAssembly )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, SuppressDependencyElement )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateCategoryTags )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, EnableDPIAwareness )
// XML Document Generator
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, ValidateIntelliSense )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, AdditionalDocumentFiles )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, OutputDocumentFile )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, DocumentLibraryDependencies )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, AdditionalOptions )
// Browse Information
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, AdditionalOptions )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, PreserveSBRFiles )
// Resources
PROPERTYNAME( WIN32_2010_RESOURCES, PreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_RESOURCES, Culture )
PROPERTYNAME( WIN32_2010_RESOURCES, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_2010_RESOURCES, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_2010_RESOURCES, ShowProgress )
PROPERTYNAME( WIN32_2010_RESOURCES, ResourceFileName )
PROPERTYNAME( WIN32_2010_RESOURCES, AdditionalOptions )
// Pre Build
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, Description )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, UseInBuild )
// Pre Link
PROPERTYNAME( WIN32_2010_PRELINKEVENT, Description )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, UseInBuild )
// Post Build
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, Description )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, UseInBuild )
// Custom Build
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, ExecuteAfter )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, ExecuteBefore )
+345
View File
@@ -0,0 +1,345 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Xbox360PropertyNames[] =
{
#include "projectgenerator_xbox360.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetXbox360ProjectGenerator()
{
static CProjectGenerator_Xbox360 *s_pProjectGenerator = NULL;
if ( !s_pProjectGenerator )
{
s_pProjectGenerator = new CProjectGenerator_Xbox360();
}
return s_pProjectGenerator->GetProjectGenerator();
}
CProjectGenerator_Xbox360::CProjectGenerator_Xbox360()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( this, "xbox360.def", s_Xbox360PropertyNames );
}
bool CProjectGenerator_Xbox360::WriteFile( CProjectFile *pFile )
{
m_XMLWriter.PushNode( "File" );
m_XMLWriter.Write( CFmtStrMax( "RelativePath=\"%s\"", pFile->m_Name.Get() ) );
m_XMLWriter.Write( ">" );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Xbox360::WriteFolder( CProjectFolder *pFolder )
{
m_XMLWriter.PushNode( "Filter" );
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", pFolder->m_Name.Get() ) );
m_XMLWriter.Write( ">" );
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex] ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex] ) )
return false;
}
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Xbox360::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "FileConfiguration" );
}
else
{
m_XMLWriter.PushNode( "Configuration" );
}
const char *pOutputName = "???";
if ( !V_stricmp( pConfig->m_Name.Get(), "debug" ) )
{
pOutputName = "Debug|Xbox 360";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "release" ) )
{
pOutputName = "Release|Xbox 360";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "profile" ) )
{
pOutputName = "Profile|Xbox 360";
}
else if ( !V_stricmp( pConfig->m_Name.Get(), "retail" ) )
{
pOutputName = "Retail|Xbox 360";
}
else
{
return false;
}
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", pOutputName ) );
// write configuration properties
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] );
}
if ( !pConfig->m_bIsFileConfig && pConfig->m_PropertyStates.m_Properties.Count() )
{
WriteProperty( NULL, "UseOfMFC", "-1" );
WriteProperty( NULL, "UseOfATL", "0" );
}
m_XMLWriter.Write( ">" );
if ( !WriteTool( "VCPreBuildEventTool", pConfig->GetPreBuildEventTool() ) )
return false;
if ( !WriteTool( "VCCustomBuildTool", pConfig->GetCustomBuildTool() ) )
return false;
if ( !WriteNULLTool( "VCXMLDataGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebServiceProxyGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCMIDLTool", pConfig ) )
return false;
if ( !WriteTool( "VCCLX360CompilerTool", pConfig->GetCompilerTool() ) )
return false;
if ( !WriteNULLTool( "VCManagedResourceCompilerTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCResourceCompilerTool", pConfig ) )
return false;
if ( !WriteTool( "VCPreLinkEventTool", pConfig->GetPreLinkEventTool() ) )
return false;
if ( !WriteTool( "VCX360LinkerTool", pConfig->GetLinkerTool() ) )
return false;
if ( !WriteTool( "VCLibrarianTool", pConfig->GetLibrarianTool() ) )
return false;
if ( !WriteNULLTool( "VCALinkTool", pConfig ) )
return false;
if ( !WriteTool( "VCX360ImageTool", pConfig->GetXboxImageTool() ) )
return false;
if ( !WriteTool( "VCBscMakeTool", pConfig->GetBrowseInfoTool() ) )
return false;
if ( !WriteTool( "VCX360DeploymentTool", pConfig->GetXboxDeploymentTool() ) )
return false;
if ( !WriteTool( "VCPostBuildEventTool", pConfig->GetPostBuildEventTool() ) )
return false;
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "DebuggerTool" );
m_XMLWriter.PopNode( false );
}
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Xbox360::WriteToXML()
{
m_XMLWriter.PushNode( "VisualStudioProject" );
m_XMLWriter.Write( "ProjectType=\"Visual C++\"" );
m_XMLWriter.Write( "Version=\"8.00\"" );
m_XMLWriter.Write( CFmtStrMax( "Name=\"%s\"", m_pVCProjGenerator->GetProjectName().Get() ) );
m_XMLWriter.Write( CFmtStrMax( "ProjectGUID=\"%s\"", m_pVCProjGenerator->GetGUIDString().Get() ) );
m_XMLWriter.Write( ">" );
m_XMLWriter.PushNode( "Platforms" );
m_XMLWriter.PushNode( "Platform" );
m_XMLWriter.Write( "Name=\"Xbox 360\"" );
m_XMLWriter.PopNode( false );
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "ToolFiles" );
m_XMLWriter.PopNode( true );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
// write the root configurations
m_XMLWriter.PushNode( "Configurations" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "References" );
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "Files" );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pRootFolder->m_Folders[iIndex] ) )
return false;
}
for ( int iIndex = pRootFolder->m_Files.Head(); iIndex != pRootFolder->m_Files.InvalidIndex(); iIndex = pRootFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pRootFolder->m_Files[iIndex] ) )
return false;
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Xbox360::Save( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename ) )
return false;
bool bValid = WriteToXML();
m_XMLWriter.Close();
return bValid;
}
bool CProjectGenerator_Xbox360::WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
return true;
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.Write( CFmtStr( "Name=\"%s\"", pToolName ) );
m_XMLWriter.PopNode( false );
return true;
}
bool CProjectGenerator_Xbox360::WriteTool( const char *pToolName, const CProjectTool *pProjectTool )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.Write( CFmtStr( "Name=\"%s\"", pToolName ) );
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] );
}
m_XMLWriter.PopNode( false );
return true;
}
bool CProjectGenerator_Xbox360::WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, pOutputValue ) );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
if ( pPropertyState )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, bEnabled ? "true" : "false" ) );
}
break;
case PT_STRING:
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ) ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.Write( CFmtStrMax( "%s=\"%s\"", pOutputName, pPropertyState->m_StringValue.Get() ) );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Xbox360: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
+41
View File
@@ -0,0 +1,41 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_XBOX360_H
#define PROJECTGENERATOR_XBOX360_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Xbox360Properties_e
{
#include "projectgenerator_xbox360.inc"
};
class CProjectGenerator_Xbox360 : public IVCProjWriter
{
public:
CProjectGenerator_Xbox360();
IBaseProjectGenerator *GetProjectGenerator() { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_XBOX360_H
+192
View File
@@ -0,0 +1,192 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( XBOX360_GENERAL, ExcludedFromBuild )
PROPERTYNAME( XBOX360_GENERAL, OutputDirectory )
PROPERTYNAME( XBOX360_GENERAL, IntermediateDirectory )
PROPERTYNAME( XBOX360_GENERAL, ConfigurationType )
PROPERTYNAME( XBOX360_GENERAL, CharacterSet )
PROPERTYNAME( XBOX360_GENERAL, WholeProgramOptimization )
PROPERTYNAME( XBOX360_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( XBOX360_GENERAL, BuildLogFile )
PROPERTYNAME( XBOX360_GENERAL, InheritedProjectPropertySheets )
// Debugging
PROPERTYNAME( XBOX360_DEBUGGING, Command )
PROPERTYNAME( XBOX360_DEBUGGING, CommandArguments )
PROPERTYNAME( XBOX360_DEBUGGING, RemoteMachine )
// Compiler
PROPERTYNAME( XBOX360_COMPILER, AdditionalOptions )
PROPERTYNAME( XBOX360_COMPILER, Optimization )
PROPERTYNAME( XBOX360_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( XBOX360_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( XBOX360_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( XBOX360_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( XBOX360_COMPILER, WholeProgramOptimization )
PROPERTYNAME( XBOX360_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( XBOX360_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( XBOX360_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( XBOX360_COMPILER, KeepComments )
PROPERTYNAME( XBOX360_COMPILER, EnableStringPooling )
PROPERTYNAME( XBOX360_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( XBOX360_COMPILER, EnableCPPExceptions )
PROPERTYNAME( XBOX360_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( XBOX360_COMPILER, SmallerTypeCheck )
PROPERTYNAME( XBOX360_COMPILER, RuntimeLibrary )
PROPERTYNAME( XBOX360_COMPILER, StructMemberAlignment )
PROPERTYNAME( XBOX360_COMPILER, BufferSecurityCheck )
PROPERTYNAME( XBOX360_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( XBOX360_COMPILER, FloatingPointModel )
PROPERTYNAME( XBOX360_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( XBOX360_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( XBOX360_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( XBOX360_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( XBOX360_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( XBOX360_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( XBOX360_COMPILER, OpenMPSupport )
PROPERTYNAME( XBOX360_COMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( XBOX360_COMPILER, CreateUsePCHThroughFile )
PROPERTYNAME( XBOX360_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( XBOX360_COMPILER, ExpandAttributedSource )
PROPERTYNAME( XBOX360_COMPILER, AssemblerOutput )
PROPERTYNAME( XBOX360_COMPILER, ASMListLocation )
PROPERTYNAME( XBOX360_COMPILER, ObjectFileName )
PROPERTYNAME( XBOX360_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( XBOX360_COMPILER, EnableBrowseInformation )
PROPERTYNAME( XBOX360_COMPILER, BrowseFile )
PROPERTYNAME( XBOX360_COMPILER, WarningLevel )
PROPERTYNAME( XBOX360_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( XBOX360_COMPILER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_COMPILER, DebugInformationFormat )
PROPERTYNAME( XBOX360_COMPILER, CompileAs )
PROPERTYNAME( XBOX360_COMPILER, ForceIncludes )
PROPERTYNAME( XBOX360_COMPILER, ShowIncludes )
PROPERTYNAME( XBOX360_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, UseFullPaths )
PROPERTYNAME( XBOX360_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( XBOX360_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( XBOX360_COMPILER, PreschedulingOptimization )
PROPERTYNAME( XBOX360_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( XBOX360_COMPILER, RegisterReservation )
PROPERTYNAME( XBOX360_COMPILER, Stalls )
PROPERTYNAME( XBOX360_COMPILER, CallAttributedProfiling )
PROPERTYNAME( XBOX360_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( XBOX360_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( XBOX360_COMPILER, DisableSpecificWarnings )
// Librarian
PROPERTYNAME( XBOX360_LIBRARIAN, OutputFile )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( XBOX360_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( XBOX360_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( XBOX360_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( XBOX360_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( XBOX360_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( XBOX360_LINKER, IgnoreImportLibrary )
PROPERTYNAME( XBOX360_LINKER, AdditionalOptions )
PROPERTYNAME( XBOX360_LINKER, AdditionalDependencies )
PROPERTYNAME( XBOX360_LINKER, ShowProgress )
PROPERTYNAME( XBOX360_LINKER, OutputFile )
PROPERTYNAME( XBOX360_LINKER, EnableIncrementalLinking )
PROPERTYNAME( XBOX360_LINKER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( XBOX360_LINKER, ModuleDefinitionFile )
PROPERTYNAME( XBOX360_LINKER, GenerateDebugInfo )
PROPERTYNAME( XBOX360_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( XBOX360_LINKER, GenerateMapFile )
PROPERTYNAME( XBOX360_LINKER, MapFileName )
PROPERTYNAME( XBOX360_LINKER, MapExports )
PROPERTYNAME( XBOX360_LINKER, StackReserveSize )
PROPERTYNAME( XBOX360_LINKER, StackCommitSize )
PROPERTYNAME( XBOX360_LINKER, References )
PROPERTYNAME( XBOX360_LINKER, EnableCOMDATFolding )
PROPERTYNAME( XBOX360_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( XBOX360_LINKER, EntryPoint )
PROPERTYNAME( XBOX360_LINKER, NoEntryPoint )
PROPERTYNAME( XBOX360_LINKER, SetChecksum )
PROPERTYNAME( XBOX360_LINKER, BaseAddress )
PROPERTYNAME( XBOX360_LINKER, ImportLibrary )
PROPERTYNAME( XBOX360_LINKER, FixedBaseAddress )
PROPERTYNAME( XBOX360_LINKER, ErrorReporting )
PROPERTYNAME( XBOX360_LINKER, FunctionOrder )
PROPERTYNAME( XBOX360_LINKER, Version )
PROPERTYNAME( XBOX360_LINKER, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( XBOX360_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_LINKER, ForceSymbolReferences )
PROPERTYNAME( XBOX360_LINKER, StripPrivateSymbols )
PROPERTYNAME( XBOX360_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( XBOX360_LINKER, MergeSections )
// Browse Information
PROPERTYNAME( XBOX360_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( XBOX360_BROWSEINFORMATION, AdditionalOptions )
// Pre Build
PROPERTYNAME( XBOX360_PREBUILDEVENT, Description )
PROPERTYNAME( XBOX360_PREBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( XBOX360_PRELINKEVENT, Description )
PROPERTYNAME( XBOX360_PRELINKEVENT, CommandLine )
PROPERTYNAME( XBOX360_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( XBOX360_POSTBUILDEVENT, Description )
PROPERTYNAME( XBOX360_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, AdditionalDependencies )
// Image Conversion
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, OutputFile )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, ProjectDefaults )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, WorkspaceSize )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, ExportByName )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, OpticalDiscDriveMapping )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, PAL50Incompatible )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, TitleID )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, LANKey )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, BaseAddress )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, HeapSize )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, AdditionalSections )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, AdditionalOptions )
// Console Deployment
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, SuppressStartupBanner )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentRoot )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentFiles )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, Progress )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, ForceCopy )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentType )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, EmulationType )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, Layout )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, LayoutRoot )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, AdditionalOptions )
+598
View File
@@ -0,0 +1,598 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Xbox360PropertyNames_2010[] =
{
#include "projectgenerator_xbox360_2010.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetXbox360ProjectGenerator_2010()
{
static CProjectGenerator_Xbox360_2010 *s_pProjectGenerator = NULL;
if ( !s_pProjectGenerator )
{
s_pProjectGenerator = new CProjectGenerator_Xbox360_2010();
}
return s_pProjectGenerator->GetProjectGenerator();
}
CProjectGenerator_Xbox360_2010::CProjectGenerator_Xbox360_2010()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( this, "xbox360_2010.def", s_Xbox360PropertyNames_2010 );
}
enum TypeKeyNames_e
{
TKN_LIBRARY = 0,
TKN_INCLUDE,
TKN_COMPILE,
TKN_RESOURCECOMPILE,
TKN_CUSTOMBUILD,
TKN_NONE,
TKN_MAX_COUNT,
};
static const char *s_TypeKeyNames[] =
{
"Library",
"ClInclude",
"ClCompile",
"ResourceCompile",
"CustomBuild",
"None"
};
const char *CProjectGenerator_Xbox360_2010::GetKeyNameForFile( CProjectFile *pFile )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_TypeKeyNames ) == TKN_MAX_COUNT );
const char *pExtension = V_GetFileExtension( pFile->m_Name.Get() );
const char *pKeyName = s_TypeKeyNames[TKN_NONE];
if ( pExtension )
{
if ( !V_stricmp( pExtension, "cpp" ) || !V_stricmp( pExtension, "cxx" ) || !V_stricmp( pExtension, "c" ) || !V_stricmp( pExtension, "cc" ) )
{
pKeyName = s_TypeKeyNames[TKN_COMPILE];
}
else if ( !V_stricmp( pExtension, "h" ) || !V_stricmp( pExtension, "hxx" ) )
{
pKeyName = s_TypeKeyNames[TKN_INCLUDE];
}
else if ( !V_stricmp( pExtension, "lib" ) )
{
pKeyName = s_TypeKeyNames[TKN_LIBRARY];
}
else if ( !V_stricmp( pExtension, "rc" ) )
{
pKeyName = s_TypeKeyNames[TKN_RESOURCECOMPILE];
}
else
{
if ( pFile->m_Configs.Count() && pFile->m_Configs[0]->GetCustomBuildTool() )
{
pKeyName = s_TypeKeyNames[TKN_CUSTOMBUILD];
}
}
}
return pKeyName;
}
bool CProjectGenerator_Xbox360_2010::WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration )
{
if ( !pProjectTool )
return true;
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFile( CProjectFile *pFile, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( !pFile->m_Configs.Count() )
{
m_XMLWriter.Write( CFmtStrMax( "<%s Include=\"%s\" />", pKeyName, pFile->m_Name.Get() ) );
}
else
{
m_XMLWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth )
{
if ( !nDepth )
{
m_XMLWriter.PushNode( "ItemGroup" );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex], pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex], pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "PropertyGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\" Label=\"Configuration\"", pConfig->m_Name.Get() ) );
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( pConfig->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
WriteProperty( NULL, false, NULL, "UseOfAtl", "false" );
m_XMLWriter.PopNode( true );
}
else
{
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteTools( CProjectConfiguration *pConfig )
{
m_XMLWriter.PushNode( "ItemDefinitionGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\"", pConfig->m_Name.Get() ) );
if ( !WriteTool( "PreBuildEvent", pConfig->GetPreBuildEventTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "PreLinkEvent", pConfig->GetPreLinkEventTool(), pConfig ) )
return false;
if ( !WriteTool( "Link", pConfig->GetLinkerTool(), pConfig ) )
return false;
if ( !WriteTool( "Lib", pConfig->GetLibrarianTool(), pConfig ) )
return false;
if ( !WriteTool( "ImageXex", pConfig->GetXboxImageTool(), pConfig ) )
return false;
if ( !WriteTool( "Bscmake", pConfig->GetBrowseInfoTool(), pConfig ) )
return false;
if ( !WriteTool( "Deploy", pConfig->GetXboxDeploymentTool(), pConfig ) )
return false;
if ( !WriteTool( "PostBuildEvent", pConfig->GetPostBuildEventTool(), pConfig ) )
return false;
m_XMLWriter.PopNode( true );
return true;
}
bool CProjectGenerator_Xbox360_2010::WritePrimaryXML( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename, true ) )
return false;
m_XMLWriter.PushNode( "Project", "DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
m_XMLWriter.PushNode( "ItemGroup", "Label=\"ProjectConfigurations\"" );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ProjectConfiguration", CFmtStr( "Include=\"%s|Xbox 360\"", configurationNames[i].Get() ) );
m_XMLWriter.WriteLineNode( "Configuration", "", configurationNames[i].Get() );
m_XMLWriter.WriteLineNode( "Platform", "", "Xbox 360" );
m_XMLWriter.PopNode( true );
}
m_XMLWriter.PopNode( true );
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"Globals\"" );
m_XMLWriter.WriteLineNode( "ProjectName", "", m_pVCProjGenerator->GetProjectName().Get() );
m_XMLWriter.WriteLineNode( "ProjectGuid", "", m_pVCProjGenerator->GetGUIDString().Get() );
m_XMLWriter.PopNode( true );
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />" );
// write the root configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />" );
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionSettings\"" );
m_XMLWriter.PopNode( true );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ImportGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\" Label=\"PropertySheets\"", configurationNames[i].Get() ) );
m_XMLWriter.Write( "<Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />" );
m_XMLWriter.PopNode( true );
}
m_XMLWriter.Write( "<PropertyGroup Label=\"UserMacros\" />" );
m_XMLWriter.PushNode( "PropertyGroup" );
m_XMLWriter.WriteLineNode( "_ProjectFileVersion", "", "10.0.30319.1" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
for ( int j = 0; j < pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder.Count(); j++ )
{
int sortedIndex = pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder[j];
if ( !pConfiguration->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfiguration->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
if ( !WritePropertyGroupTool( pConfiguration->GetPreBuildEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPreLinkEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLinkerTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLibrarianTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPostBuildEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetXboxImageTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetXboxDeploymentTool(), pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode( true );
// write the tool configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteTools( pConfiguration ) )
return false;
}
}
// write root folders
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolder( m_pVCProjGenerator->GetRootFolder(), s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLWriter.Write( "<Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />" );
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionTargets\"" );
m_XMLWriter.PopNode( true );
m_XMLWriter.PopNode( true );
m_XMLWriter.Close();
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath )
{
CUtlString parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
MD5Context_t ctx;
unsigned char digest[MD5_DIGEST_LENGTH];
V_memset( &ctx, 0, sizeof( ctx ) );
V_memset( digest, 0, sizeof( digest ) );
MD5Init( &ctx );
MD5Update( &ctx, (unsigned char *)parentPath.Get(), strlen( parentPath.Get() ) );
MD5Final( digest, &ctx );
char szMD5[64];
V_binarytohex( digest, MD5_DIGEST_LENGTH, szMD5, sizeof( szMD5 ) );
V_strupr( szMD5 );
char szGUID[MAX_PATH];
V_snprintf( szGUID, sizeof( szGUID ), "{%8.8s-%4.4s-%4.4s-%4.4s-%12.12s}", szMD5, &szMD5[8], &szMD5[12], &szMD5[16], &szMD5[20] );
m_XMLFilterWriter.PushNode( "Filter", CFmtStr( "Include=\"%s\"", parentPath.Get() ) );
m_XMLFilterWriter.WriteLineNode( "UniqueIdentifier", "", szGUID );
m_XMLFilterWriter.PopNode( true );
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( pParentPath )
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.WriteLineNode( "Filter", "", pParentPath );
m_XMLFilterWriter.PopNode( true );
}
else
{
m_XMLFilterWriter.Write( CFmtStr( "<%s Include=\"%s\" />", pKeyName, pFile->m_Name.Get() ) );
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth )
{
CUtlString parentPath;
if ( pParentPath )
{
parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
}
if ( !nDepth )
{
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFileToSecondaryXML( pFolder->m_Files[iIndex], parentPath.Get(), pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderContentsToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get(), pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLFilterWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteSecondaryXML( const char *pOutputFilename )
{
if ( !m_XMLFilterWriter.Open( pOutputFilename, true ) )
return false;
m_XMLFilterWriter.PushNode( "Project", "ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
// write the root folders
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pRootFolder->m_Folders[iIndex], "" ) )
return false;
}
m_XMLFilterWriter.PopNode( true );
// write folder contents
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolderContentsToSecondaryXML( pRootFolder, NULL, s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLFilterWriter.PopNode( true );
m_XMLFilterWriter.Close();
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( pToolName, NULL );
}
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pConfig->m_bIsFileConfig )
{
if ( pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
else
{
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PopNode( true );
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration, const char *pConfigName, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.WriteLineNode( pOutputName, "", pOutputValue );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
const char *pCondition = "";
CUtlString conditionString;
if ( bEmitConfiguration )
{
conditionString = CFmtStr( " Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\"", pConfigName );
pCondition = conditionString.Get();
}
if ( pPropertyState )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.WriteLineNode( pOutputName, pCondition, bEnabled ? "true" : "false" );
}
break;
case PT_STRING:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, pPropertyState->m_StringValue.Get() );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Xbox360_2010: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
bool CProjectGenerator_Xbox360_2010::Save( const char *pOutputFilename )
{
bool bValid = WritePrimaryXML( pOutputFilename );
if ( bValid )
{
bValid = WriteSecondaryXML( CFmtStr( "%s.filters", pOutputFilename ) );
if ( !bValid )
{
g_pVPC->VPCError( "Cannot save to the specified project '%s'", pOutputFilename );
}
}
return bValid;
}
+54
View File
@@ -0,0 +1,54 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_XBOX360_2010_H
#define PROJECTGENERATOR_XBOX360_2010_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Xbox360_2010_Properties_e
{
#include "projectgenerator_xbox360_2010.inc"
};
class CProjectGenerator_Xbox360_2010 : public IVCProjWriter
{
public:
CProjectGenerator_Xbox360_2010();
IBaseProjectGenerator *GetProjectGenerator() { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
// primary XML - foo.vcxproj
bool WritePrimaryXML( const char *pOutputFilename );
bool WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth );
bool WriteFile( CProjectFile *pFile, const char *pFileTypeName );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteTools( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration = false, const char *pConfigurationName = NULL, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
bool WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration );
bool WritePropertyGroup();
// secondary XML - foo.vcxproj.filters
bool WriteSecondaryXML( const char *pOutputFilename );
bool WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath );
bool WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth );
bool WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName );
const char *GetKeyNameForFile( CProjectFile *pFile );
CXMLWriter m_XMLWriter;
CXMLWriter m_XMLFilterWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_XBOX360_2010_H
+210
View File
@@ -0,0 +1,210 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( XBOX360_2010_GENERAL, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_GENERAL, OutputDirectory )
PROPERTYNAME( XBOX360_2010_GENERAL, IntermediateDirectory )
PROPERTYNAME( XBOX360_2010_GENERAL, ConfigurationType )
PROPERTYNAME( XBOX360_2010_GENERAL, CharacterSet )
PROPERTYNAME( XBOX360_2010_GENERAL, WholeProgramOptimization )
PROPERTYNAME( XBOX360_2010_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( XBOX360_2010_GENERAL, BuildLogFile )
PROPERTYNAME( XBOX360_2010_GENERAL, PlatformToolset )
// Debugging
PROPERTYNAME( XBOX360_2010_DEBUGGING, Command )
PROPERTYNAME( XBOX360_2010_DEBUGGING, CommandArguments )
PROPERTYNAME( XBOX360_2010_DEBUGGING, RemoteMachine )
PROPERTYNAME( XBOX360_2010_DEBUGGING, MapDVDDrive )
PROPERTYNAME( XBOX360_2010_DEBUGGING, CheckUpToDate )
// Compiler
PROPERTYNAME( XBOX360_2010_COMPILER, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_COMPILER, Optimization )
PROPERTYNAME( XBOX360_2010_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( XBOX360_2010_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( XBOX360_2010_COMPILER, WholeProgramOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, IgnoreStandardIncludePaths )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessToAFile )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessSuppressLineNumbers )
PROPERTYNAME( XBOX360_2010_COMPILER, KeepComments )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableStringPooling )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableCPPExceptions )
PROPERTYNAME( XBOX360_2010_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( XBOX360_2010_COMPILER, RuntimeLibrary )
PROPERTYNAME( XBOX360_2010_COMPILER, StructMemberAlignment )
PROPERTYNAME( XBOX360_2010_COMPILER, BufferSecurityCheck )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( XBOX360_2010_COMPILER, FloatingPointModel )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( XBOX360_2010_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( XBOX360_2010_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( XBOX360_2010_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( XBOX360_2010_COMPILER, OpenMPSupport )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeader )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeaderOutputFile )
PROPERTYNAME( XBOX360_2010_COMPILER, ExpandAttributedSource )
PROPERTYNAME( XBOX360_2010_COMPILER, AssemblerOutput )
PROPERTYNAME( XBOX360_2010_COMPILER, ASMListLocation )
PROPERTYNAME( XBOX360_2010_COMPILER, ObjectFileName )
PROPERTYNAME( XBOX360_2010_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableBrowseInformation )
PROPERTYNAME( XBOX360_2010_COMPILER, BrowseInformationFile )
PROPERTYNAME( XBOX360_2010_COMPILER, WarningLevel )
PROPERTYNAME( XBOX360_2010_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( XBOX360_2010_COMPILER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_COMPILER, DebugInformationFormat )
PROPERTYNAME( XBOX360_2010_COMPILER, CompileAs )
PROPERTYNAME( XBOX360_2010_COMPILER, ForcedIncludeFile )
PROPERTYNAME( XBOX360_2010_COMPILER, ShowIncludes )
PROPERTYNAME( XBOX360_2010_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, UseFullPaths )
PROPERTYNAME( XBOX360_2010_COMPILER, OmitDefaultLibraryName )
PROPERTYNAME( XBOX360_2010_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, PreschedulingOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, RegisterReservation )
PROPERTYNAME( XBOX360_2010_COMPILER, AnalyzeStalls )
PROPERTYNAME( XBOX360_2010_COMPILER, CallAttributedProfiling )
PROPERTYNAME( XBOX360_2010_COMPILER, SmallerTypeCheck )
PROPERTYNAME( XBOX360_2010_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( XBOX360_2010_COMPILER, MultiProcessorCompilation )
PROPERTYNAME( XBOX360_2010_COMPILER, UseUnicodeForAssemblerListing )
PROPERTYNAME( XBOX360_2010_COMPILER, ForcedUsingFile )
PROPERTYNAME( XBOX360_2010_COMPILER, DeduceVariableType )
PROPERTYNAME( XBOX360_2010_COMPILER, CodeAnalysisForCCPP )
PROPERTYNAME( XBOX360_2010_COMPILER, DisabledWarningDirectories )
// Librarian
PROPERTYNAME( XBOX360_2010_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, OutputFile )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreImportLibrary )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_LINKER, ShowProgress )
PROPERTYNAME( XBOX360_2010_LINKER, OutputFile )
PROPERTYNAME( XBOX360_2010_LINKER, Version )
PROPERTYNAME( XBOX360_2010_LINKER, EnableIncrementalLinking )
PROPERTYNAME( XBOX360_2010_LINKER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LINKER, ModuleDefinitionFile )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateDebugInfo )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateMapFile )
PROPERTYNAME( XBOX360_2010_LINKER, MapFileName )
PROPERTYNAME( XBOX360_2010_LINKER, MapExports )
PROPERTYNAME( XBOX360_2010_LINKER, StackCommitSize )
PROPERTYNAME( XBOX360_2010_LINKER, References )
PROPERTYNAME( XBOX360_2010_LINKER, EnableCOMDATFolding )
PROPERTYNAME( XBOX360_2010_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( XBOX360_2010_LINKER, EntryPoint )
PROPERTYNAME( XBOX360_2010_LINKER, NoEntryPoint )
PROPERTYNAME( XBOX360_2010_LINKER, SetChecksum )
PROPERTYNAME( XBOX360_2010_LINKER, BaseAddress )
PROPERTYNAME( XBOX360_2010_LINKER, ImportLibrary )
PROPERTYNAME( XBOX360_2010_LINKER, FixedBaseAddress )
PROPERTYNAME( XBOX360_2010_LINKER, ErrorReporting )
PROPERTYNAME( XBOX360_2010_LINKER, FunctionOrder )
PROPERTYNAME( XBOX360_2010_LINKER, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_2010_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( XBOX360_2010_LINKER, ForceSymbolReferences )
PROPERTYNAME( XBOX360_2010_LINKER, StripPrivateSymbols )
PROPERTYNAME( XBOX360_2010_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( XBOX360_2010_LINKER, MergeSections )
PROPERTYNAME( XBOX360_2010_LINKER, AutomaticModuleDefinitionFile )
// Browse Information
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, PreserveSBRFiles )
// Pre Build
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, Description )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, UseInBuild )
// Pre Link
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, Description )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, UseInBuild )
// Post Build
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, Description )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, UseInBuild )
// Custom Build
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, ExecuteAfter )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, ExecuteBefore )
// Image Conversion
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, ConfigurationFile )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, OutputFile )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, TitleID )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, LANKey )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, BaseAddress )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, HeapSize )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, WorkspaceSize )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AdditionalSections )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, ExportByName )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, OpticalDiscDriveMapping )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, PAL50Incompatible )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, MultidiscTitle )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, PreferBigButtonInput )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, CrossPlatformSystemLink )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AllowAvatarGetMetadataByXUID )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AllowControllerSwapping )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, RequireFullExperience )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, GameVoiceRequiredUI )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, KinectElevationControl )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, SkeletalTrackingRequirement )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AdditionalOptions )
// Console Deployment
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentFiles )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, Progress )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, ForceCopy )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentType )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentRoot )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, EmulationType )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, LayoutFile )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, AdditionalOptions )
+367
View File
@@ -0,0 +1,367 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "projectgenerator_xcode.h"
#ifdef WIN32
#include <direct.h>
#define mkdir(dir, mode) _mkdir(dir)
#define getcwd _getcwd
#endif
static const char *k_pchSource = "Source Files";
static const char *k_pchHeaders = "Header Files";
static const char *k_pchResources = "Resources";
static const char *k_pchVPCFiles = "VPC Files";
static const char *k_pchFrameworksAndLibs = "VPC Files";
void CProjectGenerator_XCode::GenerateXCodeProject( CBaseProjectDataCollector *pCollector, const char *pOutFilename, const char *pMakefileFilename )
{
char sPbxProjFile[MAX_PATH];
sprintf( sPbxProjFile, "%s.xcodeproj", pOutFilename );
mkdir( sPbxProjFile, 0777 );
g_pVPC->VPCStatus( true, "Saving XCode project for: '%s' File: '%s'", pCollector->GetProjectName().String(), sPbxProjFile );
sprintf( sPbxProjFile, "%s.xcodeproj/project.pbxproj", pOutFilename );
m_fp = fopen( sPbxProjFile, "wt" );
m_nIndent = 0;
m_pCollector = pCollector;
m_pMakefileFilename = pMakefileFilename;
WriteHeader();
WriteFileReferences();
WriteFiles();
WriteProject( pMakefileFilename );
//WriteBuildFiles();
WriteBuildConfigurations();
// Write the files list.
WriteTrailer();
fclose( m_fp );
m_fp = NULL;
}
void CProjectGenerator_XCode::Write( const char *pMsg, ... )
{
char sOut[8192];
va_list marker;
va_start( marker, pMsg );
V_vsnprintf( sOut, sizeof( sOut ), pMsg, marker );
va_end( marker );
for ( int i=0; i < m_nIndent; i++ )
fprintf( m_fp, "\t" );
fprintf( m_fp, "%s", sOut );
}
void CProjectGenerator_XCode::WriteHeader()
{
// preamble
Write( "// !$*UTF8*$!\n{\n" );
++m_nIndent;
Write( "archiveVersion = 1;\n" );
Write( "classes = {\n" );
Write( "};\n" );
Write( "objectVersion = 42;\n" );
Write( "objects = {\n" );
}
void CProjectGenerator_XCode::WriteProject( const char *pMakefileFilename )
{
++m_nIndent;
Write( "%024X = {\n", m_pCollector );
++m_nIndent;
Write( "isa = PBXGroup;\n" );
Write( "children = (\n" );
++m_nIndent;
Write( "%024X /* %s */,\n", k_pchSource, k_pchSource );
Write( "%024X /* %s */,\n", k_pchHeaders, k_pchHeaders );
Write( "%024X /* %s */,\n", k_pchResources, k_pchResources );
Write( "%024X /* %s */,\n", k_pchVPCFiles, k_pchVPCFiles );
--m_nIndent;
Write( ");\n" );
Write( "sourceTree = \"<group>\";\n" );
--m_nIndent;
Write( "};" );
--m_nIndent;
Write( "\n/* End PBXGroup section */\n" );
WriteLegacyTargets( pMakefileFilename );
Write( "\n/* Begin PBXProject section */\n" );
Write( "%024X /* Project object */ = {\n", this );
++m_nIndent;
Write( "isa = PBXProject;\n" );
Write( "buildConfigurationList = %024X /* Build configuration list for PBXProject \"%s\" */;\n", &(m_pCollector->m_BaseConfigData), m_pCollector->GetProjectName().String() );
Write( "compatibilityVersion = \"Xcode 2.4\";\n" );
Write( "hasScannedForEncodings = 0;\n" );
Write( "mainGroup = %024X;\n", m_pCollector );
Write( "projectDirPath = \"\";\n" );
char sSrcRootRelative[MAX_PATH];
g_pVPC->ResolveMacrosInString( "$SRCDIR", sSrcRootRelative, sizeof( sSrcRootRelative ) );
V_FixSlashes( sSrcRootRelative, '/' );
Write( "projectRoot = \"%s\";\n", sSrcRootRelative );
Write( "targets = (\n" );
++m_nIndent;
Write( "%024X /* build with make */, \n", &CProjectGenerator_XCode::WriteLegacyTargets );
--m_nIndent;
Write( ");\n" );
--m_nIndent;
Write( "};" );
Write( "\n/* End PBXProject section */\n" );
}
void CProjectGenerator_XCode::WriteBuildFiles()
{
Write( "\n/* Begin PBXBuildFile section */\n" );
for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
{
const char *pFilename = m_pCollector->m_Files[i]->GetName();
Write( "%024X /* %s */ = {isa = PBXBuildFile; fileRef = %024X /* %s */;};\n",
m_pCollector->m_Files[i],
pFilename, m_pCollector->m_Files[i]->GetName(),
pFilename, m_pCollector->m_Files[i]->GetName() );
}
Write( "\n/* End PBXBuildFile section */\n" );
}
void CProjectGenerator_XCode::WriteBuildConfigurations()
{
++m_nIndent;
CUtlVector< CUtlString > configNames;
m_pCollector->GetAllConfigurationNames( configNames );
Write( "\n/* Begin XCBuildConfiguration section */\n" );
FOR_EACH_VEC( configNames, iConfig )
{
Write( "%024X /* %s */ = {\n", &(configNames[iConfig]), configNames[iConfig].String() );
++m_nIndent;
Write( "isa = XCBuildConfiguration;\n" );
Write( "buildSettings = {\n" );
++m_nIndent;
Write( "COPY_PHASE_STRIP = %s;\n", ( V_strstr( configNames[iConfig].String(), "release" ) ? "YES" : "NO" ) );
--m_nIndent;
Write( "};\n" );
Write( "name = %s;\n", configNames[iConfig].String() );
--m_nIndent;
Write( "};\n" );
}
FOR_EACH_VEC( configNames, iConfig )
{
Write( "%024X /* %s */ = {\n", (byte*)&(configNames[iConfig])+1, configNames[iConfig].String() );
++m_nIndent;
Write( "isa = XCBuildConfiguration;\n" );
Write( "buildSettings = {\n" );
++m_nIndent;
Write( "PRODUCT_NAME = \"build with make\";\n" );
Write( "CFG = %s;\n", configNames[iConfig].String() );
--m_nIndent;
Write( "};\n" );
Write( "name = %s;\n", configNames[iConfig].String() );
--m_nIndent;
Write( "};\n" );
}
Write( "\n/* End XCBuildConfiguration section */\n" );
Write( "\n/* Begin XCBuildConfigurationList section */\n" );
Write( "%024X /* Build configuration list for PBXProject \"%s\" */ = {\n", &(m_pCollector->m_BaseConfigData), m_pCollector->GetProjectName().String() );
++m_nIndent;
Write( "isa = XCConfigurationList;\n" );
Write( "buildConfigurations = (\n" );
++m_nIndent;
FOR_EACH_VEC( configNames, iConfig )
{
Write( "%024X /* %s */,\n", &(configNames[iConfig]), configNames[iConfig].String() );
}
--m_nIndent;
Write( ");\n" );
Write( "defaultConfigurationIsVisible = 0;\n" );
Write( "defaultConfigurationName = %s;\n", configNames[0].String() );
--m_nIndent;
Write( "};\n" );
Write( "%024X /* Build configuration list for PBXLegacyTarget \"build with make\" */ = {\n", (byte*)&(m_pCollector->m_BaseConfigData)+1 );
++m_nIndent;
Write( "isa = XCConfigurationList;\n" );
Write( "buildConfigurations = (\n" );
++m_nIndent;
FOR_EACH_VEC( configNames, iConfig )
{
Write( "%024X /* %s */,\n", (byte*)&(configNames[iConfig])+1, configNames[iConfig].String() );
}
--m_nIndent;
Write( ");\n" );
Write( "defaultConfigurationIsVisible = 0;\n" );
Write( "defaultConfigurationName = %s;\n", configNames[0].String() );
--m_nIndent;
Write( "};" );
Write( "\n/* End XCBuildConfigurationList section */\n" );
--m_nIndent;
}
void CProjectGenerator_XCode::WriteLegacyTargets( const char *pchMakefileName )
{
Write( "\n/* Begin PBXLegacyTarget section */\n" );
++m_nIndent;
Write( "%024X /* build with make */ = {\n", &CProjectGenerator_XCode::WriteLegacyTargets );
++m_nIndent;
Write( "isa = PBXLegacyTarget;\n");
Write( "buildArgumentsString = \"-f %s $(ACTION) MAKE_VERBOSE=1\";\n", pchMakefileName );
Write( "buildConfigurationList = %024X /* Build configuration list for PBXLegacyTarget \"build with make\" */;\n", (byte*)&(m_pCollector->m_BaseConfigData)+1 );
Write( "buildPhases = (\n" );
Write( ");\n" );
Write( "buildToolPath = /usr/bin/make;\n" );
char rgchCurDir[MAX_PATH];
getcwd( rgchCurDir, MAX_PATH );
Write( "buildWorkingDirectory = %s;\n", rgchCurDir );
Write( "dependencies = (\n" );
Write( ");\n");
Write( "name = \"build with make\";\n" );
Write( "passBuildSettingsInEnvironment = 1;\n" );
Write( "productName = \"build with make\";\n" );
--m_nIndent;
Write( "};\n" );
--m_nIndent;
Write( "\n/* End PBXLegacyTarget section */\n" );
}
void CProjectGenerator_XCode::WriteFileReferences()
{
Write( "\n/* Begin PBXFileReference section */\n" );
++m_nIndent;
for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
{
const char *pchExtension = V_GetFileExtension( m_pCollector->m_Files[i]->GetName() );
char rgchFileType[MAX_PATH];
if ( pchExtension && ( !Q_stricmp( pchExtension, "cpp" ) || !Q_stricmp( pchExtension, "h" ) || !Q_stricmp( pchExtension, "c" ) || !Q_stricmp( pchExtension, "cc" ) ) )
sprintf( rgchFileType, "sourcecode.cpp.%s", pchExtension );
else
sprintf( rgchFileType, "text.plain" );
char rgchFilePath[MAX_PATH];
Q_strncpy( rgchFilePath, m_pCollector->m_Files[i]->GetName(), sizeof( rgchFilePath ) );
Q_RemoveDotSlashes( rgchFilePath );
Write( "%024X /* %s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = %s; path = \"%s\"; sourceTree = \"<group>\"; };\n",
m_pCollector->m_Files[i],
rgchFilePath,
rgchFileType,
rgchFilePath
);
}
--m_nIndent;
Write( "\n/* End PBXFileReference section */\n" );
}
void CProjectGenerator_XCode::WriteTrailer()
{
Write( "};\n" );
Write( "rootObject = %024X /* project object */;\n", this );
--m_nIndent;
Write( "}\n" );
}
void CProjectGenerator_XCode::WriteConfig( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteTarget_Build( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteTarget_Compile( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteTarget_Rebuild( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteTarget_Link( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteTarget_Debug( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteIncludes( CSpecificConfig *pConfig )
{
}
void CProjectGenerator_XCode::WriteFilesFolder( const char *pFolderName, const char *pExtensions )
{
CUtlVector<char*> extensions;
V_SplitString( pExtensions, ";", extensions );
Write( "%024X /* %s */ = {\n", pFolderName, pFolderName );
++m_nIndent;
Write( "isa = PBXGroup;\n" );
Write( "children = (\n" );
++m_nIndent;
for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
{
const char *pFilename = m_pCollector->m_Files[i]->GetName();
// Make sure this file's extension is one of the extensions they're asking for.
bool bValidExt = false;
const char *pFileExtension = V_GetFileExtension( pFilename );
if ( pFileExtension )
{
for ( int iExt=0; iExt < extensions.Count(); iExt++ )
{
const char *pTestExt = extensions[iExt];
if ( pTestExt[0] == '*' && pTestExt[1] == '.' && V_stricmp( pTestExt+2, pFileExtension ) == 0 )
{
bValidExt = true;
break;
}
}
}
if ( bValidExt )
{
char sFixedSlashes[MAX_PATH];
V_strncpy( sFixedSlashes, pFilename, sizeof( sFixedSlashes ) );
Write( "%024X /* %s */,\n", m_pCollector->m_Files[i], sFixedSlashes );
}
}
--m_nIndent;
Write( ");\n" );
Write( "name = \"%s\";\n", pFolderName );
Write( "sourceTree = \"<group>\";\n" );
--m_nIndent;
Write( "};\n" );
}
void CProjectGenerator_XCode::WriteFiles()
{
Write( "\n/* Begin PBXGroup section */\n" );
++m_nIndent;
WriteFilesFolder( k_pchSource, "*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.c++;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl;*.m;*.mm" );
WriteFilesFolder( k_pchHeaders, "*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if" );
WriteFilesFolder( k_pchResources, "*.plist;*.strings;*.xib" );
WriteFilesFolder( k_pchVPCFiles, "*.vpc" );
--m_nIndent;
}
+51
View File
@@ -0,0 +1,51 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_XCODE_H
#define PROJECTGENERATOR_XCODE_H
#ifdef _WIN32
#pragma once
#endif
#include "baseprojectdatacollector.h"
class CProjectGenerator_XCode
{
public:
void GenerateXCodeProject( CBaseProjectDataCollector *pCollector, const char *pOutFilename, const char *pMakefileFilename );
private:
void Write( const char *pMsg, ... );
void WriteHeader();
void WriteFileReferences();
void WriteProject( const char *pchMakefileName );
void WriteBuildFiles();
void WriteBuildConfigurations();
void WriteLegacyTargets( const char *pchMakefileName );
void WriteTrailer();
void WriteConfig( CSpecificConfig *pConfig );
void WriteTarget_Build( CSpecificConfig *pConfig );
void WriteTarget_Compile( CSpecificConfig *pConfig );
void WriteTarget_Rebuild( CSpecificConfig *pConfig );
void WriteTarget_Link( CSpecificConfig *pConfig );
void WriteTarget_Debug( CSpecificConfig *pConfig );
void WriteIncludes( CSpecificConfig *pConfig );
void WriteFilesFolder( const char *pFolderName, const char *pExtensions );
void WriteFiles();
private:
CBaseProjectDataCollector *m_pCollector;
FILE *m_fp;
const char *m_pMakefileFilename;
int m_nIndent;
};
#endif // PROJECTGENERATOR_XCODE_H
File diff suppressed because it is too large Load Diff
+565
View File
@@ -0,0 +1,565 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
//
//
//==================================================================================================
#include "vpc.h"
#define MAX_SCRIPT_STACK_SIZE 32
CScript::CScript()
{
m_ScriptName = "(empty)";
m_nScriptLine = 0;
m_pScriptData = NULL;
m_pScriptLine = &m_nScriptLine;
m_Token[0] = '\0';
m_PeekToken[0] = '\0';
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::SkipWhitespace( const char *data, bool *pHasNewLines, int* pNumLines )
{
int c;
while ( ( c = *data ) <= ' ' )
{
if ( c == '\n' )
{
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
else if ( !c )
{
return ( NULL );
}
data++;
}
return data;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::SkipToValidToken( const char *data, bool *pHasNewLines, int* pNumLines )
{
int c;
for ( ;; )
{
data = SkipWhitespace( data, pHasNewLines, pNumLines );
c = *data;
if ( !c )
{
break;
}
if ( c == '/' && data[1] == '/' )
{
// skip double slash comments
data += 2;
while ( *data && *data != '\n' )
{
data++;
}
if ( *data && *data == '\n' )
{
data++;
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
}
else if ( c == '/' && data[1] == '*' )
{
// skip /* */ comments
data += 2;
while ( *data && ( *data != '*' || data[1] != '/' ) )
{
if ( *data == '\n' )
{
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
data++;
}
if ( *data )
{
data += 2;
}
}
else
{
break;
}
}
return data;
}
//-----------------------------------------------------------------------------
// The next token should be an open brace.
// Skips until a matching close brace is found.
// Internal brace depths are properly skipped.
//-----------------------------------------------------------------------------
void CScript::SkipBracedSection( const char** dataptr, int* numlines )
{
const char* token;
int depth;
depth = 0;
do
{
token = GetToken( dataptr, true, numlines );
if ( token[1] == '\0' )
{
if ( token[0] == '{' )
depth++;
else if ( token[0] == '}' )
depth--;
}
}
while( depth && *dataptr );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CScript::SkipRestOfLine( const char** dataptr, int* numlines )
{
const char* p;
int c;
p = *dataptr;
while ( ( c = *p++ ) != '\0' )
{
if ( c == '\n' )
{
if ( numlines )
( *numlines )++;
break;
}
}
*dataptr = p;
}
//-----------------------------------------------------------------------------
// Does not corrupt results obtained with GetToken().
//-----------------------------------------------------------------------------
const char* CScript::PeekNextToken( const char *dataptr, bool bAllowLineBreaks )
{
// save the primary token, about to be corrupted
char savedToken[MAX_SYSTOKENCHARS];
V_strncpy( savedToken, m_Token, MAX_SYSTOKENCHARS );
const char *pSaved = dataptr;
const char *pToken = GetToken( &pSaved, bAllowLineBreaks, NULL );
// restore
V_strncpy( m_PeekToken, pToken, MAX_SYSTOKENCHARS );
V_strncpy( m_Token, savedToken, MAX_SYSTOKENCHARS );
return m_PeekToken;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::GetToken( const char **dataptr, bool allowLineBreaks, int *pNumLines )
{
char c;
char endSymbol;
int len;
bool hasNewLines;
const char* data;
c = 0;
data = *dataptr;
len = 0;
m_Token[0] = 0;
hasNewLines = false;
// make sure incoming data is valid
if ( !data )
{
*dataptr = NULL;
return m_Token;
}
for ( ;; )
{
// skip whitespace
data = SkipWhitespace( data, &hasNewLines, pNumLines );
if ( !data )
{
*dataptr = NULL;
return m_Token;
}
if ( hasNewLines && !allowLineBreaks )
{
*dataptr = data;
return m_Token;
}
c = *data;
if ( c == '/' && data[1] == '/' )
{
// skip double slash comments
data += 2;
while ( *data && *data != '\n' )
{
data++;
}
if ( *data && *data == '\n' )
{
if ( !allowLineBreaks )
continue;
data++;
if ( pNumLines )
{
(*pNumLines)++;
}
}
}
else if ( c =='/' && data[1] == '*' )
{
// skip /* */ comments
data += 2;
while ( *data && ( *data != '*' || data[1] != '/' ) )
{
if ( *data == '\n' && pNumLines )
{
(*pNumLines)++;
}
data++;
}
if ( *data )
{
data += 2;
}
}
else
break;
}
// handle scoped strings "???" <???> [???]
if ( c == '\"' || c == '<' || c == '[')
{
bool bConditionalExpression = false;
endSymbol = '\0';
switch ( c )
{
case '\"':
endSymbol = '\"';
break;
case '<':
endSymbol = '>';
break;
case '[':
bConditionalExpression = true;
endSymbol = ']';
break;
}
// want to preserve entire conditional expession [blah...blah...blah]
// maintain a conditional's open/close scope characters
if ( !bConditionalExpression )
{
// skip past scope character
data++;
}
for ( ;; )
{
c = *data++;
if ( c == endSymbol || !c )
{
if ( c == endSymbol && bConditionalExpression )
{
// keep end symbol
m_Token[len++] = c;
}
m_Token[len] = 0;
*dataptr = (char*)data;
return m_Token;
}
if ( len < MAX_SYSTOKENCHARS-1 )
{
m_Token[len++] = c;
}
}
}
// parse a regular word
do
{
if ( len < MAX_SYSTOKENCHARS )
{
m_Token[len++] = c;
}
data++;
c = *data;
}
while ( c > ' ' );
if ( len >= MAX_SYSTOKENCHARS )
{
len = 0;
}
m_Token[len] = '\0';
*dataptr = (char*)data;
return m_Token;
}
void CScript::PushScript( const char *pFilename )
{
// parse the text script
if ( !Sys_Exists( pFilename ) )
{
g_pVPC->VPCError( "Cannot open %s", pFilename );
}
char *pScriptBuffer = NULL; // Sys_LoadTextFileWithIncludes does not unconditionally initialize this.
Sys_LoadTextFileWithIncludes( pFilename, &pScriptBuffer );
PushScript( pFilename, pScriptBuffer, 1, true );
}
void CScript::PushScript( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop )
{
if ( m_ScriptStack.Count() > MAX_SCRIPT_STACK_SIZE )
{
g_pVPC->VPCError( "PushScript( scriptname=%s ) - stack overflow\n", pScriptName );
}
// Push the current state onto the stack.
m_ScriptStack.Push( GetCurrentScript() );
// Set their state as the current state.
m_ScriptName = pScriptName;
m_pScriptData = pScriptData;
m_nScriptLine = nScriptLine;
m_bFreeScriptAtPop = bFreeScriptAtPop;
}
void CScript::PushCurrentScript()
{
PushScript( m_ScriptName.Get(), m_pScriptData, m_nScriptLine, m_bFreeScriptAtPop );
}
CScriptSource CScript::GetCurrentScript()
{
return CScriptSource( m_ScriptName.Get(), m_pScriptData, m_nScriptLine, m_bFreeScriptAtPop );
}
void CScript::RestoreScript( const CScriptSource &scriptSource )
{
m_ScriptName = scriptSource.GetName();
m_pScriptData = scriptSource.GetData();
m_nScriptLine = scriptSource.GetLine();
m_bFreeScriptAtPop = scriptSource.IsFreeScriptAtPop();
}
void CScript::PopScript()
{
if ( m_ScriptStack.Count() == 0 )
{
g_pVPC->VPCError( "PopScript(): stack is empty" );
}
if ( m_bFreeScriptAtPop && m_pScriptData )
{
free( (void *)m_pScriptData );
}
// Restore the top entry on the stack and pop it off.
const CScriptSource &state = m_ScriptStack.Top();
m_ScriptName = state.GetName();
m_pScriptData = state.GetData();
m_nScriptLine = state.GetLine();
m_bFreeScriptAtPop = state.IsFreeScriptAtPop();
m_ScriptStack.Pop();
}
void CScript::EnsureScriptStackEmpty()
{
if ( m_ScriptStack.Count() != 0 )
{
g_pVPC->VPCError( "EnsureScriptStackEmpty(): script stack is not empty!" );
}
}
void CScript::SpewScriptStack()
{
if ( m_ScriptStack.Count() )
{
CUtlString str;
// emit stack with current at top
str += "Script Stack:\n";
str += CFmtStr( " %s Line:%d\n", m_ScriptName.String(), m_nScriptLine );
for ( int i = m_ScriptStack.Count() - 1; i >= 0; i-- )
{
if ( i == 0 && !m_ScriptStack[i].GetData() && m_ScriptStack[i].GetLine() <= 0 )
{
// ignore empty bottom of stack
break;
}
str += CFmtStr( " %s Line:%d\n", m_ScriptStack[i].GetName(), m_ScriptStack[i].GetLine() );
}
str += "\n";
Log_Msg( LOG_VPC, "%s", str.String() );
}
}
const char *CScript::GetToken( bool bAllowLineBreaks )
{
return GetToken( &m_pScriptData, bAllowLineBreaks, m_pScriptLine );
}
const char *CScript::PeekNextToken( bool bAllowLineBreaks )
{
return PeekNextToken( m_pScriptData, bAllowLineBreaks );
}
void CScript::SkipRestOfLine()
{
SkipRestOfLine( &m_pScriptData, m_pScriptLine );
}
void CScript::SkipBracedSection()
{
SkipBracedSection( &m_pScriptData, m_pScriptLine );
}
void CScript::SkipToValidToken()
{
m_pScriptData = SkipToValidToken( m_pScriptData, NULL, m_pScriptLine );
}
//-----------------------------------------------------------------------------
// Handles expressions of the form <$BASE> <xxx> ... <xxx> [condition]
// Output is a concatenated string.
//
// Returns true if expression should be used, false if it should be ignored due
// to an optional condition that evaluated false.
//-----------------------------------------------------------------------------
bool CScript::ParsePropertyValue( const char *pBaseString, char *pOutBuff, int outBuffSize )
{
const char **pScriptData = &m_pScriptData;
int *pScriptLine = m_pScriptLine;
const char *pToken;
const char *pNextToken;
char *pOut = pOutBuff;
int remaining = outBuffSize-1;
int len;
bool bAllowNextLine = false;
char buffer1[MAX_SYSTOKENCHARS];
char buffer2[MAX_SYSTOKENCHARS];
bool bResult = true;
while ( 1 )
{
pToken = GetToken( pScriptData, bAllowNextLine, pScriptLine );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
pNextToken = PeekNextToken( *pScriptData, false );
if ( !pNextToken || !pNextToken[0] )
{
// current token is last token
// last token can be optional conditional, need to identify
// backup and reparse up to last token
if ( pToken && pToken[0] == '[' )
{
// last token is an optional conditional
bResult = g_pVPC->EvaluateConditionalExpression( pToken );
break;
}
}
if ( !V_stricmp( pToken, "\\" ) )
{
bAllowNextLine = true;
continue;
}
else
{
bAllowNextLine = false;
}
if ( !V_stricmp( pToken, "\\n" ) )
{
pToken = "\n";
}
if ( pToken[0] )
{
// handle reserved macro
if ( !pBaseString )
pBaseString = "";
strcpy( buffer1, pToken );
Sys_ReplaceString( buffer1, "$base", pBaseString, buffer2, sizeof( buffer2 ) );
g_pVPC->ResolveMacrosInString( buffer2, buffer1, sizeof( buffer1 ) );
len = strlen( buffer1 );
if ( remaining < len )
len = remaining;
if ( len > 0 )
{
memcpy( pOut, buffer1, len );
pOut += len;
remaining -= len;
}
}
pToken = PeekNextToken( *pScriptData, false );
if ( !pToken || !pToken[0] )
break;
}
*pOut++ = '\0';
if ( !pOutBuff[0] )
g_pVPC->VPCSyntaxError();
return bResult;
}
+95
View File
@@ -0,0 +1,95 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
// This module manages a stack of "script sources".
//
//==================================================================================================
#ifndef SCRIPTSOURCE_H
#define SCRIPTSOURCE_H
#ifdef _WIN32
#pragma once
#endif
#define MAX_SYSPRINTMSG 4096
#define MAX_SYSTOKENCHARS 4096
class CScriptSource
{
public:
CScriptSource()
{
Set( "", NULL, 0, false );
}
CScriptSource( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop )
{
Set( pScriptName, pScriptData, nScriptLine, bFreeScriptAtPop );
}
void Set( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop )
{
m_ScriptName = pScriptName;
m_pScriptData = pScriptData;
m_nScriptLine = nScriptLine;
m_bFreeScriptAtPop = bFreeScriptAtPop;
}
const char *GetName() const { return m_ScriptName.Get(); }
const char *GetData() const { return m_pScriptData; }
int GetLine() const { return m_nScriptLine; }
bool IsFreeScriptAtPop() const { return m_bFreeScriptAtPop; }
private:
CUtlString m_ScriptName;
const char *m_pScriptData;
int m_nScriptLine;
bool m_bFreeScriptAtPop;
};
class CScript
{
public:
CScript();
void PushScript( const char *pFilename );
void PushScript( const char *pScriptName, const char *ppScriptData, int nScriptLine = 1, bool bFreeScriptAtPop = false );
void PushCurrentScript();
void PopScript();
CScriptSource GetCurrentScript();
void RestoreScript( const CScriptSource &scriptSource );
void EnsureScriptStackEmpty();
void SpewScriptStack();
const char *GetName() const { return m_ScriptName.Get(); }
const char *GetData() const { return m_pScriptData; }
int GetLine() const { return m_nScriptLine; }
const char *GetToken( bool bAllowLineBreaks );
const char *PeekNextToken( bool bAllowLineBreaks );
void SkipRestOfLine();
void SkipBracedSection();
void SkipToValidToken();
bool ParsePropertyValue( const char *pBaseString, char *pOutBuff, int outBuffSize );
private:
const char *SkipWhitespace( const char *data, bool *pHasNewLines, int *pNumLines );
const char *SkipToValidToken( const char *data, bool *pHasNewLines, int *pNumLines );
void SkipBracedSection( const char **dataptr, int *numlines );
void SkipRestOfLine( const char **dataptr, int *numlines );
const char *PeekNextToken( const char *dataptr, bool bAllowLineBreaks );
const char *GetToken( const char **dataptr, bool allowLineBreaks, int *pNumLines );
CUtlStack< CScriptSource > m_ScriptStack;
int m_nScriptLine;
int *m_pScriptLine;
const char *m_pScriptData;
CUtlString m_ScriptName;
bool m_bFreeScriptAtPop;
char m_Token[MAX_SYSTOKENCHARS];
char m_PeekToken[MAX_SYSTOKENCHARS];
};
#endif // SCRIPTSOURCE_H
+254
View File
@@ -0,0 +1,254 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "dependencies.h"
extern void V_MakeAbsoluteCygwinPath( char *pOut, int outLen, const char *pRelativePath );
extern void MakeFriendlyProjectName( char *pchProject )
{
int strLen = V_strlen( pchProject );
for ( int j = 0; j < strLen; j++ )
{
if ( pchProject[j] == ' ' )
pchProject[j] = '_';
if ( pchProject[j] == '(' || pchProject[j] == ')' )
{
V_memmove( pchProject+j, pchProject+j+1, strLen - j );
strLen--;
}
}
}
class CSolutionGenerator_Makefile : public IBaseSolutionGenerator
{
private:
void GenerateProjectNames( CUtlVector<CUtlString> &projNames, CUtlVector<CDependency_Project*> &projects )
{
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
char szFriendlyName[256];
V_strncpy( szFriendlyName, pCurProject->m_ProjectName.String(), sizeof(szFriendlyName) );
MakeFriendlyProjectName( szFriendlyName );
projNames[ projNames.AddToTail() ] = szFriendlyName;
}
}
public:
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
{
// Default extension.
char szTmpSolutionFilename[MAX_PATH];
if ( !V_GetFileExtension( pSolutionFilename ) )
{
V_snprintf( szTmpSolutionFilename, sizeof( szTmpSolutionFilename ), "%s.mak", pSolutionFilename );
pSolutionFilename = szTmpSolutionFilename;
}
Msg( "\nWriting master makefile %s.\n\n", pSolutionFilename );
// Write the file.
FILE *fp = fopen( pSolutionFilename, "wt" );
if ( !fp )
g_pVPC->VPCError( "Can't open %s for writing.", pSolutionFilename );
fprintf( fp, "# VPC MASTER MAKEFILE\n\n\n" );
fprintf( fp, "\nSHELL:=/bin/bash\n" );
fprintf( fp, "# to control parallelism, set the MAKE_JOBS environment variable\n" );
fprintf( fp, "ifeq ($(strip $(MAKE_JOBS)),)\n");
fprintf( fp, "\tifeq ($(shell uname),Darwin)\n\t\tCPUS:=$(shell /usr/sbin/sysctl -n hw.ncpu)\n\tendif\n");
fprintf( fp, "\tifeq ($(shell uname),Linux)\n\t\tCPUS:=$(shell grep processor /proc/cpuinfo | wc -l)\n\tendif\n");
fprintf( fp, "\tMAKE_JOBS:=-j$(CPUS)\n" );
fprintf( fp, "endif\n\n" );
fprintf( fp, "ifeq ($(strip $(MAKE_JOBS)),)\n");
fprintf( fp, "\tMAKE_JOBS:=-j8\n" );
fprintf( fp, "endif\n\n" );
// First, make a target with all the project names.
fprintf( fp, "# All projects (default target)\n" );
fprintf( fp, "all: \n" );
fprintf( fp, "\t$(MAKE) -f $(lastword $(MAKEFILE_LIST)) $(MAKE_JOBS) all-targets\n\n" );
fprintf( fp, "all-targets : " );
CUtlVector<CUtlString> projNames;
GenerateProjectNames( projNames, projects );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "%s ", projNames[i].String() );
}
fprintf( fp, "\n\n\n# Individual projects + dependencies\n\n" );
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
CUtlVector<CDependency_Project*> additionalProjectDependencies;
ResolveAdditionalProjectDependencies( pCurProject, projects, additionalProjectDependencies );
fprintf( fp, "%s : ", projNames[i].String() );
for ( int iTestProject=0; iTestProject < projects.Count(); iTestProject++ )
{
if ( i == iTestProject )
continue;
CDependency_Project *pTestProject = projects[iTestProject];
int dependsOnFlags = k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse;
if ( pCurProject->DependsOn( pTestProject, dependsOnFlags ) || additionalProjectDependencies.Find( pTestProject ) != additionalProjectDependencies.InvalidIndex() )
{
fprintf( fp, "%s ", projNames[iTestProject].String() );
}
}
// Now add the code to build this thing.
char sDirTemp[MAX_PATH], sDir[MAX_PATH];
V_strncpy( sDirTemp, pCurProject->m_ProjectFilename.String(), sizeof( sDirTemp ) );
V_StripFilename( sDirTemp );
V_MakeAbsoluteCygwinPath( sDir, sizeof( sDir ), sDirTemp );
const char *pFilename = V_UnqualifiedFileName( pCurProject->m_ProjectFilename.String() );
fprintf( fp, "\n\t+cd %s && $(MAKE) -f %s $(CLEANPARAM)", sDir, pFilename );
fprintf( fp, "\n\n" );
}
fprintf( fp, "# this is a bit over-inclusive, but the alternative (actually adding each referenced c/cpp/h file to\n" );
fprintf( fp, "# the tags file) seems like more work than it's worth. feel free to fix that up if it bugs you. \n" );
fprintf( fp, "TAGS:\n" );
fprintf( fp, "\t@rm -f TAGS\n" );
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
char sDirTemp[MAX_PATH], sDir[MAX_PATH];
V_strncpy( sDirTemp, pCurProject->m_ProjectFilename.String(), sizeof( sDirTemp ) );
V_StripFilename( sDirTemp );
V_MakeAbsoluteCygwinPath( sDir, sizeof( sDir ), sDirTemp );
fprintf( fp, "\t@find %s -name \'*.cpp\' -print0 | xargs -0 etags --declarations --ignore-indentation --append\n", sDir );
fprintf( fp, "\t@find %s -name \'*.h\' -print0 | xargs -0 etags --language=c++ --declarations --ignore-indentation --append\n", sDir );
fprintf( fp, "\t@find %s -name \'*.c\' -print0 | xargs -0 etags --declarations --ignore-indentation --append\n", sDir );
}
fprintf( fp, "\n\n" );
fprintf( fp, "\n# Mark all the projects as phony or else make will see the directories by the same name and think certain targets \n\n" );
fprintf( fp, ".PHONY: TAGS showtargets regen showregen clean cleantargets relink " );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "%s ", projNames[i].String() );
}
fprintf( fp, "\n\n\n" );
fprintf( fp, "\n# The standard clean command to clean it all out.\n" );
fprintf( fp, "\nclean: \n" );
fprintf( fp, "\t$(MAKE) -f $(lastword $(MAKEFILE_LIST)) $(MAKE_JOBS) all-targets CLEANPARAM=clean\n\n\n" );
fprintf( fp, "\n# clean targets, so we re-link next time.\n" );
fprintf( fp, "\ncleantargets: \n" );
fprintf( fp, "\t$(MAKE) -f $(lastword $(MAKEFILE_LIST)) $(MAKE_JOBS) all-targets CLEANPARAM=cleantargets\n\n\n" );
fprintf( fp, "\n#relink\n" );
fprintf( fp, "\nrelink: cleantargets \n" );
fprintf( fp, "\t$(MAKE) -f $(lastword $(MAKEFILE_LIST)) $(MAKE_JOBS) all-targets\n\n\n" );
// Create the showtargets target.
fprintf( fp, "\n# Here's a command to list out all the targets\n\n" );
fprintf( fp, "\nshowtargets: \n" );
fprintf( fp, "\t@echo '-------------------' && \\\n" );
fprintf( fp, "\techo '----- TARGETS -----' && \\\n" );
fprintf( fp, "\techo '-------------------' && \\\n" );
fprintf( fp, "\techo 'clean' && \\\n" );
fprintf( fp, "\techo 'regen' && \\\n" );
fprintf( fp, "\techo 'showregen' && \\\n" );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "\techo '%s'", projNames[i].String() );
if ( i != projects.Count()-1 )
fprintf( fp, " && \\" );
fprintf( fp, "\n" );
}
fprintf( fp, "\n\n" );
// Create the regen target.
fprintf( fp, "\n# Here's a command to regenerate this makefile\n\n" );
fprintf( fp, "\nregen: \n" );
fprintf( fp, "\t" );
ICommandLine *pCommandLine = CommandLine();
for ( int i=0; i < pCommandLine->ParmCount(); i++ )
{
fprintf( fp, "%s ", pCommandLine->GetParm( i ) );
}
fprintf( fp, "\n\n" );
// Create the showregen target.
fprintf( fp, "\n# Here's a command to list out all the targets\n\n" );
fprintf( fp, "\nshowregen: \n" );
fprintf( fp, "\t@echo " );
for ( int i=0; i < pCommandLine->ParmCount(); i++ )
{
fprintf( fp, "%s ", pCommandLine->GetParm( i ) );
}
fprintf( fp, "\n\n" );
fclose( fp );
}
void ResolveAdditionalProjectDependencies(
CDependency_Project *pCurProject,
CUtlVector<CDependency_Project*> &projects,
CUtlVector<CDependency_Project*> &additionalProjectDependencies )
{
for ( int i=0; i < pCurProject->m_AdditionalProjectDependencies.Count(); i++ )
{
const char *pLookingFor = pCurProject->m_AdditionalProjectDependencies[i].String();
int j;
for ( j=0; j < projects.Count(); j++ )
{
if ( V_stricmp( projects[j]->m_ProjectName.String(), pLookingFor ) == 0 )
break;
}
if ( j == projects.Count() )
g_pVPC->VPCError( "Project %s lists '%s' in its $AdditionalProjectDependencies, but there is no project by that name.", pCurProject->GetName(), pLookingFor );
additionalProjectDependencies.AddToTail( projects[j] );
}
}
const char* FindInFile( const char *pFilename, const char *pFileData, const char *pSearchFor )
{
const char *pPos = V_stristr( pFileData, pSearchFor );
if ( !pPos )
g_pVPC->VPCError( "Can't find ProjectGUID in %s.", pFilename );
return pPos + V_strlen( pSearchFor );
}
};
static CSolutionGenerator_Makefile g_SolutionGenerator_Makefile;
IBaseSolutionGenerator* GetSolutionGenerator_Makefile()
{
return &g_SolutionGenerator_Makefile;
}
+346
View File
@@ -0,0 +1,346 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "dependencies.h"
#include "tier1/checksum_md5.h"
class CVCProjInfo
{
public:
CUtlString m_ProjectName;
CUtlString m_ProjectGUID;
};
class CSolutionGenerator_Win32 : public IBaseSolutionGenerator
{
public:
void GetVCPROJSolutionGUID( char (&szSolutionGUID)[256] )
{
HKEY hKey;
int firstVer = 8;
const int lastVer = 12; // Handle up to VS 12, AKA VS 2013
if ( g_pVPC->Is2010() )
{
firstVer = 10;
}
for ( int vsVer = firstVer; vsVer <= lastVer; ++vsVer )
{
// Handle both VisualStudio and VCExpress (used by some SourceSDK customers)
const char* productName[] =
{
"VisualStudio",
"VCExpress",
};
for ( int productNumber = 0; productNumber < ARRAYSIZE(productName); ++productNumber )
{
char pRegKeyName[1000];
V_snprintf( pRegKeyName, ARRAYSIZE(pRegKeyName), "Software\\Microsoft\\%s\\%d.0\\Projects", productName[ productNumber ], vsVer );
LONG ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE, pRegKeyName, 0, KEY_READ, &hKey );
//if ( ret != ERROR_SUCCESS )
// g_pVPC->VPCError( "Unable to open registry key %s.", pRegKeyName );
for ( int i=0; i < 200; i++ )
{
char szKeyName[MAX_PATH];
DWORD dwKeyNameSize = sizeof( szKeyName );
ret = RegEnumKeyEx( hKey, i, szKeyName, &dwKeyNameSize, NULL, NULL, NULL, NULL );
if ( ret == ERROR_NO_MORE_ITEMS )
break;
HKEY hSubKey;
LONG ret = RegOpenKeyEx( hKey, szKeyName, 0, KEY_READ, &hSubKey );
if ( ret == ERROR_SUCCESS )
{
DWORD dwType;
char ext[MAX_PATH];
DWORD dwExtLen = sizeof( ext );
ret = RegQueryValueEx( hSubKey, "DefaultProjectExtension", NULL, &dwType, (BYTE*)ext, &dwExtLen );
RegCloseKey( hSubKey );
// VS 2012 and beyond has the DefaultProjectExtension as vcxproj instead of vcproj
if ( ret == ERROR_SUCCESS && dwType == REG_SZ && ( V_stricmp( ext, "vcproj" ) == 0 || V_stricmp( ext, "vcxproj" ) == 0 ) )
{
V_strncpy( szSolutionGUID, szKeyName, ARRAYSIZE(szSolutionGUID) );
RegCloseKey( hKey );
return;
}
}
}
RegCloseKey( hKey );
}
}
g_pVPC->VPCError( "Unable to find RegKey for .vcproj or .vcxproj files in solutions." );
}
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
{
// Default extension.
char szTmpSolutionFilename[MAX_PATH];
if ( !V_GetFileExtension( pSolutionFilename ) )
{
V_snprintf( szTmpSolutionFilename, sizeof( szTmpSolutionFilename ), "%s.sln", pSolutionFilename );
pSolutionFilename = szTmpSolutionFilename;
}
Msg( "\nWriting solution file %s.\n\n", pSolutionFilename );
char szSolutionGUID[256];
GetVCPROJSolutionGUID( szSolutionGUID );
CUtlVector<CVCProjInfo> vcprojInfos;
GetProjectInfos( projects, vcprojInfos );
// Write the file.
FILE *fp = fopen( pSolutionFilename, "wt" );
if ( !fp )
g_pVPC->VPCError( "Can't open %s for writing.", pSolutionFilename );
if ( g_pVPC->Is2013() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 12.00\n" ); // Format didn't change from VS 2012 to VS 2013
fprintf( fp, "# Visual Studio 2013\n" );
}
else if ( g_pVPC->Is2012() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 12.00\n" );
fprintf( fp, "# Visual Studio 2012\n" );
}
else if ( g_pVPC->Is2010() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 11.00\n" );
fprintf( fp, "# Visual Studio 2010\n" );
}
else
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 9.00\n" );
fprintf( fp, "# Visual Studio 2005\n" );
}
fprintf( fp, "#\n" );
fprintf( fp, "# Automatically generated solution:\n" );
fprintf( fp, "# devtools\\bin\\vpc " );
for ( int k = 1; k < __argc; ++ k )
fprintf( fp, "%s ", __argv[k] );
fprintf( fp, "\n" );
fprintf( fp, "#\n" );
fprintf( fp, "#\n" );
if ( !g_pVPC->Is2010() )
{
// if /slnItems <filename> is passed on the command line, build a Solution Items project
const char *pSolutionItemsFilename = g_pVPC->GetSolutionItemsFilename();
if ( pSolutionItemsFilename[0] != '\0' )
{
fprintf( fp, "Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{AAAAAAAA-8B4A-11D0-8D11-90A07D6D6F7D}\"\n" );
fprintf( fp, "\tProjectSection(SolutionItems) = preProject\n" );
WriteSolutionItems( fp );
fprintf( fp, "\tEndProjectSection\n" );
fprintf( fp, "EndProject\n" );
}
}
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
CVCProjInfo *pProjInfo = &vcprojInfos[i];
// Get a relative filename for the vcproj file.
const char *pFullProjectFilename = pCurProject->m_ProjectFilename.String();
char szRelativeFilename[MAX_PATH];
if ( !V_MakeRelativePath( pFullProjectFilename, g_pVPC->GetSourcePath(), szRelativeFilename, sizeof( szRelativeFilename ) ) )
g_pVPC->VPCError( "Can't make a relative path (to the base source directory) for %s.", pFullProjectFilename );
fprintf( fp, "Project(\"%s\") = \"%s\", \"%s\", \"{%s}\"\n", szSolutionGUID, pProjInfo->m_ProjectName.String(), szRelativeFilename, pProjInfo->m_ProjectGUID.String() );
bool bHasDependencies = false;
for ( int iTestProject=0; iTestProject < projects.Count(); iTestProject++ )
{
if ( i == iTestProject )
continue;
CDependency_Project *pTestProject = projects[iTestProject];
if ( pCurProject->DependsOn( pTestProject, k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagRecurse ) ||
pCurProject->DependsOn( pTestProject, k_EDependsOnFlagCheckAdditionalDependencies | k_EDependsOnFlagTraversePastLibs ) )
{
if ( !bHasDependencies )
{
fprintf( fp, "\tProjectSection(ProjectDependencies) = postProject\n" );
bHasDependencies = true;
}
fprintf( fp, "\t\t{%s} = {%s}\n", vcprojInfos[iTestProject].m_ProjectGUID.String(), vcprojInfos[iTestProject].m_ProjectGUID.String() );
}
}
if ( bHasDependencies )
fprintf( fp, "\tEndProjectSection\n" );
fprintf( fp, "EndProject\n" );
}
fclose( fp );
}
const char* FindInFile( const char *pFilename, const char *pFileData, const char *pSearchFor )
{
const char *pPos = V_stristr( pFileData, pSearchFor );
if ( !pPos )
{
g_pVPC->VPCError( "Can't find %s in %s.", pSearchFor, pFilename );
}
return pPos + V_strlen( pSearchFor );
}
void GetProjectInfos( CUtlVector<CDependency_Project*> &projects, CUtlVector<CVCProjInfo> &vcprojInfos )
{
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
const char *pFilename = pCurProject->m_ProjectFilename.String();
CVCProjInfo vcprojInfo;
char *pFileData;
int nResult = Sys_LoadFile( pFilename, (void**)&pFileData, false );
if ( nResult == -1 )
g_pVPC->VPCError( "Can't open %s to get ProjectGUID.", pFilename );
const char *pSearchFor;
if ( g_pVPC->Is2010() )
{
pSearchFor = "<ProjectGuid>{";
}
else
{
pSearchFor = "ProjectGUID=\"{";
}
const char *pPos = FindInFile( pFilename, pFileData, pSearchFor );
char szGuid[37];
const char *pGuid = pPos;
V_strncpy( szGuid, pGuid, sizeof( szGuid ) );
vcprojInfo.m_ProjectGUID = szGuid;
const char *pEnd;
if ( g_pVPC->Is2010() )
{
pPos = FindInFile( pFilename, pFileData, "<ProjectName>" );
pEnd = V_stristr( pPos, "<" );
}
else
{
pPos = FindInFile( pFilename, pFileData, "Name=\"" );
pEnd = V_stristr( pPos, "\"" );
}
if ( !pEnd || (pEnd - pPos) > 1024 || (pEnd - pPos) <= 0 )
g_pVPC->VPCError( "Can't find valid 'Name=' in %s.", pFilename );
char szName[256];
V_strncpy( szName, pPos, (pEnd - pPos) + 1 );
vcprojInfo.m_ProjectName = szName;
vcprojInfos.AddToTail( vcprojInfo );
free( pFileData );
}
}
// Parse g_SolutionItemsFilename, reading in filenames (including wildcards),
// and add them to the Solution Items project we're already writing.
void WriteSolutionItems( FILE *fp )
{
char szFullSolutionItemsPath[MAX_PATH];
if ( V_IsAbsolutePath( g_pVPC->GetSolutionItemsFilename() ) )
V_strncpy( szFullSolutionItemsPath, g_pVPC->GetSolutionItemsFilename(), sizeof( szFullSolutionItemsPath ) );
else
V_ComposeFileName( g_pVPC->GetStartDirectory(), g_pVPC->GetSolutionItemsFilename(), szFullSolutionItemsPath, sizeof( szFullSolutionItemsPath ) );
g_pVPC->GetScript().PushScript( szFullSolutionItemsPath );
int numSolutionItems = 0;
while ( g_pVPC->GetScript().GetData() )
{
// read a line
const char *pToken = g_pVPC->GetScript().GetToken( false );
// strip out \r\n chars
char *end = V_strstr( pToken, "\n" );
if ( end )
{
*end = '\0';
}
end = V_strstr( pToken, "\r" );
if ( end )
{
*end = '\0';
}
// bail on strings too small to be paths
if ( V_strlen( pToken ) < 3 )
continue;
// compose an absolute path w/o any ../
char szFullPath[MAX_PATH];
if ( V_IsAbsolutePath( pToken ) )
V_strncpy( szFullPath, pToken, sizeof( szFullPath ) );
else
V_ComposeFileName( g_pVPC->GetStartDirectory(), pToken, szFullPath, sizeof( szFullPath ) );
if ( !V_RemoveDotSlashes( szFullPath ) )
continue;
if ( V_strstr( szFullPath, "*" ) != NULL )
{
// wildcard!
char szWildcardPath[MAX_PATH];
V_strncpy( szWildcardPath, szFullPath, sizeof( szWildcardPath ) );
V_StripFilename( szWildcardPath );
struct _finddata32_t data;
intptr_t handle = _findfirst32( szFullPath, &data );
if ( handle != -1L )
{
do
{
if ( ( data.attrib & _A_SUBDIR ) == 0 )
{
// not a dir, just a filename - add it
V_ComposeFileName( szWildcardPath, data.name, szFullPath, sizeof( szFullPath ) );
if ( V_RemoveDotSlashes( szFullPath ) )
{
fprintf( fp, "\t\t%s = %s\n", szFullPath, szFullPath );
++numSolutionItems;
}
}
} while ( _findnext32( handle, &data ) == 0 );
_findclose( handle );
}
}
else
{
// just a file - add it
fprintf( fp, "\t\t%s = %s\n", szFullPath, szFullPath );
++numSolutionItems;
}
}
g_pVPC->GetScript().PopScript();
Msg( "Found %d solution files in %s\n", numSolutionItems, g_pVPC->GetSolutionItemsFilename() );
}
};
static CSolutionGenerator_Win32 g_SolutionGenerator_Win32;
IBaseSolutionGenerator* GetSolutionGenerator_Win32()
{
return &g_SolutionGenerator_Win32;
}
File diff suppressed because it is too large Load Diff
+554
View File
@@ -0,0 +1,554 @@
//========= Copyright 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#ifdef STEAM
#include "tier1/utlintrusivelist.h"
#endif
#ifdef POSIX
#define _O_RDONLY O_RDONLY
#define _open open
#include <sys/errno.h>
#define _lseek lseek
#define _read read
#define _close close
#define _stat stat
#else
#include <io.h>
#include <ShellAPI.h>
#endif
CXMLWriter::CXMLWriter()
{
m_fp = NULL;
m_b2010Format = false;
}
bool CXMLWriter::Open( const char *pFilename, bool b2010Format )
{
m_b2010Format = b2010Format;
m_fp = fopen( pFilename, "wt" );
if ( !m_fp )
return false;
if ( b2010Format )
{
Write( "\xEF\xBB\xBF<?xml version=\"1.0\" encoding=\"utf-8\"?>" );
}
else
{
// 2005 format
Write( "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\n" );
}
return true;
}
void CXMLWriter::Close()
{
if ( !m_fp )
return;
fclose( m_fp );
m_fp = NULL;
}
void CXMLWriter::PushNode( const char *pName )
{
Indent();
char *pNewName = strdup( pName );
m_Nodes.Push( pNewName );
fprintf( m_fp, "<%s%s\n", pName, m_Nodes.Count() == 2 ? ">" : "" );
}
void CXMLWriter::PushNode( const char *pName, const char *pString )
{
Indent();
char *pNewName = strdup( pName );
m_Nodes.Push( pNewName );
fprintf( m_fp, "<%s%s%s>\n", pName, pString ? " " : "", pString ? pString : "" );
}
void CXMLWriter::WriteLineNode( const char *pName, const char *pExtra, const char *pString )
{
Indent();
fprintf( m_fp, "<%s%s>%s</%s>\n", pName, pExtra ? pExtra : "", pString, pName );
}
void CXMLWriter::PopNode( bool bEmitLabel )
{
char *pName;
m_Nodes.Pop( pName );
Indent();
if ( bEmitLabel )
{
fprintf( m_fp, "</%s>\n", pName );
}
else
{
fprintf( m_fp, "/>\n", pName );
}
free( pName );
}
void CXMLWriter::Write( const char *p )
{
if ( m_fp )
{
Indent();
fprintf( m_fp, "%s\n", p );
}
}
CUtlString CXMLWriter::FixupXMLString( const char *pInput )
{
struct XMLFixup_t
{
const char *m_pFrom;
const char *m_pTo;
bool m_b2010Only;
};
// these tokens are not allowed in xml vcproj and be be escaped per msdev docs
XMLFixup_t xmlFixups[] =
{
{"\"", "&quot;", false},
{"\'", "&apos;", false},
{"\n", "&#x0D;&#x0A;", false},
{">", "&gt;", false},
{"<", "&lt;", false},
{"$(InputFileName)", "%(Filename)%(Extension)", true},
{"$(InputName)", "%(Filename)", true},
{"$(InputPath)", "%(FullPath)", true},
{"$(InputDir)", "%(RootDir)%(Directory)", true},
};
bool bNeedsFixups = false;
CUtlVector< bool > needsFixups;
CUtlString outString;
needsFixups.SetCount( ARRAYSIZE( xmlFixups ) );
for ( int i = 0; i < ARRAYSIZE( xmlFixups ); i++ )
{
needsFixups[i] = false;
if ( !m_b2010Format && xmlFixups[i].m_b2010Only )
continue;
if ( V_stristr( pInput, xmlFixups[i].m_pFrom ) )
{
needsFixups[i] = true;
bNeedsFixups = true;
}
}
if ( !bNeedsFixups )
{
outString = pInput;
}
else
{
int flip = 0;
char bigBuffer[2][8192];
V_strncpy( bigBuffer[flip], pInput, sizeof( bigBuffer[0] ) );
for ( int i = 0; i < ARRAYSIZE( xmlFixups ); i++ )
{
if ( !needsFixups[i] )
continue;
if ( !V_StrSubst( bigBuffer[flip], xmlFixups[i].m_pFrom, xmlFixups[i].m_pTo, bigBuffer[flip ^ 1], sizeof( bigBuffer[0] ), false ) )
{
g_pVPC->VPCError( "XML overflow - Increase big buffer" );
}
flip ^= 1;
}
outString = bigBuffer[flip];
}
return outString;
}
void CXMLWriter::Indent()
{
for ( int i = 0; i < m_Nodes.Count(); i++ )
{
if ( m_b2010Format )
{
fprintf( m_fp, " " );
}
else
{
fprintf( m_fp, "\t" );
}
}
}
//-----------------------------------------------------------------------------
// Sys_LoadFile
//
//-----------------------------------------------------------------------------
int Sys_LoadFile( const char* filename, void** bufferptr, bool bText )
{
int handle;
long length;
char* buffer;
*bufferptr = NULL;
if ( !Sys_Exists( filename ) )
return ( -1 );
int flags = _O_RDONLY;
#if !defined( POSIX )
flags |= (bText ? _O_TEXT : _O_BINARY);
#endif
handle = _open( filename, flags );
if ( handle == -1 )
Sys_Error( "Sys_LoadFile(): Error opening %s: %s", filename, strerror( errno ) );
length = _lseek( handle, 0, SEEK_END );
_lseek( handle, 0, SEEK_SET );
buffer = ( char* )malloc( length+1 );
int bytesRead = _read( handle, buffer, length );
if ( !bText && ( bytesRead != length ) )
Sys_Error( "Sys_LoadFile(): read truncated failure" );
_close( handle );
// text mode is truncated, add null for parsing
buffer[bytesRead] = '\0';
*bufferptr = ( void* )buffer;
return ( length );
}
//-----------------------------------------------------------------------------
// Sys_FileLength
//-----------------------------------------------------------------------------
long Sys_FileLength( const char* filename, bool bText )
{
long length;
if ( filename )
{
int flags = _O_RDONLY;
#if !defined( POSIX )
flags |= (bText ? _O_TEXT : _O_BINARY);
#endif
int handle = _open( filename, flags );
if ( handle == -1 )
{
// file does not exist
return ( -1 );
}
length = _lseek( handle, 0, SEEK_END );
_close( handle );
}
else
{
return ( -1 );
}
return ( length );
}
//-----------------------------------------------------------------------------
// Sys_StripPath
//
// Removes path portion from a fully qualified name, leaving filename and extension.
//-----------------------------------------------------------------------------
void Sys_StripPath( const char* inpath, char* outpath )
{
const char* src;
src = inpath + strlen( inpath );
while ( ( src != inpath ) && ( *( src-1 ) != '\\' ) && ( *( src-1 ) != '/' ) && ( *( src-1 ) != ':' ) )
src--;
strcpy( outpath,src );
}
//-----------------------------------------------------------------------------
// Sys_Exists
//
// Returns TRUE if file exists.
//-----------------------------------------------------------------------------
bool Sys_Exists( const char* filename )
{
FILE* test;
if ( ( test = fopen( filename, "rb" ) ) == NULL )
return ( false );
fclose( test );
return ( true );
}
//-----------------------------------------------------------------------------
// Sys_FileInfo
//-----------------------------------------------------------------------------
bool Sys_FileInfo( const char *pFilename, int64 &nFileSize, int64 &nModifyTime )
{
struct _stat statData;
int rt = _stat( pFilename, &statData );
if ( rt != 0 )
return false;
nFileSize = statData.st_size;
nModifyTime = statData.st_mtime;
return true;
}
//-----------------------------------------------------------------------------
// Ignores allowable trailing characters.
//-----------------------------------------------------------------------------
bool Sys_StringToBool( const char *pString )
{
if ( !V_strnicmp( pString, "no", 2 ) ||
!V_strnicmp( pString, "off", 3 ) ||
!V_strnicmp( pString, "false", 5 ) ||
!V_strnicmp( pString, "not set", 7 ) ||
!V_strnicmp( pString, "disabled", 8 ) ||
!V_strnicmp( pString, "0", 1 ) )
{
// false
return false;
}
else if ( !V_strnicmp( pString, "yes", 3 ) ||
!V_strnicmp( pString, "on", 2 ) ||
!V_strnicmp( pString, "true", 4 ) ||
!V_strnicmp( pString, "set", 3 ) ||
!V_strnicmp( pString, "enabled", 7 ) ||
!V_strnicmp( pString, "1", 1 ) )
{
// true
return true;
}
else
{
// unknown boolean expression
g_pVPC->VPCSyntaxError( "Unknown boolean expression '%s'", pString );
}
// assume false
return false;
}
bool Sys_ReplaceString( const char *pStream, const char *pSearch, const char *pReplace, char *pOutBuff, int outBuffSize )
{
const char *pFind;
const char *pStart = pStream;
char *pOut = pOutBuff;
int len;
bool bReplaced = false;
while ( 1 )
{
// find sub string
pFind = V_stristr( pStart, pSearch );
if ( !pFind )
{
/// end of string
len = strlen( pStart );
pFind = pStart + len;
memcpy( pOut, pStart, len );
pOut += len;
break;
}
else
{
bReplaced = true;
}
// copy up to sub string
len = pFind - pStart;
memcpy( pOut, pStart, len );
pOut += len;
// substitute new string
len = strlen( pReplace );
memcpy( pOut, pReplace, len );
pOut += len;
// advance past sub string
pStart = pFind + strlen( pSearch );
}
*pOut = '\0';
return bReplaced;
}
//--------------------------------------------------------------------------------
// string match with wildcards.
// '?' = match any char
//--------------------------------------------------------------------------------
bool Sys_StringPatternMatch( char const *pSrcPattern, char const *pString )
{
for (;;)
{
char nPat = *(pSrcPattern++);
char nString= *(pString++);
if ( !( ( nPat == nString ) || ( ( nPat == '?' ) && nString ) ) )
return false;
if ( !nString )
return true; // end of string
}
}
bool Sys_EvaluateEnvironmentExpression( const char *pExpression, const char *pDefault, char *pOutBuff, int nOutBuffSize )
{
char *pEnvVarName = (char*)StringAfterPrefix( pExpression, "$env(" );
if ( !pEnvVarName )
{
// not an environment specification
return false;
}
char *pLastChar = &pEnvVarName[ V_strlen( pEnvVarName ) - 1 ];
if ( !*pEnvVarName || *pLastChar != ')' )
{
g_pVPC->VPCSyntaxError( "$env() must have a closing ')' in \"%s\"\n", pExpression );
}
// get the contents of the $env( blah..blah ) expressions
// handles expresions that could have whitepsaces
g_pVPC->GetScript().PushScript( pExpression, pEnvVarName );
const char *pToken = g_pVPC->GetScript().GetToken( false );
g_pVPC->GetScript().PopScript();
if ( pToken && pToken[0] )
{
const char *pResolve = getenv( pToken );
if ( !pResolve )
{
// not defined, use default
pResolve = pDefault ? pDefault : "";
}
V_strncpy( pOutBuff, pResolve, nOutBuffSize );
}
return true;
}
//-----------------------------------------------------------------------------
// Given some arbitrary case filename, provides what the OS thinks it is.
// Windows specific. Returns false if file cannot be resolved (i.e. does not exist).
//-----------------------------------------------------------------------------
bool Sys_GetActualFilenameCase( const char *pFilename, char *pOutputBuffer, int nOutputBufferSize )
{
#if defined( _WINDOWS )
char filenameBuffer[MAX_PATH];
V_strncpy( filenameBuffer, pFilename, sizeof( filenameBuffer ) );
V_FixSlashes( filenameBuffer );
V_RemoveDotSlashes( filenameBuffer );
int nFilenameLength = V_strlen( filenameBuffer );
CUtlString actualFilename;
// march along filename, resolving up to next seperator
int nLastComponentStart = 0;
bool bAddSeparator = false;
int i = 0;
while ( i < nFilenameLength )
{
// cannot resolve these, emit as-is
if ( !V_strnicmp( filenameBuffer + i, ".\\", 2 ) )
{
i += 2;
actualFilename += CUtlString( ".\\" );
continue;
}
// cannot resolve these, emit as-is
if ( !V_strnicmp( filenameBuffer + i, "..\\", 3 ) )
{
i += 3;
actualFilename += CUtlString( "..\\" );
continue;
}
// skip until path separator
while ( i < nFilenameLength && filenameBuffer[i] != '\\' )
{
++i;
}
bool bFoundSeparator = ( i < nFilenameLength );
// truncate at separator, windows resolves each component in pieces
filenameBuffer[i] = 0;
SHFILEINFOA info = {0};
HRESULT hr = SHGetFileInfoA( filenameBuffer, 0, &info, sizeof( info ), SHGFI_DISPLAYNAME );
if ( SUCCEEDED( hr ) )
{
// reassemble based on actual component
if ( bAddSeparator )
{
actualFilename += CUtlString( "\\" );
}
actualFilename += CUtlString( info.szDisplayName );
}
else
{
return false;
}
// restore path separator
if ( bFoundSeparator )
{
filenameBuffer[i] = '\\';
}
++i;
nLastComponentStart = i;
bAddSeparator = true;
}
V_strncpy( pOutputBuffer, actualFilename.Get(), nOutputBufferSize );
return true;
#else
return false;
#endif
}
//-----------------------------------------------------------------------------
// Given some arbitrary case filename, determine if OS version matches.
//-----------------------------------------------------------------------------
bool Sys_IsFilenameCaseConsistent( const char *pFilename, char *pOutputBuffer, int nOutputBufferSize )
{
V_strncpy( pOutputBuffer, pFilename, nOutputBufferSize );
// normalize the provided filename separators
CUtlString filename = pFilename;
V_FixSlashes( filename.Get() );
V_RemoveDotSlashes( filename.Get() );
if ( !Sys_GetActualFilenameCase( filename.Get(), pOutputBuffer, nOutputBufferSize ) )
return false;
if ( !V_strcmp( filename.Get(), pOutputBuffer ) )
return true;
return false;
}
+132
View File
@@ -0,0 +1,132 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// File Utilities.
//
//=====================================================================================//
#ifdef _WIN32
#pragma once
#endif
#define _CRT_SECURE_NO_DEPRECATE 1
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#ifdef POSIX
#include <unistd.h>
#endif
#if defined( LINUX ) || defined( _LINUX )
#include <sys/io.h>
#endif
#include "tier0/platform.h"
#include "../vpccrccheck/crccheck_shared.h"
template< class T, class NullType, int nMax >
class CSimplePointerStack
{
public:
inline CSimplePointerStack()
{
m_nCount = 0;
}
inline void Purge()
{
for ( int i=0; i < m_nCount; i++ )
m_Values[i] = (NullType)NULL;
m_nCount = 0;
}
inline int Count()
{
return m_nCount;
}
inline T& Top()
{
Assert( m_nCount > 0 );
return m_Values[m_nCount-1];
}
inline void Pop( T &val )
{
Assert( m_nCount > 0 );
--m_nCount;
val = m_Values[m_nCount];
m_Values[m_nCount] = (NullType)NULL;
}
inline void Pop()
{
Assert( m_nCount > 0 );
--m_nCount;
m_Values[m_nCount] = (NullType)NULL;
}
inline void Push( T &val )
{
Assert( m_nCount+1 < nMax );
m_Values[m_nCount] = val;
++m_nCount;
}
public:
T m_Values[nMax];
int m_nCount;
};
class CXMLWriter
{
public:
CXMLWriter();
bool Open( const char *pFilename, bool bIs2010Format = false );
void Close();
void PushNode( const char *pName );
void PopNode( bool bEmitLabel );
void WriteLineNode( const char *pName, const char *pExtra, const char *pString );
void PushNode( const char *pName, const char *pString );
void Write( const char *p );
CUtlString FixupXMLString( const char *pInput );
private:
void Indent();
bool m_b2010Format;
FILE *m_fp;
CSimplePointerStack< char *, char *, 128 > m_Nodes;
};
long Sys_FileLength( const char* filename, bool bText = false );
int Sys_LoadFile( const char *filename, void **bufferptr, bool bText = false );
void Sys_StripPath( const char *path, char *outpath );
bool Sys_Exists( const char *filename );
bool Sys_FileInfo( const char *pFilename, int64 &nFileSize, int64 &nModifyTime );
bool Sys_StringToBool( const char *pString );
bool Sys_ReplaceString( const char *pStream, const char *pSearch, const char *pReplace, char *pOutBuff, int outBuffSize );
bool Sys_StringPatternMatch( char const *pSrcPattern, char const *pString );
bool Sys_EvaluateEnvironmentExpression( const char *pExpression, const char *pDefault, char *pOutBuff, int nOutBuffSize );
bool Sys_GetActualFilenameCase( const char *pFilename, char *pOutputBuffer, int nOutputBufferSize );
bool Sys_IsFilenameCaseConsistent( const char *pFilename, char *pOutputBuffer, int nOutputBufferSize );
+426
View File
@@ -0,0 +1,426 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#pragma once
// Exclude rarely-used stuff from Windows headers
#define WIN32_LEAN_AND_MEAN
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#include "utlstring.h"
#include "utlrbtree.h"
#include "utlvector.h"
#include "utlbuffer.h"
#include "utlstack.h"
#include "utldict.h"
#include "utlsortvector.h"
#include "checksum_crc.h"
#include "checksum_md5.h"
#include "fmtstr.h"
#include "exprevaluator.h"
#include "tier1/interface.h"
#include "p4lib/ip4.h"
#include "scriptsource.h"
#include "logging.h"
#ifdef STEAM
#include "vstdlib/strtools.h"
#else
#include "tier1/strtools.h"
#endif
#include "sys_utils.h"
#include "keyvalues.h"
#include "generatordefinition.h"
DECLARE_LOGGING_CHANNEL( LOG_VPC );
#if defined( WIN32 )
#include <atlbase.h>
#include <io.h>
#endif // WIN32
struct KeywordName_t
{
const char *m_pName;
configKeyword_e m_Keyword;
};
typedef bool (*procptr_t)( const char *pPropertyName );
typedef bool (*GetSymbolProc_t)( const char *pKey );
#define INVALID_INDEX -1
struct property_t
{
const char *pName;
procptr_t handler;
int platformMask;
};
enum conditionalType_e
{
CONDITIONAL_NULL,
CONDITIONAL_PLATFORM,
CONDITIONAL_GAME,
CONDITIONAL_CUSTOM
};
struct conditional_t
{
conditional_t()
{
type = CONDITIONAL_NULL;
m_bDefined = false;
m_bGameConditionActive = false;
}
CUtlString name;
CUtlString upperCaseName;
conditionalType_e type;
// a conditional can be present in the table but not defined
// e.g. default conditionals that get set by command line args
bool m_bDefined;
// only used during multiple game iterations for game conditionals as each 'defined' game becomes active
bool m_bGameConditionActive;
};
struct macro_t
{
macro_t()
{
m_bSetupDefineInProjectFile = false;
m_bInternalCreatedMacro = false;
}
CUtlString name;
CUtlString value;
// If set to true, then VPC will add this as a -Dname=value parameter to the compiler's command line.
bool m_bSetupDefineInProjectFile;
// VPC created this macro itself rather than the macro being created from a script file.
bool m_bInternalCreatedMacro;
};
typedef int scriptIndex_t;
struct script_t
{
CUtlString name;
CUtlString m_condition;
};
typedef int projectIndex_t;
struct project_t
{
CUtlString name;
CUtlVector< script_t > scripts;
};
typedef int groupIndex_t;
struct group_t
{
CUtlVector< projectIndex_t > projects;
};
typedef int groupTagIndex_t;
struct groupTag_t
{
groupTag_t()
{
bSameAsProject = false;
}
CUtlString name;
CUtlVector< groupIndex_t > groups;
// this tag is an implicit definition of the project
bool bSameAsProject;
};
struct scriptList_t
{
scriptList_t()
{
m_crc = 0;
}
CUtlString m_scriptName;
CRC32_t m_crc;
};
class IProjectIterator
{
public:
// iProject indexes g_projectList.
virtual bool VisitProject( projectIndex_t iProject, const char *szScriptPath ) = 0;
};
#include "ibasesolutiongenerator.h"
#include "ibaseprojectgenerator.h"
#if defined( WIN32 )
#include "baseprojectdatacollector.h"
#include "projectgenerator_vcproj.h"
#include "projectgenerator_win32.h"
#include "projectgenerator_win32_2010.h"
#include "projectgenerator_xbox360.h"
#include "projectgenerator_xbox360_2010.h"
#include "projectgenerator_ps3.h"
#endif
// This just calls through to both the makefile and any platform specific solution generators.
class CPosixSolutionGenerator : public IBaseSolutionGenerator
{
public:
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
{
extern IBaseSolutionGenerator* GetSolutionGenerator_Makefile();
GetSolutionGenerator_Makefile()->GenerateSolutionFile( pSolutionFilename, projects );
#ifdef OSX
extern IBaseSolutionGenerator* GetSolutionGenerator_XCode();
GetSolutionGenerator_XCode()->GenerateSolutionFile( pSolutionFilename, projects );
#endif
}
};
class CVPC
{
public:
CVPC();
~CVPC();
bool Init( int argc, char **argv );
void Shutdown( bool bHasError = false );
void VPCError( const char *pFormat, ... );
void VPCWarning( const char *pFormat, ... );
void VPCStatus( bool bAlwaysSpew, const char *pFormat, ... );
void VPCSyntaxError( const char *pFormat = NULL, ... );
bool IsProjectCurrent( const char *pVCProjFilename );
bool HasCommandLineParameter( const char *pParamName );
bool HasP4SLNCommand();
CScript &GetScript() { return m_Script; }
bool IsVerbose() { return m_bVerbose; }
bool IsQuiet() { return m_bQuiet; }
bool IsShowDependencies() { return m_bShowDeps; }
bool IsForceGenerate() { return m_bForceGenerate; }
bool IsForceIterate() { return m_bForceIterate; }
bool IsDecorateProject() { return m_bDecorateProject; }
bool IsCheckFiles() { return m_bCheckFiles; }
bool Is2010() { return m_bUse2010; }
bool Is2012() { return m_bUse2012; } // When this returns true so does Is2010() because of the file format similarities
bool Is2013() { return m_bUse2013; } // When this returns true so does Is2010() because of the file format similarities
bool IsShowCaseIssues() { return m_bShowCaseIssues; }
bool IsIgnoreRedundancyWarning() { return m_bIgnoreRedundancyWarning; }
void SetIgnoreRedundancyWarning( bool bSet ) { m_bIgnoreRedundancyWarning = bSet; }
const char *GetStartDirectory() { return m_StartDirectory.Get(); }
const char *GetSourcePath() { return m_SourcePath.Get(); }
const char *GetCRCString() { return m_SupplementalCRCString.Get(); }
const char *GetSolutionItemsFilename() { return m_SolutionItemsFilename.Get(); }
const char *GetOutputFilename() { return m_OutputFilename.Get(); }
void SetOutputFilename( const char *pOutputFilename ) { m_OutputFilename = pOutputFilename; }
const char *GetProjectName() { return m_ProjectName.Get(); }
void SetProjectName( const char *pProjectName ) { m_ProjectName = pProjectName; }
const char *GetLoadAddressName() { return m_LoadAddressName.Get(); }
void SetLoadAddressName( const char *pLoadAddressName ) { m_LoadAddressName = pLoadAddressName; }
int ProcessCommandLine();
// Returns the mask identifying what platforms whould be built
bool IsPlatformDefined( const char *pName );
const char *GetTargetPlatformName();
IBaseProjectGenerator *GetProjectGenerator() { return m_pProjectGenerator; }
void SetProjectGenerator( IBaseProjectGenerator *pGenerator ) { m_pProjectGenerator = pGenerator; }
IBaseSolutionGenerator *GetSolutionGenerator() { return m_pSolutionGenerator; }
// Conditionals
conditional_t *FindOrCreateConditional( const char *pName, bool bCreate, conditionalType_e type );
bool ResolveConditionalSymbol( const char *pSymbol );
bool EvaluateConditionalExpression( const char *pExpression );
bool ConditionHasDefinedType( const char* pCondition, conditionalType_e type );
void SetConditional( const char *pName, bool bSet = true );
// Macros
macro_t *FindOrCreateMacro( const char *pName, bool bCreate, const char *pValue );
void ResolveMacrosInString( char const *pString, char *pOutBuff, int outBuffSize );
int GetMacrosMarkedForCompilerDefines( CUtlVector< macro_t* > &macroDefines );
void RemoveScriptCreatedMacros();
const char *GetMacroValue( const char *pName );
void SetMacro( const char *pName, const char *pValue, bool bSetupDefineInProjectFile );
// Iterates all the projects in the specified list, checks their conditionals, and calls pIterator->VisitProject for
// each one that passes the conditional tests.
//
// If bForce is false, then it does a CRC check before visiting any project to see if the target project file is
// already up-to-date with its .vpc file.
void IterateTargetProjects( CUtlVector<projectIndex_t> &projectList, IProjectIterator *pIterator );
bool ParseProjectScript( const char *pScriptName, int depth, bool bQuiet, bool bWriteCRCCheckFile );
void AddScriptToCRCCheck( const char *pScriptName, CRC32_t crc );
const char *KeywordToName( configKeyword_e keyword );
configKeyword_e NameToKeyword( const char *pKeywordName );
private:
void SpewUsage( void );
bool LoadPerforceInterface();
void UnloadPerforceInterface();
void InProcessCRCCheck();
void CheckForInstalledXDK();
void CheckForInstalledPS3SDK();
void DetermineSourcePath();
void SetDefaultSourcePath();
void SetupGenerators();
void SetupDefaultConditionals();
void SetMacrosAndConditionals();
void HandleSingleCommandLineArg( const char *pArg );
void ParseBuildOptions( int argc, char *argv[] );
bool CheckBinPath( char *pOutBinPath, int outBinPathSize );
bool RestartFromCorrectLocation( bool *pIsChild );
void GenerateOptionsCRCString();
void CreateOutputFilename( project_t *pProject, const char *pchPlatform, const char *pGameName, const char *pchExtension );
void FindProjectFromVCPROJ( const char *pScriptNameVCProj );
const char *BuildTempGroupScript( const char *pScriptName );
bool HandleP4SLN( IBaseSolutionGenerator *pSolutionGenerator );
void HandleMKSLN( IBaseSolutionGenerator *pSolutionGenerator, CProjectDependencyGraph &dependencyGraph );
void GenerateBuildSet( CProjectDependencyGraph &dependencyGraph );
bool BuildTargetProjects();
bool BuildTargetProject( IProjectIterator *pIterator, projectIndex_t projectIndex, script_t *pProjectScript, const char *pGameName );
bool m_bVerbose;
bool m_bQuiet;
bool m_bUsageOnly;
bool m_bHelp;
bool m_bSpewPlatforms;
bool m_bSpewGames;
bool m_bSpewGroups;
bool m_bSpewProjects;
bool m_bIgnoreRedundancyWarning;
bool m_bSpewProperties;
bool m_bTestMode;
bool m_bForceGenerate;
bool m_bForceIterate;
bool m_bEnableVpcGameMacro;
bool m_bCheckFiles;
bool m_bDecorateProject;
bool m_bShowDeps;
bool m_bP4AutoAdd;
bool m_bP4SlnCheckEverything;
bool m_bDedicatedBuild;
bool m_bAnyProjectQualified;
bool m_bUse2010;
bool m_bWants2010;
bool m_bUse2012;
bool m_bWants2012;
bool m_bUse2013;
bool m_bWants2013;
bool m_bPS3SDKPresent;
bool m_bXDKPresent;
bool m_bShowCaseIssues;
int m_nArgc;
char **m_ppArgv;
CColorizedLoggingListener m_LoggingListener;
CSysModule *m_pP4Module;
CSysModule *m_pFilesystemModule;
CScript m_Script;
// Path where vpc was started from
CUtlString m_StartDirectory;
// Root path to the sources (i.e. the directory where the vpc_scripts directory can be found in).
CUtlString m_SourcePath;
// strings derived from command-line commands which is checked alongside project CRCs:
CUtlString m_SupplementalCRCString;
CUtlString m_ExtraOptionsCRCString;
CUtlString m_MKSolutionFilename;
CUtlString m_SolutionItemsFilename; // For /slnitems
CUtlString m_P4SolutionFilename; // For /p4sln
CUtlVector< int > m_iP4Changelists;
CUtlString m_OutputFilename;
CUtlString m_ProjectName;
CUtlString m_LoadAddressName;
CUtlString m_TempGroupScriptFilename;
// This abstracts the differences between different output methods.
IBaseProjectGenerator *m_pProjectGenerator;
IBaseSolutionGenerator *m_pSolutionGenerator;
CUtlVector< CUtlString > m_BuildCommands;
public:
CUtlVector< conditional_t > m_Conditionals;
CUtlVector< macro_t > m_Macros;
CUtlVector< scriptList_t > m_ScriptList;
CUtlVector< project_t > m_Projects;
CUtlVector< projectIndex_t > m_TargetProjects;
CUtlVector< group_t > m_Groups;
CUtlVector< groupTag_t > m_GroupTags;
CUtlVector< CUtlString > m_SchemaFiles;
CUtlDict< CUtlString, int > m_CustomBuildSteps;
bool m_bGeneratedProject;
};
extern CVPC *g_pVPC;
extern const char *g_pOption_ImportLibrary; // "$ImportLibrary";
extern const char *g_pOption_OutputFile; // "$OutputFile";
extern const char *g_pOption_AdditionalIncludeDirectories; // "$AdditionalIncludeDirectories"
extern const char *g_pOption_AdditionalProjectDependencies; // "$AdditionalProjectDependencies"
extern const char *g_pOption_AdditionalOutputFiles; // "$AdditionalOutputFiles"
extern const char *g_pOption_PreprocessorDefinitions; // "$PreprocessorDefinitions"
extern char *g_IncludeSeparators[2];
extern void VPC_ParseGroupScript( const char *pScriptName );
extern groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate );
extern void VPC_Keyword_Configuration();
extern void VPC_Keyword_FileConfiguration();
extern void VPC_Config_SpewProperties( configKeyword_e keyword );
extern bool VPC_Config_IgnoreOption( const char *pPropertyName );
extern void VPC_FakeKeyword_SchemaFolder( class CBaseProjectDataCollector *pDataCollector );
+121
View File
@@ -0,0 +1,121 @@
//-----------------------------------------------------------------------------
// VPC.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$Macro OUTBINDIR "$SRCDIR\devtools\bin" [!$OSX32]
$Macro OUTBINDIR "$SRCDIR\devtools\bin\osx" [$OSX32]
$Include "$SRCDIR\vpc_scripts\source_dll_win32_base.vpc" [!$OSX32]
$Include "$SRCDIR\vpc_scripts\source_dll_linux_base.vpc" [$OSX32]
$Configuration
{
$General
{
$AdditionalProjectDependencies "$BASE;binlaunch;p4lib;filesystem_stdio"
}
$Compiler
{
$PreprocessorDefinitions "$BASE;_USE_32BIT_TIME_T;_USRDLL"
$DisableSpecificWarnings "4005"
$AdditionalOptions "/MP1"
}
$Linker
{
$AdditionalDependencies "ws2_32.lib"
}
$PostBuildEvent [$WIN32]
{
// Copy binlaunch.exe to our exe.
$CommandLine "$BASE" "\n" \
"\n" \
"echo ... Copying BINLAUNCH.EXE to VPC.EXE" "\n" \
"call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $OUTBINDIR\vpc.exe $SRCDIR" "\n" \
"copy $SRCDIR\devtools\bin\binlaunch.exe $OUTBINDIR\vpc.exe" "\n" \
"if ERRORLEVEL 1 goto BinLaunchCopyFailed" "\n" \
"\n" \
"goto BinLaunchCopyOK" "\n" \
"\n" \
":BinLaunchCopyFailed" "\n" \
"echo *** ERROR! binlaunch copy step failed." "\n" \
"del /q $QUOTE$(TargetDir)$QUOTE$(TargetFileName)" "\n" \
"exit 1" "\n" \
"\n" \
":BinLaunchCopyOK" "\n" \
"\n"
}
}
$Project "vpc"
{
$Folder "Source Files"
{
$File "baseprojectdatacollector.cpp"
$File "configuration.cpp"
$File "../vpccrccheck/crccheck_shared.cpp"
$File "dependencies.cpp"
$File "GroupScript.cpp"
$File "main.cpp"
$File "p4sln.cpp" [$WIN32]
$File "projectgenerator_vcproj.cpp"
$File "projectgenerator_makefile.cpp"
$File "projectgenerator_xcode.cpp"
$File "projectgenerator_win32.cpp" [$WIN32]
$File "projectgenerator_win32_2010.cpp" [$WIN32]
$File "projectgenerator_ps3.cpp"
$File "projectgenerator_xbox360.cpp"
$File "projectgenerator_xbox360_2010.cpp"
$File "ProjectScript.cpp"
$File "scriptsource.cpp"
$File "solutiongenerator_makefile.cpp"
$File "solutiongenerator_xcode.cpp"
$File "solutiongenerator_win32.cpp" [$WIN32]
$File "sys_utils.cpp"
$File "macros.cpp"
$File "conditionals.cpp"
$File "generatordefinition.cpp"
}
$Folder "Header Files"
{
$File "baseprojectdatacollector.h"
$File "dependencies.h"
$File "ibaseprojectgenerator.h"
$File "ibasesolutiongenerator.h"
$File "p4sln.h" [$WIN32]
$File "projectgenerator_xcode.h"
$file "projectgenerator_ps3.h"
$file "projectgenerator_ps3.inc"
$file "projectgenerator_win32_2010.h"
$File "projectgenerator_win32_2010.inc"
$file "projectgenerator_win32.h"
$File "projectgenerator_win32.inc"
$File "projectgenerator_vcproj.h"
$File "projectgenerator_xbox360.h"
$File "projectgenerator_xbox360.inc"
$File "projectgenerator_xbox360_2010.h"
$File "projectgenerator_xbox360_2010.inc"
$File "scriptsource.h"
$file "sys_utils.h"
$File "vpc.h"
$File "generatordefinition.h"
}
$Folder "VPC Scripts"
{
$Folder "Definitions"
{
$File "$SRCDIR\vpc_scripts\definitions\ps3.def"
$File "$SRCDIR\vpc_scripts\definitions\xbox360.def"
$File "$SRCDIR\vpc_scripts\definitions\xbox360_2010.def"
$File "$SRCDIR\vpc_scripts\definitions\win32_2005.def"
$File "$SRCDIR\vpc_scripts\definitions\win32_2010.def"
}
}
}
+529
View File
@@ -0,0 +1,529 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
976DE7B71239412500E8D60A /* crccheck_shared.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 976DE7B51239412500E8D60A /* crccheck_shared.cpp */; };
976DE7BA1239423E00E8D60A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 976DE7B91239423E00E8D60A /* Foundation.framework */; };
976DE7BC1239424500E8D60A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 976DE7BB1239424500E8D60A /* CoreServices.framework */; };
976DE7BE1239424E00E8D60A /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 976DE7BD1239424E00E8D60A /* libiconv.dylib */; };
977F706212393A2A008D8433 /* baseprojectdatacollector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705012393A2A008D8433 /* baseprojectdatacollector.cpp */; };
977F706312393A2A008D8433 /* configuration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705212393A2A008D8433 /* configuration.cpp */; };
977F706412393A2A008D8433 /* dependencies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705312393A2A008D8433 /* dependencies.cpp */; };
977F706512393A2A008D8433 /* ExprSimplifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705512393A2A008D8433 /* ExprSimplifier.cpp */; };
977F706612393A2A008D8433 /* GroupScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705612393A2A008D8433 /* GroupScript.cpp */; };
977F706712393A2A008D8433 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705912393A2A008D8433 /* main.cpp */; };
977F706812393A2A008D8433 /* projectgenerator_makefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705A12393A2A008D8433 /* projectgenerator_makefile.cpp */; };
977F706912393A2A008D8433 /* projectgenerator_xcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705B12393A2A008D8433 /* projectgenerator_xcode.cpp */; };
977F706A12393A2A008D8433 /* ProjectScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705D12393A2A008D8433 /* ProjectScript.cpp */; };
977F706B12393A2A008D8433 /* solutiongenerator_makefile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705E12393A2A008D8433 /* solutiongenerator_makefile.cpp */; };
977F706C12393A2A008D8433 /* solutiongenerator_xcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F705F12393A2A008D8433 /* solutiongenerator_xcode.cpp */; };
977F706D12393A2A008D8433 /* sys_utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F706012393A2A008D8433 /* sys_utils.cpp */; };
977F708912393ADD008D8433 /* assert_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707212393ADD008D8433 /* assert_dialog.cpp */; };
977F708A12393ADD008D8433 /* cpu_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707312393ADD008D8433 /* cpu_posix.cpp */; };
977F708B12393ADD008D8433 /* cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707412393ADD008D8433 /* cpu.cpp */; };
977F708C12393ADD008D8433 /* dbg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707512393ADD008D8433 /* dbg.cpp */; };
977F708D12393ADD008D8433 /* fasttimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707612393ADD008D8433 /* fasttimer.cpp */; };
977F708E12393ADD008D8433 /* mem_helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707712393ADD008D8433 /* mem_helpers.cpp */; };
977F708F12393ADD008D8433 /* memblockhdr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707812393ADD008D8433 /* memblockhdr.cpp */; };
977F709012393ADD008D8433 /* memdbg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707912393ADD008D8433 /* memdbg.cpp */; };
977F709112393ADD008D8433 /* memstd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707A12393ADD008D8433 /* memstd.cpp */; };
977F709212393ADD008D8433 /* memvalidate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707B12393ADD008D8433 /* memvalidate.cpp */; };
977F709312393ADD008D8433 /* minidump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707C12393ADD008D8433 /* minidump.cpp */; };
977F709412393ADD008D8433 /* pch_tier0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707D12393ADD008D8433 /* pch_tier0.cpp */; };
977F709512393ADD008D8433 /* platform_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707E12393ADD008D8433 /* platform_posix.cpp */; };
977F709612393ADD008D8433 /* pme_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F707F12393ADD008D8433 /* pme_posix.cpp */; };
977F709712393ADD008D8433 /* pmelib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708012393ADD008D8433 /* pmelib.cpp */; };
977F709812393ADD008D8433 /* testthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708112393ADD008D8433 /* testthread.cpp */; };
977F709912393ADD008D8433 /* thread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708212393ADD008D8433 /* thread.cpp */; };
977F709A12393ADD008D8433 /* threadtools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708312393ADD008D8433 /* threadtools.cpp */; };
977F709B12393ADD008D8433 /* tier0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708412393ADD008D8433 /* tier0.cpp */; };
977F709C12393ADD008D8433 /* validator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708512393ADD008D8433 /* validator.cpp */; };
977F709D12393ADD008D8433 /* valobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708612393ADD008D8433 /* valobject.cpp */; };
977F709E12393ADD008D8433 /* vcrmode_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708712393ADD008D8433 /* vcrmode_posix.cpp */; };
977F709F12393ADD008D8433 /* vprof.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F708812393ADD008D8433 /* vprof.cpp */; };
977F70AB12393B10008D8433 /* checksum_crc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A012393B10008D8433 /* checksum_crc.cpp */; };
977F70AC12393B10008D8433 /* checksum_md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A112393B10008D8433 /* checksum_md5.cpp */; };
977F70AD12393B10008D8433 /* convar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A212393B10008D8433 /* convar.cpp */; };
977F70AE12393B10008D8433 /* generichash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A312393B10008D8433 /* generichash.cpp */; };
977F70AF12393B10008D8433 /* interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A412393B10008D8433 /* interface.cpp */; };
977F70B012393B10008D8433 /* KeyValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A512393B10008D8433 /* KeyValues.cpp */; };
977F70B112393B10008D8433 /* mempool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A612393B10008D8433 /* mempool.cpp */; };
977F70B212393B10008D8433 /* memstack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A712393B10008D8433 /* memstack.cpp */; };
977F70B312393B10008D8433 /* stringpool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A812393B10008D8433 /* stringpool.cpp */; };
977F70B412393B10008D8433 /* utlbuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70A912393B10008D8433 /* utlbuffer.cpp */; };
977F70B512393B10008D8433 /* utlsymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70AA12393B10008D8433 /* utlsymbol.cpp */; };
977F70BF12393B49008D8433 /* commandline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70B612393B49008D8433 /* commandline.cpp */; };
977F70C012393B49008D8433 /* cvar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70B712393B49008D8433 /* cvar.cpp */; };
977F70C112393B49008D8433 /* keyvaluessystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70B812393B49008D8433 /* keyvaluessystem.cpp */; };
977F70C212393B49008D8433 /* osversion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70B912393B49008D8433 /* osversion.cpp */; };
977F70C312393B49008D8433 /* qsort_s.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70BA12393B49008D8433 /* qsort_s.cpp */; };
977F70C412393B49008D8433 /* random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70BB12393B49008D8433 /* random.cpp */; };
977F70C512393B49008D8433 /* splitstring.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70BC12393B49008D8433 /* splitstring.cpp */; };
977F70C612393B49008D8433 /* stringnormalize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70BD12393B49008D8433 /* stringnormalize.cpp */; };
977F70C712393B49008D8433 /* strtools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 977F70BE12393B49008D8433 /* strtools.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
977F703E12393174008D8433 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
976DE7B51239412500E8D60A /* crccheck_shared.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crccheck_shared.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpccrccheck/crccheck_shared.cpp; sourceTree = "<absolute>"; };
976DE7B61239412500E8D60A /* crccheck_shared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crccheck_shared.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpccrccheck/crccheck_shared.h; sourceTree = "<absolute>"; };
976DE7B91239423E00E8D60A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Xcode4/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
976DE7BB1239424500E8D60A /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = Xcode4/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
976DE7BD1239424E00E8D60A /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = Xcode4/SDKs/MacOSX10.5.sdk/usr/lib/libiconv.dylib; sourceTree = SDKROOT; };
977F704012393174008D8433 /* vpc_osx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = vpc_osx; sourceTree = BUILT_PRODUCTS_DIR; };
977F705012393A2A008D8433 /* baseprojectdatacollector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = baseprojectdatacollector.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/baseprojectdatacollector.cpp; sourceTree = "<absolute>"; };
977F705112393A2A008D8433 /* baseprojectdatacollector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = baseprojectdatacollector.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/baseprojectdatacollector.h; sourceTree = "<absolute>"; };
977F705212393A2A008D8433 /* configuration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = configuration.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/configuration.cpp; sourceTree = "<absolute>"; };
977F705312393A2A008D8433 /* dependencies.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dependencies.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/dependencies.cpp; sourceTree = "<absolute>"; };
977F705412393A2A008D8433 /* dependencies.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dependencies.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/dependencies.h; sourceTree = "<absolute>"; };
977F705512393A2A008D8433 /* ExprSimplifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprSimplifier.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/ExprSimplifier.cpp; sourceTree = "<absolute>"; };
977F705612393A2A008D8433 /* GroupScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GroupScript.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/GroupScript.cpp; sourceTree = "<absolute>"; };
977F705712393A2A008D8433 /* ibaseprojectgenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ibaseprojectgenerator.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/ibaseprojectgenerator.h; sourceTree = "<absolute>"; };
977F705812393A2A008D8433 /* ibasesolutiongenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ibasesolutiongenerator.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/ibasesolutiongenerator.h; sourceTree = "<absolute>"; };
977F705912393A2A008D8433 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/main.cpp; sourceTree = "<absolute>"; };
977F705A12393A2A008D8433 /* projectgenerator_makefile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = projectgenerator_makefile.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/projectgenerator_makefile.cpp; sourceTree = "<absolute>"; };
977F705B12393A2A008D8433 /* projectgenerator_xcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = projectgenerator_xcode.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/projectgenerator_xcode.cpp; sourceTree = "<absolute>"; };
977F705C12393A2A008D8433 /* projectgenerator_xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = projectgenerator_xcode.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/projectgenerator_xcode.h; sourceTree = "<absolute>"; };
977F705D12393A2A008D8433 /* ProjectScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProjectScript.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/ProjectScript.cpp; sourceTree = "<absolute>"; };
977F705E12393A2A008D8433 /* solutiongenerator_makefile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = solutiongenerator_makefile.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/solutiongenerator_makefile.cpp; sourceTree = "<absolute>"; };
977F705F12393A2A008D8433 /* solutiongenerator_xcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = solutiongenerator_xcode.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/solutiongenerator_xcode.cpp; sourceTree = "<absolute>"; };
977F706012393A2A008D8433 /* sys_utils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = sys_utils.cpp; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/sys_utils.cpp; sourceTree = "<absolute>"; };
977F706112393A2A008D8433 /* sys_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sys_utils.h; path = /Users/dberger/P4Clients/steam3_main/src/utils/vpc/sys_utils.h; sourceTree = "<absolute>"; };
977F707212393ADD008D8433 /* assert_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = assert_dialog.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/assert_dialog.cpp; sourceTree = "<absolute>"; };
977F707312393ADD008D8433 /* cpu_posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpu_posix.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/cpu_posix.cpp; sourceTree = "<absolute>"; };
977F707412393ADD008D8433 /* cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cpu.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/cpu.cpp; sourceTree = "<absolute>"; };
977F707512393ADD008D8433 /* dbg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = dbg.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/dbg.cpp; sourceTree = "<absolute>"; };
977F707612393ADD008D8433 /* fasttimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = fasttimer.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/fasttimer.cpp; sourceTree = "<absolute>"; };
977F707712393ADD008D8433 /* mem_helpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mem_helpers.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/mem_helpers.cpp; sourceTree = "<absolute>"; };
977F707812393ADD008D8433 /* memblockhdr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memblockhdr.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/memblockhdr.cpp; sourceTree = "<absolute>"; };
977F707912393ADD008D8433 /* memdbg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memdbg.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/memdbg.cpp; sourceTree = "<absolute>"; };
977F707A12393ADD008D8433 /* memstd.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memstd.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/memstd.cpp; sourceTree = "<absolute>"; };
977F707B12393ADD008D8433 /* memvalidate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memvalidate.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/memvalidate.cpp; sourceTree = "<absolute>"; };
977F707C12393ADD008D8433 /* minidump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidump.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/minidump.cpp; sourceTree = "<absolute>"; };
977F707D12393ADD008D8433 /* pch_tier0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pch_tier0.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/pch_tier0.cpp; sourceTree = "<absolute>"; };
977F707E12393ADD008D8433 /* platform_posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = platform_posix.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/platform_posix.cpp; sourceTree = "<absolute>"; };
977F707F12393ADD008D8433 /* pme_posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pme_posix.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/pme_posix.cpp; sourceTree = "<absolute>"; };
977F708012393ADD008D8433 /* pmelib.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = pmelib.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/pmelib.cpp; sourceTree = "<absolute>"; };
977F708112393ADD008D8433 /* testthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testthread.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/testthread.cpp; sourceTree = "<absolute>"; };
977F708212393ADD008D8433 /* thread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = thread.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/thread.cpp; sourceTree = "<absolute>"; };
977F708312393ADD008D8433 /* threadtools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = threadtools.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/threadtools.cpp; sourceTree = "<absolute>"; };
977F708412393ADD008D8433 /* tier0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tier0.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/tier0.cpp; sourceTree = "<absolute>"; };
977F708512393ADD008D8433 /* validator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = validator.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/validator.cpp; sourceTree = "<absolute>"; };
977F708612393ADD008D8433 /* valobject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = valobject.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/valobject.cpp; sourceTree = "<absolute>"; };
977F708712393ADD008D8433 /* vcrmode_posix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vcrmode_posix.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/vcrmode_posix.cpp; sourceTree = "<absolute>"; };
977F708812393ADD008D8433 /* vprof.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = vprof.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier0/vprof.cpp; sourceTree = "<absolute>"; };
977F70A012393B10008D8433 /* checksum_crc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = checksum_crc.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/checksum_crc.cpp; sourceTree = "<absolute>"; };
977F70A112393B10008D8433 /* checksum_md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = checksum_md5.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/checksum_md5.cpp; sourceTree = "<absolute>"; };
977F70A212393B10008D8433 /* convar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = convar.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/convar.cpp; sourceTree = "<absolute>"; };
977F70A312393B10008D8433 /* generichash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = generichash.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/generichash.cpp; sourceTree = "<absolute>"; };
977F70A412393B10008D8433 /* interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = interface.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/interface.cpp; sourceTree = "<absolute>"; };
977F70A512393B10008D8433 /* KeyValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KeyValues.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/KeyValues.cpp; sourceTree = "<absolute>"; };
977F70A612393B10008D8433 /* mempool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mempool.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/mempool.cpp; sourceTree = "<absolute>"; };
977F70A712393B10008D8433 /* memstack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memstack.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/memstack.cpp; sourceTree = "<absolute>"; };
977F70A812393B10008D8433 /* stringpool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stringpool.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/stringpool.cpp; sourceTree = "<absolute>"; };
977F70A912393B10008D8433 /* utlbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = utlbuffer.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/utlbuffer.cpp; sourceTree = "<absolute>"; };
977F70AA12393B10008D8433 /* utlsymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = utlsymbol.cpp; path = /Users/dberger/P4Clients/steam3_main/src/tier1/utlsymbol.cpp; sourceTree = "<absolute>"; };
977F70B612393B49008D8433 /* commandline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = commandline.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/commandline.cpp; sourceTree = "<absolute>"; };
977F70B712393B49008D8433 /* cvar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cvar.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/cvar.cpp; sourceTree = "<absolute>"; };
977F70B812393B49008D8433 /* keyvaluessystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = keyvaluessystem.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/keyvaluessystem.cpp; sourceTree = "<absolute>"; };
977F70B912393B49008D8433 /* osversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = osversion.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/osversion.cpp; sourceTree = "<absolute>"; };
977F70BA12393B49008D8433 /* qsort_s.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qsort_s.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/qsort_s.cpp; sourceTree = "<absolute>"; };
977F70BB12393B49008D8433 /* random.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = random.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/random.cpp; sourceTree = "<absolute>"; };
977F70BC12393B49008D8433 /* splitstring.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = splitstring.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/splitstring.cpp; sourceTree = "<absolute>"; };
977F70BD12393B49008D8433 /* stringnormalize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = stringnormalize.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/stringnormalize.cpp; sourceTree = "<absolute>"; };
977F70BE12393B49008D8433 /* strtools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = strtools.cpp; path = /Users/dberger/P4Clients/steam3_main/src/vstdlib/strtools.cpp; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
977F703D12393174008D8433 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
976DE7BE1239424E00E8D60A /* libiconv.dylib in Frameworks */,
976DE7BC1239424500E8D60A /* CoreServices.framework in Frameworks */,
976DE7BA1239423E00E8D60A /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
976DE7B41239411300E8D60A /* crccheck_shared */ = {
isa = PBXGroup;
children = (
976DE7B51239412500E8D60A /* crccheck_shared.cpp */,
976DE7B61239412500E8D60A /* crccheck_shared.h */,
);
name = crccheck_shared;
sourceTree = "<group>";
};
976DE7BF1239425600E8D60A /* Libs */ = {
isa = PBXGroup;
children = (
976DE7BD1239424E00E8D60A /* libiconv.dylib */,
976DE7BB1239424500E8D60A /* CoreServices.framework */,
976DE7B91239423E00E8D60A /* Foundation.framework */,
);
name = Libs;
sourceTree = "<group>";
};
977F703312393173008D8433 = {
isa = PBXGroup;
children = (
977F703A12393174008D8433 /* Source */,
976DE7BF1239425600E8D60A /* Libs */,
977F704112393174008D8433 /* Products */,
);
sourceTree = "<group>";
};
977F703A12393174008D8433 /* Source */ = {
isa = PBXGroup;
children = (
977F706F12393A45008D8433 /* tier0 */,
977F707012393A4D008D8433 /* tier1 */,
977F707112393A56008D8433 /* vstdlib */,
976DE7B41239411300E8D60A /* crccheck_shared */,
977F706E12393A3D008D8433 /* vpc */,
);
path = Source;
sourceTree = "<group>";
};
977F704112393174008D8433 /* Products */ = {
isa = PBXGroup;
children = (
977F704012393174008D8433 /* vpc_osx */,
);
name = Products;
sourceTree = "<group>";
};
977F706E12393A3D008D8433 /* vpc */ = {
isa = PBXGroup;
children = (
977F705012393A2A008D8433 /* baseprojectdatacollector.cpp */,
977F705112393A2A008D8433 /* baseprojectdatacollector.h */,
977F705212393A2A008D8433 /* configuration.cpp */,
977F705312393A2A008D8433 /* dependencies.cpp */,
977F705412393A2A008D8433 /* dependencies.h */,
977F705512393A2A008D8433 /* ExprSimplifier.cpp */,
977F705612393A2A008D8433 /* GroupScript.cpp */,
977F705712393A2A008D8433 /* ibaseprojectgenerator.h */,
977F705812393A2A008D8433 /* ibasesolutiongenerator.h */,
977F705912393A2A008D8433 /* main.cpp */,
977F705A12393A2A008D8433 /* projectgenerator_makefile.cpp */,
977F705B12393A2A008D8433 /* projectgenerator_xcode.cpp */,
977F705C12393A2A008D8433 /* projectgenerator_xcode.h */,
977F705D12393A2A008D8433 /* ProjectScript.cpp */,
977F705E12393A2A008D8433 /* solutiongenerator_makefile.cpp */,
977F705F12393A2A008D8433 /* solutiongenerator_xcode.cpp */,
977F706012393A2A008D8433 /* sys_utils.cpp */,
977F706112393A2A008D8433 /* sys_utils.h */,
);
name = vpc;
sourceTree = "<group>";
};
977F706F12393A45008D8433 /* tier0 */ = {
isa = PBXGroup;
children = (
977F707212393ADD008D8433 /* assert_dialog.cpp */,
977F707312393ADD008D8433 /* cpu_posix.cpp */,
977F707412393ADD008D8433 /* cpu.cpp */,
977F707512393ADD008D8433 /* dbg.cpp */,
977F707612393ADD008D8433 /* fasttimer.cpp */,
977F707712393ADD008D8433 /* mem_helpers.cpp */,
977F707812393ADD008D8433 /* memblockhdr.cpp */,
977F707912393ADD008D8433 /* memdbg.cpp */,
977F707A12393ADD008D8433 /* memstd.cpp */,
977F707B12393ADD008D8433 /* memvalidate.cpp */,
977F707C12393ADD008D8433 /* minidump.cpp */,
977F707D12393ADD008D8433 /* pch_tier0.cpp */,
977F707E12393ADD008D8433 /* platform_posix.cpp */,
977F707F12393ADD008D8433 /* pme_posix.cpp */,
977F708012393ADD008D8433 /* pmelib.cpp */,
977F708112393ADD008D8433 /* testthread.cpp */,
977F708212393ADD008D8433 /* thread.cpp */,
977F708312393ADD008D8433 /* threadtools.cpp */,
977F708412393ADD008D8433 /* tier0.cpp */,
977F708512393ADD008D8433 /* validator.cpp */,
977F708612393ADD008D8433 /* valobject.cpp */,
977F708712393ADD008D8433 /* vcrmode_posix.cpp */,
977F708812393ADD008D8433 /* vprof.cpp */,
);
name = tier0;
sourceTree = "<group>";
};
977F707012393A4D008D8433 /* tier1 */ = {
isa = PBXGroup;
children = (
977F70A012393B10008D8433 /* checksum_crc.cpp */,
977F70A112393B10008D8433 /* checksum_md5.cpp */,
977F70A212393B10008D8433 /* convar.cpp */,
977F70A312393B10008D8433 /* generichash.cpp */,
977F70A412393B10008D8433 /* interface.cpp */,
977F70A512393B10008D8433 /* KeyValues.cpp */,
977F70A612393B10008D8433 /* mempool.cpp */,
977F70A712393B10008D8433 /* memstack.cpp */,
977F70A812393B10008D8433 /* stringpool.cpp */,
977F70A912393B10008D8433 /* utlbuffer.cpp */,
977F70AA12393B10008D8433 /* utlsymbol.cpp */,
);
name = tier1;
sourceTree = "<group>";
};
977F707112393A56008D8433 /* vstdlib */ = {
isa = PBXGroup;
children = (
977F70B612393B49008D8433 /* commandline.cpp */,
977F70B712393B49008D8433 /* cvar.cpp */,
977F70B812393B49008D8433 /* keyvaluessystem.cpp */,
977F70B912393B49008D8433 /* osversion.cpp */,
977F70BA12393B49008D8433 /* qsort_s.cpp */,
977F70BB12393B49008D8433 /* random.cpp */,
977F70BC12393B49008D8433 /* splitstring.cpp */,
977F70BD12393B49008D8433 /* stringnormalize.cpp */,
977F70BE12393B49008D8433 /* strtools.cpp */,
);
name = vstdlib;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
977F703F12393174008D8433 /* vpc */ = {
isa = PBXNativeTarget;
buildConfigurationList = 977F704812393174008D8433 /* Build configuration list for PBXNativeTarget "vpc" */;
buildPhases = (
977F703C12393174008D8433 /* Sources */,
977F703D12393174008D8433 /* Frameworks */,
977F703E12393174008D8433 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = vpc;
productName = vpc;
productReference = 977F704012393174008D8433 /* vpc_osx */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
977F703512393173008D8433 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 977F703812393173008D8433 /* Build configuration list for PBXProject "vpc" */;
compatibilityVersion = "Xcode 3.2";
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 977F703312393173008D8433;
productRefGroup = 977F704112393174008D8433 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
977F703F12393174008D8433 /* vpc */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
977F703C12393174008D8433 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
977F706212393A2A008D8433 /* baseprojectdatacollector.cpp in Sources */,
977F706312393A2A008D8433 /* configuration.cpp in Sources */,
977F706412393A2A008D8433 /* dependencies.cpp in Sources */,
977F706512393A2A008D8433 /* ExprSimplifier.cpp in Sources */,
977F706612393A2A008D8433 /* GroupScript.cpp in Sources */,
977F706712393A2A008D8433 /* main.cpp in Sources */,
977F706812393A2A008D8433 /* projectgenerator_makefile.cpp in Sources */,
977F706912393A2A008D8433 /* projectgenerator_xcode.cpp in Sources */,
977F706A12393A2A008D8433 /* ProjectScript.cpp in Sources */,
977F706B12393A2A008D8433 /* solutiongenerator_makefile.cpp in Sources */,
977F706C12393A2A008D8433 /* solutiongenerator_xcode.cpp in Sources */,
977F706D12393A2A008D8433 /* sys_utils.cpp in Sources */,
977F708912393ADD008D8433 /* assert_dialog.cpp in Sources */,
977F708A12393ADD008D8433 /* cpu_posix.cpp in Sources */,
977F708B12393ADD008D8433 /* cpu.cpp in Sources */,
977F708C12393ADD008D8433 /* dbg.cpp in Sources */,
977F708D12393ADD008D8433 /* fasttimer.cpp in Sources */,
977F708E12393ADD008D8433 /* mem_helpers.cpp in Sources */,
977F708F12393ADD008D8433 /* memblockhdr.cpp in Sources */,
977F709012393ADD008D8433 /* memdbg.cpp in Sources */,
977F709112393ADD008D8433 /* memstd.cpp in Sources */,
977F709212393ADD008D8433 /* memvalidate.cpp in Sources */,
977F709312393ADD008D8433 /* minidump.cpp in Sources */,
977F709412393ADD008D8433 /* pch_tier0.cpp in Sources */,
977F709512393ADD008D8433 /* platform_posix.cpp in Sources */,
977F709612393ADD008D8433 /* pme_posix.cpp in Sources */,
977F709712393ADD008D8433 /* pmelib.cpp in Sources */,
977F709812393ADD008D8433 /* testthread.cpp in Sources */,
977F709912393ADD008D8433 /* thread.cpp in Sources */,
977F709A12393ADD008D8433 /* threadtools.cpp in Sources */,
977F709B12393ADD008D8433 /* tier0.cpp in Sources */,
977F709C12393ADD008D8433 /* validator.cpp in Sources */,
977F709D12393ADD008D8433 /* valobject.cpp in Sources */,
977F709E12393ADD008D8433 /* vcrmode_posix.cpp in Sources */,
977F709F12393ADD008D8433 /* vprof.cpp in Sources */,
977F70AB12393B10008D8433 /* checksum_crc.cpp in Sources */,
977F70AC12393B10008D8433 /* checksum_md5.cpp in Sources */,
977F70AD12393B10008D8433 /* convar.cpp in Sources */,
977F70AE12393B10008D8433 /* generichash.cpp in Sources */,
977F70AF12393B10008D8433 /* interface.cpp in Sources */,
977F70B012393B10008D8433 /* KeyValues.cpp in Sources */,
977F70B112393B10008D8433 /* mempool.cpp in Sources */,
977F70B212393B10008D8433 /* memstack.cpp in Sources */,
977F70B312393B10008D8433 /* stringpool.cpp in Sources */,
977F70B412393B10008D8433 /* utlbuffer.cpp in Sources */,
977F70B512393B10008D8433 /* utlsymbol.cpp in Sources */,
977F70BF12393B49008D8433 /* commandline.cpp in Sources */,
977F70C012393B49008D8433 /* cvar.cpp in Sources */,
977F70C112393B49008D8433 /* keyvaluessystem.cpp in Sources */,
977F70C212393B49008D8433 /* osversion.cpp in Sources */,
977F70C312393B49008D8433 /* qsort_s.cpp in Sources */,
977F70C412393B49008D8433 /* random.cpp in Sources */,
977F70C512393B49008D8433 /* splitstring.cpp in Sources */,
977F70C612393B49008D8433 /* stringnormalize.cpp in Sources */,
977F70C712393B49008D8433 /* strtools.cpp in Sources */,
976DE7B71239412500E8D60A /* crccheck_shared.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
977F704612393174008D8433 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.5;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
STRIP_INSTALLED_PRODUCT = NO;
};
name = Debug;
};
977F704712393174008D8433 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_VERSION = com.apple.compilers.llvmgcc42;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.5;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
SDKROOT = macosx10.5;
STRIP_INSTALLED_PRODUCT = NO;
};
name = Release;
};
977F704912393174008D8433 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = YES;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
_POSIX,
TIER0_DLL_EXPORT,
GNUC,
POSIX,
OSX,
_OSX,
COMPILER_GCC,
STEAM,
);
GCC_VERSION = com.apple.compilers.llvmgcc42;
INSTALL_PATH = ../../devtools/bin/;
OTHER_CFLAGS = "-fpermissive";
PRODUCT_NAME = vpc_osx;
SDKROOT = macosx10.5;
USER_HEADER_SEARCH_PATHS = "../../public ../../common ../../public/tier0 ../../public/tier1 ../../public/vstdlib";
};
name = Debug;
};
977F704A12393174008D8433 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_MODEL_TUNING = G5;
"GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = (
_POSIX,
TIER0_DLL_EXPORT,
GNUC,
POSIX,
OSX,
_OSX,
COMPILER_GCC,
STEAM,
);
GCC_VERSION = com.apple.compilers.llvmgcc42;
INSTALL_PATH = ../../devtools/bin/;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-fpermissive";
PRODUCT_NAME = vpc_osx;
SDKROOT = macosx10.5;
USER_HEADER_SEARCH_PATHS = "../../public ../../common ../../public/tier0 ../../public/tier1 ../../public/vstdlib";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
977F703812393173008D8433 /* Build configuration list for PBXProject "vpc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
977F704612393174008D8433 /* Debug */,
977F704712393174008D8433 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
977F704812393174008D8433 /* Build configuration list for PBXNativeTarget "vpc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
977F704912393174008D8433 /* Debug */,
977F704A12393174008D8433 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 977F703512393173008D8433 /* Project object */;
}
+290
View File
@@ -0,0 +1,290 @@
# Make command to use for dependencies
SHELL=/bin/sh
RM:=rm
MKDIR:=mkdir
OS:=$(shell uname)
EXE_POSTFIX:=""
# ---------------------------------------------------------------- #
# Figure out if we're building in the Steam tree or not.
# ---------------------------------------------------------------- #
SRCROOT:=../../../
-include $(SRCROOT)/devtools/steam_def.mak
# ---------------------------------------------------------------- #
# Set paths to gcc.
# ---------------------------------------------------------------- #
CC:=gcc
CXX:=g++
ifeq ($(OS),Darwin)
SDKROOT:=$(shell xcodebuild -sdk macosx -version Path)
CC:=clang -m32
CXX:=clang++ -m32
EXE_POSTFIX:=_osx
endif
ifeq ($(OS),Linux)
ifeq ($(wildcard /valve/bin/gcc),)
CC:=gcc
CXX:=g++
else
CC:=/valve/bin/gcc-4.7
CXX:=/valve/bin/g++-4.7
endif
EXE_POSTFIX:=_linux
endif
ifneq ($(CC_OVERRIDE),)
CC:=$(CC_OVERRIDE)
CXX:=$(CPP_OVERRIDE)
endif
# ---------------------------------------------------------------- #
# Lists of files.
# ---------------------------------------------------------------- #
VPC_SRC:= \
baseprojectdatacollector.cpp \
clanggenerator.cpp \
conditionals.cpp \
configuration.cpp \
../vpccrccheck/crccheck_shared.cpp \
dependencies.cpp \
../../../common/environment_utils.cpp \
../../../common/bundled_module_info.cpp \
generatordefinition.cpp \
generated_files.cpp \
groupscript.cpp \
macros.cpp \
main.cpp \
pch_helpers.cpp \
projectgenerator_android.cpp \
projectgenerator_vcproj.cpp \
projectgenerator_makefile.cpp \
projectgenerator_win32.cpp \
projectgenerator_win32_2010.cpp \
projectgenerator_ps3.cpp \
projectgenerator_xbox360.cpp \
projectgenerator_xbox360_2010.cpp \
projectscript.cpp \
qtgenerator.cpp \
schemagenerator.cpp \
scriptsource.cpp \
solutiongenerator_makefile.cpp \
solutiongenerator_xcode.cpp \
solutiongenerator_win32.cpp \
sys_utils.cpp \
../../../common/clang/clang_utils.cpp \
unity.cpp
TIER0_SRC:= \
../../../tier0/assert_dialog.cpp \
../../../tier0/cpu_posix.cpp \
../../../tier0/cpu.cpp \
../../../tier0/dbg.cpp \
../../../tier0/fasttimer.cpp \
../../../tier0/mem.cpp \
../../../tier0/mem_helpers.cpp \
../../../tier0/memdbg.cpp \
../../../tier0/memstd.cpp \
../../../tier0/memvalidate.cpp \
../../../tier0/minidump.cpp \
../../../tier0/pch_tier0.cpp \
../../../tier0/threadtools.cpp \
../../../tier0/valobject.cpp \
../../../tier0/vprof.cpp
TIER1_SRC:= \
../../../tier1/keyvalues.cpp \
../../../tier1/checksum_crc.cpp \
../../../tier1/checksum_md5.cpp \
../../../tier1/convar.cpp \
../../../tier1/generichash.cpp \
../../../tier1/interface.cpp \
../../../tier1/mempool.cpp \
../../../tier1/memstack.cpp \
../../../tier1/stringpool.cpp \
../../../tier1/utlbuffer.cpp \
../../../tier1/utlsymbol.cpp \
../../../tier0/platform_posix.cpp \
../../../tier0/pme_posix.cpp \
../../../tier0/commandline.cpp \
../../../tier0/win32consoleio.cpp \
../../../tier0/logging.cpp \
../../../tier0/tier0_strtools.cpp \
../../../tier1/utlstring.cpp \
../../../tier1/tier1.cpp \
../../../tier1/characterset.cpp \
../../../tier1/splitstring.cpp \
../../../tier1/strtools.cpp \
../../../tier1/strtools_unicode.cpp \
../../../tier1/exprevaluator.cpp \
VSTDLIB_SRC:= \
../../../vstdlib/cvar.cpp \
../../../vstdlib/vstrtools.cpp \
../../../vstdlib/random.cpp \
../../../vstdlib/keyvaluessystem.cpp
INTERFACES_SRC= \
../../../interfaces/interfaces.cpp
SRC:=$(VPC_SRC) $(TIER0_SRC) $(TIER1_SRC) $(VSTDLIB_SRC) $(INTERFACES_SRC) $(BINLAUNCH_SRC)
# -----Begin user-editable area-----
# -----End user-editable area-----
# If no configuration is specified, "Debug" will be used
ifndef "CFG"
CFG:=Release
endif
#
# Configuration: Debug
#
ifeq "$(CFG)" "Debug"
OUTDIR:=obj/$(OS)/debug
CONFIG_DEPENDENT_FLAGS:=-O0 -g3 -ggdb
else
OUTDIR:=obj/$(OS)/release
CONFIG_DEPENDENT_FLAGS:=-O3 -g1 -ggdb
endif
OBJS:=$(addprefix $(OUTDIR)/, $(subst ../../../, ,$(SRC:.cpp=.o)))
OUTFILE:=$(OUTDIR)/vpc
CFG_INC:=-I../../../public -I../../../common -I../../../public/tier0 \
-I../../../public/tier1 -I../../../public/tier2 -I../../../public/vstdlib \
-I../../../thirdparty/clang/include/ -I../../../thirdparty/SDL2/
CFLAGS=-std=c++11 -DMAKE_VPC -D_POSIX -DPOSIX -DGNUC -DNDEBUG $(CONFIG_DEPENDENT_FLAGS) -msse -mmmx -pipe -w -fpermissive -fPIC $(CFG_INC)
ifeq "$(STEAM_BRANCH)" "1"
CFLAGS+= -DSTEAM
endif
ifeq "$(OS)" "Darwin"
CFLAGS+=-I$(SDKROOT)/usr/include/malloc
CFLAGS+= -DOSX -D_OSX -DOSX64
CFLAGS+= -arch i386 -fasm-blocks
endif
ifeq "$(OS)" "Linux"
CFLAGS+= -DPLATFORM_LINUX -D_LINUX -DLINUX -DLINUXSTEAMRT64
endif
ifeq ($(CYGWIN),1)
CFLAGS+=-D_CYGWIN -DCYGWIN -D_CYGWIN_WINDOWS_TARGET
endif
CFLAGS+= -DCOMPILER_GCC
# the sed magic here adds the dependency file to the list of things that depend on the computed dependency
# set, so if any of them change, the dependencies are re-made
MAKEDEPEND=$(CXX) -M -MT $@ -MM $(CFLAGS) $< | sed -e 's@^\(.*\)\.o:@\1.d \1.o:@' > $(@:.o=.d)
COMPILE=$(CXX) -c $(CFLAGS) -o $@ $<
LINK=$(CXX) $(CONFIG_DEPENDENT_FLAGS) -o "$(OUTFILE)" $(OBJS) -ldl -lpthread
ifeq "$(OS)" "Darwin"
LINK+=-liconv -framework Foundation
endif
ifeq "$(OS)" "Darwin"
LINK+= -arch i386
endif
# Build rules
all: $(OUTFILE) ../../../devtools/bin/vpc$(EXE_POSTFIX)
../../../devtools/bin/vpc$(EXE_POSTFIX) : $(OUTFILE)
cp "$(OUTFILE)" ../../../devtools/bin/vpc$(EXE_POSTFIX)
$(OUTFILE): Makefile $(OBJS)
$(LINK)
# Rebuild this project
rebuild: cleanall all
show:
echo $(OUTDIR)
echo $(OBJS)
# Clean this project
clean:
$(RM) -f $(OUTFILE)
$(RM) -f $(OBJS)
$(RM) -f $(OBJS:.o=.d)
$(RM) -f ../../../devtools/bin/vpc$(EXE_POSTFIX)
# Clean this project and all dependencies
cleanall: clean
# magic rules - tread with caution
-include $(OBJS:.o=.d)
# Pattern rules
$(OUTDIR)/%.o : %.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/common/%.o : ../../../common/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/tier0/%.o : ../../../tier0/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/tier1/%.o : ../../../tier1/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/vstdlib/%.o : ../../../vstdlib/%.cpp
-$(MKDIR) -p $(@D)
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/interfaces/%.o : ../../../interfaces/%.cpp
if [ ! -d $(@D) ]; then $(MKDIR) $(@D); fi
@$(MAKEDEPEND);
$(COMPILE)
$(OUTDIR)/utils/binlaunch/%.o : ../../../binlaunch/%.cpp
if [ ! -d $(@D) ]; then $(MKDIR) $(@D); fi
@$(MAKEDEPEND);
$(COMPILE)
# the tags file) seems like more work than it's worth. feel free to fix that up
# if it bugs you.
TAGS:
@find . -name '*.cpp' -print0 | xargs -0 etags --declarations --ignore-indentation
@find . -name '*.h' -print0 | xargs -0 etags --language=c++ --declarations --ignore-indentation --append
@find . -name '*.c' -print0 | xargs -0 etags --declarations --ignore-indentation --append
+453
View File
@@ -0,0 +1,453 @@
//===== Copyright (c) 1996-2016, Valve Corporation, All rights reserved. ======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "baseprojectdatacollector.h"
#include "tier1/utlstack.h"
#include "p4lib/ip4.h"
// ------------------------------------------------------------------------------------------------ //
// CSpecificConfig implementation.
// ------------------------------------------------------------------------------------------------ //
CSpecificConfig::CSpecificConfig( CSpecificConfig *pParentConfig )
: m_pParentConfig( pParentConfig )
{
m_pKV = new KeyValues( "" );
m_bFileExcluded = false;
}
CSpecificConfig::~CSpecificConfig()
{
m_pKV->deleteThis();
}
const char* CSpecificConfig::GetConfigName()
{
return m_pKV->GetName();
}
const char* CSpecificConfig::GetOption( const char *pOptionName, const char *pDefaultValue /*= nullptr*/ )
{
const char *pRet = m_pKV->GetString( pOptionName, NULL );
if ( pRet )
return pRet;
if ( m_pParentConfig )
return m_pParentConfig->m_pKV->GetString( pOptionName, NULL );
return pDefaultValue;
}
// ------------------------------------------------------------------------------------------------ //
// CFileConfig implementation.
// ------------------------------------------------------------------------------------------------ //
CFileConfig::~CFileConfig()
{
Term();
}
void CFileConfig::Term()
{
m_Configurations.PurgeAndDeleteElements();
m_Filename.Clear();
}
const char* CFileConfig::GetName()
{
return m_Filename.String();
}
CSpecificConfig* CFileConfig::GetConfig( const char *pConfigName )
{
int i = m_Configurations.Find( pConfigName );
if ( i == m_Configurations.InvalidIndex() )
return NULL;
else
return m_Configurations[i];
}
CSpecificConfig* CFileConfig::GetOrCreateConfig( const char *pConfigName, CSpecificConfig *pParentConfig )
{
int i = m_Configurations.Find( pConfigName );
if ( i == m_Configurations.InvalidIndex() )
{
CSpecificConfig *pConfig = new CSpecificConfig( pParentConfig );
pConfig->m_pKV->SetName( pConfigName );
i = m_Configurations.Insert( pConfigName, pConfig );
}
return m_Configurations[i];
}
bool CFileConfig::IsExcludedFrom( const char *pConfigName )
{
CSpecificConfig *pSpecificConfig = GetConfig( pConfigName );
if ( pSpecificConfig )
return pSpecificConfig->m_bFileExcluded;
else
return false;
}
// ------------------------------------------------------------------------------------------------ //
// CBaseProjectDataCollector implementation.
// ------------------------------------------------------------------------------------------------ //
CBaseProjectDataCollector::CBaseProjectDataCollector( CRelevantPropertyNames *pNames )
: m_BaseConfigData( "", VPC_FILE_FLAGS_NONE ),
m_Files( k_eDictCompareTypeFilenames )
{
m_RelevantPropertyNames.m_nNames = 0;
m_RelevantPropertyNames.m_pNames = NULL;
if ( pNames )
{
m_RelevantPropertyNames = *pNames;
}
}
CBaseProjectDataCollector::~CBaseProjectDataCollector()
{
Term();
}
void CBaseProjectDataCollector::StartProject()
{
m_ProjectName = "UNNAMED";
m_CurFileConfig.Push( &m_BaseConfigData );
m_CurSpecificConfig.Push( NULL );
// TODO: none of these support non-WIN32 platforms yet (this code emits the appropriate warnings)
g_pVPC->ShouldEmitClangProject();
}
void CBaseProjectDataCollector::EndProject( bool bSaveData )
{
if ( g_pVPC->GetMissingFilesCount() > 0 )
{
if ( g_pVPC->IsMissingFileAsErrorEnabled() )
{
g_pVPC->VPCError( "%d files missing.", g_pVPC->GetMissingFilesCount() );
}
else
{
g_pVPC->VPCWarning( "%d files missing.", g_pVPC->GetMissingFilesCount() );
}
}
VPC_GenerateProjectDependencies( this );
}
void CBaseProjectDataCollector::Term()
{
m_BaseConfigData.Term();
m_Files.PurgeAndDeleteElements();
m_CurFileConfig.Purge();
m_CurSpecificConfig.Purge();
}
const char *CBaseProjectDataCollector::GetProjectName()
{
return m_ProjectName;
}
void CBaseProjectDataCollector::SetProjectName( const char *pProjectName )
{
CUtlPathStringHolder tmpBuf( pProjectName );
V_strlower( tmpBuf.GetForModify() );
m_ProjectName = tmpBuf;
}
// Get a list of all configurations.
void CBaseProjectDataCollector::GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames )
{
configurationNames.Purge();
for ( int i=m_BaseConfigData.m_Configurations.First(); i != m_BaseConfigData.m_Configurations.InvalidIndex(); i=m_BaseConfigData.m_Configurations.Next(i) )
{
configurationNames.AddToTail( m_BaseConfigData.m_Configurations.GetElementName(i) );
}
}
void CBaseProjectDataCollector::StartConfigurationBlock( const char *pConfigName, bool bFileSpecific )
{
CFileConfig *pFileConfig = m_CurFileConfig.Top();
// Find or add a new config block.
CUtlStringHolder<50> lowerCaseConfigName( pConfigName );
V_strlower( lowerCaseConfigName.GetForModify() );
int index = pFileConfig->m_Configurations.Find( lowerCaseConfigName );
if ( index == -1 )
{
CSpecificConfig *pParent = ( pFileConfig==&m_BaseConfigData ? NULL : m_BaseConfigData.GetOrCreateConfig( lowerCaseConfigName, NULL ) );
CSpecificConfig *pConfig = new CSpecificConfig( pParent );
pConfig->m_bFileExcluded = false;
pConfig->m_pKV->SetName( lowerCaseConfigName );
index = pFileConfig->m_Configurations.Insert( lowerCaseConfigName, pConfig );
}
// Remember what the current config is.
m_CurSpecificConfig.Push( pFileConfig->m_Configurations[index] );
}
void CBaseProjectDataCollector::EndConfigurationBlock()
{
m_CurSpecificConfig.Pop();
}
const char *CBaseProjectDataCollector::GetCurrentConfigurationName()
{
const char *configName = "";
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
if ( pConfig )
{
configName = pConfig->GetConfigName();
}
return configName;
}
bool CBaseProjectDataCollector::StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip )
{
return true;
}
void CBaseProjectDataCollector::HandleProperty( const char *pProperty, const char *pCustomScriptData )
{
int i;
for ( i=0; i < m_RelevantPropertyNames.m_nNames; i++ )
{
if ( V_stricmp_fast( m_RelevantPropertyNames.m_pNames[i], pProperty ) == 0 )
break;
}
if ( i == m_RelevantPropertyNames.m_nNames )
{
// not found
return;
}
if ( pCustomScriptData )
{
g_pVPC->GetScript().PushScript( "HandleProperty( custom script data )", pCustomScriptData, 1, false, false );
}
const char *pNextToken = g_pVPC->GetScript().PeekNextToken( false );
if ( pNextToken && pNextToken[0] != 0 )
{
// Pass in the previous value so the $base substitution works.
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
const char *pBaseString = pConfig->m_pKV->GetString( pProperty );
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( g_pVPC->GetScript().ParsePropertyValue( pBaseString, pStrBuf ) )
{
pConfig->m_pKV->SetString( pProperty, pStrBuf->Get() );
}
}
if ( pCustomScriptData )
{
// Restore prior script state
g_pVPC->GetScript().PopScript();
}
}
const char *CBaseProjectDataCollector::GetPropertyValue( const char *pProperty )
{
return "";
}
void CBaseProjectDataCollector::EndPropertySection( configKeyword_e keyword )
{
}
void CBaseProjectDataCollector::StartFolder( const char *pFolderName, VpcFolderFlags_t iFlags )
{
}
void CBaseProjectDataCollector::EndFolder()
{
}
bool CBaseProjectDataCollector::StartFile( const char *pFilename, VpcFileFlags_t iFlags, bool bWarnIfAlreadyExists )
{
CFileConfig *pFileConfig = new CFileConfig( pFilename, iFlags );
if ( m_Files.Find( pFilename ) == m_Files.InvalidIndex() )
{
m_Files.Insert( pFilename, pFileConfig );
}
m_CurFileConfig.Push( pFileConfig );
m_CurSpecificConfig.Push( NULL );
char szFullPath[MAX_FIXED_PATH];
V_GetCurrentDirectory( szFullPath, sizeof( szFullPath ) );
V_AppendSlash( szFullPath, sizeof( szFullPath ) );
V_strncat( szFullPath, pFilename, sizeof( szFullPath ) );
V_RemoveDotSlashes( szFullPath );
#if 0 // FULLY DISABLED - DOES NOT WORK CORRECTLY.
if ( g_pVPC->IsP4AutoAddEnabled() )
{
// Add file to Perforce if it isn't there already
if ( Sys_Exists( szFullPath ) )
{
if ( g_pP4 && !g_pP4->IsFileInPerforce( szFullPath ) )
{
g_pP4->OpenFileForAdd( szFullPath );
VPCStatus( "%s automatically opened for add in default changelist.", szFullPath );
}
}
else
{
g_pVPC->Warning( "%s not found on disk at location specified in project script.", szFullPath );
}
}
#endif
return true;
}
void CBaseProjectDataCollector::EndFile()
{
m_CurFileConfig.Pop();
m_CurSpecificConfig.Pop();
}
// This is actually just per-file configuration data.
void CBaseProjectDataCollector::FileExcludedFromBuild( bool bExcluded )
{
CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
pConfig->m_bFileExcluded = bExcluded;
}
bool CBaseProjectDataCollector::RemoveFile( const char *pFilename )
{
bool bRet = false;
int i = m_Files.Find( pFilename );
if ( i != m_Files.InvalidIndex() )
{
delete m_Files[i];
m_Files.RemoveAt( i );
bRet = true;
}
return bRet;
}
void CBaseProjectDataCollector::DoStandardVisualStudioReplacements( const char *pInitStr, CUtlStringBuilder *pStr, const char *pFullInputFilename )
{
CUtlPathStringHolder inputDir;
char sFileBase[MAX_BASE_FILENAME];
sFileBase[0] = '\0';
if ( pInitStr )
{
pStr->Set( pInitStr );
}
// Decompose the input filename.
if ( pFullInputFilename && pFullInputFilename[0] )
{
if ( !inputDir.ExtractFilePath( pFullInputFilename ) )
{
g_pVPC->VPCError( "DoStandardVisualStudioReplacements:: V_ExtractFilePath failed on %s.", pFullInputFilename );
}
V_FileBase( pFullInputFilename, sFileBase, sizeof( sFileBase ) );
}
if ( pFullInputFilename && pFullInputFilename[0] )
{
pStr->Replace( "$(InputPath)", pFullInputFilename );
}
if ( !inputDir.IsEmpty() )
{
pStr->Replace( "$(InputDir)", inputDir );
}
if ( sFileBase[0] )
{
pStr->Replace( "$(InputName)", sFileBase );
}
pStr->Replace( "$(IntermediateOutputPath)", "$(OBJ_DIR)" );
pStr->Replace( "$(IntDir)", "$(OBJ_DIR)" );
if ( pFullInputFilename && pFullInputFilename[0] )
{
pStr->Replace( "$(InputFileName)", pFullInputFilename + V_strlen( inputDir ) );
}
pStr->Replace( "$(ConfigurationName)", "${CONFIGURATION}" );
V_FixSlashes( pStr->Access(), '/' );
}
//the input is expected to use makefile variable usage
void CBaseProjectDataCollector::DoShellScriptReplacements( CUtlStringBuilder *pStr )
{
char *pParse = pStr->AccessNoAssert();
if ( !pParse )
return;
pStr->Replace( "$(OBJ_DIR)", "${OBJ_DIR}" );
}
//the input is expected to use /bin/sh variable style
void CBaseProjectDataCollector::DoBatchScriptReplacements( CUtlStringBuilder *pStr )
{
DoShellScriptReplacements( pStr );
char *pParse = pStr->AccessNoAssert();
if ( !pParse )
return;
char *pStringEnd = pParse + V_strlen( pParse );
for ( ; pParse != pStringEnd; ++pParse )
{
if ( *pParse == '$' )
{
if ( pParse[1] == '{' )
{
char *pReplaceEnd = pParse + 2;
while ( *pReplaceEnd != '\0' && *pReplaceEnd != '}' )
{
Assert( *pReplaceEnd != '$' ); //if we find something that looks like nesting, we're probably doing something wrong
++pReplaceEnd;
}
if ( *pReplaceEnd == '}' )
{
//replace {} with %%
pParse[1] = '%';
*pReplaceEnd = '%';
//the $ is a character we don't want, shift the string remainder left
V_memmove( pParse, pParse + 1, pStringEnd - pParse );
--pStringEnd;
pParse = pReplaceEnd;
}
}
}
}
}
const char *CBaseProjectDataCollector::GetCurrentFileName()
{
if ( m_CurFileConfig.Count() == 0 )
return "";
else
return m_CurFileConfig.Top()->GetName();
}
+132
View File
@@ -0,0 +1,132 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
//
//=============================================================================
#pragma once
#include "tier1/keyvalues.h"
#include "tier1/utlstack.h"
class CSpecificConfig
{
public:
CSpecificConfig( CSpecificConfig *pParentConfig );
~CSpecificConfig();
const char *GetConfigName();
const char *GetOption( const char *pOptionName, const char *pDefaultValue = nullptr );
public:
CSpecificConfig *m_pParentConfig;
KeyValues *m_pKV;
bool m_bFileExcluded; // Is the file that holds this config excluded from the build?
};
class CFileConfig
{
public:
CFileConfig( const char *pFilename, VpcFileFlags_t iFlags ) : m_Filename( pFilename ), m_iFlags( iFlags ) {}
~CFileConfig();
void Term();
const char *GetName();
CSpecificConfig *GetConfig( const char *pConfigName );
CSpecificConfig *GetOrCreateConfig( const char *pConfigName, CSpecificConfig *pParentConfig );
bool IsExcludedFrom( const char *pConfigName );
public:
CUtlDict< CSpecificConfig*, int > m_Configurations;
CUtlString m_Filename; // "" if this is the config data for the whole project.
VpcFileFlags_t m_iFlags;
};
// This just holds the list of property names that we're supposed to scan for.
class CRelevantPropertyNames
{
public:
const char **m_pNames;
int m_nNames;
};
//
// This class is shared by the makefile and SlickEdit project file generator.
// It just collects interesting file properties into KeyValues and then the project file generator
// is responsible for using that data to write out a project file.
//
class CBaseProjectDataCollector : public IBaseProjectGenerator
{
// IBaseProjectGenerator implementation.
public:
CBaseProjectDataCollector( CRelevantPropertyNames *pNames );
~CBaseProjectDataCollector();
// Called before doing anything in a project
virtual void StartProject() OVERRIDE;
virtual void EndProject( bool bSaveData ) OVERRIDE;
// Access the project name.
virtual const char *GetProjectName() OVERRIDE;
virtual void SetProjectName( const char *pProjectName ) OVERRIDE;
// Get a list of all configurations.
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames ) OVERRIDE;
// Configuration data is specified in between these calls and inside BeginPropertySection/EndPropertySection.
// If bFileSpecific is set, then the configuration data only applies to the last file added.
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific ) OVERRIDE;
virtual void EndConfigurationBlock() OVERRIDE;
// Get the current configuration name. Only valid between StartConfigurationBlock()/EndConfigurationBlock()
virtual const char *GetCurrentConfigurationName() OVERRIDE;
// These functions are called when it enters a section like $Compiler, $Linker, etc.
// In between the BeginPropertySection/EndPropertySection, it'll call HandleProperty for any properties inside that section.
//
// If you pass pCustomScriptData to HandleProperty, it won't touch the global parsing state -
// it'll parse the platform filters and property value from pCustomScriptData instead.
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip = NULL ) OVERRIDE;
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData = NULL ) OVERRIDE;
virtual const char *GetPropertyValue( const char *pProperty ) OVERRIDE;
virtual void EndPropertySection( configKeyword_e keyword ) OVERRIDE;
// Files go in folders. The generator should maintain a stack of folders as they're added.
virtual void StartFolder( const char *pFolderName, VpcFolderFlags_t iFlags ) OVERRIDE;
virtual void EndFolder() OVERRIDE;
// Add files. Any config blocks/properties between StartFile/EndFile apply to this file only.
// It will only ever have one active file.
virtual bool StartFile( const char *pFilename, VpcFileFlags_t iFlags, bool bWarnIfAlreadyExists ) OVERRIDE;
virtual void EndFile() OVERRIDE;
// This is actually just per-file configuration data.
virtual void FileExcludedFromBuild( bool bExcluded ) OVERRIDE;
// Remove the specified file.
virtual bool RemoveFile( const char *pFilename ) OVERRIDE; // returns ture if a file was removed
virtual bool HasFile( const char *pFilename ) OVERRIDE
{
return m_Files.HasElement( pFilename );
}
virtual const char *GetCurrentFileName() OVERRIDE;
public:
void Term();
static void DoStandardVisualStudioReplacements( const char *pInitStr, CUtlStringBuilder *pStr, const char *pFullInputFilename );
static void DoShellScriptReplacements( CUtlStringBuilder *pStr );
static void DoBatchScriptReplacements( CUtlStringBuilder *pStr );
public:
CUtlString m_ProjectName;
CUtlDict< CFileConfig *, int > m_Files;
CFileConfig m_BaseConfigData;
CUtlStack< CFileConfig* > m_CurFileConfig; // Either m_BaseConfigData or one of the files.
CUtlStack< CSpecificConfig* > m_CurSpecificConfig; // Debug, release?
CRelevantPropertyNames m_RelevantPropertyNames;
};
+265
View File
@@ -0,0 +1,265 @@
//========= Copyright 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: Clang Script Generation
//
//=====================================================================================//
#include "vpc.h"
#include "baseprojectdatacollector.h"
#include "projectgenerator_vcproj.h"
#include "tier1/fmtstr.h"
#include "environment_utils.h"
#include "clang/clang_utils.h"
CUtlString JsonEscapeAndTrim( const CUtlString &str )
{
int nDepth = 0;
CUtlString esc;
for( int i = 0; i < str.Length(); ++i )
{
if( str.Get()[i] == '\\' || str.Get()[i] == '\"' )
{
if( str[i] == '\"' && nDepth == 1 )
{
nDepth = 0;
}
esc.Append( nDepth ? "\\\\\\" : "\\" );
if( str[i] == '\"' && nDepth == 0 )
{
nDepth = 1;
}
}
esc.Append( str[i] );
}
esc.TrimRight();
return esc;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GenerateClangProject_GenerateFileOutput( CProjectFile *pFile, CProjectConfiguration *pRootConfig, const CUtlString &pchName, bool bShouldBuildPCH, CUtlBuffer &buffer, CUtlBuffer &jsonBuffer )
{
const char *pFilename = pFile->m_Name.Get();
// TODO: optimize this (platform/compiler are constant for all files, and most files can use the define/include lists from pRootConfig, i.e if pFile has no file config)
CUtlVector<CUtlString> defineList;
VPC_GetPreprocessorDefines( pFile, pRootConfig, defineList );
CUtlVector<CUtlString> includeList;
VPC_GetIncludeDirectories( pFile, pRootConfig, includeList );
CUtlString clangCmdLine;
if ( !Clang_GenerateCommandLine( clangCmdLine, pFilename, g_pVPC->GetTargetPlatformName(), g_pVPC->GetTargetCompilerName(), defineList, includeList, pchName, bShouldBuildPCH ) )
return;
// Write out the command:
buffer.Printf( "@echo. %%CLANG_OUTPUT%%\n" );
buffer.Printf( "@echo -----START FILE (%s)----- %%CLANG_OUTPUT%%\n", pFilename );
buffer.Printf( "@echo %%time%% %%CLANG_OUTPUT%%\n" );
CFmtStrMax command( "%%CLANG_CMD%% %%CLANG_OPTIONS%% %s %%CLANG_OUTPUT%%\n", clangCmdLine.Get() );
buffer.PutString( command );
buffer.Printf( "@echo -----END FILE (%s)----- %%CLANG_OUTPUT%%\n", pFilename );
buffer.Printf( "@echo %%time%% %%CLANG_OUTPUT%%\n" );
buffer.Printf( "@echo. %%CLANG_OUTPUT%%\n\n" );
jsonBuffer.Printf( "\n{\n\t\"directory\":\"%s\",\n\t\"command\":\"clang %s\",\n\t\"file\":\"%s\"\n},", JsonEscapeAndTrim( g_pVPC->GetProjectPath() ).Get(), JsonEscapeAndTrim( clangCmdLine ).Get(), JsonEscapeAndTrim( pFilename ).Get() );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GenerateClangProject_ProcessFile( CProjectFile *pFile, CProjectConfiguration *pRootConfig, CUtlSymbolTable *pSchemaFiles,
CUtlVector< CUtlString > &requiredPCHs, CUtlBuffer &buffer, CUtlBuffer &jsonBuffer )
{
// Parse all CPP files but only schematised headers (and skip everything else)
const char *pFilename = pFile->m_Name.Get();
bool bIsSource = Clang_IsSourceFile( pFilename ), bIsHeader = Clang_IsHeaderFile( pFilename );
if ( !bIsSource && ( !bIsHeader || !pSchemaFiles->HasElement( pFilename ) ) )
{
return;
}
// If this file uses a PCH, make sure its in our list of required PCHs,
// but skip actually building PCHs (those commands are added in a second pass):
bool bFileCreatesPCH, bFileExcludesPCH;
CUtlString pchName;
VPC_GetPCHInclude( pFile, pRootConfig, pchName, bFileCreatesPCH, bFileExcludesPCH );
if ( bFileCreatesPCH )
return;
if ( !pchName.IsEmpty() && !requiredPCHs.HasElement( pchName ) )
requiredPCHs.AddToTail( pchName );
VPC_GenerateClangProject_GenerateFileOutput( pFile, pRootConfig, pchName, false, buffer, jsonBuffer );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GenerateClangProject_ProcessFolder( CProjectFolder *pFolder, CProjectConfiguration *pRootConfig, CUtlSymbolTable *pSchemaFiles,
CUtlVector< CUtlString > &requiredPCHs, CUtlBuffer &buffer, CUtlBuffer &jsonBuffer )
{
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
VPC_GenerateClangProject_ProcessFile( pFolder->m_Files[iIndex], pRootConfig, pSchemaFiles, requiredPCHs, buffer, jsonBuffer );
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
VPC_GenerateClangProject_ProcessFolder( pFolder->m_Folders[iIndex], pRootConfig, pSchemaFiles, requiredPCHs, buffer, jsonBuffer );
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_Clang_OnParseProjectEnd( CVCProjGenerator *pDataCollector )
{
// Skip Clang processing during dependency-generation (or we'll end up doing the work multiple times!)
if ( g_pVPC->m_bIsDependencyPass )
return;
if ( !g_pVPC->ShouldEmitClangProject() )
return;
// Build a symbol table of all the schema files, so we can skip non-schema headers:
CUtlSymbolTable schemaFiles( 0, 16, true );
int nNumSchemaFiles = g_pVPC->m_SchemaFiles.Count();
for ( int i = 0; i < nNumSchemaFiles; i++ )
{
schemaFiles.AddString( g_pVPC->m_SchemaFiles[i].Get() );
}
CUtlVector<CProjectConfiguration *> rootConfigs;
pDataCollector->GetAllRootConfigurations( rootConfigs );
for ( int i = 0; i < rootConfigs.Count(); i++ )
{
CProjectConfiguration *pRootConfig = rootConfigs[i];
// Output file is "<Project>_<GameName>_<Platform>_<Config>.bat"
CUtlString gameName = g_pVPC->GetGameName();
gameName = CUtlString( gameName.IsEmpty() ? "" : "_" ) + gameName;
CUtlString baseName = CUtlString( g_pVPC->GetProjectName() ) + gameName + CUtlString( "_" ) + g_pVPC->GetTargetPlatformName() + "_" + pRootConfig->m_Name;
// Write to the file via head/body/tail buffers:
CUtlBuffer headBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
CUtlBuffer bodyBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
CUtlBuffer tailBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
CUtlBuffer jsonPchBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
CUtlBuffer jsonBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER );
// Prologue:
// set 'CLANG_OPTIONS' at the top of the file, so its easy to add an option to all files in the project
// TODO: translate these into command-line options: CXTranslationUnit_Incomplete, CXTranslationUnit_PrecompiledPreamble, CXTranslationUnit_CacheCompletionResults, CXTranslationUnit_SkipFunctionBodies
headBuffer.Printf( "setlocal\n" );
headBuffer.Printf( "set CLANG_CMD=clang.exe\n" );
headBuffer.Printf( "set CLANG_OPTIONS=\n" );
headBuffer.Printf( "REM set CLANG_OPTIONS=%%CLANG_OPTIONS%% -detailed-preprocessing-record \n" );
// Spew into an output file, also done via an envvar (just comment CLANG_OUTPUT to spew to stdout instead)
headBuffer.Printf( "set CLANG_OUTPUT_FILE=%s_clang_output.txt\n", baseName.Get() );
headBuffer.Printf( "set CLANG_OUTPUT= ^>^> %%CLANG_OUTPUT_FILE%% 2^>^&1\n" );
headBuffer.Printf( "@echo. > %%CLANG_OUTPUT_FILE%%\n" );
headBuffer.Printf( "\n" );
// Body:
// Iterate over all the folders+files, generating compile commands (and building a list of included PCH files):
// TODO-CLANG: should we skip excluded files & build generated files, to match vcproj build behaviour? (i.e schema + qt files)
CUtlVector< CUtlString > requiredPCHs;
VPC_GenerateClangProject_ProcessFolder( pDataCollector->GetRootFolder(), pRootConfig, &schemaFiles, requiredPCHs, bodyBuffer, jsonBuffer );
// Generate info for all the PCHs used by this project:
CUtlVector< CUtlString > pchIncludeNames, pchCreatorNames;
VPC_GeneratePCHInfo( pDataCollector, pRootConfig, pchIncludeNames, pchCreatorNames, &requiredPCHs );
if ( pchIncludeNames.Count() )
{
// Add commands to build the PCH files at the head of the file (before the files which will use them)
headBuffer.Printf( "\nREM ====PCH files first:====\n\n" );
for( int j = 0; j < pchIncludeNames.Count(); j++ )
{
CProjectFile *pFile = NULL;
bool bFixSlashes = true; // We need to write '/' to the schproj file, but FindFile expects '\'
pDataCollector->FindFile( pchCreatorNames[j].Get(), &pFile, bFixSlashes );
VPC_GenerateClangProject_GenerateFileOutput( pFile, pRootConfig, pchIncludeNames[j], true, headBuffer, jsonPchBuffer );
}
headBuffer.Printf( "\nREM ====Non-PCH files second:====\n\n" );
// Add commands to delete the PCH files at the tail of the file
tailBuffer.Printf( "\n@echo.\n" );
tailBuffer.Printf( "@echo Press any key to delete PCH files, or exit now to leave them be.\n" );
tailBuffer.Printf( "pause\n" );
for( int j = 0; j < pchIncludeNames.Count(); j++ )
{
tailBuffer.Printf( "del %s.pch\n", pchIncludeNames[j].Get() );
}
tailBuffer.Printf( "\n" );
}
// Epilogue:
// Misc cleanup...
tailBuffer.Printf( "\n@echo.\n" );
tailBuffer.Printf( "@echo DONE!\n" );
tailBuffer.Printf( "pause\n\n" );
// Output the batch file:
CUtlPathStringHolder batchFilename;
g_pVPC->CreateGeneratedRootFilePath( &batchFilename, baseName.Get(), "_clang.bat" );
Sys_CreatePath( batchFilename.Get() );
FILE *batFile = fopen( batchFilename.Get(), "wt" );
if ( batFile )
{
fwrite( headBuffer.Base(), sizeof(char), headBuffer.TellMaxPut(), batFile );
fwrite( bodyBuffer.Base(), sizeof(char), bodyBuffer.TellMaxPut(), batFile );
fwrite( tailBuffer.Base(), sizeof(char), tailBuffer.TellMaxPut(), batFile );
fclose( batFile );
}
else { g_pVPC->VPCWarning( "Error saving Clang batch file: %s", batchFilename.Get() ); }
CUtlPathStringHolder jsonFilename;
g_pVPC->CreateGeneratedRootFilePath( &jsonFilename, baseName.Get(), "_compile_commands.json" );
Sys_CreatePath( jsonFilename.Get() );
FILE *jsonFile = fopen( jsonFilename.Get(), "wt" );
if( jsonFile )
{
fputs( "[", jsonFile );
fwrite( jsonPchBuffer.Base(), sizeof( char ), jsonPchBuffer.TellMaxPut(), jsonFile );
if( jsonBuffer.TellMaxPut() )
{
// don't put the last character, which is a comma..
fwrite( jsonBuffer.Base(), sizeof( char ), jsonBuffer.TellMaxPut() - 1, jsonFile );
}
fputs( "\n]\n", jsonFile );
fclose( jsonFile );
}
else { g_pVPC->VPCStatus( true, "Error saving Clang compile_database.json file: %s", jsonFilename.Get() ); }
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
bool IsClangSupportedForThisTargetPlatform( void )
{
// TODO: Only implemented+tested on WIN32/WIN64 so far...
// [ VPC_GenerateClangProject() depends upon CVCProjGenerator due to bugs in the makefile code,
// and there's some porting work to do in clang_utils.cpp ]
const char *pPlatform = g_pVPC->GetTargetPlatformName();
return ( !V_stricmp_fast( pPlatform, "WIN32" ) || !V_stricmp_fast( pPlatform, "WIN64" ) );
}
bool CVPC::IsClangEnabled( void )
{
if ( !m_bAllowClang )
return false; // Clang feature not enabled
if ( IsClangSupportedForThisTargetPlatform() )
return true; // Feature enabled & supported!
ExecuteOnce( VPCWarning( "Clang feature disabled, not supported for %s yet", g_pVPC->GetTargetPlatformName() ) )
return false; // Platform not supported
}
bool CVPC::ShouldEmitClangProject( void )
{
if ( !m_bEmitClangProject )
return false; // Feature not requested
if ( IsClangEnabled() )
return true; // Feature requested & enabled & supported!
ExecuteOnce( VPCWarning( "Ignoring '/clangall' option, Clang feature disabled" ) )
return false; // Clang not enabled
}
+496
View File
@@ -0,0 +1,496 @@
//======== Copyright 1996-2016, Valve Corporation, All rights reserved. ===========//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CVPC::SetupDefaultConditionals()
{
//
// PLATFORM Conditionals
//
{
FindOrCreateConditional( "WIN32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "WIN64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUX32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUX64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUXSERVER32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUXSERVER64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUXSTEAMRTARM32HF", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "LINUXSTEAMRTARM64HF", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "OSX32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "OSX64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "X360", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "PS3", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "IOS", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDARM32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDARM64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDMIPS32", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDMIPS64", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDX8632", true, CONDITIONAL_PLATFORM );
FindOrCreateConditional( "ANDROIDX8664", true, CONDITIONAL_PLATFORM );
}
//
// SYSTEM conditionals
//
{
// setup default system conditionals
FindOrCreateConditional( "PROFILE", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "RETAIL", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "CALLCAP", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "FASTCAP", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "CERT", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "MEMTEST", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "NOFPO", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "POSIX", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "LV", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "DEMO", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "NO_SCALEFORM", false, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "NO_STEAM", false, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "DVDEMU", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "QTDEBUG", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "NO_CEG", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "UPLOAD_CEG", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "SOURCECONTROL", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ALLOW_OS_MACRO", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "CRCCHECK_IN_PROJECT", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "MISSING_FILE_CHECK", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "MISSING_FILE_IS_ERROR", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "FILEPATTERN", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ADD_EXE_TO_CRC_CHECK", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "P4_AUTO_ADD", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ALLOW_QT", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ALLOW_SCHEMA", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ALLOW_UNITY", true, CONDITIONAL_SYSTEM );
FindOrCreateConditional( "ALLOW_CLANG", true, CONDITIONAL_SYSTEM );
}
}
CUtlString CVPC::GetCRCStringFromConditionals()
{
CUtlString CRCString;
CUtlVectorFixedGrowable<const char *, 1024> sortRelevantConditionals;
// Any enabled system conditional needs to make a CRC string that can be matched against for project staleness.
// These used to be terse abbreviations when they were passed on the CL but now not a constraint with vpccrccheck and peer crc files.
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i]->m_bDefined &&
( m_Conditionals[i]->m_Type == CONDITIONAL_SYSTEM || m_Conditionals[i]->m_Type == CONDITIONAL_CUSTOM || m_Conditionals[i]->m_Type == CONDITIONAL_SCRIPT ) )
{
sortRelevantConditionals.AddToTail( m_Conditionals[i]->m_UpperCaseName.Get() );
}
}
//sort the conditionals so the existing crc doesn't appear stale if they simply appear in a different order on the command line
sortRelevantConditionals.SortPredicate(
[] ( const char *szLeft, const char *szRight ) -> bool
{
return V_stricmp_fast( szLeft, szRight ) < 0;
} );
for ( int i = 0; i < sortRelevantConditionals.Count(); ++i )
{
CRCString += CFmtStr( ".%s", sortRelevantConditionals[i] );
}
return CRCString;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CVPC::GetTargetPlatformName()
{
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
conditional_t *pConditional = m_Conditionals[i];
if ( pConditional->m_Type == CONDITIONAL_PLATFORM && pConditional->m_bDefined )
{
return pConditional->m_Name.String();
}
}
// fatal - should have already been default set
Assert( 0 );
VPCError( "Unspecified platform." );
return NULL;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CVPC::GetTargetCompilerName()
{
const char *pPlatformName = GetTargetPlatformName();
if ( !V_stricmp_fast( pPlatformName, "WIN32" ) ||
!V_stricmp_fast( pPlatformName, "WIN64" ) ||
!V_stricmp_fast( pPlatformName, "X360" ) )
{
if ( IsConditionalDefined( "VS2005" ) )
return "VS2005";
if ( IsConditionalDefined( "VS2010" ) )
return "VS2010";
if ( IsConditionalDefined( "VS2012" ) )
return "VS2012";
if ( IsConditionalDefined( "VS2013" ) )
return "VS2013";
if ( IsConditionalDefined( "VS2015" ) )
return "VS2015";
}
else if ( VPC_IsPlatformLinux( pPlatformName ) || VPC_IsPlatformAndroid( pPlatformName ) )
{
return "GCC";
}
else if ( !V_stricmp_fast( pPlatformName, "OSX32" ) ||
!V_stricmp_fast( pPlatformName, "OSX64" ) )
{
return "Clang";
}
// TODO: support other platforms (needed by schemacompiler/clang)
ExecuteOnce( g_pVPC->VPCWarning( "TODO: GetTargetCompilerName not yet implemented for platform %s!", pPlatformName ) );
return "UNKNOWN";
}
//-----------------------------------------------------------------------------
// Case Insensitive. Returns true if platform conditional has been marked
// as defined.
//-----------------------------------------------------------------------------
bool CVPC::IsPlatformDefined( const char *pName )
{
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i]->m_Type == CONDITIONAL_PLATFORM && !V_stricmp_fast( pName, m_Conditionals[i]->m_Name.String() ) )
{
return m_Conditionals[i]->m_bDefined;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Case Insensitive. Returns true if the given string is a platform name
//-----------------------------------------------------------------------------
bool CVPC::IsPlatformName( const char *pName )
{
for ( int i=0; i<m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i]->m_Type == CONDITIONAL_PLATFORM && !V_stricmp_fast( pName, m_Conditionals[i]->m_Name.String() ) )
{
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Case Insensitive
//-----------------------------------------------------------------------------
conditional_t *CVPC::FindOrCreateConditional( const char *pName, bool bCreate, conditionalType_e type )
{
for (int i=0; i<m_Conditionals.Count(); i++)
{
if ( !V_stricmp_fast( pName, m_Conditionals[i]->m_Name.String() ) )
{
// found
return m_Conditionals[i];
}
}
if ( !bCreate )
{
return NULL;
}
int index = m_Conditionals.AddToTail();
m_Conditionals[index] = new conditional_t();
char tempName[256];
V_strncpy( tempName, pName, sizeof( tempName ) );
// primary internal use as lower case, but spewed to user as upper for style consistency
m_Conditionals[index]->m_Name = V_strlower( tempName );
m_Conditionals[index]->m_UpperCaseName = V_strupper( tempName );
m_Conditionals[index]->m_Type = type;
return m_Conditionals[index];
}
void CVPC::SetConditional( const char *pString, bool bSet, conditionalType_e conditionalType )
{
conditional_t *pConditional = FindOrCreateConditional( pString, true, conditionalType );
if ( !pConditional )
{
VPCError( "Failed to find or create $%s conditional", pString );
}
VPCStatus( false, "Set Conditional: $%s = %s", pConditional->m_UpperCaseName.Get(), ( bSet ? "1" : "0" ) );
if ( conditionalType != pConditional->m_Type )
{
VPCSyntaxError( "Cannot set reserved conditional '$%s'", pConditional->m_UpperCaseName.Get() );
}
pConditional->m_bDefined = bSet;
if ( pConditional->m_Type == CONDITIONAL_SYSTEM )
{
// system conditionals are set at specific early execution points and not mutable by scripts
// cache off the state for any possible inner loop repetitive state queries
if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "SOURCECONTROL" ) )
{
m_bSourceControl = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ALLOW_OS_MACRO" ) )
{
m_bAllowOSMacro = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "CRCCHECK_IN_PROJECT" ) )
{
m_bCRCCheckInProject = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "MISSING_FILE_CHECK" ) )
{
m_bCheckFiles = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "MISSING_FILE_IS_ERROR" ) )
{
m_bMissingFileIsError = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "FILEPATTERN" ) )
{
m_bAllowFilePattern = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ADD_EXE_TO_CRC_CHECK" ) )
{
m_bAddExecuteableToCRC = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "P4_AUTO_ADD" ) )
{
m_bP4AutoAdd = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "PREFER_VS2010" ) )
{
m_bPreferVS2010 = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "PREFER_VS2012" ) )
{
m_bPreferVS2012 = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "PREFER_VS2013" ) )
{
m_bPreferVS2013 = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "PREFER_VS2015" ) )
{
m_bPreferVS2015 = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ALLOW_QT" ) )
{
m_bAllowQt = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ALLOW_SCHEMA" ) )
{
m_bAllowSchema = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ALLOW_UNITY" ) )
{
m_bAllowUnity = bSet;
}
else if ( !V_strcmp( pConditional->m_UpperCaseName.Get(), "ALLOW_CLANG" ) )
{
m_bAllowClang = bSet;
}
}
}
//-----------------------------------------------------------------------------
// Returns true if string has a conditional of the specified type
//-----------------------------------------------------------------------------
bool CVPC::ConditionHasDefinedType( const char* pCondition, conditionalType_e type )
{
for ( int i=0; i<m_Conditionals.Count(); i++ )
{
if ( m_Conditionals[i]->m_Type != type )
continue;
const char *pScan = pCondition;
while ( *pScan )
{
pScan = strchr( pScan, '$' );
if ( !pScan )
{
break;
}
pScan++;
if ( V_strnicmp( pScan, m_Conditionals[i]->m_Name, m_Conditionals[i]->m_Name.Length() ) == 0 )
{
// a define of expected type occurs in the conditional expression
return true;
}
}
}
return false;
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
bool CVPC::ResolveConditionalSymbol( const char *pSymbol )
{
int offset = 0;
if ( ( pSymbol[0] == '$' && pSymbol[1] == '0' && pSymbol[2] == 0 ) ||
CharStrEq( pSymbol, '0' ) )
{
return false;
}
else if ( ( pSymbol[0] == '$' && pSymbol[1] == '1' && pSymbol[2] == 0 ) ||
CharStrEq( pSymbol, '1' ) )
{
return true;
}
if ( pSymbol[0] == '$' )
{
offset = 1;
}
conditional_t *pConditional = FindOrCreateConditional( (char*)pSymbol+offset, false, CONDITIONAL_NULL );
if ( pConditional )
{
// game conditionals only resolve true when they are 'defined' and 'active'
// only one game conditional is expected to be active at a time
if ( pConditional->m_Type == CONDITIONAL_GAME )
{
if ( !pConditional->m_bDefined )
{
return false;
}
return pConditional->m_bGameConditionActive;
}
// all other type of conditions are gated by their 'defined' state
return pConditional->m_bDefined;
}
else
{
// The conditional was not found.
// MACROS ARE NOT ALLOWED IN CONDITIONALS because it became too commonplace to use the wrong symbol
// causing quiet unintended results and since macros can be arbitrary strings, there placement in a
// conditional expression is invalid. Restricting to conditionals ensures we are only ever evaluating
// is valid boolean values.
CMacro *pMacro = g_pVPC->FindMacro( (char*)pSymbol+offset );
if ( pMacro )
{
// found a macro, and not allowed
g_pVPC->VPCSyntaxError( "Macro '%s' detected in conditional expression and not allowed. Use \"$Conditional <name> <0/1>\"", pSymbol );
}
}
// unknown conditional, defaults to false
return false;
}
void CVPC::SaveConditionals()
{
// only expecting a single save point
AssertMsg( m_SavedConditionals.Count() == 0, "SaveConditionals: Unexpected processing state, conditionals already saved\n" );
m_SavedConditionals.Purge();
if ( !m_Conditionals.Count() )
return;
// clone
m_SavedConditionals.SetCount( m_Conditionals.Count() );
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
m_SavedConditionals[i] = new conditional_t( *m_Conditionals[i] );
}
}
void CVPC::RestoreConditionals()
{
if ( !m_SavedConditionals.Count() )
{
// already restored or nothing saved
return;
}
// whatever state the conditionals were changed to is undesired
// these get discarded
m_Conditionals.PurgeAndDeleteElements();
// restore the saved conditionals and purge the saved
m_Conditionals.Swap( m_SavedConditionals );
for ( int i = 0; i < m_Conditionals.Count(); i++ )
{
// Call SetConditional to update cached member bools:
SetConditional( m_Conditionals[i]->m_Name.Get(), m_Conditionals[i]->m_bDefined, m_Conditionals[i]->m_Type );
}
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
static bool ResolveSymbol( const char *pSymbol )
{
return g_pVPC->ResolveConditionalSymbol( pSymbol );
}
//-----------------------------------------------------------------------------
// Callback for expression evaluator.
//-----------------------------------------------------------------------------
static void SymbolSyntaxError( const char *pReason )
{
// invoke internal syntax error hndling which spews script stack as well
g_pVPC->VPCSyntaxError( "%s", pReason );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CVPC::EvaluateConditionalExpression( const char *pExpression )
{
if ( !pExpression || !pExpression[0] )
{
// empty string, same as not having a conditional
return true;
}
bool bResult = false;
CExpressionEvaluator ExpressionHandler;
bool bValid = ExpressionHandler.Evaluate( bResult, pExpression, ::ResolveSymbol, ::SymbolSyntaxError );
if ( !bValid )
{
g_pVPC->VPCSyntaxError( "VPC Conditional Evaluation Error" );
}
return bResult;
}
bool CVPC::IsConditionalDefined( const char *pName )
{
conditional_t *pConditional = FindOrCreateConditional( pName, false, CONDITIONAL_NULL );
return pConditional && pConditional->m_bDefined;
}
+410
View File
@@ -0,0 +1,410 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
static KeywordName_t s_KeywordNameTable[] =
{
{"$General", KEYWORD_GENERAL},
{"$Debugging", KEYWORD_DEBUGGING},
{"$Compiler", KEYWORD_COMPILER},
{"$SNCCompiler", KEYWORD_PS3_SNCCOMPILER},
{"$GCCCompiler", KEYWORD_PS3_GCCCOMPILER},
{"$Librarian", KEYWORD_LIBRARIAN},
{"$Linker", KEYWORD_LINKER},
{"$SNCLinker", KEYWORD_PS3_SNCLINKER},
{"$GCCLinker", KEYWORD_PS3_GCCLINKER},
{"$ManifestTool", KEYWORD_MANIFEST},
{"$XMLDocumentGenerator", KEYWORD_XMLDOCGEN},
{"$BrowseInformation", KEYWORD_BROWSEINFO},
{"$Resources", KEYWORD_RESOURCES},
{"$PreBuildEvent", KEYWORD_PREBUILDEVENT},
{"$PreLinkEvent", KEYWORD_PRELINKEVENT},
{"$PostBuildEvent", KEYWORD_POSTBUILDEVENT},
{"$CustomBuildStep", KEYWORD_CUSTOMBUILDSTEP},
{"$Xbox360ImageConversion", KEYWORD_XBOXIMAGE},
{"$ConsoleDeployment", KEYWORD_XBOXDEPLOYMENT},
{"$Ant", KEYWORD_ANT},
{"$Intellisense", KEYWORD_INTELLISENSE},
};
const char *CVPC::KeywordToName( configKeyword_e keyword )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_KeywordNameTable ) == KEYWORD_MAX );
if ( keyword == KEYWORD_UNKNOWN )
{
return "???";
}
return s_KeywordNameTable[keyword].m_pName;
}
configKeyword_e CVPC::NameToKeyword( const char *pKeywordName )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_KeywordNameTable ) == KEYWORD_MAX );
for ( int i = 0; i < ARRAYSIZE( s_KeywordNameTable ); i++ )
{
if ( !V_stricmp_fast( pKeywordName, s_KeywordNameTable[i].m_pName ) )
{
return s_KeywordNameTable[i].m_Keyword;
}
}
return KEYWORD_UNKNOWN;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_Config_Macro()
{
// Allowing macros to be created/set inside of configurations in order to construct a macro that is vectored on the configuration
const char *pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
{
g_pVPC->VPCSyntaxError();
}
CUtlStringHolder<MAX_MACRO_NAME> macroName( pToken );
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
return;
}
g_pVPC->SetPropertyMacro( macroName, pStrBuf->Get(), g_pVPC->GetProjectGenerator()->GetCurrentConfigurationName() );
}
//-----------------------------------------------------------------------------
// VPC_Config_Keyword
//
//-----------------------------------------------------------------------------
void VPC_Config_Keyword( configKeyword_e keyword, const char *pkeywordToken )
{
const char *pToken;
if ( ( keyword == KEYWORD_LIBRARIAN ) && g_pVPC->IsProjectUsingUnity() )
{
g_pVPC->VPCWarning( "$UnityProject should not be used in .LIB projects! The unity build generates a few large OBJs, so due to per-OBJ linker dependency determination linking with a unity-built .LIB would thus incur many unnecessary link dependencies." );
}
bool bShouldSkip = false;
if ( !g_pVPC->GetProjectGenerator()->StartPropertySection( keyword, &bShouldSkip ) )
{
g_pVPC->VPCSyntaxError( "Unsupported Keyword: %s for target platform", pkeywordToken );
}
if ( bShouldSkip )
{
pToken = g_pVPC->GetScript().PeekNextToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
g_pVPC->VPCSyntaxError();
g_pVPC->GetScript().SkipBracedSection();
}
else
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
break;
if ( CharStrEq( pToken, '}' ) )
{
// end of section
break;
}
// Copy off the token name so HandleProperty() doesn't have to (or else the parser will overwrite it on the next token).
CUtlStringHolder<100> tempTokenName( pToken );
if ( !V_stricmp_fast( tempTokenName, "$PropertyMacro" ) )
{
// Allowing macros to be created/set inside of configurations in order to save off a property state into a macro.
// This provides a way for users to temp alter properties and then restore them.
// Syntax: $Macro <MacroName> <PropertyName> [condition]
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
CUtlStringHolder<MAX_MACRO_NAME> macroName( pToken );
// resolve the token that should be a recognized property key
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
continue;
}
// get the specified property key's value and set it
g_pVPC->SetPropertyMacro( macroName, g_pVPC->GetProjectGenerator()->GetPropertyValue( pStrBuf->Get() ), g_pVPC->GetProjectGenerator()->GetCurrentConfigurationName() );
}
else if ( !V_stricmp_fast( tempTokenName, "$Macro" ) )
{
VPC_Config_Macro();
}
else
{
g_pVPC->GetProjectGenerator()->HandleProperty( tempTokenName );
}
}
}
g_pVPC->GetProjectGenerator()->EndPropertySection( keyword );
}
//-----------------------------------------------------------------------------
// VPC_Keyword_Configuration
//
//-----------------------------------------------------------------------------
void VPC_Keyword_Configuration()
{
//determine project generator before any generator-dependent configuration is allowed
g_pVPC->DetermineProjectGenerator();
const char *pToken;
CUtlStringHolder<50> configName;
bool bAllowNextLine = false;
CUtlVector<CUtlString> configs;
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( bAllowNextLine );
if ( !pToken || !pToken[0] )
break;
if ( CharStrEq( pToken, '\\' ) )
{
bAllowNextLine = true;
continue;
}
else
{
bAllowNextLine = false;
}
int index = configs.AddToTail();
configs[index] = pToken;
// check for another optional config
pToken = g_pVPC->GetScript().PeekNextToken( bAllowNextLine );
if ( !pToken || !pToken[0] || CharStrEq( pToken, '{' ) || CharStrEq( pToken, '}' ) || (pToken[0] == '$') )
break;
}
// no configuration specified, use all known
if ( !configs.Count() )
{
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configs );
if ( !configs.Count() )
{
g_pVPC->VPCError( "Trying to parse a configuration block and no configs have been defined yet.\n[%s line:%d]", g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetLine() );
}
}
// save parser state
CScriptSource scriptSource = g_pVPC->GetScript().GetCurrentScript();
for ( int i = 0; i < configs.Count(); i++ )
{
// restore parser state
g_pVPC->GetScript().RestoreScript( scriptSource );
configName.Set( configs[i].String() );
// get access objects
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( configName, false );
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
{
g_pVPC->VPCSyntaxError();
}
while ( 1 )
{
g_pVPC->GetScript().SkipToValidToken();
pToken = g_pVPC->GetScript().PeekNextToken( true );
if ( pToken && pToken[0] && !V_stricmp_fast( pToken, "$Macro" ) )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
VPC_Config_Macro();
continue;
}
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
g_pVPC->GetScript().SkipBracedSection();
continue;
}
if ( CharStrEq( pStrBuf->Get(), '}' ) )
{
// end of section
break;
}
configKeyword_e keyword = g_pVPC->NameToKeyword( pStrBuf->Get() );
if ( keyword == KEYWORD_UNKNOWN )
{
g_pVPC->VPCSyntaxError();
}
else
{
CUtlStringHolder<50> keywordStr( pStrBuf->Get() );
VPC_Config_Keyword( keyword, keywordStr );
}
}
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
//-----------------------------------------------------------------------------
// VPC_Keyword_FileConfiguration
//
//-----------------------------------------------------------------------------
void VPC_Keyword_FileConfiguration()
{
const char *pToken;
bool bAllowNextLine = false;
CUtlVector< CUtlString > configurationNames;
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( bAllowNextLine );
if ( !pToken || !pToken[0] )
break;
if ( CharStrEq( pToken, '\\' ) )
{
bAllowNextLine = true;
continue;
}
else
{
bAllowNextLine = false;
}
configurationNames.AddToTail( pToken );
// check for another optional config
pToken = g_pVPC->GetScript().PeekNextToken( bAllowNextLine );
if ( !pToken || !pToken[0] || CharStrEq( pToken, '{' ) || CharStrEq( pToken, '}' ) || (pToken[0] == '$') )
break;
}
// no configuration specified, use all known
if ( configurationNames.Count() == 0 )
{
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configurationNames );
}
// save parser state
CScriptSource scriptSource = g_pVPC->GetScript().GetCurrentScript();
int nWarningLine = -1;
for ( int i=0; i < configurationNames.Count(); i++ )
{
// restore parser state
g_pVPC->GetScript().RestoreScript( scriptSource );
// Tell the generator we're about to feed it configuration data for this file.
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( configurationNames[i].String(), true );
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
{
g_pVPC->VPCSyntaxError();
}
while ( 1 )
{
g_pVPC->GetScript().SkipToValidToken();
pToken = g_pVPC->GetScript().PeekNextToken( true );
if ( pToken && pToken[0] && !V_stricmp_fast( pToken, g_pOption_ExcludedFromBuild ) )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
g_pVPC->GetProjectGenerator()->FileExcludedFromBuild( Sys_StringToBool( pStrBuf->Get() ) );
}
continue;
}
else if ( pToken && pToken[0] && !V_stricmp_fast( pToken, "$Macro" ) )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
VPC_Config_Macro();
continue;
}
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
g_pVPC->GetScript().SkipBracedSection();
continue;
}
if ( CharStrEq( pStrBuf->Get(), '}' ) )
{
// end of section
break;
}
configKeyword_e keyword = g_pVPC->NameToKeyword( pStrBuf->Get() );
switch ( keyword )
{
// these are the only tools wired to deal with file configuration overrides
case KEYWORD_COMPILER:
case KEYWORD_PS3_SNCCOMPILER:
case KEYWORD_PS3_GCCCOMPILER:
if ( !g_pVPC->IsPerFileCompileConfigEnabled() &&
!g_pVPC->GetScript().IsInPrivilegedScript() &&
g_pVPC->GetScript().GetLine() != nWarningLine )
{
g_pVPC->VPCSyntaxError( "%s(%u): per-file compile configuration not allowed",
g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetLine() );
nWarningLine = g_pVPC->GetScript().GetLine();
}
// Fall through
case KEYWORD_RESOURCES:
case KEYWORD_CUSTOMBUILDSTEP:
{
CUtlStringHolder<50> keywordStr( pStrBuf->Get() );
VPC_Config_Keyword( keyword, keywordStr );
break;
}
default:
g_pVPC->VPCSyntaxError();
}
}
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
File diff suppressed because it is too large Load Diff
+185
View File
@@ -0,0 +1,185 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#pragma once
class IBaseProjectGenerator;
enum EDependencyType
{
k_eDependencyType_SourceFile, // .cpp, .cxx, .h, .hxx
k_eDependencyType_Project, // this is a project file WITHOUT the target-specific extension (.mak, .vpj, .vcproj).
k_eDependencyType_Library, // this is a library file
k_eDependencyType_Unknown // Unrecognized file extension (probably .ico or .rc2 or somesuch).
};
SELECTANY const char *k_DependencyTypeStrings[] =
{
"k_eDependencyType_SourceFile",
"k_eDependencyType_Project",
"k_eDependencyType_Library",
"k_eDependencyType_Unknown"
};
class CProjectDependencyGraph;
enum k_EDependsOnFlags
{
k_EDependsOnFlagCheckNormalDependencies = 0x01,
k_EDependsOnFlagCheckAdditionalDependencies = 0x02,
k_EDependsOnFlagRecurse = 0x04,
k_EDependsOnFlagTraversePastLibs = 0x08
};
// Flags to CProjectDependencyGraph::BuildProjectDependencies.
#define BUILDPROJDEPS_CHECK_ALL_PROJECTS 0x01 // If set, uses the set of allowed .vpc files, otherwise restricted to the projects specified on the CL.
#define BUILDPROJDEPS_FULL_DEPENDENCY_SET 0x02 // If set, builds a graph of all projects in the source tree including all games, otherwise libs only.
#define BUILDPROJDEPS_INCLUDE_SYSTEM_FILES 0x04 // If set, add system files such as system includes to dependencies
class CDependency
{
friend class CProjectDependencyGraph;
friend class CSingleProjectScanner;
public:
CDependency( CProjectDependencyGraph *pDependencyGraph );
virtual ~CDependency();
// Flags are a combination of k_EDependsOnFlags.
bool DependsOn( CDependency *pTest, int flags=k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse );
const char* GetName() const;
// Returns true if the absolute filename of this thing (CDependency::m_Filename) matches the absolute path specified.
bool CompareAbsoluteFilename( const char *pAbsPath ) const;
// Returns true if any direct dependencies of the given type are found:
bool GetDirectDependenciesByType( EDependencyType type, CUtlVector< CDependency * > &result ) const;
// This is full path to the VPC filename for a project (use CDependency_Project::GetProjectFileName() for the VCPROJ/VPJ filename).
CUtlString m_Filename;
EDependencyType m_Type;
// Files that this depends on.
CUtlVector<CDependency*> m_Dependencies;
// Additional Files provided by $AdditionalProjectDependencies. This is in a separate list because we don't
// always want DependsOn() to check this.
CUtlVector<CDependency*> m_AdditionalDependencies;
private:
bool FindDependency_Internal( CUtlVector<CUtlBuffer> &callTreeOutputStack, CDependency *pTest, int flags, int depth );
void Mark();
bool HasBeenMarked();
CProjectDependencyGraph *m_pDependencyGraph;
unsigned int m_iDependencyMark;
bool m_bCheckedIncludes; // Set to true when we have checked all the includes for this.
// Cache info.
int64 m_nCacheFileSize;
int64 m_nCacheModificationTime;
// Used by the cache. File size or modification time don't match.
bool m_bCacheDirty;
};
// This represents a project (.vcproj) file, NOT a project like a projectIndex_t.
// There can be separate .vcproj files (and thus separate CDependency_Project) for each game and platform of a projectIndex_t.
// If m_Type == k_eDependencyType_Project, then you can cast to this.
class CDependency_Project : public CDependency
{
public:
typedef CDependency BaseClass;
CDependency_Project( CProjectDependencyGraph *pDependencyGraph );
public:
// Straight out of the $AdditionalProjectDependencies key (split on semicolons).
CUtlVector<CUtlString> m_AdditionalProjectDependencies;
CUtlString m_ProjectName; // This comes from the $Project key in the .vpc file.
const char *GetProjectFileName( void );
const char *GetProjectGUIDString( void );
// Note that there can be multiple CDependency_Projects with the same m_iProjectIndex.
projectIndex_t m_iProjectIndex;
IBaseProjectGenerator *m_pProjectGenerator;
};
// This class builds a graph of all dependencies, starting at the projects.
class CProjectDependencyGraph : public IProjectIterator
{
friend class CDependency;
public:
CProjectDependencyGraph();
// This is the main function to generate dependencies.
// nBuildProjectDepsFlags is a combination of BUILDPROJDEPS_ flags.
void BuildProjectDependencies( int nBuildProjectDepsFlags, CUtlVector< projectIndex_t > *pAllowedProjects = NULL, CUtlVector< projectIndex_t > *pOverrideProjects = NULL );
bool HasGeneratedDependencies() const;
CDependency* FindDependency( const char *pFilename, CUtlPathStringHolder *pFixedFilename = NULL );
CDependency* FindOrCreateDependency( const char *pFilename, EDependencyType type );
// Look for all projects (that we've scanned during BuildProjectDependencies) that depend on the specified project.
// If bDownwards is true, then it adds iProject and all projects that _it depends on_.
// If bDownwards is false, then it adds iProject and all projects that _depend on it_.
void GetProjectDependencyTree( projectIndex_t iProject, CUtlVector<projectIndex_t> &dependentProjects, bool bDownwards );
// This solves the central mismatch between the way VPC references projects and the way the CDependency stuff does.
//
// - VPC uses projectIndex_t, but a single projectIndex_t can turn into multiple games (server_tf, server_episodic, etc) in VPC_IterateTargetProjects.
// - The dependency code has a separate CDependency_Project for each game.
//
// This takes a bunch of project indices (usually m_targetProjects, which comes from the command line's "+this -that *theother" syntax),
// which are game-agnostic, and based on what games were specified on the command line, it builds the list of CDependency_Project*s.
void TranslateProjectIndicesToDependencyProjects( CUtlVector<projectIndex_t> &projectList, CUtlVector<CDependency_Project*> &out );
// Use ClearAllDependencyMarks with CDependency::HasBeenMarked/Mark() to optimize graph traversal
void ClearAllDependencyMarks();
// IProjectIterator overrides.
protected:
virtual bool VisitProject( projectIndex_t iProject, const char *szProjectName ) OVERRIDE;
private:
// Functions for the vpc.cache file management.
bool LoadCache();
bool SaveCache();
static const char *GetCacheFileName( void );
void WriteString( FILE *fp, CUtlString &utlString );
CUtlString ReadString( FILE *fp );
void CheckCacheEntries();
void RemoveDirtyCacheEntries();
void MarkAllCacheEntriesValid();
void ResolveAdditionalProjectDependencies();
public:
// Projects and everything they depend on.
CUtlVector<CDependency_Project*> m_Projects;
CUtlDict<CDependency*,int> m_AllFiles; // All files go in here. They should never be duplicated. These are indexed by the full filename (except .lib files, which have that stripped off).
bool m_bFullDependencySet; // See BUILDPROJDEPS_FULL_DEPENDENCY_SET flag for BuildProjectDependencies.
bool m_bIncludeSystemFiles; // See BUILDPROJDEPS_INCLUDE_SYSTEM_FILES flag for BuildProjectDependencies.
int m_nFilesParsedForIncludes;
private:
// Used when sweeping the dependency graph to prevent looping around forever.
unsigned int m_iDependencyMark;
bool m_bHasGeneratedDependencies; // Set to true after finishing BuildProjectDependencies.
};
bool IsLibraryFile( const char *pFilename );
+222
View File
@@ -0,0 +1,222 @@
//========= Copyright (C), Valve Corporation, All rights reserved. =====================//
//
// Purpose: Helper code relating to build-generated files (schema/qt/protobuf/unity)
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CSourceFileInfo::CSourceFileInfo( int folderIndex )
: m_pSourceFile( NULL ),
m_pDebugCompiledFile( NULL ),
m_pReleaseCompiledFile( NULL ),
m_pContainingUnityFile( NULL ),
m_ConfigStringCRC( 0 ),
m_bCreatesPCH( false ),
m_iFolderIndex( folderIndex )
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool VPC_GeneratedFiles_CreateFileConfigString( CSourceFileInfo &fileInfo, const CUtlVector< CProjectConfiguration *> &rootConfigs )
{
for ( int i = 0; i < rootConfigs.Count(); i++ )
{
CProjectFile *pCompiledFile = ( rootConfigs[i]->m_Name == "Debug" ) ? fileInfo.m_pDebugCompiledFile : fileInfo.m_pReleaseCompiledFile;
// Start the config string off with the PCH name (for clarity; files with different PCHs must sort into different groups)
fileInfo.m_ConfigString += fileInfo.m_PCHName;
fileInfo.m_ConfigString += " ";
// Look for configs with compiler properties
CProjectConfiguration *pFileConfig = NULL;
pCompiledFile->GetConfiguration( rootConfigs[i]->m_Name.Get(), &pFileConfig );
CCompilerTool *pCompilerTool = pFileConfig ? pFileConfig->GetCompilerTool() : NULL;
if ( !pCompilerTool || pCompilerTool->m_PropertyStates.m_Properties.IsEmpty() )
continue;
// Concat config name
fileInfo.m_ConfigString += pFileConfig->m_Name;
fileInfo.m_ConfigString += " ";
// Concat compiler property names+values in consistent sorted order
for ( int j = 0; j < pCompilerTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); j++ )
{
int sortedIndex = pCompilerTool->m_PropertyStates.m_PropertiesInOutputOrder[j];
PropertyState_t &property = pCompilerTool->m_PropertyStates.m_Properties[sortedIndex];
fileInfo.m_ConfigString += property.m_pToolProperty->m_ParseString;
fileInfo.m_ConfigString += " ";
fileInfo.m_ConfigString += property.m_StringValue;
fileInfo.m_ConfigString += " ";
}
}
fileInfo.m_ConfigString.ToLower(); // Ignore case differences
fileInfo.m_ConfigStringCRC = CRC32_ProcessSingleBuffer( fileInfo.m_ConfigString.Get(), fileInfo.m_ConfigString.Length() );
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool VPC_GeneratedFiles_GetPCHInfo( CSourceFileInfo &fileInfo, const CUtlVector< CProjectConfiguration *> &rootConfigs )
{
for ( int i = 0; i < rootConfigs.Count(); i++ )
{
CProjectFile *pCompiledFile = ( rootConfigs[i]->m_Name == "Debug" ) ? fileInfo.m_pDebugCompiledFile : fileInfo.m_pReleaseCompiledFile;
// Get the PCH used by this file [ NOTE: we expect the same PCH settings between Debug+Release ]
bool bExcludesPCH;
CUtlString pchName;
VPC_GetPCHInclude( pCompiledFile, rootConfigs[i], pchName, fileInfo.m_bCreatesPCH, bExcludesPCH );
if ( ( i > 0 ) && ( pchName != fileInfo.m_PCHName ) )
{
g_pVPC->VPCWarning( "VPC_GeneratedFiles_CreateFileConfigString: Unsupported PCH configuration for %s", pCompiledFile->m_Name.Get() );
return false;
}
fileInfo.m_PCHName = pchName;
}
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TODO: having to pass pDataCollector/rootConfigs is a pain, those should be (efficiently) accessible as globals
bool VPC_GeneratedFiles_GetSourceFileInfo( CSourceFileInfo &fileInfo, CProjectFile *pFile, bool bGenerateConfigString,
CVCProjGenerator *pDataCollector, const CUtlVector< CProjectConfiguration * > &rootConfigs )
{
// Determine if this is to be compiled directly, or if generated files will be compiled in its stead
fileInfo.m_pSourceFile = pFile;
if ( pFile->m_iFlags & VPC_FILE_FLAGS_DYNAMIC )
{
// We don't return data for a dynamic file, but rather for the source file from which it is generated
return false;
}
else if ( pFile->m_iFlags & VPC_FILE_FLAGS_SCHEMA )
{
// Get the schema-generated output files:
fileInfo.m_pDebugCompiledFile = VPC_Schema_GetGeneratedFile( pFile, "Debug", pDataCollector );
fileInfo.m_pReleaseCompiledFile = VPC_Schema_GetGeneratedFile( pFile, "Release", pDataCollector );
}
else if ( pFile->m_iFlags & VPC_FILE_FLAGS_QT )
{
// Get the Qt/MOC-generated output files (should both be the same):
fileInfo.m_pDebugCompiledFile = VPC_Qt_GetGeneratedFile( pFile, "Debug", pDataCollector );
fileInfo.m_pReleaseCompiledFile = VPC_Qt_GetGeneratedFile( pFile, "Release", pDataCollector );
}
else if ( IsCFileExtension( V_GetFileExtension( pFile->m_Name.Get() ) ) )
{
// Normal source file, outputs are the same as the input
fileInfo.m_pDebugCompiledFile = pFile;
fileInfo.m_pReleaseCompiledFile = pFile;
}
else
{
// This file yields no compilable outputs (e.g a non-code file or a non-schema header)
return false;
}
// Ignore missing input files (the output files may be missing though, if they're dynamic)
if ( !Sys_Exists( pFile->m_Name.AbsPath( NULL /*, k_bVPCForceLowerCase*/ ).Get() ) )
return false;
if ( !fileInfo.m_pDebugCompiledFile || !fileInfo.m_pReleaseCompiledFile )
{
//g_pVPC->VPCWarning( "VPC_GeneratedFiles_GetSourceFileInfo: could not determine compileable output files for %s", pFile->m_Name.Get() );
return false;
}
// Determine the containing unity file, if any
fileInfo.m_pContainingUnityFile = VPC_Unity_GetContainingUnityFile( pFile, NULL, pDataCollector );
// Determine which PCH this file uses, and whether it is responsible for building the PCH file
if ( !VPC_GeneratedFiles_GetPCHInfo( fileInfo, rootConfigs ) )
return false;
if ( bGenerateConfigString )
{
// Generate additional information summarizing the file config settings for the output file(s)
return VPC_GeneratedFiles_CreateFileConfigString( fileInfo, rootConfigs );
}
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_GeneratedFiles_ProcessFolder( CProjectFolder *pFolder, CVCProjGenerator *pDataCollector, const CUtlVector< CProjectConfiguration * > &rootConfigs,
CUtlBuffer &manifestFile )
{
// Process files
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
CProjectFile *pFile = pFolder->m_Files[iIndex];
CSourceFileInfo fileInfo;
if ( !VPC_GeneratedFiles_GetSourceFileInfo( fileInfo, pFile, true, pDataCollector, rootConfigs ) )
continue;
CUtlString absSourceFilePath = fileInfo.m_pSourceFile->m_Name.AbsPath( NULL /*, k_bVPCForceLowerCase*/ );
CUtlString absDebugOutputPath = fileInfo.m_pDebugCompiledFile->m_Name.AbsPath( NULL /*, k_bVPCForceLowerCase*/ );
CUtlString absReleaseOutputPath = fileInfo.m_pReleaseCompiledFile->m_Name.AbsPath( NULL /*, k_bVPCForceLowerCase*/ );
CUtlString absUnityFilePath = fileInfo.m_pContainingUnityFile ? fileInfo.m_pContainingUnityFile->m_Name.AbsPath( NULL /*, k_bVPCForceLowerCase*/ ) : "";
manifestFile.Printf( "%-24s%s\n", "Source file:", absSourceFilePath.Get() );
manifestFile.Printf( "%-24s%s\n", "Debug output file:", absDebugOutputPath.Get() );
manifestFile.Printf( "%-24s%s\n", "Release output file:", absReleaseOutputPath.Get() );
manifestFile.Printf( "%-24s%s\n", "Containing unity file:", absUnityFilePath.Get() );
manifestFile.Printf( "%-24s%s\n", "PCH file:", fileInfo.m_PCHName.Get() );
if ( fileInfo.m_bCreatesPCH )
manifestFile.Printf( "%-24s%s\n", "Builds PCH file:", "yes" );
manifestFile.Printf( "\n" );
}
// Recurse into child folders
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
VPC_GeneratedFiles_ProcessFolder( pFolder->m_Folders[iIndex], pDataCollector, rootConfigs, manifestFile );
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_GeneratedFiles_OnParseProjectEnd( CVCProjGenerator *pDataCollector )
{
// This generates a build manifest file, which provides data for ValveVSAddin.
// Skip building the manifest during dependency-generation (we need to see all
// the schema/qt/unity-generated files, which are not created during this pass)
if ( g_pVPC->m_bIsDependencyPass )
return;
// Write the manifest to "_vpc_\manifest_<ProjectName>_<GameName>\<Platform>\manifest.txt" to avoid filename conflicts and clutter
CUtlPathStringHolder manifestPath;
g_pVPC->CreateGeneratedSubdirPath( &manifestPath, "manifest" );
Sys_CreatePath( manifestPath );
CUtlPathStringHolder manifestName( manifestPath, "manifest.txt" );
CUtlBuffer manifestFile( 0, 0, CUtlBuffer::TEXT_BUFFER );
manifestFile.Printf( "%s\n", "// ----------------------------------------- //\n"
"// File generated by VPC //\n"
"// ----------------------------------------- //\n" );
// Iterate the folders in the project and generate data for all compiled files:
CUtlVector< CProjectConfiguration * > rootConfigs;
pDataCollector->GetAllRootConfigurations( rootConfigs );
CProjectFolder *pRootFolder = pDataCollector->GetRootFolder();
VPC_GeneratedFiles_ProcessFolder( pRootFolder, pDataCollector, rootConfigs, manifestFile );
Sys_WriteFileIfChanged( manifestName.Get(), manifestFile, true );
// Add the manifest file to the 'VPC Scripts' folder:
CProjectFolder *pVPCFolder;
if ( !pRootFolder->GetFolder( "VPC Scripts", &pVPCFolder ) )
g_pVPC->VPCError( "VPC_GeneratedFiles_OnParseProjectEnd: cannot find 'VPC Scripts' folder!" );
pDataCollector->AddFileToFolder( manifestName.Get(), pVPCFolder, true, VPC_FILE_FLAGS_DYNAMIC, NULL );
}
+373
View File
@@ -0,0 +1,373 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
//
//=====================================================================================//
#include "vpc.h"
CGeneratorDefinition::CGeneratorDefinition()
{
Clear();
}
void CGeneratorDefinition::Clear()
{
m_pPropertyNames = NULL;
m_ScriptName.Clear();
m_NameString.Clear();
m_VersionString.Clear();
m_Tools.Purge();
m_ScriptCRC = 0;
}
void CGeneratorDefinition::IterateAttributesKey( ToolProperty_t *pProperty, KeyValues *pAttributesKV )
{
const char *pAttributeName = pAttributesKV->GetName();
const char *pValue = pAttributesKV->GetString( "" );
//Msg( "Attribute name: %s\n", pAttributeName );
if ( !V_stricmp_fast( pAttributeName, "type" ) )
{
if ( !V_stricmp_fast( pValue, "bool" ) || !V_stricmp_fast( pValue, "boolean" ) )
{
pProperty->m_nType = PT_BOOLEAN;
}
else if ( !V_stricmp_fast( pValue, "string" ) )
{
pProperty->m_nType = PT_STRING;
}
else if ( !V_stricmp_fast( pValue, "list" ) )
{
pProperty->m_nType = PT_LIST;
}
else if ( !V_stricmp_fast( pValue, "int" ) || !V_stricmp_fast( pValue, "integer" ) )
{
pProperty->m_nType = PT_INTEGER;
}
else if ( !V_stricmp_fast( pValue, "ignore" ) || !V_stricmp_fast( pValue, "none" ) )
{
pProperty->m_nType = PT_IGNORE;
}
else if ( !V_stricmp_fast( pValue, "deprecated" ) || !V_stricmp_fast( pValue, "donotuse" ) )
{
pProperty->m_nType = PT_DEPRECATED;
}
else
{
// unknown
g_pVPC->VPCError( "Unknown type '%s' in '%s'", pValue, pProperty->m_ParseString.Get() );
}
}
else if ( !V_stricmp_fast( pAttributeName, "alias" ) )
{
pProperty->m_AliasString = pValue;
}
else if ( !V_stricmp_fast( pAttributeName, "legacy" ) )
{
pProperty->m_LegacyString = pValue;
}
else if ( !V_stricmp_fast( pAttributeName, "InvertOutput" ) )
{
pProperty->m_bInvertOutput = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "output" ) )
{
pProperty->m_OutputString = pValue;
}
else if ( !V_stricmp_fast( pAttributeName, "fixslashes" ) )
{
pProperty->m_bFixSlashes = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "PreferSemicolonNoComma" ) )
{
pProperty->m_bPreferSemicolonNoComma = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "PreferSemicolonNoSpace" ) )
{
pProperty->m_bPreferSemicolonNoSpace = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "AppendSlash" ) )
{
pProperty->m_bAppendSlash = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "GlobalProperty" ) )
{
pProperty->m_bEmitAsGlobalProperty = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "BreakOnRead" ) )
{
pProperty->m_bBreakOnRead = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "BreakOnWrite" ) )
{
pProperty->m_bBreakOnWrite = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "ordinals" ) )
{
if ( pProperty->m_nType == PT_UNKNOWN )
{
pProperty->m_nType = PT_LIST;
}
for ( KeyValues *pKV = pAttributesKV->GetFirstSubKey(); pKV; pKV = pKV->GetNextKey() )
{
const char *pOrdinalName = pKV->GetName();
const char *pOrdinalValue = pKV->GetString();
if ( !pOrdinalValue[0] )
{
g_pVPC->VPCError( "Unknown ordinal value for name '%s' in '%s'", pOrdinalName, pProperty->m_ParseString.Get() );
}
int iIndex = pProperty->m_Ordinals.AddToTail();
pProperty->m_Ordinals[iIndex].m_ParseString = pOrdinalName;
pProperty->m_Ordinals[iIndex].m_ValueString = pOrdinalValue;
}
}
else if ( !V_stricmp_fast( pAttributeName, "IgnoreForOutput" ) )
{
pProperty->m_bIgnoreForOutput = pAttributesKV->GetBool();
}
else if ( !V_stricmp_fast( pAttributeName, "GeneratedOnOutput" ) )
{
pProperty->m_bGeneratedOnOutput = pAttributesKV->GetBool();
}
else
{
g_pVPC->VPCError( "Unknown attribute '%s' in '%s'", pAttributeName, pProperty->m_ParseString.Get() );
}
}
void CGeneratorDefinition::IteratePropertyKey( GeneratorTool_t *pTool, KeyValues *pPropertyKV )
{
//Msg( "Property Key name: %s\n", pPropertyKV->GetName() );
int iIndex = pTool->m_Properties.AddToTail();
ToolProperty_t *pProperty = &pTool->m_Properties[iIndex];
pProperty->m_ParseString = pPropertyKV->GetName();
KeyValues *pKV = pPropertyKV->GetFirstSubKey();
if ( !pKV )
return;
for ( ;pKV; pKV = pKV->GetNextKey() )
{
IterateAttributesKey( pProperty, pKV );
}
}
void CGeneratorDefinition::IterateToolKey( KeyValues *pToolKV )
{
//Msg( "Tool Key name: %s\n", pToolKV->GetName() );
// find or create
GeneratorTool_t *pTool = NULL;
for ( int i = 0; i < m_Tools.Count(); i++ )
{
if ( !V_stricmp_fast( pToolKV->GetName(), m_Tools[i].m_ParseString.Get() ) )
{
pTool = &m_Tools[i];
break;
}
}
if ( !pTool )
{
int iIndex = m_Tools.AddToTail();
pTool = &m_Tools[iIndex];
}
pTool->m_ParseString = pToolKV->GetName();
KeyValues *pKV = pToolKV->GetFirstSubKey();
if ( !pKV )
return;
for ( ;pKV; pKV = pKV->GetNextKey() )
{
IteratePropertyKey( pTool, pKV );
}
}
void CGeneratorDefinition::AssignIdentifiers()
{
CUtlVector< bool > usedPropertyNames;
int nTotalPropertyNames = 0;
while ( m_pPropertyNames[nTotalPropertyNames].m_nPropertyId >= 0 )
{
nTotalPropertyNames++;
}
usedPropertyNames.SetCount( nTotalPropertyNames );
// assign property identifiers
for ( int i = 0; i < m_Tools.Count(); i++ )
{
GeneratorTool_t *pTool = &m_Tools[i];
// assign the tool keyword
configKeyword_e keyword = g_pVPC->NameToKeyword( pTool->m_ParseString.Get() );
if ( keyword == KEYWORD_UNKNOWN )
{
g_pVPC->VPCError( "Unknown Tool Keyword '%s' in '%s'", pTool->m_ParseString.Get(), m_ScriptName.Get() );
}
pTool->m_nKeyword = keyword;
const char *pPrefix = m_NameString.Get();
const char *pToolName = pTool->m_ParseString.Get();
if ( pToolName[0] == '$' )
{
pToolName++;
}
CUtlString prefixString = CFmtStr( "%s_%s", pPrefix, pToolName ).Get();
for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
{
ToolProperty_t *pProperty = &pTool->m_Properties[j];
if ( pProperty->m_nType == PT_IGNORE || pProperty->m_nType == PT_DEPRECATED )
{
continue;
}
const char *pPropertyName = pProperty->m_AliasString.Get();
if ( !pPropertyName[0] )
{
pPropertyName = pProperty->m_ParseString.Get();
}
if ( pPropertyName[0] == '$' )
{
pPropertyName++;
}
bool bFound = false;
for ( int k = 0; k < nTotalPropertyNames && !bFound; k++ )
{
if ( !V_stricmp_fast( prefixString.Get(), m_pPropertyNames[k].m_pPrefixName ) )
{
if ( !V_stricmp_fast( pPropertyName, m_pPropertyNames[k].m_pPropertyName ) )
{
pProperty->m_nPropertyId = m_pPropertyNames[k].m_nPropertyId;
bFound = true;
usedPropertyNames[k] = true;
}
}
}
if ( !bFound )
{
g_pVPC->VPCError( "Could not find PROPERTYNAME( %s, %s ) for %s", prefixString.Get(), pPropertyName, m_ScriptName.Get() );
}
}
}
if ( g_pVPC->IsVerbose() )
{
for ( int i = 0; i < usedPropertyNames.Count(); i++ )
{
if ( !usedPropertyNames[i] )
{
g_pVPC->VPCWarning( "Unused PROPERTYNAME( %s, %s ) in %s", m_pPropertyNames[i].m_pPrefixName, m_pPropertyNames[i].m_pPropertyName, m_ScriptName.Get() );
}
}
}
}
void CGeneratorDefinition::LoadDefinition( const char *pDefinitionName, PropertyName_t *pPropertyNames )
{
Clear();
CUtlPathStringHolder scriptFilename( g_pVPC->GetSourcePath(), "\\vpc_scripts\\definitions\\", pDefinitionName );
scriptFilename.FixSlashes();
m_pPropertyNames = pPropertyNames;
g_pVPC->GetScript().PushScript( scriptFilename.Get() );
// project definitions are KV format
KeyValues *pScriptKV = new KeyValues( g_pVPC->GetScript().GetName() );
pScriptKV->LoadFromBuffer( g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetData() );
m_ScriptName = g_pVPC->GetScript().GetName();
m_ScriptCRC = CRC32_ProcessSingleBuffer( g_pVPC->GetScript().GetData(), V_strlen( g_pVPC->GetScript().GetData() ) );
m_NameString = pScriptKV->GetName();
KeyValues *pKV = pScriptKV->GetFirstSubKey();
for ( ;pKV; pKV = pKV->GetNextKey() )
{
const char *pKeyName = pKV->GetName();
if ( !V_stricmp_fast( pKeyName, "version" ) )
{
m_VersionString = pKV->GetString();
}
else
{
IterateToolKey( pKV );
}
}
g_pVPC->GetScript().PopScript();
pScriptKV->deleteThis();
g_pVPC->VPCStatus( false, "Definition: '%s' Version: %s", m_NameString.Get(), m_VersionString.Get() );
AssignIdentifiers();
}
const char *CGeneratorDefinition::GetScriptName( CRC32_t *pCRC )
{
if ( pCRC )
{
*pCRC = m_ScriptCRC;
}
return m_ScriptName.Get();
}
ToolProperty_t *CGeneratorDefinition::GetProperty( configKeyword_e keyword, const char *pPropertyName )
{
for ( int i = 0; i < m_Tools.Count(); i++ )
{
GeneratorTool_t *pTool = &m_Tools[i];
if ( pTool->m_nKeyword != keyword )
continue;
for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
{
// TODO: use a symbol table instead of stricmp (in source2 'VPC +everything' does 16.3 million stricmps here, likely wasting several seconds)
ToolProperty_t *pToolProperty = &pTool->m_Properties[j];
if ( !V_stricmp_fast( pToolProperty->m_ParseString.Get(), pPropertyName ) )
{
// found
return pToolProperty;
}
if ( !pToolProperty->m_LegacyString.IsEmpty() && !V_stricmp_fast( pToolProperty->m_LegacyString.Get(), pPropertyName ) )
{
// found
return pToolProperty;
}
}
}
// not found
return NULL;
}
+132
View File
@@ -0,0 +1,132 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
//
//==================================================================================================
#pragma once
struct PropertyName_t
{
int m_nPropertyId;
const char *m_pPrefixName;
const char *m_pPropertyName;
};
enum configKeyword_e
{
KEYWORD_UNKNOWN = -1,
KEYWORD_GENERAL,
KEYWORD_DEBUGGING,
KEYWORD_COMPILER,
KEYWORD_PS3_SNCCOMPILER,
KEYWORD_PS3_GCCCOMPILER,
KEYWORD_LIBRARIAN,
KEYWORD_LINKER,
KEYWORD_PS3_SNCLINKER,
KEYWORD_PS3_GCCLINKER,
KEYWORD_MANIFEST,
KEYWORD_XMLDOCGEN,
KEYWORD_BROWSEINFO,
KEYWORD_RESOURCES,
KEYWORD_PREBUILDEVENT,
KEYWORD_PRELINKEVENT,
KEYWORD_POSTBUILDEVENT,
KEYWORD_CUSTOMBUILDSTEP,
KEYWORD_XBOXIMAGE,
KEYWORD_XBOXDEPLOYMENT,
KEYWORD_ANT,
KEYWORD_INTELLISENSE,
KEYWORD_MAX,
};
enum PropertyType_e
{
PT_UNKNOWN = 0,
PT_BOOLEAN,
PT_STRING,
PT_INTEGER,
PT_LIST,
PT_IGNORE,
PT_DEPRECATED,
};
struct PropertyOrdinal_t
{
CUtlString m_ParseString;
CUtlString m_ValueString;
};
struct ToolProperty_t
{
ToolProperty_t()
{
m_nPropertyId = -1;
m_nType = PT_UNKNOWN;
m_bFixSlashes = false;
m_bEmitAsGlobalProperty = false;
m_bInvertOutput = false;
m_bAppendSlash = false;
m_bPreferSemicolonNoComma = false;
m_bPreferSemicolonNoSpace = false;
m_bIgnoreForOutput = false;
m_bBreakOnRead = false;
m_bBreakOnWrite = false;
m_bGeneratedOnOutput = false;
}
CUtlString m_ParseString;
CUtlString m_AliasString;
CUtlString m_LegacyString;
CUtlString m_OutputString;
CUtlVector< PropertyOrdinal_t > m_Ordinals;
int m_nPropertyId;
PropertyType_e m_nType;
bool m_bFixSlashes;
bool m_bEmitAsGlobalProperty;
bool m_bInvertOutput;
bool m_bAppendSlash;
bool m_bPreferSemicolonNoComma;
bool m_bPreferSemicolonNoSpace;
bool m_bIgnoreForOutput;
bool m_bBreakOnRead;
bool m_bBreakOnWrite;
bool m_bGeneratedOnOutput;
};
struct GeneratorTool_t
{
GeneratorTool_t()
{
m_nKeyword = KEYWORD_UNKNOWN;
}
CUtlString m_ParseString;
CUtlVector< ToolProperty_t > m_Properties;
configKeyword_e m_nKeyword;
};
class CGeneratorDefinition
{
public:
CGeneratorDefinition();
void LoadDefinition( const char *pDefinitionName, PropertyName_t *pPropertyNames );
ToolProperty_t *GetProperty( configKeyword_e keyword, const char *pPropertyName );
const char *GetScriptName( CRC32_t *pCRC );
private:
void AssignIdentifiers();
void IterateToolKey( KeyValues *pToolKV );
void IteratePropertyKey( GeneratorTool_t *pTool, KeyValues *pPropertyKV );
void IterateAttributesKey( ToolProperty_t *pProperty, KeyValues *pAttributesKV );
void Clear();
PropertyName_t *m_pPropertyNames;
CUtlString m_ScriptName;
CUtlString m_NameString;
CUtlString m_VersionString;
CUtlVector< GeneratorTool_t > m_Tools;
CRC32_t m_ScriptCRC;
};
+456
View File
@@ -0,0 +1,456 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateProject
//
//-----------------------------------------------------------------------------
projectIndex_t VPC_Group_FindOrCreateProject( const char *pName, bool bCreate )
{
for ( int i = 0; i < g_pVPC->m_Projects.Count(); i++ )
{
if ( !V_stricmp_fast( pName, g_pVPC->m_Projects[i].name.String() ) )
{
return i;
}
}
if ( !bCreate )
return INVALID_INDEX;
int index = g_pVPC->m_Projects.AddToTail();
g_pVPC->m_Projects[index].name = pName;
return index;
}
//-----------------------------------------------------------------------------
// VPC_Group_CreateGroup
//
//-----------------------------------------------------------------------------
groupIndex_t VPC_Group_CreateGroup()
{
groupIndex_t index = g_pVPC->m_Groups.AddToTail();
return index;
}
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateGroupTag
//
//-----------------------------------------------------------------------------
groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate )
{
for (int i=0; i<g_pVPC->m_GroupTags.Count(); i++)
{
if ( !V_stricmp_fast( pName, g_pVPC->m_GroupTags[i].name.String() ) )
return i;
}
if ( !bCreate )
return INVALID_INDEX;
groupTagIndex_t index = g_pVPC->m_GroupTags.AddToTail();
g_pVPC->m_GroupTags[index].name = pName;
return index;
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Games
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Games()
{
const char *pToken;
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( CharStrEq( pToken, '}' ) )
{
// end of section
break;
}
else
{
g_pVPC->FindOrCreateConditional( pToken, true, CONDITIONAL_GAME );
}
}
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Group
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Group()
{
const char *pToken;
bool bFirstToken = true;
groupIndex_t groupIndex;
projectIndex_t projectIndex;
groupIndex = VPC_Group_CreateGroup();
while ( 1 )
{
if ( !bFirstToken )
{
pToken = g_pVPC->GetScript().PeekNextToken( false );
if ( !pToken || !pToken[0] )
break;
}
else
{
bFirstToken = false;
}
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
// specified tag now builds this group
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
}
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( CharStrEq( pToken, '}' ) )
{
// end of section
break;
}
else
{
projectIndex = VPC_Group_FindOrCreateProject( pToken, false );
if ( projectIndex != INVALID_INDEX )
{
// duplicated within a group not allowed, causes other problems later when projects enabled/disabled
for ( int i = 0; i < g_pVPC->m_Groups[groupIndex].projects.Count(); i++ )
{
if ( g_pVPC->m_Groups[groupIndex].projects[i] == projectIndex )
{
// The error will dump the script stack with the offending line.
// It's not a warning so it gets fixed.
g_pVPC->VPCError( "Duplicate project entry '%s' found in group.", pToken );
}
}
int index = g_pVPC->m_Groups[groupIndex].projects.AddToTail();
g_pVPC->m_Groups[groupIndex].projects[index] = projectIndex;
}
else
{
g_pVPC->VPCWarning( "No Project %s defined, ignoring.", pToken );
continue;
}
}
}
}
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Project
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Project()
{
const char *pToken;
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( VPC_Group_FindOrCreateProject( pToken, false ) != INVALID_INDEX )
{
// already defined
g_pVPC->VPCWarning( "project %s already defined", pToken );
g_pVPC->VPCSyntaxError();
}
projectIndex_t projectIndex = VPC_Group_FindOrCreateProject( pToken, true );
// create a default group that contains just this project
groupIndex_t groupIndex = VPC_Group_CreateGroup();
g_pVPC->m_Groups[groupIndex].projects.AddToTail( projectIndex );
// create a default tag that matches the project name
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
g_pVPC->m_GroupTags[groupTagIndex].bSameAsProject = true;
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] || !CharStrEq( pToken, '{' ) )
g_pVPC->VPCSyntaxError();
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( CharStrEq( pToken, '}' ) )
{
// end of section
break;
}
else
{
scriptIndex_t scriptIndex = g_pVPC->m_Projects[projectIndex].scripts.AddToTail();
g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].name = pToken;
pToken = g_pVPC->GetScript().PeekNextToken( false );
if ( pToken && pToken[0] )
{
pToken = g_pVPC->GetScript().GetToken( false );
g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].m_condition = pToken;
}
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Conditional()
{
const char *pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
g_pVPC->VPCSyntaxError();
if ( pToken[0] == '$' )
{
// being nice to users, quietly remove the unwanted conditional prefix '$'
pToken++;
}
CUtlStringHolder<50> name( pToken );
CUtlStringBuilder *pStrBuf = g_pVPC->GetPropertyValueBuffer();
if ( !g_pVPC->GetScript().ParsePropertyValue( NULL, pStrBuf ) )
{
return;
}
CUtlStringHolder<100> value( pStrBuf->Get() );
// a group script (i.e. defaults.vgc) can set certain types of conditionals
conditional_t *pConditional = g_pVPC->FindOrCreateConditional( name, true, CONDITIONAL_SYSTEM );
if ( pConditional->m_Type != CONDITIONAL_SYSTEM && pConditional->m_Type != CONDITIONAL_CUSTOM && pConditional->m_Type != CONDITIONAL_SCRIPT )
{
// group script cannot change conditionals outside of their restricted set
g_pVPC->VPCSyntaxError( "$Conditional cannot be used on the reserved '$%s'", pConditional->m_UpperCaseName.Get() );
}
bool bValue;
const char *pEnvValue = Sys_EvaluateEnvironmentExpression( value, "0" );
if ( pEnvValue )
{
bValue = Sys_StringToBool( pEnvValue );
}
else
{
bValue = Sys_StringToBool( value );
}
// conditional has been pre-qualified, set accordingly
g_pVPC->SetConditional( name, bValue, pConditional->m_Type );
}
//-----------------------------------------------------------------------------
// VPC_ParseGroupScript
//
//-----------------------------------------------------------------------------
void VPC_ParseGroupScript( const char *pScriptName )
{
const char *pToken;
// caller's pointer is aliased
CUtlPathStringHolder localScriptName( pScriptName );
localScriptName.FixSlashes();
g_pVPC->VPCStatus( false, "Parsing: %s", localScriptName.Get() );
g_pVPC->GetScript().PushScript( localScriptName );
while ( 1 )
{
pToken = g_pVPC->GetScript().GetToken( true );
if ( !pToken || !pToken[0] )
{
// end of file
break;
}
if ( !V_stricmp_fast( pToken, "$include" ) )
{
pToken = g_pVPC->GetScript().GetToken( false );
if ( !pToken || !pToken[0] )
{
// end of file
g_pVPC->VPCSyntaxError();
}
// recurse into and run
VPC_ParseGroupScript( pToken );
}
else if ( !V_stricmp_fast( pToken, "$games" ) )
{
VPC_GroupKeyword_Games();
}
else if ( !V_stricmp_fast( pToken, "$group" ) )
{
VPC_GroupKeyword_Group();
}
else if ( !V_stricmp_fast( pToken, "$project" ) )
{
VPC_GroupKeyword_Project();
}
else if ( !V_stricmp_fast( pToken, "$conditional" ) )
{
VPC_GroupKeyword_Conditional();
}
else
{
g_pVPC->VPCSyntaxError();
}
}
g_pVPC->GetScript().PopScript();
}
//-----------------------------------------------------------------------------
// Collect all the +XXX, remove all the -XXX
// This allows removal to be the expected trumping operation.
//-----------------------------------------------------------------------------
void CVPC::GenerateBuildSet( CProjectDependencyGraph &dependencyGraph )
{
CUtlVector< projectIndex_t > forceAllowProjects;
if ( g_pVPC->RestrictProjectsToEverything() )
{
// Since the user is restricting the projects to everything, it's possible they are trying to build a project
// that in not in the everything group. Accumulate all the build commands and treat them as unconditionally 'allowed'
// projects that the dependency generator needs to consider. i.e. They are using @foo, but foo is not in the everything group,
// the dependency generator would otherwise yield nothing unless we 'allowed' foo for consideration.
//
// Generate the 'allowed' projects without considering -XXX, which is a silly undefined complexity w.r.t dependencies. If somebody really
// wants to subtract dependencies then they should run with /allprojects.
for ( int i = 0; i < m_BuildCommands.Count(); i++ )
{
const char *pCommand = m_BuildCommands[i].Get();
if ( pCommand[0] == '-' )
{
// not applicable, ignore
continue;
}
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
if ( groupTagIndex == INVALID_INDEX )
continue;
groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
for ( int j=0; j<pGroupTag->groups.Count(); j++ )
{
group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
for ( int k=0; k<pGroup->projects.Count(); k++ )
{
projectIndex_t targetProject = pGroup->projects[k];
forceAllowProjects.AddToTail( targetProject );
}
}
}
}
// process +XXX commands
for ( int i = 0; i < m_BuildCommands.Count(); i++ )
{
const char *pCommand = m_BuildCommands[i].Get();
if ( pCommand[0] == '-' )
continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
if ( groupTagIndex == INVALID_INDEX )
continue;
groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
CUtlVector<projectIndex_t> projectsToAdd;
for ( int j=0; j<pGroupTag->groups.Count(); j++ )
{
group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
for ( int k=0; k<pGroup->projects.Count(); k++ )
{
if ( ( ( pCommand[0] == '*' ) || ( pCommand[0] == '@' ) ) && !VPC_AreProjectDependenciesSupportedForThisTargetPlatform() )
{
g_pVPC->VPCError( "Cannot build '%s' dependencies, not supported for %s yet", pCommand, g_pVPC->GetTargetPlatformName() );
}
projectIndex_t targetProject = pGroup->projects[k];
if ( pCommand[0] == '*' || pCommand[0] == '@' )
{
// Add this project and any projects that depend on it.
if ( !dependencyGraph.HasGeneratedDependencies() )
{
dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS, &forceAllowProjects );
}
// @ means depends on, * means depends on me
bool bIterateDownwards = ( pCommand[0] == '@' );
dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, bIterateDownwards );
}
else
{
projectsToAdd.AddToTail( targetProject );
}
}
}
// Add all the projects in the list.
for ( int j=0; j < projectsToAdd.Count(); j++ )
{
// add uniquely
projectIndex_t targetProject = projectsToAdd[j];
if ( g_pVPC->m_TargetProjects.Find( targetProject ) == g_pVPC->m_TargetProjects.InvalidIndex() )
{
g_pVPC->m_TargetProjects.AddToTail( targetProject );
}
}
}
// process -XXX commands, explicitly remove tagged projects
for ( int i=0; i<m_BuildCommands.Count(); i++ )
{
const char *pCommand = m_BuildCommands[i].Get();
if ( pCommand[0] == '+' || pCommand[0] == '*' || pCommand[0] == '@' )
continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
if ( groupTagIndex == INVALID_INDEX )
continue;
groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
for ( int j=0; j<pGroupTag->groups.Count(); j++ )
{
group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
for ( int k=0; k<pGroup->projects.Count(); k++ )
{
g_pVPC->m_TargetProjects.FindAndRemove( pGroup->projects[k] );
}
}
}
}
+110
View File
@@ -0,0 +1,110 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#pragma once
#include "tier1/utlstring.h"
//
// Usage:
//
// StartProject
// StartConfigurationBlock
// StartPropertySection
// HandleProperty...
// EndPropertySection
// EndConfigurationBlock
//
// AddFile...
// [inside each file it can do another configuration block as above]
// [also, files can be put in folders with StartFolder/AddFolder]
// EndProject
//
class IBaseProjectGenerator
{
public:
// What file extension does this use? (vcproj, mak, vpj).
virtual const char* GetProjectFileExtension() = 0;
// Called before doing anything in a project (in g_pVPC->GetOutputFilename()).
virtual void StartProject() = 0;
virtual void EndProject( bool bSaveData ) = 0;
// Access the project name.
virtual const char *GetProjectName() = 0;
virtual void SetProjectName( const char *pProjectName ) = 0;
// Get a list of all configurations.
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames ) = 0;
// Configuration data is specified in between these calls and inside BeginPropertySection/EndPropertySection.
// If bFileSpecific is set, then the configuration data only applies to the last file added.
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific ) = 0;
virtual void EndConfigurationBlock() = 0;
// Get the current configuration name. Only valid between StartConfigurationBlock()/EndConfigurationBlock()
virtual const char *GetCurrentConfigurationName() = 0;
// These functions are called when it enters a section like $Compiler, $Linker, etc.
// In between the BeginPropertySection/EndPropertySection, it'll call HandleProperty for any properties inside that section.
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip = NULL ) = 0;
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData=NULL ) = 0;
virtual const char *GetPropertyValue( const char *pProperty ) = 0;
virtual void EndPropertySection( configKeyword_e keyword ) = 0;
// Files go in folders. The generator should maintain a stack of folders as they're added.
virtual void StartFolder( const char *pFolderName, VpcFolderFlags_t iFlags ) = 0;
virtual void EndFolder() = 0;
// Add files. Any config blocks/properties between StartFile/EndFile apply to this file only.
// It will only ever have one active file.
virtual bool StartFile( const char *pFilename, VpcFileFlags_t iFlags, bool bWarnIfAlreadyExists ) = 0;
virtual void EndFile() = 0;
virtual bool HasFile( const char *pFilename ) = 0;
// Only valid between StartFile and EndFile
virtual const char *GetCurrentFileName() = 0;
// This is actually just per-file configuration data.
virtual void FileExcludedFromBuild( bool bExcluded ) = 0;
// Remove the specified file. return true if success
virtual bool RemoveFile( const char *pFilename ) = 0;
const char *GetOutputFileName( void )
{
if ( m_OutputFileName.IsEmpty() )
{
SetOutputFileName();
}
return m_OutputFileName;
}
const char *GetGUIDString()
{
if ( m_GUIDString.IsEmpty() )
{
SetGUID();
}
return m_GUIDString;
}
virtual void SetGUID( void );
virtual void SetOutputFileName( void );
virtual void EnumerateSupportedVPCTargetPlatforms( CUtlVector<CUtlString> &output ) = 0;
virtual bool BuildsForTargetPlatform( const char *szVPCTargetPlatform ) = 0;
virtual bool DeploysForVPCTargetPlatform( const char *szVPCTargetPlatform ) = 0;
virtual CUtlString GetSolutionPlatformAlias( const char *szVPCTargetPlatform, IBaseSolutionGenerator *pSolutionGenerator ) = 0;
protected:
CUtlString m_OutputFileName;
CUtlString m_GUIDString;
};
+30
View File
@@ -0,0 +1,30 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#pragma once
#include "dependencies.h"
class IBaseProjectGenerator;
//I know this defeats the idea of abstraction. But VisualStudio has required aliases for platforms and something has to give to make a mapping. And solution generators have less surface area
enum SolutionType_t
{
ST_VISUALSTUDIO,
ST_MAKEFILE,
ST_XCODE,
};
class IBaseSolutionGenerator
{
public:
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects ) = 0;
virtual const char *GetSolutionFileExtension() { return NULL; }
virtual void ProjectEnd( IBaseProjectGenerator *pCurGen ) {}
virtual SolutionType_t GetSolutionType( void ) = 0;
};
+450
View File
@@ -0,0 +1,450 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
inline bool IsValidMacroNameChar( char ch )
{
return ch == '_' || V_isalnum( ch );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CMacro::CMacro( const char *pMacroName, const char *pMacroValue, const char *pConfigurationName, bool bSystemMacro, bool bSetupDefine )
{
SetMacroName( pMacroName );
m_Value = pMacroValue;
if ( pConfigurationName )
{
// property macros (i.e. with configurations) are purposely narrow
// they are not interchangeable with non-property macros that provide a different set of features
// this is just to ensure that hacks don't come along with a misunderstanding
Assert( bSystemMacro == false );
Assert( bSetupDefine == false );
if ( !pConfigurationName[0] )
{
// valid configuration name is mandatory
g_pVPC->VPCError( "Missing expected configuration for property macro '%s'.", pMacroName );
}
m_ConfigurationName = pConfigurationName;
m_bSetupDefineInProjectFile = false;
m_bSystemMacro = false;
}
else
{
m_bSetupDefineInProjectFile = bSetupDefine;
m_bSystemMacro = bSystemMacro;
}
m_pFNResolveDynamicMacro = nullptr;
}
CMacro::CMacro( const char *pMacroName, void (*pFNResolveValue)( CMacro * ) )
{
SetMacroName( pMacroName );
m_pFNResolveDynamicMacro = pFNResolveValue;
m_bSetupDefineInProjectFile = false;
m_bSystemMacro = true;
}
void CMacro::SetMacroName( const char *pMacroName )
{
m_nBaseNameLength = V_strlen( pMacroName );
if ( m_nBaseNameLength >= MAX_MACRO_NAME )
{
g_pVPC->VPCError( "Macro name '%s' too long.", pMacroName );
}
for ( int i = 0; i < m_nBaseNameLength; i++ )
{
if ( !IsValidMacroNameChar( pMacroName[i] ) )
{
g_pVPC->VPCError( "Macro name '%s' contains illegal character '%c'.",
pMacroName, pMacroName[i] );
}
}
// Internally adds another one for terminator.
m_FullName.SetLength( m_nBaseNameLength + 1 );
char *pFullName = m_FullName.Access();
*pFullName = '$';
V_strcpy( pFullName + 1, pMacroName );
}
//-----------------------------------------------------------------------------
// System macros are created by VPC and are expected to persist across projects.
/// They appear as Read Only to scripts.
//-----------------------------------------------------------------------------
CMacro *CVPC::SetSystemMacro( const char *pMacroName, const char *pMacroValue, bool bSetupDefineInProjectFile )
{
VPCStatus( false, "Set System Macro: $%s = %s", pMacroName, pMacroValue );
CMacro *pMacro = FindMacro( pMacroName );
if ( pMacro )
{
// found existing macro
if ( pMacro->IsPropertyMacro() )
{
// duplicate macro names not allowed
g_pVPC->VPCError( "Macro '%s' already defined as a property macro.", pMacro->GetName() );
}
if ( !pMacro->IsSystemMacro() )
{
// internal macros cannot clash with script macros
g_pVPC->VPCError( "$Macro '%s' already defined by script.", pMacro->GetName() );
}
// update value
pMacro->SetValue( pMacroValue );
}
else
{
// create a system type macro
pMacro = new CMacro( pMacroName, pMacroValue, NULL, true, bSetupDefineInProjectFile );
m_Macros.InsertWithDupes( pMacroName, pMacro );
}
return pMacro;
}
CMacro *CVPC::SetDynamicMacro( const char *pMacroName, void (*pFNResolveValue)( CMacro *pThis ) )
{
VPCStatus( false, "Set Dynamic Macro: $%s", pMacroName );
CMacro *pMacro = FindMacro( pMacroName );
if ( pMacro )
{
// found existing macro
if ( pMacro->IsPropertyMacro() )
{
// duplicate macro names not allowed
g_pVPC->VPCError( "Macro '%s' already defined as a property macro.", pMacro->GetName() );
}
if ( !pMacro->IsSystemMacro() )
{
// internal macros cannot clash with script macros
g_pVPC->VPCError( "$Macro '%s' already defined by script.", pMacro->GetName() );
}
// update value
pMacro->SetResolveFunc( pFNResolveValue );
}
else
{
// create a system type macro
pMacro = new CMacro( pMacroName, pFNResolveValue );
m_Macros.InsertWithDupes( pMacroName, pMacro );
}
return pMacro;
}
//-----------------------------------------------------------------------------
// Script macros are created by a project script based on THEIR state. They are removed at the conclusion of that project
// to avoid polluting the next project that gets processed.
//-----------------------------------------------------------------------------
CMacro *CVPC::SetScriptMacro( const char *pMacroName, const char *pMacroValue, bool bSetupDefineInProjectFile )
{
VPCStatus( false, "Set Script Macro: $%s = %s", pMacroName, pMacroValue );
CMacro *pMacro = FindMacro( pMacroName );
if ( pMacro )
{
// found existing macro
if ( pMacro->IsPropertyMacro() )
{
// duplicate macro names not allowed
g_pVPC->VPCError( "Macro '%s' already defined as a property macro.", pMacro->GetName() );
}
/*
if ( pMacro->IsSystemMacro() )
{
// scripts are not allowed to alter system macros
g_pVPC->VPCError( "Script not allowed to alter system macro '%s'.", pMacro->GetName() );
}*/
// update value
pMacro->SetValue( pMacroValue );
}
else
{
// create a script type macro
pMacro = new CMacro( pMacroName, pMacroValue, NULL, false, bSetupDefineInProjectFile );
m_Macros.InsertWithDupes( pMacroName, pMacro );
}
return pMacro;
}
//-----------------------------------------------------------------------------
// Property macros are a variant of script macros that are highly constrained and can only
// be used to capture the state of a property key within a configuration block. They can then
// only be resolved with a configuration block.
//-----------------------------------------------------------------------------
CMacro *CVPC::SetPropertyMacro( const char *pMacroName, const char *pMacroValue, const char *pConfigurationName )
{
VPCStatus( false, "Set Property Macro (%s): $%s = %s", ( pConfigurationName && pConfigurationName[0] ? pConfigurationName : "???" ), pMacroName, pMacroValue );
if ( !pConfigurationName || !pConfigurationName[0] )
{
// configuration is mandatory
VPCError( "Missing expected configuration for property macro '%s'.", pMacroName );
}
CMacro *pMacro = FindMacro( pMacroName );
if ( pMacro && !pMacro->IsPropertyMacro() )
{
// duplicate macro names are not allowed
// found an existing non-property based macro with same name
VPCError( "Cannot set pre-existing macro '%s' as a property macro.", pMacroName );
}
// resolve with expected configuration
pMacro = FindMacro( pMacroName, pConfigurationName );
if ( pMacro )
{
// update the macro
pMacro->SetValue( pMacroValue );
}
else
{
// create property macro
pMacro = new CMacro( pMacroName, pMacroValue, pConfigurationName, false, false );
m_Macros.InsertWithDupes( pMacroName, pMacro );
}
return pMacro;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CMacro *CVPC::FindMacro( const char *pMacroName, const char *pConfigurationName )
{
if ( pConfigurationName && pConfigurationName[0] )
{
// iterate to find macro (duplicated due to configuration) with matching configuration
for ( int nMacroIndex = m_Macros.FindFirst( pMacroName ); nMacroIndex != m_Macros.InvalidIndex(); nMacroIndex = m_Macros.NextInorderSameKey( nMacroIndex ) )
{
CMacro *pMacro = m_Macros[nMacroIndex];
if ( pMacro->IsPropertyMacro() && !V_stricmp_fast( pConfigurationName, pMacro->GetConfigurationName() ) )
{
// found matching configuration based macro
return pMacro;
}
}
// not found
return NULL;
}
// direct lookup
int nMacroIndex = m_Macros.Find( pMacroName );
if ( nMacroIndex != m_Macros.InvalidIndex() )
{
return m_Macros[nMacroIndex];
}
// not found
return NULL;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int CVPC::GetMacrosMarkedForCompilerDefines( CUtlVector< CMacro* > &macroDefines )
{
macroDefines.Purge();
for ( int nMacroIndex = m_Macros.FirstInorder(); nMacroIndex != m_Macros.InvalidIndex(); nMacroIndex = m_Macros.NextInorder( nMacroIndex ) )
{
CMacro *pMacro = m_Macros[nMacroIndex];
if ( pMacro->ShouldDefineInProjectFile() )
{
macroDefines.AddToTail( pMacro );
}
}
return macroDefines.Count();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CVPC::ResolveMacrosInString( char const *pString, CUtlStringBuilder *pOutBuff, CUtlVector< CUtlString > *pMacrosReplaced )
{
// iterate and resolve user macros until all macros resolved
if ( pString )
{
pOutBuff->Set( pString );
}
int nScanIndex = 0;
while ( (size_t)nScanIndex < pOutBuff->Length() )
{
const char *pStartOfMacroToken = strchr( pOutBuff->Get() + nScanIndex, '$' );
if ( !pStartOfMacroToken )
{
break;
}
// Skip over $.
pStartOfMacroToken++;
// If we don't find a macro for this $token we start scanning
// right after the $. If we do find a macro and replace some
// text we'll start right where we did the replacement at the $.
nScanIndex = (int)( pStartOfMacroToken - pOutBuff->Get() );
if ( !IsValidMacroNameChar( *pStartOfMacroToken ) )
{
continue;
}
char macroToken[MAX_MACRO_NAME];
int nTokenChars = 0;
CMacro *pMacro = NULL;
for ( int nMacroIndex = m_Macros.FirstInorder(); nMacroIndex != m_Macros.InvalidIndex(); nMacroIndex = m_Macros.NextInorder( nMacroIndex ) )
{
CMacro *pCheck = m_Macros[nMacroIndex];
if ( ( nTokenChars <= 0 ||
pCheck->GetNameLength() >= nTokenChars ) &&
V_strnicmp( pStartOfMacroToken, pCheck->GetName(), pCheck->GetNameLength() ) == 0 )
{
//
// resolve substring match as possible larger token for disqualifying an unintended replacement collision
// i.e. $FOO cannot be replaced in a string that contains $FOOBAR, where $FOOBAR is a macro as well
//
// Collect token if we haven't already.
if ( nTokenChars <= 0 )
{
const char *pEndOfMacroToken = pStartOfMacroToken;
while ( *pEndOfMacroToken )
{
char ch = *pEndOfMacroToken;
if ( !IsValidMacroNameChar( ch ) )
{
break;
}
if ( nTokenChars < MAX_MACRO_NAME - 1 )
{
macroToken[nTokenChars] = ch;
nTokenChars++;
}
pEndOfMacroToken++;
}
macroToken[nTokenChars] = 0;
// We matched a macro name so there must
// be some legal token chars.
Assert( nTokenChars > 0 );
}
if ( pCheck->GetNameLength() < nTokenChars )
{
if ( FindMacro( macroToken ) )
{
// cannot replace this macro since it is colliding with the name of a larger macro.
// the iterations will converge to the correct macro.
continue;
}
}
pMacro = pCheck;
break;
}
}
if ( !pMacro )
{
continue;
}
if ( pMacro->HasConfigurationName() )
{
// property macros store a unique value for multiple configurations
const char *configurationName = GetProjectGenerator()->GetCurrentConfigurationName();
if ( !configurationName || !configurationName[0] )
{
// no current configuration
// trying to use a property macro outside a configuration block is nonsense
// a property macro is paired to a configuration
VPCError( "Cannot use property macro '%s' in an expression outside of a configuration block", pMacro->GetName() );
}
if ( V_stricmp_fast( pMacro->GetConfigurationName(), configurationName ) )
{
// correct macro, but wrong configuration, get correct macro
CMacro *pCorrectMacro = FindMacro( pMacro->GetName(), configurationName );
if ( !pCorrectMacro )
{
// script expected macro to resolve
VPCError( "Property macro '%s' does not have an expected configuration '%s'.", pMacro->GetName(), configurationName );
}
else
{
// this is the correct property macro with the expected configuration
pMacro = pCorrectMacro;
}
}
}
if ( pOutBuff->ReplaceAt( nScanIndex - 1, pMacro->GetFullNameLength(), pMacro->GetValue(), pMacro->GetValueLength() ) )
{
if ( pMacrosReplaced )
{
pMacrosReplaced->AddToTail( pMacro->GetFullName() );
}
// We replaced the text starting from the $ so restart
// the scan there to pick up any new macro that came in.
nScanIndex--;
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CVPC::RemoveScriptCreatedMacros()
{
// remove all the script created macros
// this is to ensure the next project to be processed starts out with an unpolluted state
for ( int nMacroIndex = m_Macros.FirstInorder(); nMacroIndex != m_Macros.InvalidIndex(); )
{
int nNextMacroIndex = m_Macros.NextInorder( nMacroIndex );
CMacro *pMacro = m_Macros[nMacroIndex];
if ( !pMacro->IsSystemMacro() )
{
m_Macros.RemoveAt( nMacroIndex );
delete pMacro;
}
nMacroIndex = nNextMacroIndex;
}
}
const char *CVPC::GetMacroValue( const char *pMacroName, const char *pConfigurationName )
{
CMacro *pMacro = FindMacro( pMacroName, pConfigurationName );
if ( pMacro )
{
if ( pMacro->IsPropertyMacro() && ( !pConfigurationName || !pConfigurationName[0] ) )
{
VPCError( "Missing required configuration to access property macro '%s'.", pMacroName );
}
return pMacro->GetValue();
}
// not found
return "";
}
File diff suppressed because it is too large Load Diff
+233
View File
@@ -0,0 +1,233 @@
//====== Copyright © 1996-2016, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "p4lib/ip4.h"
// fix filenames that have double backslashes at the start
// (Perforce will return this if the root of a clientspec is e.g. "D:\")
static const char* FixPerforceFilename( const char *filename )
{
if ( filename && V_strlen( filename ) > 2 && !V_strnicmp( filename + 1, ":\\\\", 3 ) )
{
// strip out the first backslash
static char newFilename[MAX_FIXED_PATH];
V_snprintf( newFilename, sizeof(newFilename), "%c:%s",
filename[0],
&filename[3]
);
return newFilename;
}
return filename;
}
static void GetChangelistFilenames( CUtlVector<int> &changelists, CUtlVector<CUtlString> &changelistFilenames )
{
// P4 interface didn't initalize in main - abort
if (!p4)
{
g_pVPC->VPCWarning( "P4SLN: Perforce interface not available. Unable to generate solution from the given Perforce changelist." );
return;
}
CUtlVector<P4File_t> fileList;
int changeListIndex = 0;
if ( changelists.Count() )
{
changeListIndex = changelists[0];
}
if ( changeListIndex == -1 )
{
p4->GetOpenedFileList( fileList, false );
}
else if ( changeListIndex == 0 )
{
p4->GetOpenedFileList(fileList, true);
}
else
{
CUtlVector<P4File_t> partialFileList;
FOR_EACH_VEC( changelists, i )
{
p4->GetFileListInChangelist(changelists[i], partialFileList);
FOR_EACH_VEC( partialFileList, j )
{
fileList.AddToTail( partialFileList[j] );
}
}
}
// If -1 is in the changelist index, then include all.
bool bIncludeAllChangelists = ( changelists.Find( -1 ) != changelists.InvalidIndex() );
for ( int i=0; i < fileList.Count(); i++ )
{
if ( bIncludeAllChangelists || changelists.Find( fileList[i].m_iChangelist ) != changelists.InvalidIndex() )
{
const char *pFilename = p4->String(fileList[i].m_sLocalFile);
const char *pNewFilename = FixPerforceFilename( pFilename );
changelistFilenames.AddToTail( pNewFilename );
}
}
}
static void GetProjectsDependingOnFiles( CProjectDependencyGraph &dependencyGraph, CUtlVector<CUtlString> &filenames, CUtlVector<CDependency_Project*> &projects )
{
// Now figure out the projects that depend on each of these files.
for ( int iFile=0; iFile < filenames.Count(); iFile++ )
{
CDependency *pFile = dependencyGraph.FindDependency( filenames[iFile].String() );
if ( !pFile )
{
char szRelative[MAX_FIXED_PATH];
if ( !V_MakeRelativePath( filenames[iFile].String(), g_pVPC->GetSourcePath(), szRelative, sizeof( szRelative ) ) )
{
V_strncpy( szRelative, filenames[iFile].String(), sizeof( szRelative ) );
}
// This probably means their build commands on the command line didn't include
// any projects that included this file.
g_pVPC->VPCWarning( "%s is not found in the projects searched.", szRelative );
continue;
}
// Now see which projects depend on this file.
for ( int iProject=0; iProject < dependencyGraph.m_Projects.Count(); iProject++ )
{
CDependency_Project *pProject = dependencyGraph.m_Projects[iProject];
if ( pProject->DependsOn( pFile, k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse | k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagCheckAdditionalDependencies ) )
{
if ( projects.Find( pProject ) == -1 )
projects.AddToTail( pProject );
}
}
}
// generate the group restrictions
// the user can explicitly provide a set of groups to narrow the wide dependency target
CUtlVector< CUtlString > groupRestrictions;
groupRestrictions = g_pVPC->m_P4GroupRestrictions;
if ( !groupRestrictions.Count() && g_pVPC->RestrictProjectsToEverything() )
{
// the default restriction is to the "everything" group
groupRestrictions.AddToTail( "everything" );
}
CUtlVector< projectIndex_t > allowedProjectIndices;
if ( groupRestrictions.Count() )
{
// get all of the allowed projects by iterating the restrict-to-groups
for ( int i = 0; i < groupRestrictions.Count(); i++ )
{
CUtlVector< projectIndex_t > projectIndices;
if ( !g_pVPC->GetProjectsInGroup( projectIndices, groupRestrictions[i].Get() ) )
{
g_pVPC->VPCError( "No projects found in group '%s'.", groupRestrictions[i].Get() );
}
// aggregate into wider list
for ( int j = 0; j < projectIndices.Count(); j++ )
{
allowedProjectIndices.AddToTail( projectIndices[j] );
}
}
}
// Make sure that each of the dependent projects are members of the restricted groups, otherwise prevent their inclusion.
CUtlVector< int > doomedProjectIndices;
if ( allowedProjectIndices.Count() )
{
for ( int j = 0; j < projects.Count(); j++ )
{
// find the target project in the allowed set
if ( allowedProjectIndices.Find( projects[j]->m_iProjectIndex ) == allowedProjectIndices.InvalidIndex() )
{
// the target project is not in the allowed set
// add in descending order so indices can be properly removed below from largest index to smallest
doomedProjectIndices.AddToHead( j );
}
}
// Remove the projects that are not part of the restrict-to-groups
// Indexes were added in descending order, so removal is actually from the end, truncating the set
for ( int j = 0; j < doomedProjectIndices.Count(); j++ )
{
projects.Remove( doomedProjectIndices[j] );
}
}
}
class CStringFastCaseless
{
public:
bool Less( const char *lhs, const char *rhs, void *pCtx )
{
return ( V_stricmp_fast( lhs, rhs ) < 0 ? true : false );
}
};
void GenerateSolutionForPerforceChangelist( CProjectDependencyGraph &dependencyGraph, CUtlVector<int> &changelists, IBaseSolutionGenerator *pGenerator, const char *pSolutionFilename )
{
// We want to check against ALL projects in projects.vgc.
// We ignore any system files as that keeps dependency sets smaller
// and system files won't be open for edit in p4.
int nDepFlags = BUILDPROJDEPS_FULL_DEPENDENCY_SET | BUILDPROJDEPS_CHECK_ALL_PROJECTS;
dependencyGraph.BuildProjectDependencies( nDepFlags );
// Get the list of files from Perforce.
CUtlVector<CUtlString> filenames;
GetChangelistFilenames( changelists, filenames );
// Get the list of projects that depend on these files.
CUtlVector<CDependency_Project*> projects;
GetProjectsDependingOnFiles( dependencyGraph, filenames, projects );
// Add g_targetProjects, which will include any other projects that they added on the command line with +tier0 *engine syntax.
CUtlVector<CDependency_Project*> commandLineProjects;
dependencyGraph.TranslateProjectIndicesToDependencyProjects( g_pVPC->m_TargetProjects, commandLineProjects );
for ( int i = 0; i < commandLineProjects.Count(); i++ )
{
if ( projects.Find( commandLineProjects[i] ) == projects.InvalidIndex() )
{
projects.AddToTail( commandLineProjects[i] );
}
}
// Make sure the latest .vcproj files are generated.
g_pVPC->BuildDependencyProjects( projects );
// List the projects.
CUtlSortVector< CUtlString, CStringFastCaseless > sortedProjectNames;
for ( int i=0; i < projects.Count(); i++ )
{
sortedProjectNames.InsertNoSort( projects[i]->GetName() );
}
sortedProjectNames.RedoSort();
if ( !sortedProjectNames.Count() )
{
g_pVPC->VPCWarning( "\nNo dependent projects found." );
}
else
{
g_pVPC->VPCStatus( true, "\nDependent Projects:" );
for ( int i = 0; i < sortedProjectNames.Count(); i++ )
{
g_pVPC->VPCStatus( true, "%s", sortedProjectNames[i].Get() );
}
}
// Write the solution file.
pGenerator->GenerateSolutionFile( pSolutionFilename, projects );
}
+9
View File
@@ -0,0 +1,9 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#pragma once
void GenerateSolutionForPerforceChangelist( CProjectDependencyGraph &dependencyGraph, CUtlVector<int> &changelists, IBaseSolutionGenerator *pGenerator, const char *pSolutionFilename );
+565
View File
@@ -0,0 +1,565 @@
//========= Copyright 1996-2016, Valve Corporation, All rights reserved. ==============//
//
//
//=====================================================================================//
#include "vpc.h"
#include "tier1/utlvector.h"
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void CleanStrings( CUtlVector< CUtlString > &strings )
{
for ( int i = 0; i < strings.Count(); i++ )
{
// Remove surrounding whitespace & quotes
// NOTE: strings[i].Length() is temporarily invalidated
char *pString = strings[i].Access();
V_StripLeadingWhitespace( pString );
V_StripTrailingWhitespace( pString );
V_StripSurroundingQuotes( pString );
strings[i].Set( pString );
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
PropertyState_t *VPC_GetToolProperty( configKeyword_e tool, CProjectConfiguration *pRootConfig, CProjectConfiguration *pFileConfig, const char *pPropertyName )
{
CProjectTool *pRootTool = NULL, *pFileTool = NULL;
switch( tool )
{
case KEYWORD_GENERAL:
break; // Special case, see below
case KEYWORD_COMPILER:
if ( pRootConfig ) pRootTool = pRootConfig->GetCompilerTool();
if ( pFileConfig ) pFileTool = pFileConfig->GetCompilerTool();
break;
case KEYWORD_LIBRARIAN:
if ( pRootConfig ) pRootTool = pRootConfig->GetLibrarianTool();
if ( pFileConfig ) pFileTool = pFileConfig->GetLibrarianTool();
break;
case KEYWORD_LINKER:
if ( pRootConfig ) pRootTool = pRootConfig->GetLinkerTool();
if ( pFileConfig ) pFileTool = pFileConfig->GetLinkerTool();
break;
default: Assert(0); return NULL; // Add more tools as needed
}
// If there is a file config (with this property) then use that, otherwise fall back to the root config:
PropertyState_t *pResult = NULL;
if ( tool == KEYWORD_GENERAL )
{
// In this case, the config directly contains the property, rather than a sub-tool (TODO: refactor)
if ( pFileConfig )
pResult = pFileConfig->m_PropertyStates.GetProperty( pPropertyName );
if ( !pResult && pRootConfig )
pResult = pRootConfig->m_PropertyStates.GetProperty( pPropertyName );
}
else
{
if ( pFileTool )
pResult = pFileTool->m_PropertyStates.GetProperty( pPropertyName );
if ( !pResult && pRootTool )
pResult = pRootTool->m_PropertyStates.GetProperty( pPropertyName );
}
return pResult;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
bool VPC_GetPropertyBool( configKeyword_e tool, CProjectConfiguration *pRootConfig, CProjectConfiguration *pFileConfig, const char *pPropertyName, bool *pResult )
{
// TODO: generalize these property helpers to more property types and usage patterns...
// deduplicate functionality w/ projectgenerator_vcproj.cpp (many redundant 'GetPropertyValue/SetProperty/GetPropertyValue' methods)
PropertyState_t *pProperty = VPC_GetToolProperty( tool, pRootConfig, pFileConfig, pPropertyName );
if ( !pProperty )
return false;
if ( pProperty->m_pToolProperty->m_nType != PT_BOOLEAN )
g_pVPC->VPCError( "[VPC_GetPropertyBool] Property %s (%s) in project %s is not a PT_BOOLEAN!", pPropertyName, g_pVPC->KeywordToName( tool ), g_pVPC->GetProjectName() );
*pResult = Sys_StringToBool( pProperty->m_StringValue.Get() );
return true;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
bool VPC_GetPropertyString( configKeyword_e tool, CProjectConfiguration *pRootConfig, CProjectConfiguration *pFileConfig, const char *pPropertyName, CUtlString *pResult )
{
PropertyState_t *pProperty = VPC_GetToolProperty( tool, pRootConfig, pFileConfig, pPropertyName );
if ( !pProperty )
return false;
if ( pProperty->m_pToolProperty->m_nType == PT_STRING )
{
*pResult = pProperty->m_StringValue.Get();
}
else if ( pProperty->m_pToolProperty->m_nType == PT_LIST )
{
// Convert from PT_LIST to string
*pResult = pProperty->m_OrdinalString;
}
else g_pVPC->VPCError( "[VPC_GetPropertyBool] Property %s (%s) in project %s is not a PT_STRING!", pPropertyName, g_pVPC->KeywordToName( tool ), g_pVPC->GetProjectName() );
return true;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
const char *VPC_ResolveCompilerMacrosInString( const char *szSourceString, CUtlString &outputScratchSpace, CProjectConfiguration *pRootConfig, CProjectConfiguration *pFileConfig )
{
//this should probably be driven from the .def file, but that's a lot more work than I want to sign up for at the moment
CUtlString tempString;
CUtlString propertyString;
auto replaceWithString =
[&] ( const char *pFind, const char *pReplaceWith ) -> bool
{
if ( V_strstr( szSourceString, pFind ) != nullptr )
{
propertyString.Clear();
tempString = szSourceString;
outputScratchSpace = tempString.Replace( pFind, pReplaceWith, true );
szSourceString = outputScratchSpace.Get();
return true;
}
return false;
};
auto replaceWithProperty =
[&] ( const char *pFind, configKeyword_e replaceKeyword, const char *szReplaceVPCProperty ) -> bool
{
if ( V_strstr( szSourceString, pFind ) != nullptr )
{
propertyString.Clear();
VPC_GetPropertyString( replaceKeyword, pRootConfig, pFileConfig, szReplaceVPCProperty, &propertyString );
if ( !propertyString.IsEmpty() )
{
tempString = szSourceString;
outputScratchSpace = tempString.Replace( pFind, propertyString.Get(), true );
szSourceString = outputScratchSpace.Get();
return true;
}
}
return false;
};
bool bReplacedAnything;
do //loop to handle recursive indirection
{
bReplacedAnything = false;
//MSVC
{
bReplacedAnything |= replaceWithString( "$(Configuration)", pRootConfig->m_Name );
bReplacedAnything |= replaceWithString( "$(ConfigurationName)", pRootConfig->m_Name );
bReplacedAnything |= replaceWithProperty( "$(IntDir)", KEYWORD_GENERAL, "$IntermediateDirectory" );
bReplacedAnything |= replaceWithProperty( "$(IntermediateOutputPath)", KEYWORD_GENERAL, "$IntermediateDirectory" );
bReplacedAnything |= replaceWithProperty( "$(OutDir)", KEYWORD_GENERAL, "$OutputDirectory" );
bReplacedAnything |= replaceWithProperty( "$(OutputPath)", KEYWORD_GENERAL, "$OutputDirectory" );
bReplacedAnything |= replaceWithProperty( "$(TargetName)", KEYWORD_LINKER, g_pOption_OutputFile );
bReplacedAnything |= replaceWithProperty( "$(TargetName)", KEYWORD_LIBRARIAN, g_pOption_OutputFile );
}
//POSIX
{
bReplacedAnything |= replaceWithString( "${CONFIGURATION}", pRootConfig->m_Name );
//replicated from src/devtools/makefile_base_posix.mak
// At some point we should have VPC either read that from the file or drive the value directly from vpc scripts so they're guaranteed to be in sync
if ( V_strstr( szSourceString, "$(OBJ_DIR)" ) != nullptr )
{
char szName[256];
V_strncpy( szName, g_pVPC->GetProjectName(), sizeof(szName) );
extern void MakeFriendlyProjectName( char *pchProject );
MakeFriendlyProjectName( szName );
//OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG)
CUtlString objDirVal = "./obj_";
objDirVal += szName;
objDirVal += "_";
objDirVal += g_pVPC->GetTargetPlatformName();
objDirVal += g_pVPC->IsDedicatedBuild() ? "" : "_client";
objDirVal += "/";
objDirVal += pRootConfig->m_LowerCaseName.Get();
bReplacedAnything |= replaceWithString( "$(OBJ_DIR)", objDirVal );
}
}
} while ( bReplacedAnything );
#if defined( DBGFLAG_ASSERT )
{
const char *pUnhandled = V_strstr( szSourceString, "$(" );
if ( !pUnhandled )
{
pUnhandled = V_strstr( szSourceString, "%(" );
}
if ( !pUnhandled )
{
pUnhandled = V_strstr( szSourceString, "${" );
}
if ( pUnhandled )
{
CUtlString unhandled = pUnhandled;
const char *pEndChar = ( pUnhandled[1] == '(' ) ? ")" : "{";
const char *pUnhandledEnd = V_strstr( unhandled.Get(), pEndChar );
if ( pUnhandledEnd )
{
++pUnhandledEnd;
unhandled.SetLength( pUnhandledEnd - unhandled.Get() );
}
else
{
unhandled.Clear();
}
AssertMsg1( false, "Unhandled string replacement %s", unhandled.Get() );
}
}
#endif
return szSourceString;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
bool VPC_GetGlobalPropertyString( configKeyword_e tool, CVCProjGenerator *pDataCollector, const char *pPropertyName, CUtlString *pResult )
{
// This variant assumes that this property matches across all root configs - and validates that assumption!
CUtlVector< CProjectConfiguration * > rootConfigs;
pDataCollector->GetAllRootConfigurations( rootConfigs );
pResult->Clear();
bool bFound = false;
for ( int i = 0; i < rootConfigs.Count(); i++ )
{
CUtlString value;
if ( VPC_GetPropertyString( tool, rootConfigs[i], NULL, pPropertyName, &value ) )
bFound = true;
// Validate that this property matches across all configs
if ( ( i > 0 ) && ( value != *pResult ) )
g_pVPC->VPCError( "[VPC_GetGlobalPropertyString] Found multiple conflicting values for property %s (%s) in project %s!", pPropertyName, g_pVPC->KeywordToName( tool ), g_pVPC->GetProjectName() );
*pResult = value;
}
return bFound;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
bool VPC_SetToolProperty( configKeyword_e tool, CProjectConfiguration *pFileConfig, ToolProperty_t *pToolProperty, const char *pPropertyValue )
{
CProjectTool *pFileTool = NULL;
switch( tool )
{
case KEYWORD_GENERAL:
break; // Special case, see below
case KEYWORD_COMPILER:
if ( pFileConfig ) pFileTool = pFileConfig->GetCompilerTool();
break;
case KEYWORD_LIBRARIAN:
if ( pFileConfig ) pFileTool = pFileConfig->GetLibrarianTool();
break;
case KEYWORD_LINKER:
if ( pFileConfig ) pFileTool = pFileConfig->GetLinkerTool();
break;
default: Assert(0); return false; // Add more tools as needed
}
// If there is a file config (with this property) then use that, otherwise fall back to the root config:
bool bResult = false;
g_pVPC->GetScript().PushScript( CFmtStrMax( "VPC_SetCompilerPropertyString_ForFiles( %s )", pToolProperty->m_ParseString.Get() ).Get(), pPropertyValue, 1, false, false );
if ( tool == KEYWORD_GENERAL )
{
// In this case, the config directly contains the property, rather than a sub-tool (TODO: refactor)
bResult = pFileConfig->m_PropertyStates.SetProperty( pToolProperty );
}
else
{
bResult = pFileTool->m_PropertyStates.SetProperty( pToolProperty );
}
g_pVPC->GetScript().PopScript();
return bResult;
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_SetProperty_ForFiles( const CUtlVector< CProjectFile * > &files, const char *pConfigName, configKeyword_e tool,
const char *pPropertyName, const char *pPropertyValue, CVCProjGenerator *pDataCollector )
{
// TODO: refactor to a generalized SetProperty method, ala VPC_GetToolProperty/VPC_GetPropertyString
// Process one or multiple configs
CUtlVector<CUtlString > configNames;
configNames.AddToTail( pConfigName );
if ( configNames[0].IsEmpty() )
pDataCollector->GetAllConfigurationNames( configNames );
// Set up the property to update:
CGeneratorDefinition * pGenerator = pDataCollector->GetGeneratorDefinition();
ToolProperty_t * pToolProperty = pGenerator->GetProperty( tool, pPropertyName );
CUtlString quotedPropertyValue = CUtlString( "\"" ) + pPropertyValue + "\"";
if ( quotedPropertyValue.Length() == 2 )
{
// TODO: (BUG) CVCProjGenerator::HandleProperty discards empty strings as invalid... workaround by padding pPropertyValue with spaces:
quotedPropertyValue = "\" \"";
}
for ( int i = 0; i < files.Count(); i++ )
{
for ( int j = 0; j < configNames.Count(); j++ )
{
// Add this config to the file if absent
CProjectConfiguration *pFileConfig = NULL;
if ( !files[i]->GetConfiguration( configNames[j].Get(), &pFileConfig ) )
files[i]->AddConfiguration( configNames[j].Get(), &pFileConfig );
Assert( pFileConfig );
// Parse the property value, in the context of the current file's configuration
if ( !VPC_SetToolProperty( tool, pFileConfig, pToolProperty, quotedPropertyValue.Get() ) )
g_pVPC->VPCError( "VPC_SetProperty_ForFiles: Failed to set property %s for file %s", pPropertyName, pFileConfig->m_Name.Get() );
}
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_SetProperty_ForFile( CProjectFile *pFile, const char *pConfigName, configKeyword_e tool,
const char *pPropertyName, const char *pPropertyValue, CVCProjGenerator *pDataCollector )
{
CUtlVector< CProjectFile * > files( &pFile, 1, 1 );
return VPC_SetProperty_ForFiles( files, pConfigName, tool, pPropertyName, pPropertyValue, pDataCollector );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GetPreprocessorDefines( CProjectFile *pFile, CProjectConfiguration *pRootConfig, CUtlVector< CUtlString > &defines )
{
defines.RemoveAll();
CProjectConfiguration *pFileConfig = NULL;
if ( pFile )
{
pFile->GetConfiguration( pRootConfig->m_Name.Get(), &pFileConfig );
}
CUtlString cfgString;
if ( !VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, pFileConfig, g_pOption_PreprocessorDefinitions, &cfgString ) )
return;
int nMacroCount = 0;
for ( int nMacroIndex = g_pVPC->m_Macros.FirstInorder(); nMacroIndex != g_pVPC->m_Macros.InvalidIndex(); nMacroIndex = g_pVPC->m_Macros.NextInorder( nMacroIndex ) )
{
nMacroCount += g_pVPC->m_Macros[nMacroIndex]->ShouldDefineInProjectFile() ? 1 : 0;
}
// Add defines from $PreprocessorDefinitions
CSplitString outStrings( cfgString.Get(), (const char**)g_IncludeSeparators, V_ARRAYSIZE(g_IncludeSeparators) );
defines.EnsureCapacity( outStrings.Count() + nMacroCount ); // Presize to avoid realloc'ing and copying strings
for ( int i=0; i < outStrings.Count(); i++ )
{
defines.AddToTail( outStrings[i] );
}
// Add defines from VPC macros
for ( int nMacroIndex = g_pVPC->m_Macros.FirstInorder(); nMacroIndex != g_pVPC->m_Macros.InvalidIndex(); nMacroIndex = g_pVPC->m_Macros.NextInorder( nMacroIndex ) )
{
CMacro *pMacro = g_pVPC->m_Macros[nMacroIndex];
if ( pMacro->ShouldDefineInProjectFile() )
{
defines.AddToTail( CFmtStrMax( "%s=%s", pMacro->GetName(), pMacro->GetValue() ).Get() );
}
}
// Remove surrounding whitespace & quotes (caller can add surrounding quotes if desired):
CleanStrings( defines );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GetIncludeDirectories( CProjectFile *pFile, CProjectConfiguration *pRootConfig, CUtlVector< CUtlString > &includes )
{
includes.RemoveAll();
CProjectConfiguration *pFileConfig = NULL;
if ( pFile )
{
pFile->GetConfiguration( pRootConfig->m_Name.Get(), &pFileConfig );
}
CUtlString cfgString;
if ( !VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, pFileConfig, g_pOption_AdditionalIncludeDirectories, &cfgString ) )
return;
CUtlStringBuilder *pStrBuf = g_pVPC->GetTempStringBuffer1();
CSplitString outStrings( cfgString.Get(), (const char**)g_IncludeSeparators, V_ARRAYSIZE(g_IncludeSeparators) );
includes.EnsureCapacity( outStrings.Count() ); // Presize to avoid realloc'ing and copying strings
for ( int i=0; i < outStrings.Count(); i++ )
{
pStrBuf->Set( outStrings[i] );
pStrBuf->ReplaceFastCaseless( "$(IntDir)", "$(OBJ_DIR)" );
V_FixSlashes( pStrBuf->Access(), '/' );
includes.AddToTail( pStrBuf->Get() );
}
// Remove surrounding whitespace & quotes (caller can add surrounding quotes if desired):
CleanStrings( includes );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GetPCHInclude( CProjectFile *pFile, CProjectConfiguration *pRootConfig, CUtlString &pchFile, bool &bCreatesPCH, bool &bExcludesPCH )
{
pchFile = "";
bCreatesPCH = false;
bExcludesPCH = false;
CProjectConfiguration *pFileConfig = NULL;
if ( pFile )
{
pFile->GetConfiguration( pRootConfig->m_Name.Get(), &pFileConfig );
}
// Look for the $Create/UsePrecompiledHeader state, which should be set to either
// "Create Precompiled Header (/Yc)" or "Use Precompiled Header (/Yu)":
CUtlString cfgString;
if ( !VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, pFileConfig, g_pOption_PrecompiledHeader, &cfgString ) )
return;
if ( V_stristr( cfgString.Get(), "Create" ) )
bCreatesPCH = true;
else if ( V_stristr( cfgString.Get(), "Use" ) )
bCreatesPCH = false;
else
{
// Value is: "Not Using Precompiled Headers"
if ( pFileConfig )
{
// If the property came from pFileConfig, then this file is specifically configured to not use PCHs, so flag it as excluded:
bExcludesPCH = !!VPC_GetToolProperty( KEYWORD_COMPILER, NULL, pFileConfig, g_pOption_PrecompiledHeader );
}
return;
}
// Now look for the $Create/UsePCHThroughFile state, which specifies the name of the PCH file to include/create:
if ( !VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, pFileConfig, g_pOption_UsePCHThroughFile, &pchFile ) )
{
const char *pFilename = pFile ? pFile->m_Name.Get() : "unknown";
if ( bCreatesPCH )
{
// Emit a warning so we can ensure VPCs provide explicit information about how each PCH file is built:
g_pVPC->VPCWarning( "File (%s) creates a PCH (/Yc), but has no 'UsePCHThroughFile' command, so there is no way to tell *which* PCH it creates!\n", pFilename );
bCreatesPCH = false;
}
else
{
// This is also an error case: it says 'use PCH' but doesn't specify *which* PCH to use!:
// TODO: Work out if this warning is needed.
//g_pVPC->VPCWarning( "File (%s) uses a PCH (/Yu), but has no 'UsePCHThroughFile' command, so there is no way to tell *which* PCH it uses!\n", pFilename );
}
return;
}
pchFile.FixSlashes( '/' );
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GeneratePCHInfoList_ProcessFile( CProjectFile *pFile, CProjectConfiguration *pRootConfig,
CUtlVector< CUtlString > &pchIncludeNames, CUtlVector< CUtlString > &pchCreatorNames, CUtlVector< CUtlString > &usedPCHs,
CUtlVector< CProjectFile * > *pFilesExcludingPCH )
{
bool bFileCreatesPCH, bFileExcludesPCH;
CUtlString pchName;
VPC_GetPCHInclude( pFile, pRootConfig, pchName, bFileCreatesPCH, bFileExcludesPCH );
if ( pFilesExcludingPCH && bFileExcludesPCH )
{
Assert( !pFilesExcludingPCH->HasElement( pFile ) );
pFilesExcludingPCH->AddToTail( pFile );
}
if ( bFileCreatesPCH )
{
if ( pchIncludeNames.HasElement( pchName ) )
{
// Each PCH should only be created by one source file!
int index = pchIncludeNames.Find( pchName );
NOTE_UNUSED( index );
AssertMsg4( !pchIncludeNames.HasElement( pchName ), "ERROR (%s): PCH file '%s' created by two separate files in the same VPC! ('%s' and '%s')\n",
__FUNCTION__, pchName.Get(), pFile->m_Name.Get(), pchCreatorNames[ index ].Get() );
return;
}
pchIncludeNames.AddToTail( pchName );
pchCreatorNames.AddToTail( pFile->m_Name );
pchIncludeNames.Tail().FixSlashes( '/' );
pchCreatorNames.Tail().FixSlashes( '/' );
}
else if ( !pchName.IsEmpty() )
{
if ( !usedPCHs.HasElement( pchName ) )
usedPCHs.AddToTail( pchName );
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GeneratePCHInfoList_ProcessFolder( CProjectFolder *pFolder, CProjectConfiguration *pRootConfig,
CUtlVector< CUtlString > &pchIncludeNames, CUtlVector< CUtlString > &pchCreatorNames, CUtlVector< CUtlString > &usedPCHs,
CUtlVector< CProjectFile * > *pFilesExcludingPCH )
{
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
VPC_GeneratePCHInfoList_ProcessFile( pFolder->m_Files[iIndex], pRootConfig, pchIncludeNames, pchCreatorNames, usedPCHs, pFilesExcludingPCH );
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
VPC_GeneratePCHInfoList_ProcessFolder( pFolder->m_Folders[iIndex], pRootConfig, pchIncludeNames, pchCreatorNames, usedPCHs, pFilesExcludingPCH );
}
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void VPC_GeneratePCHInfo( CVCProjGenerator *pDataCollector, CProjectConfiguration *pRootConfig,
CUtlVector< CUtlString > &pchIncludeNames, CUtlVector< CUtlString > &pchCreatorNames,
CUtlVector< CUtlString > const *pRequiredPCHs, CUtlVector< CProjectFile * > *pFilesExcludingPCH )
{
// Generate a list of all PCH headers used by this project, with the corresponding source files used to build the PCHs
Assert( pRootConfig );
CUtlVector< CUtlString > usedPCHs; // Which PCH files are included by source files in the project?
pchIncludeNames.RemoveAll();
pchCreatorNames.RemoveAll();
VPC_GeneratePCHInfoList_ProcessFolder( pDataCollector->GetRootFolder(), pRootConfig, pchIncludeNames, pchCreatorNames, usedPCHs, pFilesExcludingPCH );
// Error-check: all used PCHs must actually be created!
for ( int i = 0; i < pchIncludeNames.Count(); i++ )
{
usedPCHs.FindAndFastRemove( pchIncludeNames[i] );
}
for ( int i = 0; i < usedPCHs.Count(); i++ )
{
g_pVPC->VPCWarning( "[VPC_GeneratePCHInfo] Could not find VPC entry which generates PCH file for PCH header %s, in project %s!\n", usedPCHs[i].Get(), pDataCollector->GetProjectName() );
DebuggerBreakIfDebugging();
}
if ( pRequiredPCHs )
{
// Filter out superfluous infos, based on the given list of required PCHs:
for ( int i = 0; i < pchIncludeNames.Count(); i++ )
{
if ( !pRequiredPCHs->HasElement( pchIncludeNames[i] ) )
{
pchIncludeNames.FastRemove( i );
pchCreatorNames.FastRemove( i );
i--;
}
}
}
}
+575
View File
@@ -0,0 +1,575 @@
//================= Copyright Valve Corporation, All rights reserved. =================//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#include "projectgenerator_android.h"
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_AndroidPropertyNames[] =
{
#include "projectgenerator_android.inc"
{ -1, NULL, NULL }
};
//all of the defined properties are relevant
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) "$" #Y,
static const char *sg_RelevantPropertyStrings[] =
{
#include "projectgenerator_android.inc"
};
static CRelevantPropertyNames s_RelevantPropertyNames = { sg_RelevantPropertyStrings, ARRAYSIZE( sg_RelevantPropertyStrings ) };
IBaseProjectGenerator* GetAndroidProjectGenerator()
{
return new CProjectGenerator_Android();
}
CProjectGenerator_Android::CProjectGenerator_Android()
: CBaseProjectDataCollector( &s_RelevantPropertyNames )
{
m_BaseConfigData.GetOrCreateConfig( "Debug", nullptr );
m_BaseConfigData.GetOrCreateConfig( "Release", nullptr );
m_GeneratorDefinition.LoadDefinition( "android.def", s_AndroidPropertyNames );
}
void CProjectGenerator_Android::EndProject( bool bSaveData )
{
BaseClass::EndProject( bSaveData );
if ( !bSaveData || g_pVPC->m_bIsDependencyPass )
return;
if ( m_BaseConfigData.m_Configurations.Count() == 0 )
return;
CSpecificConfig *pBaseConfig = m_BaseConfigData.m_Configurations[m_BaseConfigData.m_Configurations.Find( "Release" )];
CUtlVectorFixedGrowableCompat<CSpecificConfig *,2> generalConfigurations;
for ( int nConfigIter = m_BaseConfigData.m_Configurations.First(); m_BaseConfigData.m_Configurations.IsValidIndex( nConfigIter ); nConfigIter = m_BaseConfigData.m_Configurations.Next( nConfigIter ) )
{
generalConfigurations.AddToTail( m_BaseConfigData.m_Configurations.Element( nConfigIter ) );
}
if ( !WriteAndroidProj( pBaseConfig, generalConfigurations ) )
{
g_pVPC->VPCError( "Unable to write \"%s\"", GetOutputFileName() );
UNREACHABLE();
}
if ( !WriteBuildXML( pBaseConfig, generalConfigurations ) )
{
g_pVPC->VPCError( "Unable to write \"%s\" build.xml", GetProjectName() );
UNREACHABLE();
}
if ( !WriteAndroidManifestXML( pBaseConfig, generalConfigurations ) )
{
g_pVPC->VPCError( "Unable to write \"%s\" androidmanifest.xml", GetProjectName() );
UNREACHABLE();
}
if ( !WriteProjectProperties( pBaseConfig, generalConfigurations ) )
{
g_pVPC->VPCError( "Unable to write \"%s\" project.properties", GetProjectName() );
UNREACHABLE();
}
//success
}
const char *CProjectGenerator_Android::GetTargetAndroidPlatformName( const char *szVPCPlatformName )
{
if ( !V_stricmp_fast( szVPCPlatformName, "androidx8632" ) )
{
return "x86";
}
else if ( !V_stricmp_fast( szVPCPlatformName, "androidx8664" ) )
{
return "x64";
}
else if ( !V_stricmp_fast( szVPCPlatformName, "androidarm32" ) )
{
return "ARM";
}
else if ( !V_stricmp_fast( szVPCPlatformName, "androidarm64" ) )
{
return "ARM64";
}
else
{
g_pVPC->VPCError( "AndroidProj does not have a Visual Studio platform mapping for VPC platform \"%s\"", szVPCPlatformName );
UNREACHABLE();
return nullptr;
}
}
bool CProjectGenerator_Android::WriteAndroidProj( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations )
{
CXMLWriter xmlWriter;
if ( !xmlWriter.Open( GetOutputFileName(), true, g_pVPC->IsForceGenerate() ) )
return false;
const char *szVPCPlatformName = g_pVPC->GetTargetPlatformName();
const char *szVisualStudioPlatformName = GetTargetAndroidPlatformName( szVPCPlatformName );
xmlWriter.PushNode( "Project" );
{
xmlWriter.AddNodeProperty( "DefaultTargets", "Build" );
xmlWriter.AddNodeProperty( "ToolsVersion", "14.0" );
xmlWriter.AddNodeProperty( "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003" );
xmlWriter.PushNode( "ItemGroup" );
{
xmlWriter.AddNodeProperty( "Label", "ProjectConfigurations" );
for ( int i = 0; i < generalConfigurations.Count(); i++ )
{
xmlWriter.PushNode( "ProjectConfiguration" );
{
xmlWriter.AddNodeProperty( "Include", CFmtStr( "%s|%s", generalConfigurations[i]->GetConfigName(), szVisualStudioPlatformName ) );
xmlWriter.WriteLineNode( "Configuration", "", generalConfigurations[i]->GetConfigName() );
xmlWriter.WriteLineNode( "Platform", "", CFmtStr( "%s", szVisualStudioPlatformName ) );
}
xmlWriter.PopNode();
}
}
xmlWriter.PopNode();
xmlWriter.PushNode( "PropertyGroup" );
{
xmlWriter.AddNodeProperty( "Label", "Globals" );
xmlWriter.WriteLineNode( "RootNamespace", "", GetProjectName() );
xmlWriter.WriteLineNode( "MinimumVisualStudioVersion", "", "14.0" ); //VS2015
xmlWriter.WriteLineNode( "ProjectVersion", "", "1.0" );
xmlWriter.WriteLineNode( "ProjectGuid", "", CFmtStr( "{%s}", GetGUIDString() ) );
xmlWriter.WriteLineNode( "_PackagingProjectWithoutNativeComponent", "", "true" ); //failing to set this will cause us to fail to deploy (blank ABI name) if we don't reference a native component directly. And I'm not sure what that reference actually buys us
//<LaunchActivity Condition="'$(LaunchActivity)' == ''">com.example.hellojni.HelloJni</LaunchActivity>
xmlWriter.WriteLineNode( "JavaSourceRoots", "", "src" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "Import" );
{
xmlWriter.AddNodeProperty( "Project", "$(AndroidTargetsPath)\\Android.Default.props" );
}
xmlWriter.PopNode();
//general config part 1, not sure why, but this group has "Label=\"Configuration\"" and part 2 doesn't
for ( int i = 0; i < generalConfigurations.Count(); i++ )
{
xmlWriter.PushNode( "PropertyGroup", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
xmlWriter.AddNodeProperty( "Condition", CFmtStr( "'$(Configuration)|$(Platform)'=='%s|%s'", generalConfigurations[i]->GetConfigName(), szVisualStudioPlatformName ) );
xmlWriter.AddNodeProperty( "Label", "Configuration" );
xmlWriter.WriteLineNode( "UseDebugLibraries", nullptr, (V_stricmp_fast( generalConfigurations[i]->GetConfigName(), "debug" ) == 0) ? "true" : "false", XMLOIE_OMIT_ON_EMPTY_EVERYTHING ); //HACKY mapping of debug config to debug libraries
xmlWriter.WriteLineNode( "TargetName", nullptr, generalConfigurations[i]->GetOption( "$TargetName" ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "ConfigurationType", nullptr, generalConfigurations[i]->GetOption( "$ConfigurationType" ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "AndroidAPILevel", nullptr, generalConfigurations[i]->GetOption( "$AndroidAPILevel", "android-21" ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
}
xmlWriter.PopNode();
}
xmlWriter.PushNode( "Import" );
{
xmlWriter.AddNodeProperty( "Project", "$(AndroidTargetsPath)\\Android.props" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "ImportGroup" );
{
xmlWriter.AddNodeProperty( "Label", "ExtensionSettings" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "PropertyGroup" );
{
xmlWriter.AddNodeProperty( "Label", "UserMacros" );
}
xmlWriter.PopNode();
//general config part 2
for ( int i = 0; i < generalConfigurations.Count(); i++ )
{
xmlWriter.PushNode( "PropertyGroup", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
xmlWriter.AddNodeProperty( "Condition", CFmtStr( "'$(Configuration)|$(Platform)'=='%s|%s'", generalConfigurations[i]->GetConfigName(), szVisualStudioPlatformName ).Get() );
xmlWriter.WriteLineNode( "OutDir", nullptr, generalConfigurations[i]->GetOption( "$OutputDirectory", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "IntDir", nullptr, generalConfigurations[i]->GetOption( "$IntermediateDirectory", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
//xmlWriter.WriteLineNode( "TargetExt", nullptr, "vpctest_targetextension", XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
}
xmlWriter.PopNode();
}
//debugger properties
for ( int i = 0; i < generalConfigurations.Count(); i++ )
{
xmlWriter.PushNode( "PropertyGroup", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
xmlWriter.AddNodeProperty( "Condition", CFmtStr( "'$(Configuration)|$(Platform)'=='%s|%s'", generalConfigurations[i]->GetConfigName(), szVisualStudioPlatformName ).Get() );
//xmlWriter.WriteLineNode( "AndroidDeviceID", nullptr, "vpctest_debugtarget", XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "PackagePath", nullptr, generalConfigurations[i]->GetOption( "$PackagePath", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "LaunchActivity", nullptr, CFmtStr( "%s.%s", generalConfigurations[i]->GetOption( "$PackageName", nullptr ), generalConfigurations[i]->GetOption( "$LauncherActivity", "LaunchActivity" ) ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "AdditionalSymbolSearchPaths", nullptr, generalConfigurations[i]->GetOption( "$AdditionalSymbolSearchPaths", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "AdditionalSourceSearchPaths", nullptr, generalConfigurations[i]->GetOption( "$AdditionalSourceSearchPaths", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "DebuggerFlavor", nullptr, generalConfigurations[i]->GetOption( "$DebuggerFlavor", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
}
xmlWriter.PopNode();
}
//ant properties
for ( int i = 0; i < generalConfigurations.Count(); i++ )
{
xmlWriter.PushNode( "ItemDefinitionGroup", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
xmlWriter.AddNodeProperty( "Condition", CFmtStr( "'$(Configuration)|$(Platform)'=='%s|%s'", generalConfigurations[i]->GetConfigName(), szVisualStudioPlatformName ).Get() );
xmlWriter.PushNode( "AntPackage", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
xmlWriter.WriteLineNode( "AndroidAppLibName", nullptr, generalConfigurations[i]->GetOption( "$AndroidAppLibName", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "ApplicationName", nullptr, generalConfigurations[i]->GetOption( "$ApplicationName", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
xmlWriter.WriteLineNode( "WorkingDirectory", nullptr, generalConfigurations[i]->GetOption( "$WorkingDirectory", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
//xmlWriter.WriteLineNode( "AntTarget", nullptr, generalConfigurations[i]->GetOption( "", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING ); //vpctest_antbuildtarget
xmlWriter.WriteLineNode( "AdditionalOptions", nullptr, generalConfigurations[i]->GetOption( "$AdditionalOptions", nullptr ), XMLOIE_OMIT_ON_EMPTY_EVERYTHING );
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
}
//files
xmlWriter.PushNode( "ItemGroup", XMLOIE_OMIT_ON_EMPTY_CONTENTS );
{
/*xmlWriter.PushNode( "Content" );
{
xmlWriter.AddNodeProperty( "Include", "res\\values\\strings.xml" );
xmlWriter.WriteLineNode( "SubType", "", "Designer" );
}
xmlWriter.PopNode();*/
xmlWriter.PushNode( "AntBuildXml" );
{
xmlWriter.AddNodeProperty( "Include", "build.xml" );
xmlWriter.WriteLineNode( "SubType", "", "Designer" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "AndroidManifest" );
{
xmlWriter.AddNodeProperty( "Include", "AndroidManifest.xml" );
xmlWriter.WriteLineNode( "SubType", "", "Designer" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "AntProjectPropertiesFile" );
{
xmlWriter.AddNodeProperty( "Include", "project.properties" );
}
xmlWriter.PopNode();
for ( unsigned int i = 0; i < m_Files.Count(); ++i )
{
CFileConfig *pCurFile = m_Files[i];
if ( (pCurFile->m_iFlags & (VPC_FILE_FLAGS_STATIC_LIB | VPC_FILE_FLAGS_IMPORT_LIB)) != 0 )
{
continue;
//g_pVPC->VPCError( "Android projects aren't set up to do anything with static or import libs \"%s\"", pCurFile->GetName() );
//UNREACHABLE();
}
if ( (pCurFile->m_iFlags & (VPC_FILE_FLAGS_QT | VPC_FILE_FLAGS_SCHEMA | VPC_FILE_FLAGS_SCHEMA_INCLUDE)) != 0 )
{
g_pVPC->VPCError( "Android projects aren't set up to do anything with Schema or Qt files \"%s\"", pCurFile->GetName() );
UNREACHABLE();
}
if ( (pCurFile->m_iFlags & (VPC_FILE_FLAGS_SHARED_LIB)) != 0 )
{
//reference the shared lib so it's listed in the solution?
}
//regular file
const char *pExtension = V_GetFileExtension( pCurFile->GetName() );
if ( !pExtension )
{
g_pVPC->VPCWarning( "Don't know what to do with file \"%s\"", pCurFile->GetName() );
continue;
}
const char *szNodeTypeForFile = nullptr;
if ( IsLibraryFile( pCurFile->GetName() ) || (V_stricmp( pExtension, "vpc" ) == 0) )
{
szNodeTypeForFile = "None";
}
else if ( V_stricmp( pExtension, "java" ) == 0 )
{
szNodeTypeForFile = "JavaCompile";
}
else
{
szNodeTypeForFile = "Content";
}
Assert( szNodeTypeForFile != nullptr );
xmlWriter.PushNode( szNodeTypeForFile );
{
xmlWriter.AddNodeProperty( "Include", xmlWriter.FixupXMLString( pCurFile->GetName() ) );
}
xmlWriter.PopNode();
}
}
xmlWriter.PopNode();
xmlWriter.PushNode( "Import" );
{
xmlWriter.AddNodeProperty( "Project", "$(AndroidTargetsPath)\\Android.targets" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "ImportGroup" );
{
xmlWriter.AddNodeProperty( "Label", "ExtensionTargets" );
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
xmlWriter.Close();
return true;
}
bool CProjectGenerator_Android::WriteBuildXML( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations )
{
CXMLWriter xmlWriter;
if ( !xmlWriter.Open( "build.xml", true, g_pVPC->IsForceGenerate() ) )
return false;
const char *szVPCPlatformName = g_pVPC->GetTargetPlatformName();
const char *szVisualStudioPlatformName = GetTargetAndroidPlatformName( szVPCPlatformName );
xmlWriter.PushNode( "project" );
{
xmlWriter.AddNodeProperty( "name", pBaseConfig->GetOption( "$ApplicationName", GetProjectName() ) );
xmlWriter.AddNodeProperty( "default", "help" );
xmlWriter.PushNode( "property", "file=\"ant.properties\"" );
xmlWriter.PopNode();
xmlWriter.PushNode( "property", "environment=\"env\"" );
xmlWriter.PopNode();
xmlWriter.PushNode( "condition" );
{
xmlWriter.AddNodeProperty( "property", "sdk.dir" );
xmlWriter.AddNodeProperty( "value", "${env.ANDROID_HOME}" );
xmlWriter.PushNode( "isset", "property=\"env.ANDROID_HOME\"" );
xmlWriter.PopNode();
}
xmlWriter.PopNode();
xmlWriter.PushNode( "loadproperties", "srcfile=\"project.properties\"" );
xmlWriter.PopNode();
xmlWriter.PushNode( "fail" );
{
xmlWriter.AddNodeProperty( "unless=\"sdk.dir\"" );
xmlWriter.AddNodeProperty( "message=\"sdk.dir is missing. Make sure ANDROID_HOME environment variable is correctly set.\"" );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "target", "name=\"-pre-build\"" );
{
//copy shared libs to the packaging dir
for ( unsigned int i = 0; i < m_Files.Count(); ++i )
{
CFileConfig *pCurFile = m_Files[i];
if ( (pCurFile->m_iFlags & VPC_FILE_FLAGS_SHARED_LIB) == 0 )
continue;
//switch to absolute path because the build script can move from the VPC write location before executing. Might want to make this a more robust relative path in the future for smoother cross compilation
char szAbsolutePath[MAX_PATH];
V_MakeAbsolutePath( szAbsolutePath, ARRAYSIZE( szAbsolutePath ), pCurFile->GetName(), nullptr, false );
xmlWriter.PushNode( "copy" );
{
xmlWriter.AddNodeProperty( "file", szAbsolutePath ); //This will probably need to account for the script being moved
xmlWriter.AddNodeProperty( "tofile", CFmtStr( "libs/%s/%s", szVisualStudioPlatformName, V_UnqualifiedFileName( szAbsolutePath ) ) );
}
xmlWriter.PopNode();
}
//copy shared libs from the packaging directory to the ".gdb" directory so the visual studio debugger can find them
xmlWriter.PushNode( "copy", "todir=\"../.gdb\"" );
{
xmlWriter.PushNode( "fileset" );
{
xmlWriter.AddNodeProperty( "dir", CFmtStr( "libs/%s", szVisualStudioPlatformName ) );
xmlWriter.PushNode( "include", "name=\"*.so\"" );
xmlWriter.PopNode();
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
xmlWriter.PushNode( "import", "file=\"${sdk.dir}/tools/ant/build.xml\"" );
xmlWriter.PopNode();
}
xmlWriter.PopNode();
xmlWriter.Close();
return true;
}
bool CProjectGenerator_Android::WriteAndroidManifestXML( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations )
{
CXMLWriter xmlWriter;
if ( !xmlWriter.Open( "AndroidManifest.xml", true, g_pVPC->IsForceGenerate() ) )
return false;
const char *szPackageName = pBaseConfig->GetOption( "$PackageName" );
xmlWriter.PushNode( "manifest" );
{
xmlWriter.AddNodeProperty( "xmlns:android", "http://schemas.android.com/apk/res/android" );
xmlWriter.AddNodeProperty( "package", szPackageName );
xmlWriter.AddNodeProperty( "android:versionCode", "1" );
xmlWriter.AddNodeProperty( "android:versionName", "1.0" );
xmlWriter.PushNode( "uses-sdk" );
{
const char *pMinSDK = pBaseConfig->GetOption( "$MinAndroidAPILevel", "android-19" );
if ( V_strnicmp( pMinSDK, "android-", 8 ) != 0 )
{
g_pVPC->VPCError( "Expecting $MinAndroidAPILevel to being with \"android-\", was actually \"%s\"", pMinSDK );
UNREACHABLE();
}
const char *pTargetSDK = pBaseConfig->GetOption( "$AndroidAPILevel", "android-19" );
if ( V_strnicmp( pTargetSDK, "android-", 8 ) != 0 )
{
g_pVPC->VPCError( "Expecting $AndroidAPILevel to being with \"android-\", was actually \"%s\"", pMinSDK );
UNREACHABLE();
}
xmlWriter.AddNodeProperty( "android:minSdkVersion", pMinSDK + 8 );
xmlWriter.AddNodeProperty( "android:targetSdkVersion", pTargetSDK + 8 );
}
xmlWriter.PopNode();
xmlWriter.PushNode( "application" );
{
xmlWriter.AddNodeProperty( "android:label", pBaseConfig->GetOption( "$ApplicationName", GetProjectName() ) );
xmlWriter.AddNodeProperty( "android:hasCode", "true" );
xmlWriter.AddNodeProperty( "android:debuggable", "true" );
xmlWriter.AddNodeProperty( "android:name", ".application" );
xmlWriter.PushNode( "activity" );
{
xmlWriter.AddNodeProperty( "android:name", CFmtStr( ".%s", pBaseConfig->GetOption( "$LauncherActivity", "LaunchActivity" ) ) );
xmlWriter.AddNodeProperty( "android:label", pBaseConfig->GetOption( "$ApplicationName", GetProjectName() ) );
xmlWriter.PushNode( "intent-filter" );
{
xmlWriter.PushNode( "action", "android:name=\"android.intent.action.MAIN\"" );
xmlWriter.PopNode();
xmlWriter.PushNode( "category", "android:name=\"android.intent.category.LAUNCHER\"" );
xmlWriter.PopNode();
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
}
xmlWriter.PopNode();
CSplitString splitPermissions( pBaseConfig->GetOption( "$Permissions" ), ";" );
for ( int i = 0; i < splitPermissions.Count(); ++i )
{
const char *szPermission = splitPermissions[i];
if ( szPermission[0] )
{
xmlWriter.PushNode( "uses-permission" );
{
xmlWriter.AddNodeProperty( "android:name", szPermission );
}
xmlWriter.PopNode();
}
}
}
xmlWriter.PopNode();
xmlWriter.Close();
return true;
}
bool CProjectGenerator_Android::WriteProjectProperties( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations )
{
CUtlBuffer projectProperties;
projectProperties.SetBufferType( true, false );
projectProperties.PutString( "# Project target.\n" );
projectProperties.Printf( "target=%s\n", pBaseConfig->GetOption( "$AndroidAPILevel", "android-21" ) );
Sys_WriteFileIfChanged( "project.properties", projectProperties, true );
return true;
}
void CProjectGenerator_Android::EnumerateSupportedVPCTargetPlatforms( CUtlVector<CUtlString> &output )
{
output.AddToTail( g_pVPC->GetTargetPlatformName() );
}
bool CProjectGenerator_Android::BuildsForTargetPlatform( const char *szVPCTargetPlatform )
{
return VPC_IsPlatformAndroid( szVPCTargetPlatform );
}
bool CProjectGenerator_Android::DeploysForVPCTargetPlatform( const char *szVPCTargetPlatform )
{
return VPC_IsPlatformAndroid( szVPCTargetPlatform );
}
CUtlString CProjectGenerator_Android::GetSolutionPlatformAlias( const char *szVPCTargetPlatform, IBaseSolutionGenerator *pSolutionGenerator )
{
switch ( pSolutionGenerator->GetSolutionType() )
{
case ST_VISUALSTUDIO:
return GetTargetAndroidPlatformName( szVPCTargetPlatform );
case ST_MAKEFILE:
case ST_XCODE:
return szVPCTargetPlatform;
NO_DEFAULT;
};
}
+46
View File
@@ -0,0 +1,46 @@
//============= Copyright Valve Corporation, All rights reserved. =============
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_ANDROID_H
#define PROJECTGENERATOR_ANDROID_H
#pragma once
#include "sys_utils.h"
#include "ibaseprojectgenerator.h"
#include "projectgenerator_vcproj.h"
#define PROPERTYNAME( X, Y ) X##_##Y,
enum AndroidProperties_e
{
#include "projectgenerator_android.inc"
};
class CProjectGenerator_Android : public CBaseProjectDataCollector
{
public:
typedef CBaseProjectDataCollector BaseClass;
CProjectGenerator_Android();
virtual const char* GetProjectFileExtension() OVERRIDE { return "androidproj"; }
virtual void EndProject( bool bSaveData ) OVERRIDE;
CGeneratorDefinition m_GeneratorDefinition;
const char *GetTargetAndroidPlatformName( const char *szVPCPlatformName );
bool WriteAndroidProj( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations );
bool WriteBuildXML( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations );
bool WriteAndroidManifestXML( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations );
bool WriteProjectProperties( CSpecificConfig *pBaseConfig, const CUtlVector<CSpecificConfig *> &generalConfigurations );
virtual void EnumerateSupportedVPCTargetPlatforms( CUtlVector<CUtlString> &output ) OVERRIDE;
virtual bool BuildsForTargetPlatform( const char *szVPCTargetPlatform ) OVERRIDE;
virtual bool DeploysForVPCTargetPlatform( const char *szVPCTargetPlatform ) OVERRIDE;
virtual CUtlString GetSolutionPlatformAlias( const char *szVPCTargetPlatform, IBaseSolutionGenerator *pSolutionGenerator ) OVERRIDE;
};
#endif // PROJECTGENERATOR_ANDROID_H
@@ -0,0 +1,33 @@
//================= Copyright Valve Corporation, All rights reserved. =================//
//
// Property Enumerations
//
//=====================================================================================//
// General
PROPERTYNAME( ANDROID_GENERAL, MinAndroidAPILevel )
PROPERTYNAME( ANDROID_GENERAL, AndroidAPILevel )
PROPERTYNAME( ANDROID_GENERAL, TargetName )
PROPERTYNAME( ANDROID_GENERAL, OutputDirectory )
PROPERTYNAME( ANDROID_GENERAL, IntermediateDirectory )
PROPERTYNAME( ANDROID_GENERAL, ConfigurationType )
PROPERTYNAME( ANDROID_GENERAL, PackageName )
PROPERTYNAME( ANDROID_GENERAL, LauncherActivity )
PROPERTYNAME( ANDROID_GENERAL, Permissions ) //Hacky, should be more like the $File syntax so we can set minsdk on individual permissions and remove them in leafy projects
// Compiler
PROPERTYNAME( ANDROID_COMPILER, PreprocessorDefinitions )
// Debugging
PROPERTYNAME( ANDROID_DEBUGGING, DebuggerFlavor )
PROPERTYNAME( ANDROID_DEBUGGING, PackagePath )
PROPERTYNAME( ANDROID_DEBUGGING, LaunchActivity )
PROPERTYNAME( ANDROID_DEBUGGING, AdditionalSymbolSearchPaths )
PROPERTYNAME( ANDROID_DEBUGGING, AdditionalSourceSearchPaths )
// Ant
PROPERTYNAME( ANDROID_ANT, AndroidAppLibName )
PROPERTYNAME( ANDROID_ANT, ApplicationName )
PROPERTYNAME( ANDROID_ANT, WorkingDirectory )
PROPERTYNAME( ANDROID_ANT, AdditionalOptions )
+150
View File
@@ -0,0 +1,150 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "projectgenerator_codelite.h"
static const char *k_pchSource = "Source Files";
static const char *k_pchHeaders = "Header Files";
static const char *k_pchResources = "Resources";
static const char *k_pchVPCFiles = "VPC Files";
void CProjectGenerator_CodeLite::GenerateCodeLiteProject( CBaseProjectDataCollector *pCollector, const char *pOutFilename, const char *pMakefileFilename )
{
char szProjectFile[MAX_PATH];
sprintf( szProjectFile, "%s.project", pOutFilename );
g_pVPC->VPCStatus( true, "Saving CodeLite project for: '%s' File: '%s'", pCollector->GetProjectName().String(), szProjectFile );
m_fp = fopen( szProjectFile, "wt" );
m_nIndent = 0;
m_pCollector = pCollector;
m_pMakefileFilename = pMakefileFilename;
Write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" );
Write( "<CodeLite_Project Name=\"%s\" InternalType=\"\">\n", pCollector->GetProjectName().String() );
{
++m_nIndent;
Write( "<Description/>\n" );
Write( "<Dependencies/>\n" );
Write( "<Settings Type=\"Dynamic Library\">\n" );
{
++m_nIndent;
Write( "<GlobalSettings>\n" );
++m_nIndent;
Write( "<Compiler Options=\"\" C_Options=\"\">\n" );
++m_nIndent;
Write( "<IncludePath Value=\"\"/>\n" );
--m_nIndent;
Write( "</Compiler>\n" );
Write( "<Linker Options=\"\">\n" );
++m_nIndent;
Write( "<LibraryPath Value=\"\"/>\n" );
--m_nIndent;
Write( "</Linker>\n" );
Write( "<ResourceCompiler Options=\"\"/>\n" );
--m_nIndent;
Write( "</GlobalSettings>\n" );
Write( "<Configuration Name=\"Debug\" CompilerType=\"gnu g++\" DebuggerType=\"GNU gdb debugger\" Type=\"Dynamic Library\" BuildCmpWithGlobalSettings=\"append\" BuildLnkWithGlobalSettings=\"append\" BuildResWithGlobalSettings=\"append\">\n" );
{
++m_nIndent;
Write( "<CustomBuild Enabled=\"yes\">\n" );
{
++m_nIndent;
Write( "<RebuildCommand>make CFG=debug -f %s clean all</RebuildCommand>\n", pMakefileFilename );
Write( "<CleanCommand>make CFG=debug -f %s clean</CleanCommand>\n", pMakefileFilename );
Write( "<BuildCommand>make CFG=debug -f %s -j `getconf _NPROCESSORS_ONLN`</BuildCommand>\n", pMakefileFilename );
Write( "<WorkingDirectory>$(ProjectPath)</WorkingDirectory>\n" );
--m_nIndent;
}
Write( "</CustomBuild>\n" );
--m_nIndent;
}
Write( "</Configuration>\n" );
Write( "<Configuration Name=\"Release\" CompilerType=\"gnu g++\" DebuggerType=\"GNU gdb debugger\" Type=\"Dynamic Library\" BuildCmpWithGlobalSettings=\"append\" BuildLnkWithGlobalSettings=\"append\" BuildResWithGlobalSettings=\"append\">\n" );
{
++m_nIndent;
Write( "<CustomBuild Enabled=\"yes\">\n" );
{
++m_nIndent;
Write( "<RebuildCommand>make -f %s clean all</RebuildCommand>\n", pMakefileFilename );
Write( "<CleanCommand>make -f %s clean</CleanCommand>\n", pMakefileFilename );
Write( "<BuildCommand>make -f %s -j `getconf _NPROCESSORS_ONLN`</BuildCommand>\n", pMakefileFilename );
Write( "<WorkingDirectory>$(ProjectPath)</WorkingDirectory>\n" );
--m_nIndent;
}
Write( "</CustomBuild>\n" );
--m_nIndent;
}
Write( "</Configuration>\n" );
--m_nIndent;
}
Write( "</Settings>\n" );
{
++m_nIndent;
WriteFilesFolder( k_pchSource, "*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.c++;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl;*.m;*.mm" );
WriteFilesFolder( k_pchHeaders, "*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if" );
WriteFilesFolder( k_pchResources, "*.plist;*.strings;*.xib" );
WriteFilesFolder( k_pchVPCFiles, "*.vpc" );
--m_nIndent;
}
--m_nIndent;
}
Write( "</CodeLite_Project>\n" );
fclose( m_fp );
}
void CProjectGenerator_CodeLite::WriteFilesFolder( const char *pFolderName, const char *pExtensions ) {
CUtlVector<char*> extensions;
V_SplitString( pExtensions, ";", extensions );
Write( "<VirtualDirectory Name=\"%s\">\n", pFolderName );
{
++m_nIndent;
for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) ) {
const char *pFilename = m_pCollector->m_Files[i]->GetName();
// Make sure this file's extension is one of the extensions they're asking for.
bool bValidExt = false;
const char *pFileExtension = V_GetFileExtension( pFilename );
if ( pFileExtension ) {
for ( int iExt=0; iExt < extensions.Count(); iExt++ ) {
const char *pTestExt = extensions[iExt];
if ( pTestExt[0] == '*' && pTestExt[1] == '.' && V_stricmp( pTestExt+2, pFileExtension ) == 0 ) {
bValidExt = true;
break;
}
}
}
if ( bValidExt ) {
char sFixedSlashes[MAX_PATH];
V_strncpy( sFixedSlashes, pFilename, sizeof( sFixedSlashes ) );
Write( "<File Name=\"%s\"/>\n", sFixedSlashes );
}
}
--m_nIndent;
}
Write( "</VirtualDirectory>\n");
}
void CProjectGenerator_CodeLite::Write( const char *pMsg, ... ) {
char sOut[8192];
va_list marker;
va_start( marker, pMsg );
V_vsnprintf( sOut, sizeof( sOut ), pMsg, marker );
va_end( marker );
for ( int i=0; i < m_nIndent; i++ )
fprintf( m_fp, " " );
fprintf( m_fp, "%s", sOut );
}
+51
View File
@@ -0,0 +1,51 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_CODELITE_H
#define PROJECTGENERATOR_CODELITE_H
#ifdef _WIN32
#pragma once
#endif
#include "baseprojectdatacollector.h"
class CProjectGenerator_CodeLite
{
public:
void GenerateCodeLiteProject( CBaseProjectDataCollector *pCollector, const char *pOutFilename, const char *pMakefileFilename );
private:
void Write( const char *pMsg, ... );
void WriteHeader();
void WriteFileReferences();
void WriteProject( const char *pchMakefileName );
void WriteBuildFiles();
void WriteBuildConfigurations();
void WriteLegacyTargets( const char *pchMakefileName );
void WriteTrailer();
void WriteConfig( CSpecificConfig *pConfig );
void WriteTarget_Build( CSpecificConfig *pConfig );
void WriteTarget_Compile( CSpecificConfig *pConfig );
void WriteTarget_Rebuild( CSpecificConfig *pConfig );
void WriteTarget_Link( CSpecificConfig *pConfig );
void WriteTarget_Debug( CSpecificConfig *pConfig );
void WriteIncludes( CSpecificConfig *pConfig );
void WriteFilesFolder( const char *pFolderName, const char *pExtensions );
void WriteFiles();
private:
CBaseProjectDataCollector *m_pCollector;
FILE *m_fp;
const char *m_pMakefileFilename;
int m_nIndent;
};
#endif // PROJECTGENERATOR_CODELITE_H
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//==================================================================================================
#ifndef PROJECTGENERATOR_MAKEFILE_H
#define PROJECTGENERATOR_MAKEFILE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utlsymbollarge.h"
class CProjectGenerator_Makefile : public IVCProjWriter
{
public:
CProjectGenerator_Makefile();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
virtual const char *GetProjectFileExtension() { return "mak"; }
private:
enum ScriptType_t
{
ST_SH,
ST_BAT,
ST_COUNT,
};
struct ScriptHelpers_t
{
const char *szExtension;
const char *szContentsPreamble;
void (*pFN_ScriptConversion)( CUtlStringBuilder * );
};
static ScriptHelpers_t s_ScriptHelpers[ST_COUNT];
typedef CUtlSymbolTableLargeBase< CNonThreadsafeTree< false >, false, 16000 > DependencyTable_t;
void WriteSourceFilesList( CUtlBuffer &outBuf, const char *pListName, const char **pExtensions, const char *pConfigName );
void WriteNonConfigSpecificStuff( CUtlBuffer &outBuf );
void CollectDependencies( const char *pDependencies, DependencyTable_t &dependenciesOut, const char *pFullFileNameForVisualStudioReplacements = nullptr );
void WriteCustomDependencies( const char *pDependencies, CUtlBuffer &outBuf, DependencyTable_t *pDependenciesOut );
bool WriteCustomBuildTool( CProjectConfiguration *pConfig,
CUtlBuffer &outBuf,
ScriptType_t scriptType,
CProjectFile *pProjectFile,
const char *pFixedProjectFileName,
const char *szVPCGeneratedScriptsBasePath,
DependencyTable_t &dependenciesOut,
DependencyTable_t &generatedScriptsOut,
DependencyTable_t &outputsOut );
void WriteDefines( CProjectConfiguration *pConfig,
CUtlBuffer &outBuf,
CProjectFile *pProjectFile );
void WriteIncludes( CProjectConfiguration *pConfig,
CUtlBuffer &outBuf,
CProjectFile *pProjectFile );
void WriteCompileRule( CUtlBuffer &outBuf, CProjectFile *pProjectFile, CProjectConfiguration *pConfig,
const char *pCompileFunction, const char *pTarget, const char *pSource, const char *pAdditionalDeps, const char *pOrderOnlyDeps,
const char *pPchInclude );
void WriteConfigSpecificStuff( CProjectConfiguration *pConfig, CUtlBuffer &outBuf, ScriptType_t scriptType );
void WriteDependencies( const char *szVarName, DependencyTable_t &otherDependencies, CUtlBuffer &outBuf );
bool WriteMakefile( const char *pFilename );
//returns true if the file changed
bool WriteScriptFile( const char *pFileName, CUtlStringBuilder *pContents, ScriptType_t scriptType );
void BuildFileSet();
const char *UsePOSIXSlashes( const char *pStr );
CVCProjGenerator *m_pVCProjGenerator;
CUtlVector< CProjectFile * > m_Files;
CUtlVector< CProjectConfiguration * > m_RootConfigurations;
CUtlVector< CUtlString > m_CustomBuildTools;
CUtlStringBuilder m_TempFixedPath;
};
#endif
File diff suppressed because it is too large Load Diff
+47
View File
@@ -0,0 +1,47 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_PS3_H
#define PROJECTGENERATOR_PS3_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum PS3Properties_e
{
#include "projectgenerator_ps3.inc"
};
class CProjectGenerator_PS3 : public IVCProjWriter
{
public:
CProjectGenerator_PS3();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WritePreBuildEventTool( CPreBuildEventTool *pPreBuildEventTool );
bool WriteCustomBuildTool( CCustomBuildTool *pCustomBuildTool );
bool WriteSNCCompilerTool( CCompilerTool *pCompilerTool );
bool WriteGCCCompilerTool( CCompilerTool *pCompilerTool );
bool WriteSNCLinkerTool( CLinkerTool *pLinkerTool );
bool WriteGCCLinkerTool( CLinkerTool *pLinkerTool );
bool WritePreLinkEventTool( CPreLinkEventTool *pPreLinkEventTool );
bool WriteLibrarianTool( CLibrarianTool *pLibrarianTool );
bool WritePostBuildEventTool( CPostBuildEventTool *pPostBuildEventTool );
const char *BoolStringToTrueFalseString( const char *pValue );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_PS3_H
+140
View File
@@ -0,0 +1,140 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( PS3_GENERAL, ConfigurationType )
PROPERTYNAME( PS3_GENERAL, ExcludedFromBuild )
PROPERTYNAME( PS3_GENERAL, OutputDirectory )
PROPERTYNAME( PS3_GENERAL, IntermediateDirectory )
PROPERTYNAME( PS3_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( PS3_GENERAL, BuildLogFile )
PROPERTYNAME( PS3_GENERAL, SystemIncludeDependencies )
PROPERTYNAME( PS3_GENERAL, SaveDebuggerPropertiesInProject )
PROPERTYNAME( PS3_GENERAL, DisableFastUpToDateCheck )
PROPERTYNAME( PS3_GENERAL, AdditionalProjectDependencies )
PROPERTYNAME( PS3_GENERAL, AdditionalOutputFiles )
// GCC Compiler
PROPERTYNAME( PS3_GCCCOMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( PS3_GCCCOMPILER, PreprocessorDefinitions )
PROPERTYNAME( PS3_GCCCOMPILER, ForceIncludes )
PROPERTYNAME( PS3_GCCCOMPILER, GenerateDebugInformation )
PROPERTYNAME( PS3_GCCCOMPILER, Warnings )
PROPERTYNAME( PS3_GCCCOMPILER, ExtraWarnings )
PROPERTYNAME( PS3_GCCCOMPILER, WarnLoadHitStores )
PROPERTYNAME( PS3_GCCCOMPILER, WarnMicrocodedInstruction )
PROPERTYNAME( PS3_GCCCOMPILER, TreatWarningsAsErrors )
PROPERTYNAME( PS3_GCCCOMPILER, ObjectFileName )
PROPERTYNAME( PS3_GCCCOMPILER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_GCCCOMPILER, SPURSUsage )
PROPERTYNAME( PS3_GCCCOMPILER, OptimizationLevel )
PROPERTYNAME( PS3_GCCCOMPILER, FastMath )
PROPERTYNAME( PS3_GCCCOMPILER, NoStrictAliasing )
PROPERTYNAME( PS3_GCCCOMPILER, UnrollLoops )
PROPERTYNAME( PS3_GCCCOMPILER, InlineFunctionSizeLimit )
PROPERTYNAME( PS3_GCCCOMPILER, TOCUsage )
PROPERTYNAME( PS3_GCCCOMPILER, SaveRestoreFunctions )
PROPERTYNAME( PS3_GCCCOMPILER, GenerateMicrocodedInstructions )
PROPERTYNAME( PS3_GCCCOMPILER, PositionIndependentCode )
PROPERTYNAME( PS3_GCCCOMPILER, FunctionSections )
PROPERTYNAME( PS3_GCCCOMPILER, DataSections )
PROPERTYNAME( PS3_GCCCOMPILER, StackCheck )
PROPERTYNAME( PS3_GCCCOMPILER, CPPExceptionsAndRTTIUsage )
PROPERTYNAME( PS3_GCCCOMPILER, CheckANSICompliance )
PROPERTYNAME( PS3_GCCCOMPILER, DefaultCharSigned )
PROPERTYNAME( PS3_GCCCOMPILER, Permissive )
PROPERTYNAME( PS3_GCCCOMPILER, EnableMSExtensions )
PROPERTYNAME( PS3_GCCCOMPILER, RelaxCPPCompliance )
PROPERTYNAME( PS3_GCCCOMPILER, AdditionalOptions )
// Librarian
PROPERTYNAME( PS3_LIBRARIAN, OutputFile )
PROPERTYNAME( PS3_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( PS3_LIBRARIAN, WholeArchive )
PROPERTYNAME( PS3_LIBRARIAN, LinkLibraryDependencies )
// GCC Linker
PROPERTYNAME( PS3_GCCLINKER, OutputFile )
PROPERTYNAME( PS3_GCCLINKER, AdditionalDependencies )
PROPERTYNAME( PS3_GCCLINKER, AdditionalLibraryDirectories )
PROPERTYNAME( PS3_GCCLINKER, ImportLibrary )
PROPERTYNAME( PS3_GCCLINKER, SPURSUsage )
PROPERTYNAME( PS3_GCCLINKER, PositionIndependentCode )
PROPERTYNAME( PS3_GCCLINKER, EmitRelocations )
PROPERTYNAME( PS3_GCCLINKER, GarbageCollection )
PROPERTYNAME( PS3_GCCLINKER, GenerateMapFile )
PROPERTYNAME( PS3_GCCLINKER, MapFileName )
PROPERTYNAME( PS3_GCCLINKER, LinkLibraryDependencies )
PROPERTYNAME( PS3_GCCLINKER, AdditionalOptions )
// SNC Compiler
PROPERTYNAME( PS3_SNCCOMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( PS3_SNCCOMPILER, PreprocessorDefinitions )
PROPERTYNAME( PS3_SNCCOMPILER, ForceIncludes )
PROPERTYNAME( PS3_SNCCOMPILER, GenerateDebugInformation )
PROPERTYNAME( PS3_SNCCOMPILER, Warnings )
PROPERTYNAME( PS3_SNCCOMPILER, TreatMessagesAsErrors )
PROPERTYNAME( PS3_SNCCOMPILER, DisableSpecificWarnings )
PROPERTYNAME( PS3_SNCCOMPILER, ObjectFileName )
PROPERTYNAME( PS3_SNCCOMPILER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_SNCCOMPILER, OptimizationLevel )
PROPERTYNAME( PS3_SNCCOMPILER, FastMath )
PROPERTYNAME( PS3_SNCCOMPILER, RelaxAliasChecking )
PROPERTYNAME( PS3_SNCCOMPILER, BranchlessCompares )
PROPERTYNAME( PS3_SNCCOMPILER, UnrollLoops )
PROPERTYNAME( PS3_SNCCOMPILER, AssumeAlignedPointers )
PROPERTYNAME( PS3_SNCCOMPILER, AssumeCorrectSign )
PROPERTYNAME( PS3_SNCCOMPILER, TOCPointerPreservation )
PROPERTYNAME( PS3_SNCCOMPILER, InitializedDataPlacement )
PROPERTYNAME( PS3_SNCCOMPILER, PromoteFPConstantsToDoubles )
PROPERTYNAME( PS3_SNCCOMPILER, CCPPDialect )
PROPERTYNAME( PS3_SNCCOMPILER, CPPExceptionsAndRTTIUsage )
PROPERTYNAME( PS3_SNCCOMPILER, DefaultCharUnsigned )
PROPERTYNAME( PS3_SNCCOMPILER, DefaultFPConstantsAsTypeFloat )
PROPERTYNAME( PS3_SNCCOMPILER, BuiltInDefinitionForWCHAR_TType )
PROPERTYNAME( PS3_SNCCOMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( PS3_SNCCOMPILER, PrecompiledHeaderFile )
PROPERTYNAME( PS3_SNCCOMPILER, AdditionalOptions )
// SNC Linker
PROPERTYNAME( PS3_SNCLINKER, OutputFile )
PROPERTYNAME( PS3_SNCLINKER, OutputFormat )
PROPERTYNAME( PS3_SNCLINKER, AdditionalDependencies )
PROPERTYNAME( PS3_SNCLINKER, AdditionalLibraryDirectories )
PROPERTYNAME( PS3_SNCLINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( PS3_SNCLINKER, UsingExceptionHandling )
PROPERTYNAME( PS3_SNCLINKER, TOCPointerElimination )
PROPERTYNAME( PS3_SNCLINKER, ForceSymbolReferences )
PROPERTYNAME( PS3_SNCLINKER, CallprofHierarchicalProfiling )
PROPERTYNAME( PS3_SNCLINKER, DebugInfoAndSymbolStripping )
PROPERTYNAME( PS3_SNCLINKER, UnusedFunctionAndDataStripping )
PROPERTYNAME( PS3_SNCLINKER, ImportLibrary )
PROPERTYNAME( PS3_SNCLINKER, GenerateMapFile )
PROPERTYNAME( PS3_SNCLINKER, MapFileName )
PROPERTYNAME( PS3_SNCLINKER, LinkLibraryDependencies )
PROPERTYNAME( PS3_SNCLINKER, AdditionalOptions )
// Pre Build
PROPERTYNAME( PS3_PREBUILDEVENT, CommandLine )
PROPERTYNAME( PS3_PREBUILDEVENT, Description )
PROPERTYNAME( PS3_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( PS3_PRELINKEVENT, CommandLine )
PROPERTYNAME( PS3_PRELINKEVENT, Description )
PROPERTYNAME( PS3_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( PS3_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( PS3_POSTBUILDEVENT, Description )
PROPERTYNAME( PS3_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( PS3_CUSTOMBUILDSTEP, AdditionalDependencies )
File diff suppressed because it is too large Load Diff
+425
View File
@@ -0,0 +1,425 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#pragma once
class CProjectConfiguration;
class CVCProjGenerator;
class CProjectTool;
struct PropertyState_t
{
ToolProperty_t *m_pToolProperty;
CUtlString m_OrdinalString;
CUtlString m_StringValue;
};
// ps3 visual studio integration
enum PS3VSIType_e
{
PS3_VSI_TYPE_UNDEFINED = -1,
PS3_VSI_TYPE_SNC = 0,
PS3_VSI_TYPE_GCC = 1,
};
class CProjectFile
{
public:
CProjectFile( CVCProjGenerator *pGenerator, const char *pFilename, VpcFileFlags_t iFlags );
~CProjectFile();
bool GetConfiguration( const char *pConfigName, CProjectConfiguration **ppConfig );
bool AddConfiguration( const char *pConfigName, CProjectConfiguration **ppConfig );
bool RemoveConfiguration( CProjectConfiguration *pConfig );
bool IsExcludedFrom( const char *pConfigName );
CUtlString m_Name;
VpcFileFlags_t m_iFlags;
CVCProjGenerator *m_pGenerator;
CUtlVector< CProjectConfiguration* > m_Configs;
uint32 m_nInsertOrder;
int64 m_nBuildOrderModifier;
// Arbitrary ID assigned by the generator for its own uses.
// For example the Xcode generator uses this to track per-file OID values.
uint64 m_nGeneratorId;
};
class CProjectFolder
{
public:
CProjectFolder( CVCProjGenerator *pGenerator, const char *pFolderName, VpcFolderFlags_t iFlags );
~CProjectFolder();
bool GetFolder( const char *pFolderName, CProjectFolder **pFolder );
bool AddFolder( const char *pFolderName, VpcFolderFlags_t iFlags, CProjectFolder **pFolder );
void AddFile( const char *pFilename, VpcFileFlags_t iFlags, CProjectFile **ppFile );
bool FindFile( const char *pFilename );
bool RemoveFile( const char *pFilename );
CUtlString m_Name;
VpcFolderFlags_t m_iFlags;
CVCProjGenerator *m_pGenerator;
CUtlLinkedList< CProjectFolder* > m_Folders;
CUtlLinkedList< CProjectFile* > m_Files;
};
class CPropertyStateLessFunc
{
public:
bool Less( const int& lhs, const int& rhs, void *pContext );
};
class CPropertyStates
{
public:
CPropertyStates();
bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, bool bEnabled );
const char *GetPropertyValue( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
PropertyState_t *GetProperty( int nPropertyId );
PropertyState_t *GetProperty( const char *pPropertyName );
CUtlVector< PropertyState_t > m_Properties;
CUtlSortVector< int, CPropertyStateLessFunc > m_PropertiesInOutputOrder;
private:
bool SetStringProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetListProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
bool SetBoolProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool, bool bEnabled );
bool SetIntegerProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
};
class CProjectTool
{
public:
CProjectTool( CVCProjGenerator *pGenerator )
{
m_pGenerator = pGenerator;
}
CVCProjGenerator *GetGenerator() { return m_pGenerator; }
// when the property belongs to the root tool (i.e. linker), no root tool is passed in
// when the property is for the file's specific configuration tool, (i.e. compiler/debug), the root tool must be supplied
virtual bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
virtual const char *GetPropertyValue( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL );
CPropertyStates m_PropertyStates;
private:
CVCProjGenerator *m_pGenerator;
};
class CDebuggingTool : public CProjectTool
{
public:
CDebuggingTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CCompilerTool : public CProjectTool
{
public:
CCompilerTool( CVCProjGenerator *pGenerator, const char *pConfigName, bool bIsFileConfig ) : CProjectTool( pGenerator )
{
m_ConfigName = pConfigName;
m_bIsFileConfig = bIsFileConfig;
}
virtual bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
virtual const char *GetPropertyValue( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
private:
CUtlString m_ConfigName;
bool m_bIsFileConfig;
};
class CLibrarianTool : public CProjectTool
{
public:
CLibrarianTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CLinkerTool : public CProjectTool
{
public:
CLinkerTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CManifestTool : public CProjectTool
{
public:
CManifestTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CXMLDocGenTool : public CProjectTool
{
public:
CXMLDocGenTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CBrowseInfoTool : public CProjectTool
{
public:
CBrowseInfoTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CResourcesTool : public CProjectTool
{
public:
CResourcesTool( CVCProjGenerator *pGenerator, const char *pConfigName, bool bIsFileConfig ) : CProjectTool( pGenerator )
{
m_ConfigName = pConfigName;
m_bIsFileConfig = bIsFileConfig;
}
virtual bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
virtual const char *GetPropertyValue( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
private:
CUtlString m_ConfigName;
bool m_bIsFileConfig;
};
class CPreBuildEventTool : public CProjectTool
{
public:
CPreBuildEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CPreLinkEventTool : public CProjectTool
{
public:
CPreLinkEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CPostBuildEventTool : public CProjectTool
{
public:
CPostBuildEventTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CCustomBuildTool : public CProjectTool
{
public:
CCustomBuildTool( CVCProjGenerator *pGenerator, const char *pConfigName, bool bIsFileConfig ) : CProjectTool( pGenerator )
{
m_ConfigName = pConfigName;
m_bIsFileConfig = bIsFileConfig;
}
virtual bool SetProperty( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
virtual const char *GetPropertyValue( ToolProperty_t *pToolProperty, CProjectTool *pRootTool = NULL ) OVERRIDE;
private:
CUtlString m_ConfigName;
bool m_bIsFileConfig;
};
class CXboxImageTool : public CProjectTool
{
public:
CXboxImageTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CXboxDeploymentTool : public CProjectTool
{
public:
CXboxDeploymentTool( CVCProjGenerator *pGenerator ) : CProjectTool( pGenerator ) {}
};
class CProjectConfiguration
{
public:
CProjectConfiguration( CVCProjGenerator *pGenerator, const char *pConfigName, const char *pFilename );
~CProjectConfiguration();
CDebuggingTool *GetDebuggingTool() { return m_pDebuggingTool; }
CCompilerTool *GetCompilerTool() { return m_pCompilerTool; }
CLibrarianTool *GetLibrarianTool() { return m_pLibrarianTool; }
CLinkerTool *GetLinkerTool() { return m_pLinkerTool; }
CManifestTool *GetManifestTool() { return m_pManifestTool; }
CXMLDocGenTool *GetXMLDocGenTool() { return m_pXMLDocGenTool; }
CBrowseInfoTool *GetBrowseInfoTool() { return m_pBrowseInfoTool; }
CResourcesTool *GetResourcesTool() { return m_pResourcesTool; }
CPreBuildEventTool *GetPreBuildEventTool() { return m_pPreBuildEventTool; }
CPreLinkEventTool *GetPreLinkEventTool() { return m_pPreLinkEventTool; }
CPostBuildEventTool *GetPostBuildEventTool() { return m_pPostBuildEventTool; }
CCustomBuildTool *GetCustomBuildTool() { return m_pCustomBuildTool; }
CXboxImageTool *GetXboxImageTool() { return m_pXboxImageTool; }
CXboxDeploymentTool *GetXboxDeploymentTool() { return m_pXboxDeploymentTool; }
CProjectTool *GetIntellisenseTool() { return m_pIntellisenseTool; }
bool IsEmpty();
bool SetProperty( ToolProperty_t *pToolProperty );
const char *GetPropertyValue( ToolProperty_t *pToolProperty );
CVCProjGenerator *m_pGenerator;
// type of config, and config's properties
bool m_bIsFileConfig;
CUtlString m_Name;
CUtlString m_LowerCaseName;
CPropertyStates m_PropertyStates;
private:
// the config's tools
CDebuggingTool *m_pDebuggingTool;
CCompilerTool *m_pCompilerTool;
CLibrarianTool *m_pLibrarianTool;
CLinkerTool *m_pLinkerTool;
CManifestTool *m_pManifestTool;
CXMLDocGenTool *m_pXMLDocGenTool;
CBrowseInfoTool *m_pBrowseInfoTool;
CResourcesTool *m_pResourcesTool;
CPreBuildEventTool *m_pPreBuildEventTool;
CPreLinkEventTool *m_pPreLinkEventTool;
CPostBuildEventTool *m_pPostBuildEventTool;
CCustomBuildTool *m_pCustomBuildTool;
CXboxImageTool *m_pXboxImageTool;
CXboxDeploymentTool *m_pXboxDeploymentTool;
CProjectTool *m_pIntellisenseTool;
};
class IVCProjWriter
{
public:
virtual bool Save( const char *pOutputFilename ) = 0;
virtual const char *GetProjectFileExtension() { return NULL; }
virtual CVCProjGenerator *GetProjectGenerator() = 0;
};
class CVCProjGenerator : public CBaseProjectDataCollector
{
public:
typedef CBaseProjectDataCollector BaseClass;
CVCProjGenerator();
virtual const char *GetProjectFileExtension() OVERRIDE;
virtual void StartProject() OVERRIDE;
virtual void EndProject( bool bSaveData ) OVERRIDE;
virtual const char *GetProjectName() OVERRIDE;
virtual void SetProjectName( const char *pProjectName ) OVERRIDE;
virtual void GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames ) OVERRIDE;
virtual void StartConfigurationBlock( const char *pConfigName, bool bFileSpecific ) OVERRIDE;
virtual void EndConfigurationBlock() OVERRIDE;
virtual bool StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip ) OVERRIDE;
virtual void HandleProperty( const char *pProperty, const char *pCustomScriptData ) OVERRIDE;
virtual const char *GetPropertyValue( const char *pPropertyName ) OVERRIDE;
virtual void EndPropertySection( configKeyword_e keyword ) OVERRIDE;
virtual void StartFolder( const char *pFolderName, VpcFolderFlags_t iFlags ) OVERRIDE;
virtual void EndFolder() OVERRIDE;
virtual bool StartFile( const char *pFilename, VpcFileFlags_t iFlags, bool bWarnIfAlreadyExists ) OVERRIDE;
virtual void EndFile() OVERRIDE;
virtual void FileExcludedFromBuild( bool bExcluded ) OVERRIDE;
virtual bool RemoveFile( const char *pFilename ) OVERRIDE;
virtual void EnumerateSupportedVPCTargetPlatforms( CUtlVector<CUtlString> &output ) OVERRIDE;
virtual bool BuildsForTargetPlatform( const char *szVPCTargetPlatform ) OVERRIDE;
virtual bool DeploysForVPCTargetPlatform( const char *szVPCTargetPlatform ) OVERRIDE;
virtual CUtlString GetSolutionPlatformAlias( const char *szVPCTargetPlatform, IBaseSolutionGenerator *pSolutionGenerator ) OVERRIDE;
CGeneratorDefinition *GetGeneratorDefinition() { return m_pGeneratorDefinition; }
void SetupGeneratorDefinition( const char *pDefinitionName, PropertyName_t *pPropertyNames );
void AddProjectWriter( IVCProjWriter *pVCProjWriter );
void RemoveLastProjectWriter() { m_VCProjWriters.RemoveMultipleFromTail( 1 ); }
PS3VSIType_e GetVSIType() { return m_VSIType; }
bool GetRootConfiguration( const char *pConfigName, CProjectConfiguration **pConfig );
void GetAllRootConfigurations( CUtlVector< CProjectConfiguration * > &rootConfigurations );
CProjectFolder *GetRootFolder() { return m_pRootFolder; }
// returns true if found, false otherwise (bFixSlashes fixes up slashes in the search string first)
bool FindFile( const char *pFilename, CProjectFile **pFile, bool bFixSlashes = false );
void AddFileToFolder( const char *pFilename, CProjectFolder *pFolder, bool bWarnIfExists, VpcFileFlags_t iFlags, CProjectFile **pFile );
void GetAllProjectFiles( CUtlVector< CProjectFile * > &projectFiles );
// See if the file has a file-specific property.
bool HasFilePropertyValue( CProjectFile *pProjectFile, const char *pConfigrationName, configKeyword_e configKeyword, const char *pPropertyName );
const char *GetPropertyValueAsString( CProjectFile *pProjectFile, const char *pConfigrationName, configKeyword_e configKeyword, const char *pPropertyName, const char *pDefaultValue = "" );
bool GetPropertyValueAsBool( CProjectFile *pProjectFile, const char *pConfigrationName, configKeyword_e configKeyword, const char *pPropertyName, bool bDefaultValue = false );
private:
void Clear();
bool Config_GetConfigurations( const char *pszConfigName );
// returns true if found, false otherwise
bool GetFolder( const char *pFolderName, CProjectFolder *pParentFolder, CProjectFolder **pOutFolder );
// returns true if added, false otherwise (duplicate)
bool AddFolder( const char *pFolderName, CProjectFolder *pParentFolder, VpcFolderFlags_t iFlags, CProjectFolder **pOutFolder );
// returns true if removed, false otherwise (not found)
bool RemoveFileFromFolder( const char *pFilename, CProjectFolder *pFolder );
bool IsConfigurationNameValid( const char *pConfigName );
configKeyword_e SetPS3VisualStudioIntegrationType( configKeyword_e eKeyword );
void ApplyInternalPreprocessorDefinitions();
void LogOutputFiles( const char *pConfigName );
int FindFileInDictionary( const char *pFilename );
void EvaluateHackMacro_HACK_DEPENDENCIES_ALLVPCSCRIPTS( void );
void AddIndirectCustomBuildDependencies( void );
private:
configKeyword_e m_nActivePropertySection;
CGeneratorDefinition *m_pGeneratorDefinition;
CDebuggingTool *m_pDebuggingTool;
CCompilerTool *m_pCompilerTool;
CLibrarianTool *m_pLibrarianTool;
CLinkerTool *m_pLinkerTool;
CManifestTool *m_pManifestTool;
CXMLDocGenTool *m_pXMLDocGenTool;
CBrowseInfoTool *m_pBrowseInfoTool;
CResourcesTool *m_pResourcesTool;
CPreBuildEventTool *m_pPreBuildEventTool;
CPreLinkEventTool *m_pPreLinkEventTool;
CPostBuildEventTool *m_pPostBuildEventTool;
CCustomBuildTool *m_pCustomBuildTool;
CXboxImageTool *m_pXboxImageTool;
CXboxDeploymentTool *m_pXboxDeploymentTool;
CProjectTool *m_pIntellisenseTool;
CProjectConfiguration *m_pConfig;
CProjectConfiguration *m_pFileConfig;
CProjectFile *m_pProjectFile;
CSimplePointerStack< CProjectFolder*, CProjectFolder*, 128 > m_spFolderStack;
CSimplePointerStack< CCompilerTool*, CCompilerTool*, 128 > m_spCompilerStack;
CSimplePointerStack< CCustomBuildTool*, CCustomBuildTool*, 128 > m_spCustomBuildToolStack;
CSimplePointerStack< CResourcesTool*, CResourcesTool*, 128 > m_spResourcesToolStack;
CUtlString m_ProjectName;
CProjectFolder *m_pRootFolder;
CUtlVector< CProjectConfiguration* > m_RootConfigurations;
// primary file dictionary
CUtlRBTree< CProjectFile*, int > m_FileDictionary;
CUtlVector< IVCProjWriter* > m_VCProjWriters;
// ps3 visual studio integration
PS3VSIType_e m_VSIType;
};
+337
View File
@@ -0,0 +1,337 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
extern const char *GetVCProjTargetPlatformName( const char *szVPCTargetPlatformName );
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Win32PropertyNames[] =
{
#include "projectgenerator_win32.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetWin32ProjectGenerator()
{
CProjectGenerator_Win32 *pNew = new CProjectGenerator_Win32;
return pNew->GetProjectGenerator();
}
CProjectGenerator_Win32::CProjectGenerator_Win32()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( "win32_2005.def", s_Win32PropertyNames );
m_pVCProjGenerator->AddProjectWriter( this );
}
bool CProjectGenerator_Win32::WriteFile( CProjectFile *pFile )
{
m_XMLWriter.PushNode( "File" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "RelativePath=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::WriteFolder( CProjectFolder *pFolder )
{
m_XMLWriter.PushNode( "Filter" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s\"", m_XMLWriter.FixupXMLString( pFolder->m_Name.Get() ).Get() ) );
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex] ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex] ) )
return false;
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::WriteConfiguration( CProjectConfiguration *pConfig )
{
const char *szVisualStudioPlatformName = GetVCProjTargetPlatformName( g_pVPC->GetTargetPlatformName() );
if ( pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "FileConfiguration" );
}
else
{
m_XMLWriter.PushNode( "Configuration" );
}
const char *pOutputName = "???";
if ( !V_stricmp_fast( pConfig->m_Name.Get(), "debug" ) )
{
pOutputName = "Debug";
}
else if ( !V_stricmp_fast( pConfig->m_Name.Get(), "release" ) )
{
pOutputName = "Release";
}
else
{
return false;
}
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s|%s\"", pOutputName, szVisualStudioPlatformName ) );
// write configuration properties
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] );
}
if ( !WriteTool( "VCPreBuildEventTool", pConfig->GetPreBuildEventTool() ) )
return false;
if ( !WriteTool( "VCCustomBuildTool", pConfig->GetCustomBuildTool() ) )
return false;
if ( !WriteNULLTool( "VCXMLDataGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebServiceProxyGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCMIDLTool", pConfig ) )
return false;
if ( !WriteTool( "VCCLCompilerTool", pConfig->GetCompilerTool() ) )
return false;
if ( !WriteNULLTool( "VCManagedResourceCompilerTool", pConfig ) )
return false;
if ( !WriteTool( "VCResourceCompilerTool", pConfig->GetResourcesTool() ) )
return false;
if ( !WriteTool( "VCPreLinkEventTool", pConfig->GetPreLinkEventTool() ) )
return false;
if ( !WriteTool( "VCLinkerTool", pConfig->GetLinkerTool() ) )
return false;
if ( !WriteTool( "VCLibrarianTool", pConfig->GetLibrarianTool() ) )
return false;
if ( !WriteNULLTool( "VCALinkTool", pConfig ) )
return false;
if ( !WriteTool( "VCManifestTool", pConfig->GetManifestTool() ) )
return false;
if ( !WriteTool( "VCXDCMakeTool", pConfig->GetXMLDocGenTool() ) )
return false;
if ( !WriteTool( "VCBscMakeTool", pConfig->GetBrowseInfoTool() ) )
return false;
if ( !WriteNULLTool( "VCFxCopTool", pConfig ) )
return false;
if ( !pConfig->GetLibrarianTool() )
{
if ( !WriteNULLTool( "VCAppVerifierTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebDeploymentTool", pConfig ) )
return false;
}
if ( !WriteTool( "VCPostBuildEventTool", pConfig->GetPostBuildEventTool() ) )
return false;
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::WriteToXML()
{
const char *szVisualStudioPlatformName = GetVCProjTargetPlatformName( g_pVPC->GetTargetPlatformName() );
m_XMLWriter.PushNode( "VisualStudioProject" );
m_XMLWriter.AddNodeProperty( "ProjectType=\"Visual C++\"" );
m_XMLWriter.AddNodeProperty( "Version=\"8.00\"" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s\"", m_pVCProjGenerator->GetProjectName() ) );
m_XMLWriter.AddNodeProperty( "ProjectGUID", CFmtStr( "{%s}", m_pVCProjGenerator->GetGUIDString() ) );
if ( g_pVPC->IsSourceControlEnabled() )
{
m_XMLWriter.AddNodeProperty( "SccProjectName=\"Perforce Project\"" );
m_XMLWriter.AddNodeProperty( "SccLocalPath=\"..\"" );
m_XMLWriter.AddNodeProperty( "SccProvider=\"MSSCCI:Perforce SCM\"\n" );
}
m_XMLWriter.PushNode( "Platforms" );
m_XMLWriter.AddNodeProperty( CFmtStr( "<Platform Name=\"%s\"/>", szVisualStudioPlatformName ).Get() );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ToolFiles" );
m_XMLWriter.PopNode();
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
// write the root configurations
m_XMLWriter.PushNode( "Configurations" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "References" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "Files" );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pRootFolder->m_Folders[iIndex] ) )
return false;
}
for ( int iIndex = pRootFolder->m_Files.Head(); iIndex != pRootFolder->m_Files.InvalidIndex(); iIndex = pRootFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pRootFolder->m_Files[iIndex] ) )
return false;
}
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::Save( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename, false, g_pVPC->IsForceGenerate() ) )
return false;
bool bValid = WriteToXML();
m_XMLWriter.Close();
return bValid;
}
bool CProjectGenerator_Win32::WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
return true;
m_XMLWriter.PushNode( "Tool", CFmtStr( "Name=\"%s\"", pToolName ).Get() );
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::WriteTool( const char *pToolName, const CProjectTool *pProjectTool )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.AddNodeProperty( CFmtStr( "Name=\"%s\"", pToolName ) );
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] );
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32::WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, pOutputValue ) );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
if ( pPropertyState && !pPropertyState->m_pToolProperty->m_bIgnoreForOutput )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, bEnabled ? "true" : "false" ) );
}
break;
case PT_STRING:
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ).Get() ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, pPropertyState->m_StringValue.Get() ) );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Win32: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
+41
View File
@@ -0,0 +1,41 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_WIN32_H
#define PROJECTGENERATOR_WIN32_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Win32Properties_e
{
#include "projectgenerator_win32.inc"
};
class CProjectGenerator_Win32 : public IVCProjWriter
{
public:
CProjectGenerator_Win32();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_WIN32_H
+255
View File
@@ -0,0 +1,255 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( WIN32_GENERAL, ExcludedFromBuild )
PROPERTYNAME( WIN32_GENERAL, OutputDirectory )
PROPERTYNAME( WIN32_GENERAL, IntermediateDirectory )
PROPERTYNAME( WIN32_GENERAL, ConfigurationType )
PROPERTYNAME( WIN32_GENERAL, CharacterSet )
PROPERTYNAME( WIN32_GENERAL, WholeProgramOptimization )
PROPERTYNAME( WIN32_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( WIN32_GENERAL, BuildLogFile )
PROPERTYNAME( WIN32_GENERAL, InheritedProjectPropertySheets )
PROPERTYNAME( WIN32_GENERAL, UseOfMFC )
PROPERTYNAME( WIN32_GENERAL, UseOfATL )
PROPERTYNAME( WIN32_GENERAL, MinimizeCRTUseInATL )
PROPERTYNAME( WIN32_GENERAL, DisableFastUpToDateCheck )
PROPERTYNAME( WIN32_GENERAL, AdditionalProjectDependencies )
PROPERTYNAME( WIN32_GENERAL, AdditionalOutputFiles )
// Debugging
PROPERTYNAME( WIN32_DEBUGGING, Command )
PROPERTYNAME( WIN32_DEBUGGING, CommandArguments )
PROPERTYNAME( WIN32_DEBUGGING, RemoteMachine )
PROPERTYNAME( WIN32_DEBUGGING, WorkingDirectory )
PROPERTYNAME( WIN32_DEBUGGING, Attach )
PROPERTYNAME( WIN32_DEBUGGING, DebuggerType )
PROPERTYNAME( WIN32_DEBUGGING, Environment )
PROPERTYNAME( WIN32_DEBUGGING, MergeEnvironment )
PROPERTYNAME( WIN32_DEBUGGING, SQLDebugging )
// Compiler
PROPERTYNAME( WIN32_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_COMPILER, AdditionalOptions )
PROPERTYNAME( WIN32_COMPILER, Optimization )
PROPERTYNAME( WIN32_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( WIN32_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( WIN32_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( WIN32_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( WIN32_COMPILER, WholeProgramOptimization )
PROPERTYNAME( WIN32_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( WIN32_COMPILER, KeepComments )
PROPERTYNAME( WIN32_COMPILER, EnableStringPooling )
PROPERTYNAME( WIN32_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( WIN32_COMPILER, EnableCPPExceptions )
PROPERTYNAME( WIN32_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( WIN32_COMPILER, SmallerTypeCheck )
PROPERTYNAME( WIN32_COMPILER, RuntimeLibrary )
PROPERTYNAME( WIN32_COMPILER, StructMemberAlignment )
PROPERTYNAME( WIN32_COMPILER, BufferSecurityCheck )
PROPERTYNAME( WIN32_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( WIN32_COMPILER, EnableEnhancedInstructionSet )
PROPERTYNAME( WIN32_COMPILER, FloatingPointModel )
PROPERTYNAME( WIN32_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( WIN32_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( WIN32_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( WIN32_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( WIN32_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( WIN32_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( WIN32_COMPILER, OpenMPSupport )
PROPERTYNAME( WIN32_COMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( WIN32_COMPILER, CreateUsePCHThroughFile )
PROPERTYNAME( WIN32_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( WIN32_COMPILER, ExpandAttributedSource )
PROPERTYNAME( WIN32_COMPILER, AssemblerOutput )
PROPERTYNAME( WIN32_COMPILER, ASMListLocation )
PROPERTYNAME( WIN32_COMPILER, ObjectFileName )
PROPERTYNAME( WIN32_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( WIN32_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( WIN32_COMPILER, EnableBrowseInformation )
PROPERTYNAME( WIN32_COMPILER, BrowseFile )
PROPERTYNAME( WIN32_COMPILER, WarningLevel )
PROPERTYNAME( WIN32_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( WIN32_COMPILER, Detect64bitPortabilityIssues )
PROPERTYNAME( WIN32_COMPILER, SuppressStartupBanner )
PROPERTYNAME( WIN32_COMPILER, DebugInformationFormat )
PROPERTYNAME( WIN32_COMPILER, CompileAs )
PROPERTYNAME( WIN32_COMPILER, ForceIncludes )
PROPERTYNAME( WIN32_COMPILER, ShowIncludes )
PROPERTYNAME( WIN32_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( WIN32_COMPILER, UseFullPaths )
PROPERTYNAME( WIN32_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( WIN32_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( WIN32_COMPILER, PreschedulingOptimization )
PROPERTYNAME( WIN32_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( WIN32_COMPILER, RegisterReservation )
PROPERTYNAME( WIN32_COMPILER, Stalls )
PROPERTYNAME( WIN32_COMPILER, CallAttributedProfiling )
PROPERTYNAME( WIN32_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( WIN32_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( WIN32_COMPILER, ResolveUsingReferences )
PROPERTYNAME( WIN32_COMPILER, OmitFramePointers )
PROPERTYNAME( WIN32_COMPILER, CallingConvention )
PROPERTYNAME( WIN32_COMPILER, ForceUsing )
PROPERTYNAME( WIN32_COMPILER, ErrorReporting )
// Librarian
PROPERTYNAME( WIN32_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( WIN32_LIBRARIAN, OutputFile )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( WIN32_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( WIN32_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( WIN32_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( WIN32_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( WIN32_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( WIN32_LINKER, IgnoreImportLibrary )
PROPERTYNAME( WIN32_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_LINKER, AdditionalOptions )
PROPERTYNAME( WIN32_LINKER, AdditionalDependencies )
PROPERTYNAME( WIN32_LINKER, ShowProgress )
PROPERTYNAME( WIN32_LINKER, OutputFile )
PROPERTYNAME( WIN32_LINKER, Version )
PROPERTYNAME( WIN32_LINKER, EnableIncrementalLinking )
PROPERTYNAME( WIN32_LINKER, SuppressStartupBanner )
PROPERTYNAME( WIN32_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_LINKER, GenerateManifest )
PROPERTYNAME( WIN32_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_LINKER, ModuleDefinitionFile )
PROPERTYNAME( WIN32_LINKER, GenerateDebugInfo )
PROPERTYNAME( WIN32_LINKER, DebuggableAssembly )
PROPERTYNAME( WIN32_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( WIN32_LINKER, GenerateMapFile )
PROPERTYNAME( WIN32_LINKER, MapFileName )
PROPERTYNAME( WIN32_LINKER, SubSystem )
PROPERTYNAME( WIN32_LINKER, EnableLargeAddresses )
PROPERTYNAME( WIN32_LINKER, MapExports )
PROPERTYNAME( WIN32_LINKER, StackReserveSize )
PROPERTYNAME( WIN32_LINKER, StackCommitSize )
PROPERTYNAME( WIN32_LINKER, References )
PROPERTYNAME( WIN32_LINKER, EnableCOMDATFolding )
PROPERTYNAME( WIN32_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( WIN32_LINKER, EntryPoint )
PROPERTYNAME( WIN32_LINKER, NoEntryPoint )
PROPERTYNAME( WIN32_LINKER, SetChecksum )
PROPERTYNAME( WIN32_LINKER, BaseAddress )
PROPERTYNAME( WIN32_LINKER, ImportLibrary )
PROPERTYNAME( WIN32_LINKER, TargetMachine )
PROPERTYNAME( WIN32_LINKER, FixedBaseAddress )
PROPERTYNAME( WIN32_LINKER, ErrorReporting )
PROPERTYNAME( WIN32_LINKER, FunctionOrder )
PROPERTYNAME( WIN32_LINKER, LinkLibraryDependencies )
PROPERTYNAME( WIN32_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( WIN32_LINKER, ForceSymbolReferences )
PROPERTYNAME( WIN32_LINKER, StripPrivateSymbols )
PROPERTYNAME( WIN32_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( WIN32_LINKER, MergeSections )
PROPERTYNAME( WIN32_LINKER, RegisterOutput )
PROPERTYNAME( WIN32_LINKER, AddModuleToAssembly )
PROPERTYNAME( WIN32_LINKER, EmbedManagedResourceFile )
PROPERTYNAME( WIN32_LINKER, DelayLoadedDLLs )
PROPERTYNAME( WIN32_LINKER, AssemblyLinkResource )
PROPERTYNAME( WIN32_LINKER, ManifestFile )
PROPERTYNAME( WIN32_LINKER, AdditionalManifestDependencies )
PROPERTYNAME( WIN32_LINKER, AllowIsolation )
PROPERTYNAME( WIN32_LINKER, HeapReserveSize )
PROPERTYNAME( WIN32_LINKER, HeapCommitSize )
PROPERTYNAME( WIN32_LINKER, TerminalServer )
PROPERTYNAME( WIN32_LINKER, SwapRunFromCD )
PROPERTYNAME( WIN32_LINKER, SwapRunFromNetwork )
PROPERTYNAME( WIN32_LINKER, Driver )
PROPERTYNAME( WIN32_LINKER, OptimizeForWindows98 )
PROPERTYNAME( WIN32_LINKER, MIDLCommands )
PROPERTYNAME( WIN32_LINKER, IgnoreEmbeddedIDL )
PROPERTYNAME( WIN32_LINKER, MergeIDLBaseFileName )
PROPERTYNAME( WIN32_LINKER, TypeLibrary )
PROPERTYNAME( WIN32_LINKER, TypeLibResourceID )
PROPERTYNAME( WIN32_LINKER, TurnOffAssemblyGeneration )
PROPERTYNAME( WIN32_LINKER, DelayLoadedDLL )
PROPERTYNAME( WIN32_LINKER, Profile )
PROPERTYNAME( WIN32_LINKER, CLRThreadAttribute )
PROPERTYNAME( WIN32_LINKER, CLRImageType )
PROPERTYNAME( WIN32_LINKER, KeyFile )
PROPERTYNAME( WIN32_LINKER, KeyContainer )
PROPERTYNAME( WIN32_LINKER, DelaySign )
PROPERTYNAME( WIN32_LINKER, CLRUnmanagedCodeCheck )
// Manifest
PROPERTYNAME( WIN32_MANIFESTTOOL, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, SuppressStartupBanner )
PROPERTYNAME( WIN32_MANIFESTTOOL, VerboseOutput )
PROPERTYNAME( WIN32_MANIFESTTOOL, AssemblyIdentity )
PROPERTYNAME( WIN32_MANIFESTTOOL, UseFAT32WorkAround )
PROPERTYNAME( WIN32_MANIFESTTOOL, AdditionalManifestFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, InputResourceManifests )
PROPERTYNAME( WIN32_MANIFESTTOOL, EmbedManifest )
PROPERTYNAME( WIN32_MANIFESTTOOL, OutputManifestFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, ManifestResourceFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, GenerateCatalogFiles )
PROPERTYNAME( WIN32_MANIFESTTOOL, DependencyInformationFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, TypeLibraryFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, RegistrarScriptFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, ComponentFileName )
PROPERTYNAME( WIN32_MANIFESTTOOL, ReplacementsFile )
PROPERTYNAME( WIN32_MANIFESTTOOL, UpdateFileHashes )
PROPERTYNAME( WIN32_MANIFESTTOOL, UpdateFileHashesSearchPath )
PROPERTYNAME( WIN32_MANIFESTTOOL, AdditionalOptions )
// XML Document Generator
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, SuppressStartupBanner )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, ValidateIntelliSense )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, AdditionalDocumentFiles )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, OutputDocumentFile )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, DocumentLibraryDependencies )
PROPERTYNAME( WIN32_XMLDOCUMENTGENERATOR, AdditionalOptions )
// Browse Information
PROPERTYNAME( WIN32_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( WIN32_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( WIN32_BROWSEINFORMATION, AdditionalOptions )
// Resources
PROPERTYNAME( WIN32_RESOURCES, PreprocessorDefinitions )
PROPERTYNAME( WIN32_RESOURCES, Culture )
PROPERTYNAME( WIN32_RESOURCES, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_RESOURCES, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_RESOURCES, ShowProgress )
PROPERTYNAME( WIN32_RESOURCES, ResourceFileName )
PROPERTYNAME( WIN32_RESOURCES, AdditionalOptions )
// Pre Build
PROPERTYNAME( WIN32_PREBUILDEVENT, Description )
PROPERTYNAME( WIN32_PREBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( WIN32_PRELINKEVENT, Description )
PROPERTYNAME( WIN32_PRELINKEVENT, CommandLine )
PROPERTYNAME( WIN32_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( WIN32_POSTBUILDEVENT, Description )
PROPERTYNAME( WIN32_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( WIN32_CUSTOMBUILDSTEP, Outputs )
@@ -0,0 +1,844 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
const char *GetVCProjTargetPlatformName( const char *szVPCTargetPlatformName )
{
//makefile wrappers still have to be labeled as a valid windows platform to even try executing >_<
if ( VPC_IsPlatform64Bits( szVPCTargetPlatformName ) )
{
return "x64";
}
else if ( VPC_IsPlatform32Bits( szVPCTargetPlatformName ) )
{
return "Win32";
}
Assert( false );
return szVPCTargetPlatformName;
}
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Win32PropertyNames_2010[] =
{
#include "projectgenerator_win32_2010.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetWin32ProjectGenerator_2010()
{
CProjectGenerator_Win32_2010 *pGen = new CProjectGenerator_Win32_2010();
return (CVCProjGenerator*)pGen->GetProjectGenerator();
}
IVCProjWriter* GetWin32ProjectGenerator_VCProjWriter_2010()
{
// Make sure we have an instance.
return new CProjectGenerator_Win32_2010();
}
CProjectGenerator_Win32_2010::CProjectGenerator_Win32_2010()
{
m_bGenerateMakefileVCXProj = false;
m_bVisualGDB = false;
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( "win32_2010.def", s_Win32PropertyNames_2010 );
m_pVCProjGenerator->AddProjectWriter( this );
}
enum TypeKeyNames_e
{
TKN_LIBRARY = 0,
TKN_INCLUDE,
TKN_COMPILE,
TKN_RESOURCECOMPILE,
TKN_CUSTOMBUILD,
TKN_NONE,
TKN_MAX_COUNT,
};
static const char *s_TypeKeyNames[] =
{
"Library",
"ClInclude",
"ClCompile",
"ResourceCompile",
"CustomBuild",
"None"
};
const char *CProjectGenerator_Win32_2010::GetKeyNameForFile( CProjectFile *pFile )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_TypeKeyNames ) == TKN_MAX_COUNT );
const char *pExtension = V_GetFileExtension( pFile->m_Name.Get() );
const char *pKeyName = s_TypeKeyNames[TKN_NONE];
if ( pExtension )
{
if ( pFile->m_Configs.Count() && pFile->m_Configs[0]->GetCustomBuildTool() )
{
pKeyName = s_TypeKeyNames[TKN_CUSTOMBUILD];
}
else if ( IsCFileExtension( pExtension ) )
{
pKeyName = s_TypeKeyNames[TKN_COMPILE];
}
else if ( IsHFileExtension( pExtension ) )
{
pKeyName = s_TypeKeyNames[TKN_INCLUDE];
}
else if ( !V_stricmp_fast( pExtension, "lib" ) )
{
pKeyName = s_TypeKeyNames[TKN_LIBRARY];
}
else if ( !V_stricmp_fast( pExtension, "rc" ) )
{
pKeyName = s_TypeKeyNames[TKN_RESOURCECOMPILE];
}
}
return pKeyName;
}
bool CProjectGenerator_Win32_2010::WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration, const char *szPlatformName )
{
if ( !pProjectTool )
return true;
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], szPlatformName, true, pConfiguration->m_Name.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFile( CProjectFile *pFile, const char *pFileTypeName, const char *szPlatformName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp_fast( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( !pFile->m_Configs.Count() )
{
m_XMLWriter.PushNode( pKeyName, CFmtStrMax( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLWriter.PopNode();
}
else
{
m_XMLWriter.PushNode( pKeyName, CFmtStrMax( "Include=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i], szPlatformName ) )
return false;
}
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth, const char *szPlatformName )
{
if ( !nDepth )
{
m_XMLWriter.PushNode( "ItemGroup" );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex], pFileTypeName, szPlatformName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex], pFileTypeName, nDepth+1, szPlatformName ) )
return false;
}
if ( !nDepth )
{
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteConfiguration( CProjectConfiguration *pConfig, const char *szPlatformName )
{
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "PropertyGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"Configuration\"", pConfig->m_Name.Get(), szPlatformName ) );
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( pConfig->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex], szPlatformName ) )
return false;
}
m_XMLWriter.PopNode();
}
else
{
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex], szPlatformName, true, pConfig->m_Name.Get() ) )
return false;
}
if ( !m_bGenerateMakefileVCXProj )
{
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "ResourceCompile", pConfig->GetResourcesTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig, szPlatformName ) )
return false;
}
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteTools( CProjectConfiguration *pConfig, const char *szPlatformName )
{
m_XMLWriter.PushNode( "ItemDefinitionGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\"", pConfig->m_Name.Get(), szPlatformName ) );
if ( !m_bGenerateMakefileVCXProj )
{
if ( !WriteTool( "PreBuildEvent", pConfig->GetPreBuildEventTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "ResourceCompile", pConfig->GetResourcesTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "PreLinkEvent", pConfig->GetPreLinkEventTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "Link", pConfig->GetLinkerTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "Lib", pConfig->GetLibrarianTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "Manifest", pConfig->GetManifestTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "Xdcmake", pConfig->GetXMLDocGenTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "Bscmake", pConfig->GetBrowseInfoTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "PostBuildEvent", pConfig->GetPostBuildEventTool(), pConfig, szPlatformName ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig, szPlatformName ) )
return false;
}
else
{
if ( !WriteTool( "Intellisense", pConfig->GetIntellisenseTool(), pConfig, szPlatformName ) )
return false;
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Win32_2010::WritePrimaryXML( const char *pOutputFilename, const char *szPlatformName )
{
if ( !m_XMLWriter.Open( pOutputFilename, true, g_pVPC->IsForceGenerate() ) )
return false;
m_XMLWriter.PushNode( "Project", "DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
m_XMLWriter.PushNode( "ItemGroup", "Label=\"ProjectConfigurations\"" );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ProjectConfiguration" );
{
m_XMLWriter.AddNodeProperty( "Include", CFmtStr( "%s|%s", configurationNames[i].Get(), szPlatformName ) );
m_XMLWriter.WriteLineNode( "Configuration", "", configurationNames[i].Get() );
m_XMLWriter.WriteLineNode( "Platform", "", szPlatformName );
}
m_XMLWriter.PopNode();
}
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"Globals\"" );
m_XMLWriter.WriteLineNode( "ProjectName", "", m_pVCProjGenerator->GetProjectName() );
m_XMLWriter.WriteLineNode( "ProjectGuid", "", CFmtStr( "{%s}", m_pVCProjGenerator->GetGUIDString() ) );
// Suppress bogus warning MSB8027 in schemacompiler files in VS 2013 caused by this bug:
// https://connect.microsoft.com/VisualStudio/feedback/details/797460/incorrect-warning-msb8027-reported-for-files-excluded-from-build
m_XMLWriter.WriteLineNode( "IgnoreWarnCompileDuplicatedFilename", "", "true" );
if ( g_pVPC->IsSourceControlEnabled() )
{
m_XMLWriter.WriteLineNode( "SccProjectName", "", "Perforce Project" );
// it looks like 2k10 (at least) doesn't hook files in the project but not under
// the project root into source control, so make all the projects local paths
// the solution dir
char szCurrentDirectory[MAX_FIXED_PATH];
V_GetCurrentDirectory( szCurrentDirectory, V_ARRAYSIZE( szCurrentDirectory ) );
char szRelativeFilename[MAX_FIXED_PATH];
if ( !V_MakeRelativePath( g_pVPC->GetStartDirectory(), szCurrentDirectory, szRelativeFilename, sizeof( szRelativeFilename ) ) )
{
V_strncpy( szRelativeFilename, ".", V_ARRAYSIZE( szRelativeFilename ) );
}
m_XMLWriter.WriteLineNode( "SccLocalPath", "", szRelativeFilename );
m_XMLWriter.WriteLineNode( "SccProvider", "", "MSSCCI:Perforce SCM" );
}
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\"" );
m_XMLWriter.PopNode();
// write the root configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration, szPlatformName ) )
return false;
}
}
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionSettings\"" );
m_XMLWriter.PopNode();
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ImportGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\" Label=\"PropertySheets\"", configurationNames[i].Get(), szPlatformName ) );
m_XMLWriter.PushNode( "Import" );
m_XMLWriter.AddNodeProperty( "Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\"" );
m_XMLWriter.AddNodeProperty( "Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\"" );
m_XMLWriter.AddNodeProperty( "Label=\"LocalAppDataPlatform\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
}
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"UserMacros\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "PropertyGroup" );
m_XMLWriter.WriteLineNode( "_ProjectFileVersion", "", "10.0.30319.1" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
for ( int j = 0; j < pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder.Count(); j++ )
{
int sortedIndex = pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder[j];
if ( !pConfiguration->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfiguration->m_PropertyStates.m_Properties[sortedIndex], szPlatformName, true, pConfiguration->m_Name.Get() ) )
return false;
}
if ( !WritePropertyGroupTool( pConfiguration->GetPreBuildEventTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPreLinkEventTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLinkerTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLibrarianTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPostBuildEventTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetCustomBuildTool(), pConfiguration, szPlatformName ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetIntellisenseTool(), pConfiguration, szPlatformName ) )
return false;
}
}
m_XMLWriter.PopNode();
// write the tool configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteTools( pConfiguration, szPlatformName ) )
return false;
}
}
// write root folders
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolder( m_pVCProjGenerator->GetRootFolder(), s_TypeKeyNames[i], 0, szPlatformName ) )
return false;
}
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionTargets\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
m_XMLWriter.Close();
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath )
{
CUtlString parentPath = CFmtStrMax( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() ).Get();
CUtlString lowerParentPath = parentPath;
lowerParentPath.ToLower();
MD5Context_t ctx;
unsigned char digest[MD5_DIGEST_LENGTH];
V_memset( &ctx, 0, sizeof( ctx ) );
V_memset( digest, 0, sizeof( digest ) );
MD5Init( &ctx );
MD5Update( &ctx, (unsigned char *)lowerParentPath.Get(), V_strlen( lowerParentPath.Get() ) );
MD5Final( digest, &ctx );
char szMD5[64];
V_binarytohex( digest, MD5_DIGEST_LENGTH, szMD5, sizeof( szMD5 ) );
V_strupper( szMD5 );
char szGUID[100];
V_snprintf( szGUID, sizeof( szGUID ), "{%8.8s-%4.4s-%4.4s-%4.4s-%12.12s}", szMD5, &szMD5[8], &szMD5[12], &szMD5[16], &szMD5[20] );
m_XMLFilterWriter.PushNode( "Filter", CFmtStrMax( "Include=\"%s\"", parentPath.Get() ) );
m_XMLFilterWriter.WriteLineNode( "UniqueIdentifier", "", szGUID );
m_XMLFilterWriter.PopNode();
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp_fast( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( pParentPath )
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStrMax( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.WriteLineNode( "Filter", "", pParentPath );
m_XMLFilterWriter.PopNode();
}
else
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStrMax( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth )
{
CUtlString parentPath;
if ( pParentPath )
{
parentPath = CFmtStrMax( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
}
if ( !nDepth )
{
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFileToSecondaryXML( pFolder->m_Files[iIndex], parentPath.Get(), pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderContentsToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get(), pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLFilterWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteSecondaryXML( const char *pOutputFilename )
{
if ( !m_XMLFilterWriter.Open( pOutputFilename, true, g_pVPC->IsForceGenerate() ) )
return false;
m_XMLFilterWriter.PushNode( "Project", "ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
// write the root folders
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pRootFolder->m_Folders[iIndex], "" ) )
return false;
}
m_XMLFilterWriter.PopNode();
// write folder contents
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolderContentsToSecondaryXML( pRootFolder, NULL, s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLFilterWriter.PopNode();
m_XMLFilterWriter.Close();
return true;
}
bool CProjectGenerator_Win32_2010::WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig, const char *szPlatformName )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( pToolName, NULL );
}
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pConfig->m_bIsFileConfig )
{
if ( pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], szPlatformName ) )
return false;
}
else
{
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], szPlatformName, true, pConfig->m_Name.Get() ) )
return false;
}
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteProperty( const PropertyState_t *pPropertyState, const char *szPlatformName, bool bEmitConfiguration, const char *pConfigName, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.WriteLineNode( pOutputName, "", pOutputValue );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
const char *pCondition = "";
CUtlString conditionString;
if ( bEmitConfiguration )
{
conditionString = CFmtStr( " Condition=\"'$(Configuration)|$(Platform)'=='%s|%s'\"", pConfigName, szPlatformName );
pCondition = conditionString.Get();
}
if ( pPropertyState && !pPropertyState->m_pToolProperty->m_bIgnoreForOutput )
{
const char *pValueStr = pPropertyState->m_StringValue.Get();
CUtlString generatedValueBuffer;
if ( pPropertyState->m_pToolProperty->m_bGeneratedOnOutput && GenerateToolProperty( pOutputName, pValueStr, generatedValueBuffer, pPropertyState, szPlatformName, pConfigName ) )
{
pValueStr = generatedValueBuffer.Get();
}
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pValueStr );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.WriteLineNode( pOutputName, pCondition, bEnabled ? "true" : "false" );
}
break;
case PT_STRING:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, m_XMLWriter.FixupXMLString( pValueStr ).Get() );
break;
case PT_LIST:
case PT_INTEGER:
// When we're generating a makefile wrapper we have to
// force the configuration type to Makefile. We can't
// do this in vpc scripts themselves as the makefile
// output pass needs the correct configuration type.
if ( m_bGenerateMakefileVCXProj && !V_stricmp_fast( pOutputName, "ConfigurationType" ) )
{
pValueStr = "Makefile";
}
m_XMLWriter.WriteLineNode( pOutputName, pCondition, pValueStr );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Win32_2010: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
bool CProjectGenerator_Win32_2010::WriteVisualGDBSettings( const char *pConfiguration )
{
const char *pConfigType = m_pVCProjGenerator->
GetPropertyValueAsString( NULL, pConfiguration, KEYWORD_GENERAL, g_pOption_ConfigurationType );
if ( !V_stristr( pConfigType, ".exe" ) )
{
return true;
}
CUtlPathStringHolder finalSettingsFile( g_pVPC->FormatTemp1( "%s-%s.vgdbsettings", GetProjectGenerator()->GetOutputFileName(), pConfiguration ) );
// Print just the filename first for status output.
g_pVPC->VPCStatus( true, "Saving... Project: '%s' File: '%s'",
g_pVPC->GetProjectName(), finalSettingsFile.Get() );
// Now create the full path.
finalSettingsFile.Set( g_pVPC->FormatTemp1( "%s/%s-%s.vgdbsettings", g_pVPC->GetProjectPath(), GetProjectGenerator()->GetOutputFileName(), pConfiguration ) );
finalSettingsFile.FixSlashes();
CUtlPathStringHolder settingsPath( g_pVPC->GetSourcePath(), "/devtools/vpc.vgdbsettings" );
settingsPath.FixSlashes();
CUtlBuffer settingsBuf;
if ( !Sys_LoadFileIntoBuffer( settingsPath, settingsBuf, true ) )
{
g_pVPC->VPCError( "Cannot open .vgdbsettings file '%s'", settingsPath.Get() );
return false;
}
CUtlStringBuilder *pStrBuf = g_pVPC->GetTempStringBuffer1();
const char *pTargetOutput = m_pVCProjGenerator->
GetPropertyValueAsString( NULL, pConfiguration, KEYWORD_LINKER, g_pOption_OutputFile );
V_MakeAbsolutePath( pStrBuf->Access(), pStrBuf->Capacity(), pTargetOutput, g_pVPC->GetProjectPath() );
pStrBuf->ReplaceFastCaseless( g_pVPC->GetSourcePath(), "$(LinuxDebugRoot)/src" );
V_FixSlashes( pStrBuf->Access(), '/' );
CUtlStringBuilder strSettings( (char*)settingsBuf.Base() );
strSettings.Replace( "$$CONFIGURATION$$", pConfiguration );
strSettings.Replace( "$$TARGET$$", pStrBuf->Get() );
const char *pEnv;
pEnv = getenv( "LINUX_DEBUG_HOST_NAME" );
if ( pEnv != NULL )
{
strSettings.Replace( "$(LinuxDebugHostName)", pEnv );
}
pEnv = getenv( "LINUX_DEBUG_USER_NAME" );
if ( pEnv != NULL )
{
strSettings.Replace( "$(LinuxDebugUserName)", pEnv );
}
pEnv = getenv( "LINUX_DEBUG_ROOT" );
if ( pEnv != NULL )
{
strSettings.Replace( "$(LinuxDebugRoot)", pEnv );
}
FILE *pFile = fopen( finalSettingsFile, "wt" );
if ( !pFile )
{
g_pVPC->VPCError( "Cannot open '%s' for writing", finalSettingsFile.Get() );
return false;
}
fwrite( strSettings, 1, V_strlen( strSettings ), pFile );
fclose( pFile );
return true;
}
bool CProjectGenerator_Win32_2010::Save( const char *pOutputFilename )
{
bool bValid = true;
m_bGenerateMakefileVCXProj = g_pVPC->IsConditionalDefined( "GENERATE_MAKEFILE_VCXPROJ" );
m_bVisualGDB = g_pVPC->IsConditionalDefined( "VISUALGDB" );
const char *szPlatformName = GetVCProjTargetPlatformName( g_pVPC->GetTargetPlatformName() );
if ( m_bGenerateMakefileVCXProj && m_bVisualGDB )
{
CUtlVector< CUtlString > vConfigurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( vConfigurationNames );
for ( int i = 0; i < vConfigurationNames.Count(); i++ )
{
if ( !WriteVisualGDBSettings( vConfigurationNames[i] ) )
{
bValid = false;
break;
}
}
}
if ( bValid )
{
bValid = WritePrimaryXML( pOutputFilename, szPlatformName );
}
if ( bValid )
{
bValid = WriteSecondaryXML( CFmtStrMax( "%s.filters", pOutputFilename ) );
if ( !bValid )
{
g_pVPC->VPCError( "Cannot save to the specified project '%s'", pOutputFilename );
}
}
return bValid;
}
bool CProjectGenerator_Win32_2010::GenerateToolProperty( const char *pOutputName, const char *pScriptValue, CUtlString &outputWrite, const PropertyState_t *pPropertyState, const char *szPlatformName, const char *pConfigName )
{
CProjectConfiguration *pRootConfig = nullptr;
if ( pConfigName )
{
if ( !m_pVCProjGenerator->GetRootConfiguration( pConfigName, &pRootConfig ) || !pRootConfig )
{
g_pVPC->VPCError( "Could not get config \"%s\"", pConfigName );
UNREACHABLE();
}
}
else
{
CUtlVector<CProjectConfiguration *> rootConfigs;
m_pVCProjGenerator->GetAllRootConfigurations( rootConfigs );
if ( rootConfigs.Count() == 0 )
{
if ( !m_pVCProjGenerator->GetRootConfiguration( pConfigName, &pRootConfig ) || !pRootConfig )
{
g_pVPC->VPCError( "No configs found" );
UNREACHABLE();
}
}
pRootConfig = rootConfigs[0];
}
Assert( outputWrite.IsEmpty() );
if ( !V_stricmp_fast( pOutputName, "NMakePreprocessorDefinitions" ) )
{
CUtlString cfgString;
if ( VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, nullptr, g_pOption_PreprocessorDefinitions, &cfgString ) && !cfgString.IsEmpty() )
{
outputWrite = pScriptValue;
outputWrite += cfgString;
return true;
}
return false;
}
else if ( !V_stricmp_fast( pOutputName, "NMakeIncludeSearchPath" ) )
{
CUtlString cfgString;
if ( VPC_GetPropertyString( KEYWORD_COMPILER, pRootConfig, nullptr, g_pOption_AdditionalIncludeDirectories, &cfgString ) && !cfgString.IsEmpty() )
{
outputWrite = cfgString;
if ( pScriptValue && pScriptValue[0] )
{
outputWrite += ";";
outputWrite += pScriptValue;
}
outputWrite.FixSlashes();
return true;
}
return false;
}
else
{
g_pVPC->VPCWarning( "No property generator defined for \"%s\"", pOutputName );
return false;
}
UNREACHABLE();
}
@@ -0,0 +1,63 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_WIN32_2010_H
#define PROJECTGENERATOR_WIN32_2010_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Win32_2010_Properties_e
{
#include "projectgenerator_win32_2010.inc"
};
class CProjectGenerator_Win32_2010 : public IVCProjWriter
{
public:
CProjectGenerator_Win32_2010();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
virtual const char *GetProjectFileExtension() { return "vcxproj"; }
private:
// primary XML - foo.vcxproj
bool WritePrimaryXML( const char *pOutputFilename, const char *szPlatformName );
bool WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth, const char *szPlatformName );
bool WriteFile( CProjectFile *pFile, const char *pFileTypeName, const char *szPlatformName );
bool WriteConfiguration( CProjectConfiguration *pConfig, const char *szPlatformName );
bool WriteTools( CProjectConfiguration *pConfig, const char *szPlatformName );
bool WriteProperty( const PropertyState_t *pPropertyState, const char *szPlatformName, bool bEmitConfiguration = false, const char *pConfigurationName = NULL, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig, const char *szPlatformName );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
bool WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration, const char *szPlatformName );
bool WritePropertyGroup();
// secondary XML - foo.vcxproj.filters
bool WriteSecondaryXML( const char *pOutputFilename );
bool WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath );
bool WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth );
bool WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName );
// VisualGDB support files
bool WriteVisualGDBSettings( const char *pConfiguration );
const char *GetKeyNameForFile( CProjectFile *pFile );
bool GenerateToolProperty( const char *pOutputName, const char *pScriptValue, CUtlString &outputWrite, const PropertyState_t *pPropertyState, const char *szPlatformName, const char *pConfigName );
CXMLWriter m_XMLWriter;
CXMLWriter m_XMLFilterWriter;
CVCProjGenerator *m_pVCProjGenerator;
bool m_bGenerateMakefileVCXProj;
bool m_bVisualGDB;
};
#endif // PROJECTGENERATOR_WIN32_2010_H
@@ -0,0 +1,332 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( WIN32_2010_GENERAL, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_GENERAL, OutputDirectory )
PROPERTYNAME( WIN32_2010_GENERAL, IntermediateDirectory )
PROPERTYNAME( WIN32_2010_GENERAL, ConfigurationType )
PROPERTYNAME( WIN32_2010_GENERAL, CharacterSet )
PROPERTYNAME( WIN32_2010_GENERAL, WholeProgramOptimization )
PROPERTYNAME( WIN32_2010_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( WIN32_2010_GENERAL, BuildLogFile )
PROPERTYNAME( WIN32_2010_GENERAL, InheritedProjectPropertySheets )
PROPERTYNAME( WIN32_2010_GENERAL, UseOfMFC )
PROPERTYNAME( WIN32_2010_GENERAL, UseOfATL )
PROPERTYNAME( WIN32_2010_GENERAL, MinimizeCRTUseInATL )
PROPERTYNAME( WIN32_2010_GENERAL, TargetName )
PROPERTYNAME( WIN32_2010_GENERAL, TargetExtension )
PROPERTYNAME( WIN32_2010_GENERAL, PlatformToolset )
PROPERTYNAME( WIN32_2010_GENERAL, PreferredToolArchitecture )
PROPERTYNAME( WIN32_2010_GENERAL, ExecutableDirectories )
PROPERTYNAME( WIN32_2010_GENERAL, DisableFastUpToDateCheck )
PROPERTYNAME( WIN32_2010_GENERAL, AdditionalProjectDependencies )
PROPERTYNAME( WIN32_2010_GENERAL, AdditionalOutputFiles )
PROPERTYNAME( WIN32_2010_GENERAL, SchemaPreIncludeFiles )
PROPERTYNAME( WIN32_2010_GENERAL, LowerCaseFileNames )
PROPERTYNAME( WIN32_2010_GENERAL, GameOutputFile )
PROPERTYNAME( WIN32_2010_GENERAL, NMakeBuildCommandLine )
PROPERTYNAME( WIN32_2010_GENERAL, NMakeReBuildCommandLine )
PROPERTYNAME( WIN32_2010_GENERAL, NMakeCleanCommandLine )
PROPERTYNAME( WIN32_2010_GENERAL, NMakeOutput )
// Debugging
PROPERTYNAME( WIN32_2010_DEBUGGING, Command )
PROPERTYNAME( WIN32_2010_DEBUGGING, CommandArguments )
PROPERTYNAME( WIN32_2010_DEBUGGING, RemoteMachine )
PROPERTYNAME( WIN32_2010_DEBUGGING, WorkingDirectory )
PROPERTYNAME( WIN32_2010_DEBUGGING, Attach )
PROPERTYNAME( WIN32_2010_DEBUGGING, DebuggerType )
PROPERTYNAME( WIN32_2010_DEBUGGING, Environment )
PROPERTYNAME( WIN32_2010_DEBUGGING, MergeEnvironment )
PROPERTYNAME( WIN32_2010_DEBUGGING, SQLDebugging )
// Compiler
PROPERTYNAME( WIN32_2010_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_COMPILER, AdditionalOptions )
PROPERTYNAME( WIN32_2010_COMPILER, Optimization )
PROPERTYNAME( WIN32_2010_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( WIN32_2010_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( WIN32_2010_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( WIN32_2010_COMPILER, WholeProgramOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_2010_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( WIN32_2010_COMPILER, KeepComments )
PROPERTYNAME( WIN32_2010_COMPILER, EnableStringPooling )
PROPERTYNAME( WIN32_2010_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( WIN32_2010_COMPILER, EnableCPPExceptions )
PROPERTYNAME( WIN32_2010_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( WIN32_2010_COMPILER, SmallerTypeCheck )
PROPERTYNAME( WIN32_2010_COMPILER, RuntimeLibrary )
PROPERTYNAME( WIN32_2010_COMPILER, StructMemberAlignment )
PROPERTYNAME( WIN32_2010_COMPILER, BufferSecurityCheck )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( WIN32_2010_COMPILER, EnableEnhancedInstructionSet )
PROPERTYNAME( WIN32_2010_COMPILER, FloatingPointModel )
PROPERTYNAME( WIN32_2010_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( WIN32_2010_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( WIN32_2010_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( WIN32_2010_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( WIN32_2010_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( WIN32_2010_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( WIN32_2010_COMPILER, OpenMPSupport )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeader )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( WIN32_2010_COMPILER, PrecompiledHeaderOutputFile )
PROPERTYNAME( WIN32_2010_COMPILER, ExpandAttributedSource )
PROPERTYNAME( WIN32_2010_COMPILER, AssemblerOutput )
PROPERTYNAME( WIN32_2010_COMPILER, ASMListLocation )
PROPERTYNAME( WIN32_2010_COMPILER, ObjectFileName )
PROPERTYNAME( WIN32_2010_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( WIN32_2010_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( WIN32_2010_COMPILER, EnableBrowseInformation )
PROPERTYNAME( WIN32_2010_COMPILER, BrowseFile )
PROPERTYNAME( WIN32_2010_COMPILER, WarningLevel )
PROPERTYNAME( WIN32_2010_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( WIN32_2010_COMPILER, Detect64bitPortabilityIssues )
PROPERTYNAME( WIN32_2010_COMPILER, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_COMPILER, DebugInformationFormat )
PROPERTYNAME( WIN32_2010_COMPILER, CompileAs )
PROPERTYNAME( WIN32_2010_COMPILER, ForceIncludes )
PROPERTYNAME( WIN32_2010_COMPILER, ShowIncludes )
PROPERTYNAME( WIN32_2010_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_COMPILER, UseFullPaths )
PROPERTYNAME( WIN32_2010_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( WIN32_2010_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, PreschedulingOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( WIN32_2010_COMPILER, RegisterReservation )
PROPERTYNAME( WIN32_2010_COMPILER, Stalls )
PROPERTYNAME( WIN32_2010_COMPILER, CallAttributedProfiling )
PROPERTYNAME( WIN32_2010_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( WIN32_2010_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( WIN32_2010_COMPILER, ResolveUsingReferences )
PROPERTYNAME( WIN32_2010_COMPILER, OmitFramePointers )
PROPERTYNAME( WIN32_2010_COMPILER, CallingConvention )
PROPERTYNAME( WIN32_2010_COMPILER, ForceUsing )
PROPERTYNAME( WIN32_2010_COMPILER, ErrorReporting )
PROPERTYNAME( WIN32_2010_COMPILER, CommonLanguageRuntimeSupport )
PROPERTYNAME( WIN32_2010_COMPILER, MultiProcessorCompilation )
PROPERTYNAME( WIN32_2010_COMPILER, UseUnicodeForAssemblerListing )
PROPERTYNAME( WIN32_2010_COMPILER, IgnoreStandardIncludePaths )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessToAFile )
PROPERTYNAME( WIN32_2010_COMPILER, PreprocessSuppressLineNumbers )
PROPERTYNAME( WIN32_2010_COMPILER, CreateHotpatchableImage )
PROPERTYNAME( WIN32_2010_COMPILER, BrowseInformationFile )
PROPERTYNAME( WIN32_2010_COMPILER, ForcedIncludeFile )
PROPERTYNAME( WIN32_2010_COMPILER, ForcedUsingFile )
PROPERTYNAME( WIN32_2010_COMPILER, OmitDefaultLibraryName )
PROPERTYNAME( WIN32_2010_COMPILER, InternalCompilerErrorReporting )
PROPERTYNAME( WIN32_2010_COMPILER, TreatSpecificWarningsAsErrors )
PROPERTYNAME( WIN32_2010_COMPILER, GCC_ExtraCompilerFlags )
PROPERTYNAME( WIN32_2010_COMPILER, GCC_ExtraCxxCompilerFlags )
PROPERTYNAME( WIN32_2010_COMPILER, SymbolVisibility )
PROPERTYNAME( WIN32_2010_COMPILER, OptimizerLevel )
// Intellisense
PROPERTYNAME( WIN32_2010_INTELLISENSE, NMakePreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_INTELLISENSE, NMakeIncludeSearchPath )
PROPERTYNAME( WIN32_2010_INTELLISENSE, NMakeForcedIncludes )
PROPERTYNAME( WIN32_2010_INTELLISENSE, NMakeAssemblySearchPath )
PROPERTYNAME( WIN32_2010_INTELLISENSE, NMakeForcedUsingAssemblies )
PROPERTYNAME( WIN32_2010_INTELLISENSE, AdditionalOptions )
// Librarian
PROPERTYNAME( WIN32_2010_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_LIBRARIAN, OutputFile )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_2010_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( WIN32_2010_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_2010_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( WIN32_2010_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( WIN32_2010_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( WIN32_2010_LIBRARIAN, TargetMachine )
PROPERTYNAME( WIN32_2010_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( WIN32_2010_LINKER, IgnoreImportLibrary )
PROPERTYNAME( WIN32_2010_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalOptions )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_LINKER, ShowProgress )
PROPERTYNAME( WIN32_2010_LINKER, OutputFile )
PROPERTYNAME( WIN32_2010_LINKER, Version )
PROPERTYNAME( WIN32_2010_LINKER, EnableIncrementalLinking )
PROPERTYNAME( WIN32_2010_LINKER, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( WIN32_2010_LINKER, GenerateManifest )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( WIN32_2010_LINKER, ModuleDefinitionFile )
PROPERTYNAME( WIN32_2010_LINKER, GenerateDebugInfo )
PROPERTYNAME( WIN32_2010_LINKER, DebuggableAssembly )
PROPERTYNAME( WIN32_2010_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( WIN32_2010_LINKER, GenerateMapFile )
PROPERTYNAME( WIN32_2010_LINKER, MapFileName )
PROPERTYNAME( WIN32_2010_LINKER, SubSystem )
PROPERTYNAME( WIN32_2010_LINKER, EnableLargeAddresses )
PROPERTYNAME( WIN32_2010_LINKER, MapExports )
PROPERTYNAME( WIN32_2010_LINKER, StackReserveSize )
PROPERTYNAME( WIN32_2010_LINKER, StackCommitSize )
PROPERTYNAME( WIN32_2010_LINKER, References )
PROPERTYNAME( WIN32_2010_LINKER, EnableCOMDATFolding )
PROPERTYNAME( WIN32_2010_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( WIN32_2010_LINKER, EntryPoint )
PROPERTYNAME( WIN32_2010_LINKER, NoEntryPoint )
PROPERTYNAME( WIN32_2010_LINKER, SetChecksum )
PROPERTYNAME( WIN32_2010_LINKER, BaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, ImportLibrary )
PROPERTYNAME( WIN32_2010_LINKER, TargetMachine )
PROPERTYNAME( WIN32_2010_LINKER, FixedBaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, ErrorReporting )
PROPERTYNAME( WIN32_2010_LINKER, FunctionOrder )
PROPERTYNAME( WIN32_2010_LINKER, LinkLibraryDependencies )
PROPERTYNAME( WIN32_2010_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( WIN32_2010_LINKER, ForceSymbolReferences )
PROPERTYNAME( WIN32_2010_LINKER, StripPrivateSymbols )
PROPERTYNAME( WIN32_2010_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( WIN32_2010_LINKER, MergeSections )
PROPERTYNAME( WIN32_2010_LINKER, RegisterOutput )
PROPERTYNAME( WIN32_2010_LINKER, AddModuleToAssembly )
PROPERTYNAME( WIN32_2010_LINKER, EmbedManagedResourceFile )
PROPERTYNAME( WIN32_2010_LINKER, DelayLoadedDLLs )
PROPERTYNAME( WIN32_2010_LINKER, AssemblyLinkResource )
PROPERTYNAME( WIN32_2010_LINKER, ManifestFile )
PROPERTYNAME( WIN32_2010_LINKER, AdditionalManifestDependencies )
PROPERTYNAME( WIN32_2010_LINKER, AllowIsolation )
PROPERTYNAME( WIN32_2010_LINKER, HeapReserveSize )
PROPERTYNAME( WIN32_2010_LINKER, HeapCommitSize )
PROPERTYNAME( WIN32_2010_LINKER, TerminalServer )
PROPERTYNAME( WIN32_2010_LINKER, SwapRunFromCD )
PROPERTYNAME( WIN32_2010_LINKER, SwapRunFromNetwork )
PROPERTYNAME( WIN32_2010_LINKER, Driver )
PROPERTYNAME( WIN32_2010_LINKER, OptimizeForWindows98 )
PROPERTYNAME( WIN32_2010_LINKER, MIDLCommands )
PROPERTYNAME( WIN32_2010_LINKER, IgnoreEmbeddedIDL )
PROPERTYNAME( WIN32_2010_LINKER, MergeIDLBaseFileName )
PROPERTYNAME( WIN32_2010_LINKER, TypeLibrary )
PROPERTYNAME( WIN32_2010_LINKER, TypeLibResourceID )
PROPERTYNAME( WIN32_2010_LINKER, TurnOffAssemblyGeneration )
PROPERTYNAME( WIN32_2010_LINKER, DelayLoadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, Profile )
PROPERTYNAME( WIN32_2010_LINKER, CLRThreadAttribute )
PROPERTYNAME( WIN32_2010_LINKER, CLRImageType )
PROPERTYNAME( WIN32_2010_LINKER, KeyFile )
PROPERTYNAME( WIN32_2010_LINKER, KeyContainer )
PROPERTYNAME( WIN32_2010_LINKER, DelaySign )
PROPERTYNAME( WIN32_2010_LINKER, CLRUnmanagedCodeCheck )
PROPERTYNAME( WIN32_2010_LINKER, PerUserRedirection )
PROPERTYNAME( WIN32_2010_LINKER, LinkStatus )
PROPERTYNAME( WIN32_2010_LINKER, PreventDllBinding )
PROPERTYNAME( WIN32_2010_LINKER, TreatLinkerWarningsAsErrors )
PROPERTYNAME( WIN32_2010_LINKER, ForceFileOutput )
PROPERTYNAME( WIN32_2010_LINKER, CreateHotpatchableImage )
PROPERTYNAME( WIN32_2010_LINKER, SpecifySectionAttributes )
PROPERTYNAME( WIN32_2010_LINKER, EnableUserAccountControl )
PROPERTYNAME( WIN32_2010_LINKER, UACExecutionLevel )
PROPERTYNAME( WIN32_2010_LINKER, UACBypassUIProtection )
PROPERTYNAME( WIN32_2010_LINKER, MinimumRequiredVersion )
PROPERTYNAME( WIN32_2010_LINKER, RandomizedBaseAddress )
PROPERTYNAME( WIN32_2010_LINKER, DataExecutionPrevention )
PROPERTYNAME( WIN32_2010_LINKER, UnloaddelayloadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, NobinddelayloadedDLL )
PROPERTYNAME( WIN32_2010_LINKER, SectionAlignment )
PROPERTYNAME( WIN32_2010_LINKER, PreserveLastErrorCodeforPInvokeCalls )
PROPERTYNAME( WIN32_2010_LINKER, ImageHasSafeExceptionHandlers )
PROPERTYNAME( WIN32_2010_LINKER, GCC_ExtraLinkerFlags )
PROPERTYNAME( WIN32_2010_LINKER, POSIX_RPaths )
PROPERTYNAME( WIN32_2010_LINKER, SystemLibraries )
PROPERTYNAME( WIN32_2010_LINKER, SystemFrameworks )
PROPERTYNAME( WIN32_2010_LINKER, LocalFrameworks )
PROPERTYNAME( WIN32_2010_LINKER, DisableLinkerDeadCodeElimination )
// Manifest
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, VerboseOutput )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AssemblyIdentity )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UseFAT32WorkAround )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AdditionalManifestFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, InputResourceManifests )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, EmbedManifest )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, OutputManifestFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ManifestResourceFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateCatalogFiles )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, DependencyInformationFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, TypeLibraryFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, RegistrarScriptFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ComponentFileName )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, ReplacementsFile )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UpdateFileHashes )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, UpdateFileHashesSearchPath )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, AdditionalOptions )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateManifestFromManagedAssembly )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, SuppressDependencyElement )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, GenerateCategoryTags )
PROPERTYNAME( WIN32_2010_MANIFESTTOOL, EnableDPIAwareness )
// XML Document Generator
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, UseUNICODEResponseFiles )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, ValidateIntelliSense )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, AdditionalDocumentFiles )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, OutputDocumentFile )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, DocumentLibraryDependencies )
PROPERTYNAME( WIN32_2010_XMLDOCUMENTGENERATOR, AdditionalOptions )
// Browse Information
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, AdditionalOptions )
PROPERTYNAME( WIN32_2010_BROWSEINFORMATION, PreserveSBRFiles )
// Resources
PROPERTYNAME( WIN32_2010_RESOURCES, PreprocessorDefinitions )
PROPERTYNAME( WIN32_2010_RESOURCES, Culture )
PROPERTYNAME( WIN32_2010_RESOURCES, AdditionalIncludeDirectories )
PROPERTYNAME( WIN32_2010_RESOURCES, IgnoreStandardIncludePath )
PROPERTYNAME( WIN32_2010_RESOURCES, ShowProgress )
PROPERTYNAME( WIN32_2010_RESOURCES, ResourceFileName )
PROPERTYNAME( WIN32_2010_RESOURCES, AdditionalOptions )
// Pre Build
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, Description )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_PREBUILDEVENT, UseInBuild )
// Pre Link
PROPERTYNAME( WIN32_2010_PRELINKEVENT, Description )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_PRELINKEVENT, UseInBuild )
// Post Build
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, Description )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( WIN32_2010_POSTBUILDEVENT, UseInBuild )
// Custom Build
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, AdditionalDependencies_Proj )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, OrderOnlyFileDependencies )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, OrderOnlyProjectDependencies )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, PotentialOutputs )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, ExecuteAfter )
PROPERTYNAME( WIN32_2010_CUSTOMBUILDSTEP, ExecuteBefore )
+329
View File
@@ -0,0 +1,329 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Xbox360PropertyNames[] =
{
#include "projectgenerator_xbox360.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetXbox360ProjectGenerator()
{
CProjectGenerator_Xbox360 *pNew = new CProjectGenerator_Xbox360();
return pNew->GetProjectGenerator();
}
CProjectGenerator_Xbox360::CProjectGenerator_Xbox360()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( "xbox360.def", s_Xbox360PropertyNames );
m_pVCProjGenerator->AddProjectWriter( this );
}
bool CProjectGenerator_Xbox360::WriteFile( CProjectFile *pFile )
{
m_XMLWriter.PushNode( "File" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "RelativePath=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::WriteFolder( CProjectFolder *pFolder )
{
m_XMLWriter.PushNode( "Filter" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s\"", m_XMLWriter.FixupXMLString( pFolder->m_Name.Get() ).Get() ) );
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex] ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex] ) )
return false;
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "FileConfiguration" );
}
else
{
m_XMLWriter.PushNode( "Configuration" );
}
const char *pOutputName = "???";
if ( !V_stricmp_fast( pConfig->m_Name.Get(), "debug" ) )
{
pOutputName = "Debug|Xbox 360";
}
else if ( !V_stricmp_fast( pConfig->m_Name.Get(), "release" ) )
{
pOutputName = "Release|Xbox 360";
}
else
{
return false;
}
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s\"", pOutputName ) );
// write configuration properties
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] );
}
if ( !pConfig->m_bIsFileConfig && pConfig->m_PropertyStates.m_Properties.Count() )
{
WriteProperty( NULL, "UseOfMFC", "-1" );
WriteProperty( NULL, "UseOfATL", "0" );
}
if ( !WriteTool( "VCPreBuildEventTool", pConfig->GetPreBuildEventTool() ) )
return false;
if ( !WriteTool( "VCCustomBuildTool", pConfig->GetCustomBuildTool() ) )
return false;
if ( !WriteNULLTool( "VCXMLDataGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCWebServiceProxyGeneratorTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCMIDLTool", pConfig ) )
return false;
if ( !WriteTool( "VCCLX360CompilerTool", pConfig->GetCompilerTool() ) )
return false;
if ( !WriteNULLTool( "VCManagedResourceCompilerTool", pConfig ) )
return false;
if ( !WriteNULLTool( "VCResourceCompilerTool", pConfig ) )
return false;
if ( !WriteTool( "VCPreLinkEventTool", pConfig->GetPreLinkEventTool() ) )
return false;
if ( !WriteTool( "VCX360LinkerTool", pConfig->GetLinkerTool() ) )
return false;
if ( !WriteTool( "VCLibrarianTool", pConfig->GetLibrarianTool() ) )
return false;
if ( !WriteNULLTool( "VCALinkTool", pConfig ) )
return false;
if ( !WriteTool( "VCX360ImageTool", pConfig->GetXboxImageTool() ) )
return false;
if ( !WriteTool( "VCBscMakeTool", pConfig->GetBrowseInfoTool() ) )
return false;
if ( !WriteTool( "VCX360DeploymentTool", pConfig->GetXboxDeploymentTool() ) )
return false;
if ( !WriteTool( "VCPostBuildEventTool", pConfig->GetPostBuildEventTool() ) )
return false;
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "DebuggerTool" );
m_XMLWriter.PopNode();
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::WriteToXML()
{
m_XMLWriter.PushNode( "VisualStudioProject" );
m_XMLWriter.AddNodeProperty( "ProjectType=\"Visual C++\"" );
m_XMLWriter.AddNodeProperty( "Version=\"8.00\"" );
m_XMLWriter.AddNodeProperty( CFmtStrMax( "Name=\"%s\"", m_pVCProjGenerator->GetProjectName() ) );
m_XMLWriter.AddNodeProperty( "ProjectGUID", CFmtStr( "{%s}", m_pVCProjGenerator->GetGUIDString() ) );
m_XMLWriter.PushNode( "Platforms" );
m_XMLWriter.PushNode( "Platform" );
m_XMLWriter.AddNodeProperty( "Name=\"Xbox 360\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ToolFiles" );
m_XMLWriter.PopNode();
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
// write the root configurations
m_XMLWriter.PushNode( "Configurations" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "References" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "Files" );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pRootFolder->m_Folders[iIndex] ) )
return false;
}
for ( int iIndex = pRootFolder->m_Files.Head(); iIndex != pRootFolder->m_Files.InvalidIndex(); iIndex = pRootFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pRootFolder->m_Files[iIndex] ) )
return false;
}
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::Save( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename, false, g_pVPC->IsForceGenerate() ) )
return false;
bool bValid = WriteToXML();
m_XMLWriter.Close();
return bValid;
}
bool CProjectGenerator_Xbox360::WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig )
{
if ( pConfig->m_bIsFileConfig )
return true;
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.AddNodeProperty( CFmtStr( "Name=\"%s\"", pToolName ) );
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::WriteTool( const char *pToolName, const CProjectTool *pProjectTool )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
m_XMLWriter.PushNode( "Tool" );
m_XMLWriter.AddNodeProperty( CFmtStr( "Name=\"%s\"", pToolName ) );
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] );
}
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360::WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, pOutputValue ) );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
if ( pPropertyState && !pPropertyState->m_pToolProperty->m_bIgnoreForOutput )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, bEnabled ? "true" : "false" ) );
}
break;
case PT_STRING:
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ).Get() ) );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.AddNodeProperty( CFmtStrMax( "%s=\"%s\"", pOutputName, pPropertyState->m_StringValue.Get() ) );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Xbox360: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
+41
View File
@@ -0,0 +1,41 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_XBOX360_H
#define PROJECTGENERATOR_XBOX360_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Xbox360Properties_e
{
#include "projectgenerator_xbox360.inc"
};
class CProjectGenerator_Xbox360 : public IVCProjWriter
{
public:
CProjectGenerator_Xbox360();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
bool WriteToXML();
bool WriteFolder( CProjectFolder *pFolder );
bool WriteFile( CProjectFile *pFile );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
CXMLWriter m_XMLWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_XBOX360_H
+195
View File
@@ -0,0 +1,195 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( XBOX360_GENERAL, ExcludedFromBuild )
PROPERTYNAME( XBOX360_GENERAL, OutputDirectory )
PROPERTYNAME( XBOX360_GENERAL, IntermediateDirectory )
PROPERTYNAME( XBOX360_GENERAL, ConfigurationType )
PROPERTYNAME( XBOX360_GENERAL, CharacterSet )
PROPERTYNAME( XBOX360_GENERAL, WholeProgramOptimization )
PROPERTYNAME( XBOX360_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( XBOX360_GENERAL, BuildLogFile )
PROPERTYNAME( XBOX360_GENERAL, InheritedProjectPropertySheets )
PROPERTYNAME( XBOX360_GENERAL, DisableFastUpToDateCheck )
PROPERTYNAME( XBOX360_GENERAL, AdditionalProjectDependencies )
PROPERTYNAME( XBOX360_GENERAL, AdditionalOutputFiles )
// Debugging
PROPERTYNAME( XBOX360_DEBUGGING, Command )
PROPERTYNAME( XBOX360_DEBUGGING, CommandArguments )
PROPERTYNAME( XBOX360_DEBUGGING, RemoteMachine )
// Compiler
PROPERTYNAME( XBOX360_COMPILER, AdditionalOptions )
PROPERTYNAME( XBOX360_COMPILER, Optimization )
PROPERTYNAME( XBOX360_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( XBOX360_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( XBOX360_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( XBOX360_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( XBOX360_COMPILER, WholeProgramOptimization )
PROPERTYNAME( XBOX360_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( XBOX360_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, IgnoreStandardIncludePath )
PROPERTYNAME( XBOX360_COMPILER, GeneratePreprocessedFile )
PROPERTYNAME( XBOX360_COMPILER, KeepComments )
PROPERTYNAME( XBOX360_COMPILER, EnableStringPooling )
PROPERTYNAME( XBOX360_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( XBOX360_COMPILER, EnableCPPExceptions )
PROPERTYNAME( XBOX360_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( XBOX360_COMPILER, SmallerTypeCheck )
PROPERTYNAME( XBOX360_COMPILER, RuntimeLibrary )
PROPERTYNAME( XBOX360_COMPILER, StructMemberAlignment )
PROPERTYNAME( XBOX360_COMPILER, BufferSecurityCheck )
PROPERTYNAME( XBOX360_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( XBOX360_COMPILER, FloatingPointModel )
PROPERTYNAME( XBOX360_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( XBOX360_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( XBOX360_COMPILER, DefaultCharUnsigned )
PROPERTYNAME( XBOX360_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( XBOX360_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( XBOX360_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( XBOX360_COMPILER, OpenMPSupport )
PROPERTYNAME( XBOX360_COMPILER, CreateUsePrecompiledHeader )
PROPERTYNAME( XBOX360_COMPILER, CreateUsePCHThroughFile )
PROPERTYNAME( XBOX360_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( XBOX360_COMPILER, ExpandAttributedSource )
PROPERTYNAME( XBOX360_COMPILER, AssemblerOutput )
PROPERTYNAME( XBOX360_COMPILER, ASMListLocation )
PROPERTYNAME( XBOX360_COMPILER, ObjectFileName )
PROPERTYNAME( XBOX360_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( XBOX360_COMPILER, EnableBrowseInformation )
PROPERTYNAME( XBOX360_COMPILER, BrowseFile )
PROPERTYNAME( XBOX360_COMPILER, WarningLevel )
PROPERTYNAME( XBOX360_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( XBOX360_COMPILER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_COMPILER, DebugInformationFormat )
PROPERTYNAME( XBOX360_COMPILER, CompileAs )
PROPERTYNAME( XBOX360_COMPILER, ForceIncludes )
PROPERTYNAME( XBOX360_COMPILER, ShowIncludes )
PROPERTYNAME( XBOX360_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( XBOX360_COMPILER, UseFullPaths )
PROPERTYNAME( XBOX360_COMPILER, OmitDefaultLibraryNames )
PROPERTYNAME( XBOX360_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( XBOX360_COMPILER, PreschedulingOptimization )
PROPERTYNAME( XBOX360_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( XBOX360_COMPILER, RegisterReservation )
PROPERTYNAME( XBOX360_COMPILER, Stalls )
PROPERTYNAME( XBOX360_COMPILER, CallAttributedProfiling )
PROPERTYNAME( XBOX360_COMPILER, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_COMPILER, GenerateXMLDocumentationFiles )
PROPERTYNAME( XBOX360_COMPILER, XMLDocumentationFileName )
PROPERTYNAME( XBOX360_COMPILER, DisableSpecificWarnings )
// Librarian
PROPERTYNAME( XBOX360_LIBRARIAN, OutputFile )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( XBOX360_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( XBOX360_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_LIBRARIAN, IgnoreSpecificLibrary )
PROPERTYNAME( XBOX360_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( XBOX360_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( XBOX360_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( XBOX360_LINKER, IgnoreImportLibrary )
PROPERTYNAME( XBOX360_LINKER, AdditionalOptions )
PROPERTYNAME( XBOX360_LINKER, AdditionalDependencies )
PROPERTYNAME( XBOX360_LINKER, ShowProgress )
PROPERTYNAME( XBOX360_LINKER, OutputFile )
PROPERTYNAME( XBOX360_LINKER, EnableIncrementalLinking )
PROPERTYNAME( XBOX360_LINKER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_LINKER, IgnoreSpecificLibrary )
PROPERTYNAME( XBOX360_LINKER, ModuleDefinitionFile )
PROPERTYNAME( XBOX360_LINKER, GenerateDebugInfo )
PROPERTYNAME( XBOX360_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( XBOX360_LINKER, GenerateMapFile )
PROPERTYNAME( XBOX360_LINKER, MapFileName )
PROPERTYNAME( XBOX360_LINKER, MapExports )
PROPERTYNAME( XBOX360_LINKER, StackReserveSize )
PROPERTYNAME( XBOX360_LINKER, StackCommitSize )
PROPERTYNAME( XBOX360_LINKER, References )
PROPERTYNAME( XBOX360_LINKER, EnableCOMDATFolding )
PROPERTYNAME( XBOX360_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( XBOX360_LINKER, EntryPoint )
PROPERTYNAME( XBOX360_LINKER, NoEntryPoint )
PROPERTYNAME( XBOX360_LINKER, SetChecksum )
PROPERTYNAME( XBOX360_LINKER, BaseAddress )
PROPERTYNAME( XBOX360_LINKER, ImportLibrary )
PROPERTYNAME( XBOX360_LINKER, FixedBaseAddress )
PROPERTYNAME( XBOX360_LINKER, ErrorReporting )
PROPERTYNAME( XBOX360_LINKER, FunctionOrder )
PROPERTYNAME( XBOX360_LINKER, Version )
PROPERTYNAME( XBOX360_LINKER, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( XBOX360_LINKER, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_LINKER, ForceSymbolReferences )
PROPERTYNAME( XBOX360_LINKER, StripPrivateSymbols )
PROPERTYNAME( XBOX360_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( XBOX360_LINKER, MergeSections )
// Browse Information
PROPERTYNAME( XBOX360_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( XBOX360_BROWSEINFORMATION, AdditionalOptions )
// Pre Build
PROPERTYNAME( XBOX360_PREBUILDEVENT, Description )
PROPERTYNAME( XBOX360_PREBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_PREBUILDEVENT, ExcludedFromBuild )
// Pre Link
PROPERTYNAME( XBOX360_PRELINKEVENT, Description )
PROPERTYNAME( XBOX360_PRELINKEVENT, CommandLine )
PROPERTYNAME( XBOX360_PRELINKEVENT, ExcludedFromBuild )
// Post Build
PROPERTYNAME( XBOX360_POSTBUILDEVENT, Description )
PROPERTYNAME( XBOX360_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_POSTBUILDEVENT, ExcludedFromBuild )
// Custom Build
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( XBOX360_CUSTOMBUILDSTEP, AdditionalDependencies )
// Image Conversion
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, OutputFile )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, ProjectDefaults )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, WorkspaceSize )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, ExportByName )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, OpticalDiscDriveMapping )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, PAL50Incompatible )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, TitleID )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, LANKey )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, BaseAddress )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, HeapSize )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, AdditionalSections )
PROPERTYNAME( XBOX360_XBOX360IMAGECONVERSION, AdditionalOptions )
// Console Deployment
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, SuppressStartupBanner )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentRoot )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentFiles )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, Progress )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, ForceCopy )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, DeploymentType )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, EmulationType )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, Layout )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, LayoutRoot )
PROPERTYNAME( XBOX360_CONSOLEDEPLOYMENT, AdditionalOptions )
@@ -0,0 +1,609 @@
//========= Copyright © 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
#undef PROPERTYNAME
#define PROPERTYNAME( X, Y ) { X##_##Y, #X, #Y },
static PropertyName_t s_Xbox360PropertyNames_2010[] =
{
#include "projectgenerator_xbox360_2010.inc"
{ -1, NULL, NULL }
};
IBaseProjectGenerator* GetXbox360ProjectGenerator_2010()
{
CProjectGenerator_Xbox360_2010 *pNew = new CProjectGenerator_Xbox360_2010();
return pNew->GetProjectGenerator();
}
CProjectGenerator_Xbox360_2010::CProjectGenerator_Xbox360_2010()
{
m_pVCProjGenerator = new CVCProjGenerator();
m_pVCProjGenerator->SetupGeneratorDefinition( "xbox360_2010.def", s_Xbox360PropertyNames_2010 );
m_pVCProjGenerator->AddProjectWriter( this );
}
enum TypeKeyNames_e
{
TKN_LIBRARY = 0,
TKN_INCLUDE,
TKN_COMPILE,
TKN_RESOURCECOMPILE,
TKN_CUSTOMBUILD,
TKN_NONE,
TKN_MAX_COUNT,
};
static const char *s_TypeKeyNames[] =
{
"Library",
"ClInclude",
"ClCompile",
"ResourceCompile",
"CustomBuild",
"None"
};
const char *CProjectGenerator_Xbox360_2010::GetKeyNameForFile( CProjectFile *pFile )
{
COMPILE_TIME_ASSERT( ARRAYSIZE( s_TypeKeyNames ) == TKN_MAX_COUNT );
const char *pExtension = V_GetFileExtension( pFile->m_Name.Get() );
const char *pKeyName = s_TypeKeyNames[TKN_NONE];
if ( pExtension )
{
if ( pFile->m_Configs.Count() && pFile->m_Configs[0]->GetCustomBuildTool() )
{
pKeyName = s_TypeKeyNames[TKN_CUSTOMBUILD];
}
else if ( IsCFileExtension( pExtension ) )
{
pKeyName = s_TypeKeyNames[TKN_COMPILE];
}
else if ( IsHFileExtension( pExtension ) )
{
pKeyName = s_TypeKeyNames[TKN_INCLUDE];
}
else if ( !V_stricmp_fast( pExtension, "lib" ) )
{
pKeyName = s_TypeKeyNames[TKN_LIBRARY];
}
else if ( !V_stricmp_fast( pExtension, "rc" ) )
{
pKeyName = s_TypeKeyNames[TKN_RESOURCECOMPILE];
}
}
return pKeyName;
}
bool CProjectGenerator_Xbox360_2010::WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration )
{
if ( !pProjectTool )
return true;
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFile( CProjectFile *pFile, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp_fast( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( !pFile->m_Configs.Count() )
{
m_XMLWriter.PushNode( pKeyName, CFmtStrMax( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLWriter.PopNode();
}
else
{
m_XMLWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
for ( int i = 0; i < pFile->m_Configs.Count(); i++ )
{
if ( !WriteConfiguration( pFile->m_Configs[i] ) )
return false;
}
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth )
{
if ( !nDepth )
{
m_XMLWriter.PushNode( "ItemGroup" );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFile( pFolder->m_Files[iIndex], pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolder( pFolder->m_Folders[iIndex], pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteConfiguration( CProjectConfiguration *pConfig )
{
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( "PropertyGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\" Label=\"Configuration\"", pConfig->m_Name.Get() ) );
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( pConfig->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
WriteProperty( NULL, false, NULL, "UseOfAtl", "false" );
m_XMLWriter.PopNode();
}
else
{
for ( int i = 0; i < pConfig->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pConfig->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !WriteProperty( &pConfig->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteTools( CProjectConfiguration *pConfig )
{
m_XMLWriter.PushNode( "ItemDefinitionGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\"", pConfig->m_Name.Get() ) );
if ( !WriteTool( "PreBuildEvent", pConfig->GetPreBuildEventTool(), pConfig ) )
return false;
if ( !WriteTool( "CustomBuildStep", pConfig->GetCustomBuildTool(), pConfig ) )
return false;
if ( !WriteTool( "ClCompile", pConfig->GetCompilerTool(), pConfig ) )
return false;
if ( !WriteTool( "PreLinkEvent", pConfig->GetPreLinkEventTool(), pConfig ) )
return false;
if ( !WriteTool( "Link", pConfig->GetLinkerTool(), pConfig ) )
return false;
if ( !WriteTool( "Lib", pConfig->GetLibrarianTool(), pConfig ) )
return false;
if ( !WriteTool( "ImageXex", pConfig->GetXboxImageTool(), pConfig ) )
return false;
if ( !WriteTool( "Bscmake", pConfig->GetBrowseInfoTool(), pConfig ) )
return false;
if ( !WriteTool( "Deploy", pConfig->GetXboxDeploymentTool(), pConfig ) )
return false;
if ( !WriteTool( "PostBuildEvent", pConfig->GetPostBuildEventTool(), pConfig ) )
return false;
m_XMLWriter.PopNode();
return true;
}
bool CProjectGenerator_Xbox360_2010::WritePrimaryXML( const char *pOutputFilename )
{
if ( !m_XMLWriter.Open( pOutputFilename, true, g_pVPC->IsForceGenerate() ) )
return false;
m_XMLWriter.PushNode( "Project", "DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
m_XMLWriter.PushNode( "ItemGroup", "Label=\"ProjectConfigurations\"" );
CUtlVector< CUtlString > configurationNames;
m_pVCProjGenerator->GetAllConfigurationNames( configurationNames );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ProjectConfiguration", CFmtStr( "Include=\"%s|Xbox 360\"", configurationNames[i].Get() ) );
m_XMLWriter.WriteLineNode( "Configuration", "", configurationNames[i].Get() );
m_XMLWriter.WriteLineNode( "Platform", "", "Xbox 360" );
m_XMLWriter.PopNode();
}
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"Globals\"" );
m_XMLWriter.WriteLineNode( "ProjectName", "", m_pVCProjGenerator->GetProjectName() );
m_XMLWriter.WriteLineNode( "ProjectGuid", "", CFmtStr( "{%s}", m_pVCProjGenerator->GetGUIDString() ) );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\"" );
m_XMLWriter.PopNode();
// write the root configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteConfiguration( pConfiguration ) )
return false;
}
}
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionSettings\"" );
m_XMLWriter.PopNode();
for ( int i = 0; i < configurationNames.Count(); i++ )
{
m_XMLWriter.PushNode( "ImportGroup", CFmtStr( "Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\" Label=\"PropertySheets\"", configurationNames[i].Get() ) );
m_XMLWriter.PushNode( "Import" );
m_XMLWriter.AddNodeProperty( "Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\"" );
m_XMLWriter.AddNodeProperty( "Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\"" );
m_XMLWriter.AddNodeProperty( "Label=\"LocalAppDataPlatform\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
}
m_XMLWriter.PushNode( "PropertyGroup", "Label=\"UserMacros\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "PropertyGroup" );
m_XMLWriter.WriteLineNode( "_ProjectFileVersion", "", "10.0.30319.1" );
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
for ( int j = 0; j < pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder.Count(); j++ )
{
int sortedIndex = pConfiguration->m_PropertyStates.m_PropertiesInOutputOrder[j];
if ( !pConfiguration->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pConfiguration->m_PropertyStates.m_Properties[sortedIndex], true, pConfiguration->m_Name.Get() ) )
return false;
}
if ( !WritePropertyGroupTool( pConfiguration->GetPreBuildEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPreLinkEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLinkerTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetLibrarianTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetPostBuildEventTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetXboxImageTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetXboxDeploymentTool(), pConfiguration ) )
return false;
if ( !WritePropertyGroupTool( pConfiguration->GetCustomBuildTool(), pConfiguration ) )
return false;
}
}
m_XMLWriter.PopNode();
// write the tool configurations
for ( int i = 0; i < configurationNames.Count(); i++ )
{
CProjectConfiguration *pConfiguration = NULL;
if ( m_pVCProjGenerator->GetRootConfiguration( configurationNames[i].Get(), &pConfiguration ) )
{
if ( !WriteTools( pConfiguration ) )
return false;
}
}
// write root folders
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolder( m_pVCProjGenerator->GetRootFolder(), s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLWriter.PushNode( "Import", "Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PushNode( "ImportGroup", "Label=\"ExtensionTargets\"" );
m_XMLWriter.PopNode();
m_XMLWriter.PopNode();
m_XMLWriter.Close();
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath )
{
CUtlString parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() ).Get();
CUtlString lowerParentPath = parentPath;
lowerParentPath.ToLower();
MD5Context_t ctx;
unsigned char digest[MD5_DIGEST_LENGTH];
V_memset( &ctx, 0, sizeof( ctx ) );
V_memset( digest, 0, sizeof( digest ) );
MD5Init( &ctx );
MD5Update( &ctx, (unsigned char *)lowerParentPath.Get(), V_strlen( lowerParentPath.Get() ) );
MD5Final( digest, &ctx );
char szMD5[64];
V_binarytohex( digest, MD5_DIGEST_LENGTH, szMD5, sizeof( szMD5 ) );
V_strupper( szMD5 );
char szGUID[MAX_PATH];
V_snprintf( szGUID, sizeof( szGUID ), "{%8.8s-%4.4s-%4.4s-%4.4s-%12.12s}", szMD5, &szMD5[8], &szMD5[12], &szMD5[16], &szMD5[20] );
m_XMLFilterWriter.PushNode( "Filter", CFmtStr( "Include=\"%s\"", parentPath.Get() ) );
m_XMLFilterWriter.WriteLineNode( "UniqueIdentifier", "", szGUID );
m_XMLFilterWriter.PopNode();
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get() ) )
return false;
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName )
{
const char *pKeyName = GetKeyNameForFile( pFile );
if ( V_stricmp_fast( pFileTypeName, pKeyName ) )
{
// skip it
return true;
}
if ( pParentPath )
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.WriteLineNode( "Filter", "", pParentPath );
m_XMLFilterWriter.PopNode();
}
else
{
m_XMLFilterWriter.PushNode( pKeyName, CFmtStr( "Include=\"%s\"", pFile->m_Name.Get() ) );
m_XMLFilterWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth )
{
CUtlString parentPath;
if ( pParentPath )
{
parentPath = CFmtStr( "%s%s%s", pParentPath, pParentPath[0] ? "\\" : "", pFolder->m_Name.Get() );
}
if ( !nDepth )
{
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
}
for ( int iIndex = pFolder->m_Files.Head(); iIndex != pFolder->m_Files.InvalidIndex(); iIndex = pFolder->m_Files.Next( iIndex ) )
{
if ( !WriteFileToSecondaryXML( pFolder->m_Files[iIndex], parentPath.Get(), pFileTypeName ) )
return false;
}
for ( int iIndex = pFolder->m_Folders.Head(); iIndex != pFolder->m_Folders.InvalidIndex(); iIndex = pFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderContentsToSecondaryXML( pFolder->m_Folders[iIndex], parentPath.Get(), pFileTypeName, nDepth+1 ) )
return false;
}
if ( !nDepth )
{
m_XMLFilterWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteSecondaryXML( const char *pOutputFilename )
{
if ( !m_XMLFilterWriter.Open( pOutputFilename, true, g_pVPC->IsForceGenerate() ) )
return false;
m_XMLFilterWriter.PushNode( "Project", "ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"" );
// write the root folders
m_XMLFilterWriter.PushNode( "ItemGroup", NULL );
CProjectFolder *pRootFolder = m_pVCProjGenerator->GetRootFolder();
for ( int iIndex = pRootFolder->m_Folders.Head(); iIndex != pRootFolder->m_Folders.InvalidIndex(); iIndex = pRootFolder->m_Folders.Next( iIndex ) )
{
if ( !WriteFolderToSecondaryXML( pRootFolder->m_Folders[iIndex], "" ) )
return false;
}
m_XMLFilterWriter.PopNode();
// write folder contents
for ( int i = 0; i < TKN_MAX_COUNT; i++ )
{
if ( !WriteFolderContentsToSecondaryXML( pRootFolder, NULL, s_TypeKeyNames[i], 0 ) )
return false;
}
m_XMLFilterWriter.PopNode();
m_XMLFilterWriter.Close();
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig )
{
if ( !pProjectTool )
{
// not an error, some tools n/a for a config
return true;
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PushNode( pToolName, NULL );
}
for ( int i = 0; i < pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder.Count(); i++ )
{
int sortedIndex = pProjectTool->m_PropertyStates.m_PropertiesInOutputOrder[i];
if ( !pConfig->m_bIsFileConfig )
{
if ( pProjectTool->m_PropertyStates.m_Properties[sortedIndex].m_pToolProperty->m_bEmitAsGlobalProperty )
continue;
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex] ) )
return false;
}
else
{
if ( !WriteProperty( &pProjectTool->m_PropertyStates.m_Properties[sortedIndex], true, pConfig->m_Name.Get() ) )
return false;
}
}
if ( !pConfig->m_bIsFileConfig )
{
m_XMLWriter.PopNode();
}
return true;
}
bool CProjectGenerator_Xbox360_2010::WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration, const char *pConfigName, const char *pOutputName, const char *pOutputValue )
{
if ( !pPropertyState )
{
m_XMLWriter.WriteLineNode( pOutputName, "", pOutputValue );
return true;
}
if ( !pOutputName )
{
pOutputName = pPropertyState->m_pToolProperty->m_OutputString.Get();
if ( !pOutputName[0] )
{
pOutputName = pPropertyState->m_pToolProperty->m_ParseString.Get();
if ( pOutputName[0] == '$' )
{
pOutputName++;
}
}
}
const char *pCondition = "";
CUtlString conditionString;
if ( bEmitConfiguration )
{
conditionString = CFmtStr( " Condition=\"'$(Configuration)|$(Platform)'=='%s|Xbox 360'\"", pConfigName );
pCondition = conditionString.Get();
}
if ( pPropertyState && !pPropertyState->m_pToolProperty->m_bIgnoreForOutput )
{
switch ( pPropertyState->m_pToolProperty->m_nType )
{
case PT_BOOLEAN:
{
bool bEnabled = Sys_StringToBool( pPropertyState->m_StringValue.Get() );
if ( pPropertyState->m_pToolProperty->m_bInvertOutput )
{
bEnabled ^= 1;
}
m_XMLWriter.WriteLineNode( pOutputName, pCondition, bEnabled ? "true" : "false" );
}
break;
case PT_STRING:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, m_XMLWriter.FixupXMLString( pPropertyState->m_StringValue.Get() ).Get() );
break;
case PT_LIST:
case PT_INTEGER:
m_XMLWriter.WriteLineNode( pOutputName, pCondition, pPropertyState->m_StringValue.Get() );
break;
case PT_IGNORE:
break;
default:
g_pVPC->VPCError( "CProjectGenerator_Xbox360_2010: WriteProperty, %s - not implemented", pOutputName );
}
}
return true;
}
bool CProjectGenerator_Xbox360_2010::Save( const char *pOutputFilename )
{
bool bValid = WritePrimaryXML( pOutputFilename );
if ( bValid )
{
bValid = WriteSecondaryXML( CFmtStr( "%s.filters", pOutputFilename ) );
if ( !bValid )
{
g_pVPC->VPCError( "Cannot save to the specified project '%s'", pOutputFilename );
}
}
return bValid;
}
@@ -0,0 +1,54 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef PROJECTGENERATOR_XBOX360_2010_H
#define PROJECTGENERATOR_XBOX360_2010_H
#ifdef _WIN32
#pragma once
#endif
#define PROPERTYNAME( X, Y ) X##_##Y,
enum Xbox360_2010_Properties_e
{
#include "projectgenerator_xbox360_2010.inc"
};
class CProjectGenerator_Xbox360_2010 : public IVCProjWriter
{
public:
CProjectGenerator_Xbox360_2010();
virtual CVCProjGenerator *GetProjectGenerator() OVERRIDE { return m_pVCProjGenerator; }
virtual bool Save( const char *pOutputFilename );
private:
// primary XML - foo.vcxproj
bool WritePrimaryXML( const char *pOutputFilename );
bool WriteFolder( CProjectFolder *pFolder, const char *pFileTypeName, int nDepth );
bool WriteFile( CProjectFile *pFile, const char *pFileTypeName );
bool WriteConfiguration( CProjectConfiguration *pConfig );
bool WriteTools( CProjectConfiguration *pConfig );
bool WriteProperty( const PropertyState_t *pPropertyState, bool bEmitConfiguration = false, const char *pConfigurationName = NULL, const char *pOutputName = NULL, const char *pValue = NULL );
bool WriteTool( const char *pToolName, const CProjectTool *pProjectTool, CProjectConfiguration *pConfig );
bool WriteNULLTool( const char *pToolName, const CProjectConfiguration *pConfig );
bool WritePropertyGroupTool( CProjectTool *pProjectTool, CProjectConfiguration *pConfiguration );
bool WritePropertyGroup();
// secondary XML - foo.vcxproj.filters
bool WriteSecondaryXML( const char *pOutputFilename );
bool WriteFolderToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath );
bool WriteFolderContentsToSecondaryXML( CProjectFolder *pFolder, const char *pParentPath, const char *pFileTypeName, int nDepth );
bool WriteFileToSecondaryXML( CProjectFile *pFile, const char *pParentPath, const char *pFileTypeName );
const char *GetKeyNameForFile( CProjectFile *pFile );
CXMLWriter m_XMLWriter;
CXMLWriter m_XMLFilterWriter;
CVCProjGenerator *m_pVCProjGenerator;
};
#endif // PROJECTGENERATOR_XBOX360_2010_H
@@ -0,0 +1,214 @@
//========= Copyright © 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Property Enumerations
//
//=====================================================================================//
// Config
PROPERTYNAME( XBOX360_2010_GENERAL, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_GENERAL, OutputDirectory )
PROPERTYNAME( XBOX360_2010_GENERAL, IntermediateDirectory )
PROPERTYNAME( XBOX360_2010_GENERAL, ConfigurationType )
PROPERTYNAME( XBOX360_2010_GENERAL, CharacterSet )
PROPERTYNAME( XBOX360_2010_GENERAL, WholeProgramOptimization )
PROPERTYNAME( XBOX360_2010_GENERAL, ExtensionsToDeleteOnClean )
PROPERTYNAME( XBOX360_2010_GENERAL, BuildLogFile )
PROPERTYNAME( XBOX360_2010_GENERAL, PlatformToolset )
PROPERTYNAME( XBOX360_2010_GENERAL, DisableFastUpToDateCheck )
PROPERTYNAME( XBOX360_2010_GENERAL, AdditionalProjectDependencies )
PROPERTYNAME( XBOX360_2010_GENERAL, AdditionalOutputFiles )
// Debugging
PROPERTYNAME( XBOX360_2010_DEBUGGING, Command )
PROPERTYNAME( XBOX360_2010_DEBUGGING, CommandArguments )
PROPERTYNAME( XBOX360_2010_DEBUGGING, RemoteMachine )
PROPERTYNAME( XBOX360_2010_DEBUGGING, MapDVDDrive )
PROPERTYNAME( XBOX360_2010_DEBUGGING, CheckUpToDate )
// Compiler
PROPERTYNAME( XBOX360_2010_COMPILER, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_COMPILER, Optimization )
PROPERTYNAME( XBOX360_2010_COMPILER, InlineFunctionExpansion )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableIntrinsicFunctions )
PROPERTYNAME( XBOX360_2010_COMPILER, FavorSizeOrSpeed )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFiberSafeOptimizations )
PROPERTYNAME( XBOX360_2010_COMPILER, WholeProgramOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, AdditionalIncludeDirectories )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, IgnoreStandardIncludePaths )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessToAFile )
PROPERTYNAME( XBOX360_2010_COMPILER, PreprocessSuppressLineNumbers )
PROPERTYNAME( XBOX360_2010_COMPILER, KeepComments )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableStringPooling )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableMinimalRebuild )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableCPPExceptions )
PROPERTYNAME( XBOX360_2010_COMPILER, BasicRuntimeChecks )
PROPERTYNAME( XBOX360_2010_COMPILER, RuntimeLibrary )
PROPERTYNAME( XBOX360_2010_COMPILER, StructMemberAlignment )
PROPERTYNAME( XBOX360_2010_COMPILER, BufferSecurityCheck )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFunctionLevelLinking )
PROPERTYNAME( XBOX360_2010_COMPILER, FloatingPointModel )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableFloatingPointExceptions )
PROPERTYNAME( XBOX360_2010_COMPILER, DisableLanguageExtensions )
PROPERTYNAME( XBOX360_2010_COMPILER, TreatWCHAR_TAsBuiltInType )
PROPERTYNAME( XBOX360_2010_COMPILER, ForceConformanceInForLoopScope )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableRunTimeTypeInfo )
PROPERTYNAME( XBOX360_2010_COMPILER, OpenMPSupport )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeader )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeaderFile )
PROPERTYNAME( XBOX360_2010_COMPILER, PrecompiledHeaderOutputFile )
PROPERTYNAME( XBOX360_2010_COMPILER, ExpandAttributedSource )
PROPERTYNAME( XBOX360_2010_COMPILER, AssemblerOutput )
PROPERTYNAME( XBOX360_2010_COMPILER, ASMListLocation )
PROPERTYNAME( XBOX360_2010_COMPILER, ObjectFileName )
PROPERTYNAME( XBOX360_2010_COMPILER, ProgramDatabaseFileName )
PROPERTYNAME( XBOX360_2010_COMPILER, EnableBrowseInformation )
PROPERTYNAME( XBOX360_2010_COMPILER, BrowseInformationFile )
PROPERTYNAME( XBOX360_2010_COMPILER, WarningLevel )
PROPERTYNAME( XBOX360_2010_COMPILER, TreatWarningsAsErrors )
PROPERTYNAME( XBOX360_2010_COMPILER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_COMPILER, DebugInformationFormat )
PROPERTYNAME( XBOX360_2010_COMPILER, CompileAs )
PROPERTYNAME( XBOX360_2010_COMPILER, ForcedIncludeFile )
PROPERTYNAME( XBOX360_2010_COMPILER, ShowIncludes )
PROPERTYNAME( XBOX360_2010_COMPILER, UndefineAllPreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, UndefinePreprocessorDefinitions )
PROPERTYNAME( XBOX360_2010_COMPILER, UseFullPaths )
PROPERTYNAME( XBOX360_2010_COMPILER, OmitDefaultLibraryName )
PROPERTYNAME( XBOX360_2010_COMPILER, TrapIntegerDividesOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, PreschedulingOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, InlineAssemblyOptimization )
PROPERTYNAME( XBOX360_2010_COMPILER, RegisterReservation )
PROPERTYNAME( XBOX360_2010_COMPILER, AnalyzeStalls )
PROPERTYNAME( XBOX360_2010_COMPILER, CallAttributedProfiling )
PROPERTYNAME( XBOX360_2010_COMPILER, SmallerTypeCheck )
PROPERTYNAME( XBOX360_2010_COMPILER, DisableSpecificWarnings )
PROPERTYNAME( XBOX360_2010_COMPILER, MultiProcessorCompilation )
PROPERTYNAME( XBOX360_2010_COMPILER, UseUnicodeForAssemblerListing )
PROPERTYNAME( XBOX360_2010_COMPILER, ForcedUsingFile )
PROPERTYNAME( XBOX360_2010_COMPILER, DeduceVariableType )
PROPERTYNAME( XBOX360_2010_COMPILER, CodeAnalysisForCCPP )
PROPERTYNAME( XBOX360_2010_COMPILER, DisabledWarningDirectories )
// Librarian
PROPERTYNAME( XBOX360_2010_LIBRARIAN, UseUNICODEResponseFiles )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, OutputFile )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ModuleDefinitionFileName )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ExportNamedFunctions )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, ForceSymbolReferences )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_2010_LIBRARIAN, AdditionalOptions )
// Linker
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreImportLibrary )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_LINKER, ShowProgress )
PROPERTYNAME( XBOX360_2010_LINKER, OutputFile )
PROPERTYNAME( XBOX360_2010_LINKER, Version )
PROPERTYNAME( XBOX360_2010_LINKER, EnableIncrementalLinking )
PROPERTYNAME( XBOX360_2010_LINKER, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_LINKER, AdditionalLibraryDirectories )
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreAllDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LINKER, IgnoreSpecificDefaultLibraries )
PROPERTYNAME( XBOX360_2010_LINKER, ModuleDefinitionFile )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateDebugInfo )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateProgramDatabaseFile )
PROPERTYNAME( XBOX360_2010_LINKER, GenerateMapFile )
PROPERTYNAME( XBOX360_2010_LINKER, MapFileName )
PROPERTYNAME( XBOX360_2010_LINKER, MapExports )
PROPERTYNAME( XBOX360_2010_LINKER, StackCommitSize )
PROPERTYNAME( XBOX360_2010_LINKER, References )
PROPERTYNAME( XBOX360_2010_LINKER, EnableCOMDATFolding )
PROPERTYNAME( XBOX360_2010_LINKER, LinkTimeCodeGeneration )
PROPERTYNAME( XBOX360_2010_LINKER, EntryPoint )
PROPERTYNAME( XBOX360_2010_LINKER, NoEntryPoint )
PROPERTYNAME( XBOX360_2010_LINKER, SetChecksum )
PROPERTYNAME( XBOX360_2010_LINKER, BaseAddress )
PROPERTYNAME( XBOX360_2010_LINKER, ImportLibrary )
PROPERTYNAME( XBOX360_2010_LINKER, FixedBaseAddress )
PROPERTYNAME( XBOX360_2010_LINKER, ErrorReporting )
PROPERTYNAME( XBOX360_2010_LINKER, FunctionOrder )
PROPERTYNAME( XBOX360_2010_LINKER, LinkLibraryDependencies )
PROPERTYNAME( XBOX360_2010_LINKER, UseLibraryDependencyInputs )
PROPERTYNAME( XBOX360_2010_LINKER, ForceSymbolReferences )
PROPERTYNAME( XBOX360_2010_LINKER, StripPrivateSymbols )
PROPERTYNAME( XBOX360_2010_LINKER, ProfileGuidedDatabase )
PROPERTYNAME( XBOX360_2010_LINKER, MergeSections )
PROPERTYNAME( XBOX360_2010_LINKER, AutomaticModuleDefinitionFile )
// Browse Information
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, OutputFile )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, AdditionalOptions )
PROPERTYNAME( XBOX360_2010_BROWSEINFORMATION, PreserveSBRFiles )
// Pre Build
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, Description )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_PREBUILDEVENT, UseInBuild )
// Pre Link
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, Description )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_PRELINKEVENT, UseInBuild )
// Post Build
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, Description )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, CommandLine )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_POSTBUILDEVENT, UseInBuild )
// Custom Build
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, Description )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, CommandLine )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, AdditionalDependencies )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, AdditionalDependencies_Proj )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, Outputs )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, ExecuteAfter )
PROPERTYNAME( XBOX360_2010_CUSTOMBUILDSTEP, ExecuteBefore )
// Image Conversion
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, ConfigurationFile )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, OutputFile )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, TitleID )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, LANKey )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, BaseAddress )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, HeapSize )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, WorkspaceSize )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AdditionalSections )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, ExportByName )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, OpticalDiscDriveMapping )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, PAL50Incompatible )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, MultidiscTitle )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, PreferBigButtonInput )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, CrossPlatformSystemLink )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AllowAvatarGetMetadataByXUID )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AllowControllerSwapping )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, RequireFullExperience )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, GameVoiceRequiredUI )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, KinectElevationControl )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, SkeletalTrackingRequirement )
PROPERTYNAME( XBOX360_2010_XBOX360IMAGECONVERSION, AdditionalOptions )
// Console Deployment
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, ExcludedFromBuild )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, SuppressStartupBanner )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentFiles )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, Progress )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, ForceCopy )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentType )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, DeploymentRoot )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, EmulationType )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, LayoutFile )
PROPERTYNAME( XBOX360_2010_CONSOLEDEPLOYMENT, AdditionalOptions )
File diff suppressed because it is too large Load Diff
+330
View File
@@ -0,0 +1,330 @@
//========= Copyright 1996-2016, Valve Corporation, All rights reserved. ============//
//
// Purpose: Qt MOC integration
//
//=====================================================================================//
#include "vpc.h"
#include "baseprojectdatacollector.h"
#include "projectgenerator_vcproj.h"
//-----------------------------------------------------------------------------
#define QT_COMPILER_CONFIG_START "\n" \
"{\n" \
" $Configuration\n" \
" {\n" \
" $Compiler\n" \
" {\n" \
" $DisableSpecificWarnings \"$BASE;$QT_MOC_DISABLED_WARNINGS\"\n"
#define QT_COMPILER_CONFIG_END " }\n" \
" }\n" \
"}\n"
#define QT_FAKEMOC_BLOCK "\n" \
"$DynamicFile \"%s\"\n" \
"$DynamicFile \"%s\"\n" \
"{\n" \
" $Configuration\n" \
" {\n" \
" $CustomBuildStep\n" \
" {\n" \
" $AdditionalDependencies \"%s\"\n" \
" $CommandLine \"$QT_MOC_COMMAND_PREFIX %s -o %s\"\n" \
" $Description \"$QT_DESCRIPTION_CPP\"\n" \
" $Outputs \"$QT_OUTPUT_CPP\"\n" \
" }\n" \
" }\n" \
"}\n"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_VerifyQtMacrosPresent()
{
if ( 0 == V_strlen( g_pVPC->GetMacroValue( "QT_MACROS_DEFINED" ) ) )
{
g_pVPC->VPCError( "Cannot have Qt files without defining the Qt macros (QT_MACROS_DEFINED) - ensure you include the core Qt script (in project %s).", g_pVPC->GetProjectName() );
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_Qt_TrackFile( const char *pName, bool bRemove, VpcFileFlags_t iFileFlags )
{
#ifdef STEAM
return;
#else
if ( !bRemove )
{
// Ignore files without the QT flag
if ( !( iFileFlags & VPC_FILE_FLAGS_QT ) )
return;
// Skip Qt processing during dependency-generation (let that code see the original, unmodified contents of the VPC)
if ( g_pVPC->m_bIsDependencyPass )
return;
// Ignore if this script opts out of the Qt feature
if ( g_pVPC->IsConditionalDefined( "NOQTFOLDER" ) )
{
g_pVPC->VPCWarning( "Ignoring Qt file '%s', project '%s' specifies NOQTFOLDER!", pName, g_pVPC->GetProjectName() );
return;
}
// Ignore if the Qt feature is disabled
if ( !g_pVPC->IsQtEnabled() )
return;
// Add the file (if not already added)
if ( !g_pVPC->m_QtFiles.HasElement( pName ) )
g_pVPC->m_QtFiles.AddToTail( pName );
}
else
{
// remove the file
g_pVPC->m_QtFiles.FindAndRemove( pName );
return;
}
VPC_VerifyQtMacrosPresent();
// Qt header files get a custom build step
const char *pExt = V_GetFileExtension( pName );
if ( IsHFileExtension( pExt ) )
{
CUtlVector< CUtlString > configurationNames;
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configurationNames );
bool bShouldSkip;
for ( int i=0; i < configurationNames.Count(); i++ )
{
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( configurationNames[i].String(), true );
g_pVPC->GetProjectGenerator()->StartPropertySection( KEYWORD_CUSTOMBUILDSTEP, &bShouldSkip );
g_pVPC->GetProjectGenerator()->HandleProperty( "$CommandLine", "\"$QT_CUSTOM_BUILD_H\"" );
g_pVPC->GetProjectGenerator()->HandleProperty( "$Description", "\"$QT_DESCRIPTION_H\"" );
g_pVPC->GetProjectGenerator()->HandleProperty( "$Outputs", "\"$QT_OUTPUT_H\"" );
g_pVPC->GetProjectGenerator()->EndPropertySection( KEYWORD_CUSTOMBUILDSTEP );
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
else if ( !V_stricmp_fast( pExt, "ui" ) )
{
CUtlVector< CUtlString > configurationNames;
g_pVPC->GetProjectGenerator()->GetAllConfigurationNames( configurationNames );
bool bShouldSkip;
for ( int i=0; i < configurationNames.Count(); i++ )
{
g_pVPC->GetProjectGenerator()->StartConfigurationBlock( configurationNames[i].String(), true );
g_pVPC->GetProjectGenerator()->StartPropertySection( KEYWORD_CUSTOMBUILDSTEP, &bShouldSkip );
g_pVPC->GetProjectGenerator()->HandleProperty( "$CommandLine", "\"$QT_CUSTOM_BUILD_UI\"" );
g_pVPC->GetProjectGenerator()->HandleProperty( "$Description", "\"$QT_DESCRIPTION_UI\"" );
g_pVPC->GetProjectGenerator()->HandleProperty( "$Outputs", "\"$QT_OUTPUT_UI\"" );
g_pVPC->GetProjectGenerator()->EndPropertySection( KEYWORD_CUSTOMBUILDSTEP );
g_pVPC->GetProjectGenerator()->EndConfigurationBlock();
}
}
#endif
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_Qt_OnParseProjectStart( void )
{
g_pVPC->m_QtFiles.Purge();
g_pVPC->m_QtOutputFileMap.Clear();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_Qt_GetPCHFile( CVCProjGenerator *pDataCollector, const char *pQtHeaderFile, CUtlString *pOutPCHFile )
{
CUtlVector<CProjectConfiguration *> rootConfigs;
pDataCollector->GetAllRootConfigurations( rootConfigs );
CSourceFileInfo fileInfo;
char pFileNoExt[ MAX_BASE_FILENAME ];
V_StripExtension( pQtHeaderFile, pFileNoExt, sizeof( pFileNoExt ) );
char cppFileName[ MAX_BASE_FILENAME ];
const int nNumCFileExtensions = GetNumCFileExtensions();
for ( int i = 0; i < nNumCFileExtensions; ++i )
{
V_strcpy_safe( cppFileName, pFileNoExt );
V_strcat_safe( cppFileName, "." );
V_strcat_safe( cppFileName, GetCFileExtension( i ) );
CProjectFile *pProjectFile = NULL;
if ( pDataCollector->FindFile( cppFileName, &pProjectFile ) )
{
VPC_GeneratedFiles_GetSourceFileInfo( fileInfo, pProjectFile, true, pDataCollector, rootConfigs );
*pOutPCHFile = fileInfo.m_PCHName;
break;
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void VPC_Qt_OnParseProjectEnd( CVCProjGenerator *pDataCollector )
{
if ( g_pVPC->m_QtFiles.Count() == 0 )
return;
CUtlBuffer vpcBuffer;
vpcBuffer.SetBufferType( true, true );
vpcBuffer.Printf( "$Folder \"%s\"\n{\n", g_QtFolderName );
CUtlStringBuilder qtTargetSubdir;
g_pVPC->ResolveMacrosInString( "$QT_TARGET_SUBDIR", &qtTargetSubdir );
CUtlStringBuilder qtUISubdir;
g_pVPC->ResolveMacrosInString( "$QT_UI_SUBDIR", &qtUISubdir );
for ( int i = 0; i < g_pVPC->m_QtFiles.Count(); ++i )
{
const char *pFilename = g_pVPC->m_QtFiles[i].Get();
char pFileBase[MAX_BASE_FILENAME];
V_FileBase( pFilename, pFileBase, sizeof( pFileBase ) );
char pFileNoExt[MAX_BASE_FILENAME];
V_StripExtension( pFilename, pFileNoExt, sizeof(pFileNoExt) );
const char *pFileSuff = "";
const char *pExt = V_GetFileExtension( pFilename );
if ( IsHFileExtension( pExt ) )
{
CUtlString pchConfig;
CUtlString pchFile;
VPC_Qt_GetPCHFile( pDataCollector, pFilename, &pchFile );
if ( pchFile.IsEmpty() )
{
pFileSuff = "_NoPCH";
}
else
{
pchConfig.Format( " $Create/UsePCHThroughFile \"%s\"\n" \
" $ForceIncludes \"%s\"\n", pchFile.Get(), pchFile.Get() );
}
CUtlString configBlock = QT_COMPILER_CONFIG_START;
configBlock += pchConfig;
configBlock += QT_COMPILER_CONFIG_END;
const char *pOutputFilename = g_pVPC->FormatTemp1( "%s/moc_%s.cpp", qtTargetSubdir.Get(), pFileBase );
vpcBuffer.Printf( "$DynamicFile%s \"%s\" %s\n\n", pFileSuff, pOutputFilename, configBlock.Get() );
// Record the relationship between the input/output files:
g_pVPC->m_QtOutputFileMap[ pFilename ] = pOutputFilename;
}
else if ( IsCFileExtension( pExt ) )
{
CUtlString mocFilePath;
mocFilePath.Format( "%s/%s.moc", qtTargetSubdir.Get(), pFileNoExt );
CUtlString fakemocFilePath;
fakemocFilePath.Format( "%s/%s.fakemoc", qtTargetSubdir.Get(), pFileNoExt );
// Inject the fakemoc block
vpcBuffer.Printf( QT_FAKEMOC_BLOCK, mocFilePath.Get(), fakemocFilePath.Get(), pFilename, pFilename, mocFilePath.Get() );
// Resolve the paths to the moc and fakemoc files
// Ensure the directory structure is there because MOC and Visual Studio will be unhappy if it's not
CUtlStringBuilder *pStrBuf = g_pVPC->GetTempStringBuffer1();
g_pVPC->ResolveMacrosInString( mocFilePath.Get(), pStrBuf );
Sys_CreatePath( pStrBuf->Get() );
g_pVPC->ResolveMacrosInString( fakemocFilePath.Get(), pStrBuf );
Sys_CreatePath( pStrBuf->Get() );
// Write an empty fakemoc so IncrediBuild in VS2010 doesn't keep trying to build projects that include this file
if ( !Sys_Exists( pStrBuf->Get() ) ) // only write the file if it's not already there
{
FILE *fp = fopen( pStrBuf->Get(), "wt" );
if ( fp )
{
fclose( fp );
}
}
// Record the relationship between the input/output files (in this special case, they are the same;
// the source CPP file is still compiled, but must explicitly #include the generated MOC file):
g_pVPC->m_QtOutputFileMap[ pFilename ] = pFilename;
}
else if ( !V_stricmp_fast( pExt, "ui" ) )
{
vpcBuffer.Printf( "$DynamicFile \"%s/ui_%s.h\"\n", qtUISubdir.Get(), pFileBase );
}
else
{
g_pVPC->VPCSyntaxError( "Can only use $QtFile for cpp, header, or ui files. (%s)", pFilename );
continue;
}
}
vpcBuffer.Printf( "}\n" );
// save parser
bool bIgnoreRedundancyWarning = g_pVPC->IsIgnoreRedundancyWarning();
g_pVPC->SetIgnoreRedundancyWarning( true );
g_pVPC->GetScript().PushScript( "Internal List [Qt]", (char*)vpcBuffer.Base(), 1, false, false );
const char *pToken = g_pVPC->GetScript().GetToken( true );
if ( pToken && pToken[0] && !V_stricmp_fast( pToken, "$folder" ) )
{
VPC_Keyword_Folder( VPC_FOLDER_FLAGS_DYNAMIC );
}
// restore parser
g_pVPC->GetScript().PopScript();
g_pVPC->SetIgnoreRedundancyWarning( bIgnoreRedundancyWarning );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CProjectFile *VPC_Qt_GetGeneratedFile( CProjectFile *pInputFile, const char * /*pConfigName*/, CVCProjGenerator *pDataCollector )
{
CUtlString &generatedFilename = g_pVPC->m_QtOutputFileMap[ pInputFile->m_Name.Get() ];
generatedFilename.FixSlashes();
CProjectFile *pGeneratedFile = NULL;
pDataCollector->FindFile( generatedFilename.Get(), &pGeneratedFile );
if ( !pGeneratedFile )
g_pVPC->VPCWarning( "VPC_Qt_GetGeneratedFile: could not find generated file for '%s'", pInputFile->m_Name.Get() );
return pGeneratedFile;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool IsQtSupportedForThisTargetPlatform( void )
{
// TODO: Only implemented+tested on WIN32/WIN64 so far...
// [ uses CBaseProjectDataCollector, so may work on other platforms, but untested ]
const char *pPlatform = g_pVPC->GetTargetPlatformName();
return ( !V_stricmp_fast( pPlatform, "WIN32" ) || !V_stricmp_fast( pPlatform, "WIN64" ) );
}
bool CVPC::IsQtEnabled( void )
{
if ( !m_bAllowQt )
return false; // Schema not enabled
if ( IsQtSupportedForThisTargetPlatform() )
return true; // Feature enabled & supported!
ExecuteOnce( VPCWarning( "Qt feature disabled, not supported for %s yet", g_pVPC->GetTargetPlatformName() ) )
return false; // Platform not supported
}
File diff suppressed because it is too large Load Diff
+665
View File
@@ -0,0 +1,665 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
//
//
//==================================================================================================
#include "vpc.h"
#define MAX_SCRIPT_STACK_SIZE 32
CScript::CScript()
{
m_ScriptName = "(empty)";
m_nScriptLine = 0;
m_pScriptData = NULL;
m_pScriptLine = &m_nScriptLine;
m_nInPrivilegedScript = 0;
m_bScriptNameIsAFile = false;
m_DefaultToken.EnsureCapacity( 10000 );
m_pTokenBuf = &m_DefaultToken;
m_PeekToken.EnsureCapacity( m_DefaultToken.Capacity() );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::SkipWhitespace( const char *data, bool *pHasNewLines, int* pNumLines )
{
int c;
// Avoid crash hit while trying to VPC @VPC
if ( !data )
return NULL;
while ( ( c = *data ) <= ' ' )
{
if ( c == '\n' )
{
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
else if ( !c )
{
return ( NULL );
}
data++;
}
return data;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::SkipToValidToken( const char *data, bool *pHasNewLines, int* pNumLines )
{
int c;
for ( ;; )
{
data = SkipWhitespace( data, pHasNewLines, pNumLines );
if ( !data )
break;
c = *data;
if ( !c )
{
break;
}
if ( c == '/' && data[1] == '/' )
{
// skip double slash comments
data += 2;
while ( *data && *data != '\n' )
{
data++;
}
if ( *data && *data == '\n' )
{
data++;
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
}
else if ( c == '/' && data[1] == '*' )
{
// skip /* */ comments
data += 2;
while ( *data && ( *data != '*' || data[1] != '/' ) )
{
if ( *data == '\n' )
{
if ( pNumLines )
{
(*pNumLines)++;
}
if ( pHasNewLines )
{
*pHasNewLines = true;
}
}
data++;
}
if ( *data )
{
data += 2;
}
}
else
{
break;
}
}
return data;
}
//-----------------------------------------------------------------------------
// The next token should be an open brace.
// Skips until a matching close brace is found.
// Internal brace depths are properly skipped.
//-----------------------------------------------------------------------------
void CScript::SkipBracedSection( const char** dataptr, int* numlines, int nInitialDepth )
{
const char* token;
int depth;
depth = nInitialDepth;
do
{
token = GetToken( dataptr, true, numlines );
if ( token[1] == '\0' )
{
if ( token[0] == '{' )
depth++;
else if ( token[0] == '}' )
depth--;
}
}
while( depth && *dataptr );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CScript::SkipRestOfLine( const char** dataptr, int* numlines )
{
const char* p;
int c;
p = *dataptr;
while ( ( c = *p++ ) != '\0' )
{
if ( c == '\n' )
{
if ( numlines )
( *numlines )++;
break;
}
}
*dataptr = p;
}
//-----------------------------------------------------------------------------
// Does not corrupt results obtained with GetToken().
//-----------------------------------------------------------------------------
const char* CScript::PeekNextToken( const char *dataptr, bool bAllowLineBreaks )
{
// Switch to the peek token buffer so that the current
// token is unchanged.
CUtlStringBuilder *pOldTokenBuf = SetTokenBuffer( &m_PeekToken );
const char *pSaved = dataptr;
GetToken( &pSaved, bAllowLineBreaks, NULL );
// restore
SetTokenBuffer( pOldTokenBuf );
return m_PeekToken.Get();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
const char *CScript::GetToken( const char **dataptr, bool allowLineBreaks, int *pNumLines )
{
char c;
char endSymbol;
bool hasNewLines;
const char* data;
CUtlStringBuilder *pTokenBuf = m_pTokenBuf;
c = 0;
data = *dataptr;
pTokenBuf->SetLength( 0 );
hasNewLines = false;
// make sure incoming data is valid
if ( !data )
{
*dataptr = NULL;
return pTokenBuf->Get();
}
for ( ;; )
{
// skip whitespace
data = SkipWhitespace( data, &hasNewLines, pNumLines );
if ( !data )
{
*dataptr = NULL;
return pTokenBuf->Get();
}
if ( hasNewLines && !allowLineBreaks )
{
*dataptr = data;
return pTokenBuf->Get();
}
c = *data;
if ( c == '/' && data[1] == '/' )
{
// skip double slash comments
data += 2;
while ( *data && *data != '\n' )
{
data++;
}
if ( *data && *data == '\n' )
{
if ( !allowLineBreaks )
continue;
data++;
if ( pNumLines )
{
(*pNumLines)++;
}
}
}
else if ( c =='/' && data[1] == '*' )
{
// skip /* */ comments
data += 2;
while ( *data && ( *data != '*' || data[1] != '/' ) )
{
if ( *data == '\n' && pNumLines )
{
(*pNumLines)++;
}
data++;
}
if ( *data )
{
data += 2;
}
}
else
break;
}
// handle scoped strings "???" <???> [???]
if ( c == '\"' || c == '<' || c == '[')
{
bool bConditionalExpression = false;
endSymbol = '\0';
switch ( c )
{
case '\"':
endSymbol = '\"';
break;
case '<':
endSymbol = '>';
break;
case '[':
bConditionalExpression = true;
endSymbol = ']';
break;
}
// want to preserve entire conditional expession [blah...blah...blah]
// maintain a conditional's open/close scope characters
if ( !bConditionalExpression )
{
// skip past scope character
data++;
}
for ( ;; )
{
c = *data++;
if ( c == endSymbol || !c )
{
if ( c == endSymbol && bConditionalExpression )
{
// keep end symbol
pTokenBuf->AppendChar( c );
}
*dataptr = (char*)data;
return pTokenBuf->Get();
}
pTokenBuf->AppendChar( c );
}
}
// parse a regular word
do
{
pTokenBuf->AppendChar( c );
data++;
c = *data;
}
while ( c > ' ' );
*dataptr = (char*)data;
return pTokenBuf->Get();
}
void CScript::UpdateThisVpc()
{
const char *szScriptName = nullptr;
if ( m_bScriptNameIsAFile )
{
szScriptName = m_ScriptName.Get();
}
else
{
//crawl down the stack looking for the most recently pushed script with an actual filename
for ( int nScriptStackIndex = m_ScriptStack.Count(); --nScriptStackIndex >= 0; )
{
if ( m_ScriptStack[nScriptStackIndex].IsScriptNameAFile() )
{
szScriptName = m_ScriptStack[nScriptStackIndex].GetName();
break;
}
}
}
if ( szScriptName == nullptr )
{
g_pVPC->SetScriptMacro( "THISVPC", "" );
g_pVPC->SetScriptMacro( "THISVPCFILE", "" );
return;
}
char absFile[MAX_FIXED_PATH];
char tempPath[2][MAX_FIXED_PATH];
V_MakeAbsolutePath( absFile, ARRAYSIZE( absFile ), szScriptName, NULL, k_bVPCForceLowerCase );
V_strcpy_safe( tempPath[0], absFile );
V_StripFilename( tempPath[0] );
g_pVPC->SetScriptMacro( "THISVPC", tempPath[0] );
V_strcpy_safe( tempPath[0], absFile );
V_MakeRelativePath( tempPath[0], g_pVPC->GetProjectPath(), tempPath[1], ARRAYSIZE( tempPath[1] ) );
g_pVPC->SetScriptMacro( "THISVPCFILE", tempPath[1] );
}
void CScript::PushScript( const char *pFilename, bool bAddScriptToCRCCheck )
{
// parse the text script
if ( !Sys_Exists( pFilename ) )
{
g_pVPC->VPCError( "Cannot open %s", pFilename );
}
char *pScriptBuffer;
int nScriptLength = Sys_LoadFile( pFilename, (void**)&pScriptBuffer, true );
if ( nScriptLength < 0 )
{
// Unexpected due to existence check
g_pVPC->VPCError( "Cannot open %s", pFilename );
}
g_pVPC->AddScriptToParsedList( pFilename, bAddScriptToCRCCheck, bAddScriptToCRCCheck ? CRC32_ProcessSingleBuffer( pScriptBuffer, nScriptLength ) : 0 );
PushScript( pFilename, pScriptBuffer, 1, true, true );
}
void CScript::PushScript( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop, bool bScriptNameIsAFile )
{
if ( m_ScriptStack.Count() > MAX_SCRIPT_STACK_SIZE )
{
g_pVPC->VPCError( "PushScript( scriptname=%s ) - stack overflow\n", pScriptName );
}
// Push the current state onto the stack.
m_ScriptStack.Push( GetCurrentScript() );
// Set their state as the current state.
m_ScriptName = pScriptName;
m_pScriptData = pScriptData;
m_nScriptLine = nScriptLine;
m_bFreeScriptAtPop = bFreeScriptAtPop;
m_bScriptNameIsAFile = bScriptNameIsAFile;
UpdateThisVpc();
}
void CScript::PushCurrentScript()
{
// We always push false for free-at-pop so that only the least nested
// push will actually free the pointer.
PushScript( m_ScriptName.Get(), m_pScriptData, m_nScriptLine, false, m_bScriptNameIsAFile );
}
CScriptSource CScript::GetCurrentScript()
{
return CScriptSource( m_ScriptName.Get(), m_pScriptData, m_nScriptLine, m_bFreeScriptAtPop, m_nInPrivilegedScript, m_bScriptNameIsAFile );
}
void CScript::RestoreScript( const CScriptSource &scriptSource )
{
m_ScriptName = scriptSource.GetName();
m_pScriptData = scriptSource.GetData();
m_nScriptLine = scriptSource.GetLine();
m_bFreeScriptAtPop = scriptSource.IsFreeScriptAtPop();
m_nInPrivilegedScript = scriptSource.GetInPrivilegedScript();
m_bScriptNameIsAFile = scriptSource.IsScriptNameAFile();
UpdateThisVpc();
}
void CScript::PopScript()
{
if ( m_ScriptStack.Count() == 0 )
{
g_pVPC->VPCError( "PopScript(): stack is empty" );
}
if ( m_bFreeScriptAtPop && m_pScriptData )
{
delete [] m_pScriptData;
}
// Restore the top entry on the stack and pop it off.
const CScriptSource &state = m_ScriptStack.Top();
m_ScriptName = state.GetName();
m_pScriptData = state.GetData();
m_nScriptLine = state.GetLine();
m_bFreeScriptAtPop = state.IsFreeScriptAtPop();
m_bScriptNameIsAFile = state.IsScriptNameAFile();
UpdateThisVpc();
m_ScriptStack.Pop();
}
void CScript::EnsureScriptStackEmpty()
{
if ( m_ScriptStack.Count() != 0 )
{
g_pVPC->VPCError( "EnsureScriptStackEmpty(): script stack is not empty!" );
}
}
void CScript::SpewScriptStack( bool bDueToError )
{
if ( m_ScriptStack.Count() )
{
CUtlString str;
// user really want to see absolute paths, but all sorts of code was written with relative versions
#if defined( POSIX )
char fullPath[PATH_MAX];
#else
char fullPath[MAX_FIXED_PATH];
#endif
fullPath[0] = '\0';
if ( !m_ScriptName.IsEmpty() && !V_IsAbsolutePath( m_ScriptName.Get() ) )
{
#if defined( PLATFORM_WINDOWS )
_fullpath( fullPath, m_ScriptName.Get(), sizeof( fullPath ) );
#elif defined( POSIX )
if ( realpath( m_ScriptName.Get(), fullPath ) == NULL )
{
fullPath[0] = '\0';
}
#else
V_strncpy( fullPath, m_ScriptName.Get(), sizeof( fullPath ) );
#endif
}
// emit stack with current at top
str += "Script Stack:\n";
str += CFmtStr( " %s Line:%d\n", fullPath[0] ? fullPath : m_ScriptName.Get(), m_nScriptLine );
for ( int i = m_ScriptStack.Count() - 1; i >= 0; i-- )
{
if ( i == 0 && !m_ScriptStack[i].GetData() && m_ScriptStack[i].GetLine() <= 0 )
{
// ignore empty bottom of stack
break;
}
// user really want to see absolute paths, but all sorts of code was written with relative versions
fullPath[0] = '\0';
if ( m_ScriptStack[i].GetName()[0] && !V_IsAbsolutePath( m_ScriptStack[i].GetName() ) )
{
#if defined( PLATFORM_WINDOWS )
_fullpath( fullPath, m_ScriptStack[i].GetName(), sizeof( fullPath ) );
#elif defined( POSIX )
if ( realpath( m_ScriptStack[i].GetName(), fullPath ) == NULL )
{
fullPath[0] = '\0';
}
#else
V_strncpy( fullPath, m_ScriptStack[i].GetName(), sizeof( fullPath ) );
#endif
}
str += CFmtStr( " %s Line:%d\n", fullPath[0] ? fullPath : m_ScriptStack[i].GetName(), m_ScriptStack[i].GetLine() );
}
str += "\n";
if ( bDueToError )
{
Log_Warning( LOG_VPC, Color( 255, 0, 0, 255 ), "%s", str.String() );
}
else
{
Log_Msg( LOG_VPC, "%s", str.String() );
}
}
}
const char *CScript::GetToken( bool bAllowLineBreaks )
{
return GetToken( &m_pScriptData, bAllowLineBreaks, m_pScriptLine );
}
const char *CScript::PeekNextToken( bool bAllowLineBreaks )
{
return PeekNextToken( m_pScriptData, bAllowLineBreaks );
}
void CScript::SkipRestOfLine()
{
SkipRestOfLine( &m_pScriptData, m_pScriptLine );
}
void CScript::SkipBracedSection( int nInitialDepth )
{
SkipBracedSection( &m_pScriptData, m_pScriptLine, nInitialDepth );
}
void CScript::SkipToValidToken()
{
m_pScriptData = SkipToValidToken( m_pScriptData, NULL, m_pScriptLine );
}
//-----------------------------------------------------------------------------
// Handles expressions of the form <$BASE> <xxx> ... <xxx> [condition]
// Output is a concatenated string.
//
// Returns true if expression should be used, false if it should be ignored due
// to an optional condition that evaluated false.
//-----------------------------------------------------------------------------
bool CScript::ParsePropertyValue( const char *pBaseString, CUtlStringBuilder *pOutBuff )
{
if ( !pBaseString )
{
// $BASE default
pBaseString = "";
}
pOutBuff->SetLength( 0 );
const char **pScriptData = &m_pScriptData;
int *pScriptLine = m_pScriptLine;
bool bAllowNextLine = false;
bool bResult = true;
bool bFoundReservedEmptyTokenOnly = true;
while ( 1 )
{
const char *pToken = GetToken( pScriptData, bAllowNextLine, pScriptLine );
if ( !pToken || !pToken[0] )
{
g_pVPC->VPCSyntaxError();
}
const char *pNextToken = PeekNextToken( *pScriptData, false );
if ( ( !pNextToken || !pNextToken[0] ) && pToken[0] == '[' )
{
// current token is last token
// last token can be optional conditional, need to identify
// backup and reparse up to last token
// last token is an optional conditional
bResult = g_pVPC->EvaluateConditionalExpression( pToken );
break;
}
else if ( pToken[0] == '[' && pNextToken && pNextToken[0] == '[' )
{
g_pVPC->VPCSyntaxError( "Bad conditional syntax. Use C style boolean expression operators to express compound conditionals." );
}
else if ( bFoundReservedEmptyTokenOnly )
{
bFoundReservedEmptyTokenOnly = !V_stricmp_fast( pToken, "$EMPTY" );
}
bAllowNextLine = CharStrEq( pToken, '\\' );
if ( bAllowNextLine )
continue;
if ( pToken[0] == '\\' &&
( pToken[1] == 'n' || pToken[1] == 'N' ) &&
pToken[2] == 0 )
{
pToken = "\n";
}
if ( pToken[0] )
{
// handle reserved replacements
CUtlStringBuilder *pStrBuf = g_pVPC->GetMacroReplaceBuffer();
pStrBuf->Set( pToken );
pStrBuf->ReplaceFastCaseless( "$BASE", pBaseString );
g_pVPC->ResolveMacrosInString( NULL, pStrBuf );
pOutBuff->Append( pStrBuf->Get() );
}
pToken = PeekNextToken( *pScriptData, false );
if ( !pToken || !pToken[0] || CharStrEq( pNextToken, '}' ) )
break;
}
if ( pOutBuff->IsEmpty() && bResult )
{
// The property value resolved empty and was not conditionally disabled.
// Check the tokens scanned to quietly allow an explicit "$EMPTY".
// Allow quietly a usage of "$EMPTY" or "$EMPTY" [$Condition]
// This provides a no-op state where properties can be explicitly purged by using $EMPTY.
if ( !bFoundReservedEmptyTokenOnly )
{
// error due to unexpected fully empty state
g_pVPC->VPCSyntaxError( "Unexpected empty value." );
}
}
return bResult;
}
+110
View File
@@ -0,0 +1,110 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
// This module manages a stack of "script sources".
//
//==================================================================================================
#pragma once
#define MAX_SYSPRINTMSG 4096
class CScriptSource
{
public:
CScriptSource()
{
Set( "", NULL, 0, false, 0, false );
}
CScriptSource( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop, int nInPrivilegedScript, bool bScriptNameIsAFile )
{
Set( pScriptName, pScriptData, nScriptLine, bFreeScriptAtPop, nInPrivilegedScript, bScriptNameIsAFile );
}
void Set( const char *pScriptName, const char *pScriptData, int nScriptLine, bool bFreeScriptAtPop, int nInPrivilegedScript, bool bScriptNameIsAFile )
{
m_ScriptName = pScriptName;
m_pScriptData = pScriptData;
m_nScriptLine = nScriptLine;
m_bFreeScriptAtPop = bFreeScriptAtPop;
m_nInPrivilegedScript = nInPrivilegedScript;
m_bScriptNameIsAFile = bScriptNameIsAFile;
}
const char *GetName() const { return m_ScriptName.Get(); }
const char *GetData() const { return m_pScriptData; }
int GetLine() const { return m_nScriptLine; }
bool IsFreeScriptAtPop() const { return m_bFreeScriptAtPop; }
int GetInPrivilegedScript() const { return m_nInPrivilegedScript; }
bool IsScriptNameAFile() const { return m_bScriptNameIsAFile; }
private:
CUtlString m_ScriptName;
const char *m_pScriptData;
int m_nScriptLine;
bool m_bFreeScriptAtPop;
int m_nInPrivilegedScript;
bool m_bScriptNameIsAFile;
};
class CScript
{
public:
CScript();
void PushScript( const char *pFilename, bool bAddScriptToCRCCheck = false );
void PushScript( const char *pScriptName, const char *ppScriptData, int nScriptLine, bool bFreeScriptAtPop, bool bScriptNameIsAFile );
void PushCurrentScript();
void PopScript();
CScriptSource GetCurrentScript();
void RestoreScript( const CScriptSource &scriptSource );
void EnsureScriptStackEmpty();
void SpewScriptStack( bool bDueToError );
const char *GetName() const { return m_ScriptName.Get(); }
const char *GetData() const { return m_pScriptData; }
int GetLine() const { return m_nScriptLine; }
bool IsInPrivilegedScript() { return m_nInPrivilegedScript > 0; }
void EnterPrivilegedScript() { m_nInPrivilegedScript++; }
void LeavePrivilegedScript() { m_nInPrivilegedScript--; }
CUtlStringBuilder *SetTokenBuffer( CUtlStringBuilder *pBuf )
{
CUtlStringBuilder *pCur = m_pTokenBuf;
m_pTokenBuf = pBuf;
return pCur;
}
const char *GetToken( bool bAllowLineBreaks );
const char *PeekNextToken( bool bAllowLineBreaks );
void SkipRestOfLine();
void SkipBracedSection( int nInitialDepth = 0 );
void SkipToValidToken();
bool ParsePropertyValue( const char *pBaseString, CUtlStringBuilder *pOutBuff );
private:
const char *SkipWhitespace( const char *data, bool *pHasNewLines, int *pNumLines );
const char *SkipToValidToken( const char *data, bool *pHasNewLines, int *pNumLines );
void SkipBracedSection( const char **dataptr, int *numlines, int nInitialDepth );
void SkipRestOfLine( const char **dataptr, int *numlines );
const char *PeekNextToken( const char *dataptr, bool bAllowLineBreaks );
const char *GetToken( const char **dataptr, bool allowLineBreaks, int *pNumLines );
void UpdateThisVpc();
CUtlStack< CScriptSource > m_ScriptStack;
int m_nScriptLine;
int *m_pScriptLine;
const char *m_pScriptData;
CUtlString m_ScriptName;
bool m_bFreeScriptAtPop;
int m_nInPrivilegedScript;
bool m_bScriptNameIsAFile;
CUtlStringBuilder *m_pTokenBuf;
CUtlStringBuilder m_DefaultToken;
CUtlStringBuilder m_PeekToken;
};
@@ -0,0 +1,285 @@
//====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "dependencies.h"
#include "utlgraph.h"
class CSolutionGenerator_CodeLite : public IBaseSolutionGenerator {
public:
CSolutionGenerator_CodeLite() {
m_nIndent = 0;
m_fp = NULL;
}
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects ) {
char szSolutionName[MAX_PATH];
V_FileBase( pSolutionFilename, szSolutionName, MAX_PATH );
char szSolutionFileBaseName[MAX_PATH];
// Default extension.
char szTmpSolutionFilename[MAX_PATH];
if ( !V_GetFileExtension( pSolutionFilename ) ) {
V_strncpy( szSolutionFileBaseName, pSolutionFilename, sizeof( szSolutionFileBaseName ) );
V_snprintf( szTmpSolutionFilename, sizeof( szTmpSolutionFilename ), "%s.workspace", pSolutionFilename );
pSolutionFilename = szTmpSolutionFilename;
} else {
V_StripExtension( pSolutionFilename, szSolutionFileBaseName, sizeof( szSolutionFileBaseName ) );
}
Msg( "\nWriting CodeLite workspace %s.\n\n", pSolutionFilename );
// Write the file.
m_fp = fopen( pSolutionFilename, "wt" );
if ( !m_fp )
g_pVPC->VPCError( "Can't open %s for writing.", pSolutionFilename );
Write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" );
Write( "<CodeLite_Workspace Name=\"%s\" Database=\"%s.tags\">\n", szSolutionName, szSolutionFileBaseName );
++m_nIndent;
Write( "<Project Name=\"all\" Path=\"%s.project\" Active=\"Yes\"/>\n", szSolutionFileBaseName);
for ( int i=0; i < projects.Count(); i++ ) {
CDependency_Project *pCurProject = projects[i];
project_t *pProjectT = &g_pVPC->m_Projects[ pCurProject->m_iProjectIndex ];
char szProjectFileBaseName[MAX_PATH];
V_StripExtension( pCurProject->m_ProjectFilename.String(), szProjectFileBaseName, sizeof( szProjectFileBaseName ) );
Write( "<Project Name=\"%s\" Path=\"%s.project\"/>\n", pProjectT->name.String(), szProjectFileBaseName );
}
Write( "<BuildMatrix>\n" );
++m_nIndent;
Write( "<WorkspaceConfiguration Name=\"Debug\" Selected=\"no\">\n" );
++m_nIndent;
Write( "<Project Name=\"all\" ConfigName=\"Debug\"/>\n" );
for ( int i=0; i < projects.Count(); i++ ) {
CDependency_Project *pCurProject = projects[i];
project_t *pProjectT = &g_pVPC->m_Projects[ pCurProject->m_iProjectIndex ];
Write( "<Project Name=\"%s\" ConfigName=\"Debug\"/>\n", pProjectT->name.String() );
}
--m_nIndent;
Write( "</WorkspaceConfiguration>\n" );
Write( "<WorkspaceConfiguration Name=\"Release\" Selected=\"yes\">\n" );
++m_nIndent;
Write( "<Project Name=\"all\" ConfigName=\"Release\"/>\n" );
for ( int i=0; i < projects.Count(); i++ ) {
CDependency_Project *pCurProject = projects[i];
project_t *pProjectT = &g_pVPC->m_Projects[ pCurProject->m_iProjectIndex ];
Write( "<Project Name=\"%s\" ConfigName=\"Release\"/>\n", pProjectT->name.String() );
}
--m_nIndent;
Write( "</WorkspaceConfiguration>\n" );
--m_nIndent;
Write( "</BuildMatrix>\n" );
--m_nIndent;
Write( "</CodeLite_Workspace>\n" );
fclose( m_fp );
WriteBuildOrderProject( szSolutionFileBaseName, projects );
}
void WriteBuildOrderProject( const char *pszSolutionFileBaseName, CUtlVector<CDependency_Project*> &projects ) {
// write out a project with no files to encode the build order (dependencies)
char szProjectFileName[MAX_PATH];
V_snprintf( szProjectFileName, sizeof( szProjectFileName ), "%s.project", pszSolutionFileBaseName );
m_nIndent = 0;
m_fp = fopen( szProjectFileName, "wt" );
if ( !m_fp )
g_pVPC->VPCError( "Can't open %s for writing.", szProjectFileName );
Write( "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" );
Write( "<CodeLite_Project Name=\"all\" InternalType=\"\">\n" );
{
++m_nIndent;
Write( "<Description/>\n" );
Write( "<Dependencies/>\n" );
Write( "<Settings Type=\"Static Library\">\n" );
{
++m_nIndent;
Write( "<GlobalSettings>\n" );
++m_nIndent;
Write( "<Compiler Options=\"\" C_Options=\"\">\n" );
++m_nIndent;
Write( "<IncludePath Value=\"\"/>\n" );
--m_nIndent;
Write( "</Compiler>\n" );
Write( "<Linker Options=\"\">\n" );
++m_nIndent;
Write( "<LibraryPath Value=\"\"/>\n" );
--m_nIndent;
Write( "</Linker>\n" );
Write( "<ResourceCompiler Options=\"\"/>\n" );
--m_nIndent;
Write( "</GlobalSettings>\n" );
Write( "<Configuration Name=\"Debug\" CompilerType=\"gnu g++\" DebuggerType=\"GNU gdb debugger\" Type=\"Executable\" BuildCmpWithGlobalSettings=\"append\" BuildLnkWithGlobalSettings=\"append\" BuildResWithGlobalSettings=\"append\">\n" );
#if 0
++m_nIndent;
Write( "<Compiler Options=\"-g\" C_Options="" Required="yes" PreCompiledHeader="">\n" );
++m_nIndent;
Write( "<IncludePath Value=\"\"/>" );
--m_nIndent;
--m_nIndent;
#endif
Write( "</Configuration>\n" );
Write( "<Configuration Name=\"Release\" CompilerType=\"gnu g++\" DebuggerType=\"GNU gdb debugger\" Type=\"Executable\" BuildCmpWithGlobalSettings=\"append\" BuildLnkWithGlobalSettings=\"append\" BuildResWithGlobalSettings=\"append\">\n" );
#if 0
++m_nIndent;
Write( "<Compiler Options=\"-g\" C_Options="" Required="yes" PreCompiledHeader="">\n" );
++m_nIndent;
Write( "<IncludePath Value=\"\"/>" );
--m_nIndent;
--m_nIndent;
#endif
Write( "</Configuration>\n" );
--m_nIndent;
}
Write( "</Settings>\n" );
--m_nIndent;
CUtlGraph<int, int> dependencyGraph;
// walk the project list building a dependency graph
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
CUtlVector<CDependency_Project*> additionalProjectDependencies;
ResolveAdditionalProjectDependencies( pCurProject, projects, additionalProjectDependencies );
//project_t *pProjectT = &g_projects[ pCurProject->m_iProjectIndex ];
//printf( "%s depends on\n", pProjectT->name.String() );
for ( int iTestProject=0; iTestProject < projects.Count(); iTestProject++ ) {
if ( i == iTestProject )
continue;
// do I depend on anyone?
CDependency_Project *pTestProject = projects[iTestProject];
int dependsOnFlags = k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse;
if ( pCurProject->DependsOn( pTestProject, dependsOnFlags ) || additionalProjectDependencies.Find( pTestProject ) != additionalProjectDependencies.InvalidIndex() ) {
// add an edge from this project to the one it depends on
dependencyGraph.AddEdge( i, iTestProject, 1 );
//printf( " %s -> %s\n", projects[ i ]->m_ProjectName.String(),
// projects[ iTestProject ]->m_ProjectName.String() );
}
}
}
Write( "<Dependencies Name=\"Debug\">\n" );
++m_nIndent;
CUtlVector<int> visitedList;
for( int i = 0; i < projects.Count(); i++ ) {
TraverseFrom( projects, dependencyGraph, visitedList, i );
}
--m_nIndent;
Write( "</Dependencies>\n" );
Write( "<Dependencies Name=\"Release\">\n" );
++m_nIndent;
visitedList.Purge();
for( int i = 0; i < projects.Count(); i++ ) {
TraverseFrom( projects, dependencyGraph, visitedList, i );
}
--m_nIndent;
Write( "</Dependencies>\n" );
}
Write( "</CodeLite_Project>\n" );
fclose( m_fp );
}
void TraverseFrom( CUtlVector<CDependency_Project*> &projects, CUtlGraph<int, int> &dependencyGraph, CUtlVector<int> &visitedList, int root ) {
CUtlGraphVisitor<int> visitor( dependencyGraph );
if ( visitedList.Find( root ) != visitedList.InvalidIndex() )
return;
// this project has no dependencies, just emit it
if ( !visitor.Begin( root ) )
{
Write( "<Project Name=\"%s\"/>\n", projects[ root ]->m_ProjectName.String() );
visitedList.AddToTail( root );
return;
}
// printf( "considering %i (%s)\n", root, projects[ root ]->m_ProjectName.String() );
while ( visitor.Advance() ) {
// printf( "%i (%s) depends on %i (%s)\n", root, projects[ root ]->m_ProjectName.String(), visitor.CurrentNode(), projects[ visitor.CurrentNode() ]->m_ProjectName.String() );
TraverseFrom( projects, dependencyGraph, visitedList, visitor.CurrentNode() );
}
Write( "<Project Name=\"%s\"/>\n", projects[ root ]->m_ProjectName.String() );
visitedList.AddToTail( root );
// printf( "emitting %i (%s)\n", root, projects[ root ]->m_ProjectName.String() );
}
void ResolveAdditionalProjectDependencies(
CDependency_Project *pCurProject,
CUtlVector<CDependency_Project*> &projects,
CUtlVector<CDependency_Project*> &additionalProjectDependencies ) {
for ( int i=0; i < pCurProject->m_AdditionalProjectDependencies.Count(); i++ ) {
const char *pLookingFor = pCurProject->m_AdditionalProjectDependencies[i].String();
int j;
for ( j=0; j < projects.Count(); j++ ) {
if ( V_stricmp( projects[j]->m_ProjectName.String(), pLookingFor ) == 0 )
break;
}
if ( j == projects.Count() )
g_pVPC->VPCError( "Project %s lists '%s' in its $AdditionalProjectDependencies, but there is no project by that name.", pCurProject->GetName(), pLookingFor );
additionalProjectDependencies.AddToTail( projects[j] );
}
}
const char* FindInFile( const char *pFilename, const char *pFileData, const char *pSearchFor ) {
const char *pPos = V_stristr( pFileData, pSearchFor );
if ( !pPos )
g_pVPC->VPCError( "Can't find ProjectGUID in %s.", pFilename );
return pPos + V_strlen( pSearchFor );
}
void Write( const char *pMsg, ... ) {
char sOut[8192];
va_list marker;
va_start( marker, pMsg );
V_vsnprintf( sOut, sizeof( sOut ), pMsg, marker );
va_end( marker );
for ( int i=0; i < m_nIndent; i++ )
fprintf( m_fp, " " );
fprintf( m_fp, "%s", sOut );
}
FILE *m_fp;
int m_nIndent;
};
static CSolutionGenerator_CodeLite g_SolutionGenerator_CodeLite;
IBaseSolutionGenerator* GetSolutionGenerator_CodeLite() {
return &g_SolutionGenerator_CodeLite;
}
@@ -0,0 +1,323 @@
//======= Copyright 1996-2016, Valve Corporation, All rights reserved. ========
//
// Purpose:
//
//=============================================================================
#include "vpc.h"
#include "dependencies.h"
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
void MakeFriendlyProjectName( char *pchProject )
{
int strLen = V_strlen( pchProject );
for ( int j = 0; j < strLen; j++ )
{
if ( pchProject[j] == ' ' )
pchProject[j] = '_';
if ( pchProject[j] == '(' || pchProject[j] == ')' )
{
V_memmove( pchProject+j, pchProject+j+1, strLen - j );
strLen--;
}
}
}
class CSolutionGenerator_Makefile : public IBaseSolutionGenerator
{
private:
void GenerateProjectNames( CUtlVector<CUtlString> &projNames, CUtlVector<CDependency_Project*> &projects )
{
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
char szFriendlyName[256];
V_strncpy( szFriendlyName, pCurProject->m_ProjectName.String(), sizeof(szFriendlyName) );
MakeFriendlyProjectName( szFriendlyName );
projNames[ projNames.AddToTail() ] = szFriendlyName;
}
}
public:
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
{
// Default extension.
CUtlPathStringHolder tmpSolutionFilename;
if ( !V_GetFileExtension( pSolutionFilename ) )
{
tmpSolutionFilename.Set( pSolutionFilename, ".mak" );
pSolutionFilename = tmpSolutionFilename.Get();
}
Msg( "\nWriting master makefile %s.\n\n", pSolutionFilename );
// Write the file.
FILE *fp = fopen( pSolutionFilename, "wt" );
if ( !fp )
g_pVPC->VPCError( "Can't open %s for writing.", pSolutionFilename );
fprintf( fp, "# VPC MASTER MAKEFILE\n\n\n" );
/*
fprintf( fp, "# Disable built-in rules/variables. We don't depend on them, and they slow down make processing.\n" );
fprintf( fp, "MAKEFLAGS += --no-builtin-rules --no-builtin-variables\n" );
fprintf( fp, "ifeq ($(MAKE_VERBOSE),)\n" );
fprintf( fp, "MAKEFLAGS += --no-print-directory\n" );
fprintf( fp, "endif\n\n");
*/
fprintf( fp, "ifneq \"$(LINUX_TOOLS_PATH)\" \"\"\n" );
fprintf( fp, "TOOL_PATH = $(LINUX_TOOLS_PATH)/\n" );
fprintf( fp, "SHELL := $(TOOL_PATH)bash\n" );
fprintf( fp, "else\n" );
fprintf( fp, "SHELL := /bin/bash\n" );
fprintf( fp, "endif\n" );
fprintf( fp, "\n");
fprintf( fp, "ifdef MAKE_CHROOT\n");
fprintf( fp, " ifneq (\"$(wildcard /etc/schroot/chroot.d/$(MAKE_CHROOT).conf)\",\"\")\n" );
fprintf( fp, " export CHROOT_NAME ?= $(MAKE_CHROOT)\n" );
fprintf( fp, " endif\n" );
fprintf( fp, " export CHROOT_NAME ?= $(subst /,_,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))\n");
fprintf( fp, " CHROOT_CONF := /etc/schroot/chroot.d/$(CHROOT_NAME).conf\n");
fprintf( fp, " ifeq \"$(CHROOT_NAME)\" \"steamrt_scout_amd64\"\n" );
fprintf( fp, " CHROOT_DIR := /var/chroots\n" );
fprintf( fp, " else\n" );
fprintf( fp, " CHROOT_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/tools/runtime/linux)\n");
fprintf( fp, " endif\n" );
fprintf( fp, " RUNTIME_NAME ?= steamrt_scout_amd64\n");
fprintf( fp, " ifneq (\"$(SCHROOT_CHROOT_NAME)\", \"$(CHROOT_NAME)\")\n");
fprintf( fp, " SHELL:=schroot --chroot $(CHROOT_NAME) -- /bin/bash\n");
fprintf( fp, " endif\n");
fprintf( fp, "\n" );
fprintf( fp, " CHROOT_TARBALL = $(CHROOT_DIR)/$(RUNTIME_NAME).tar.xz\n" );
fprintf( fp, " CHROOT_TIMESTAMP_FILE = $(CHROOT_DIR)/$(RUNTIME_NAME)/timestamp\n" );
fprintf( fp, "\n");
fprintf( fp, " ifneq (\"$(wildcard $(CHROOT_TIMESTAMP_FILE))\",\"\")\n" );
fprintf( fp, " ifneq (\"$(wildcard $(CHROOT_TARBALL))\",\"\")\n" );
fprintf( fp, " CHROOT_DEPENDENCY = $(CHROOT_CONF)\n" );
fprintf( fp, " endif\n" );
fprintf( fp, " endif\n" );
fprintf( fp, "endif\n");
fprintf( fp, "ECHO = $(TOOL_PATH)echo\n" );
fprintf( fp, "ETAGS = $(TOOL_PATH)etags\n" );
fprintf( fp, "FIND = $(TOOL_PATH)find\n" );
fprintf( fp, "UNAME = $(TOOL_PATH)uname\n" );
fprintf( fp, "XARGS = $(TOOL_PATH)xargs\n" );
fprintf( fp, "\n");
fprintf( fp, "# to control parallelism, set the MAKE_JOBS environment variable\n" );
fprintf( fp, "ifeq ($(strip $(MAKE_JOBS)),)\n");
fprintf( fp, " ifeq ($(shell $(UNAME)),Darwin)\n" );
fprintf( fp, " CPUS := $(shell /usr/sbin/sysctl -n hw.ncpu)\n" );
fprintf( fp, " endif\n" );
fprintf( fp, " ifeq ($(shell $(UNAME)),Linux)\n" );
fprintf( fp, " CPUS := $(shell $(TOOL_PATH)grep processor /proc/cpuinfo | $(TOOL_PATH)wc -l)\n" );
fprintf( fp, " endif\n" );
fprintf( fp, " MAKE_JOBS := $(CPUS)\n" );
fprintf( fp, "endif\n\n" );
fprintf( fp, "ifeq ($(strip $(MAKE_JOBS)),)\n");
fprintf( fp, " MAKE_JOBS := 8\n" );
fprintf( fp, "endif\n\n" );
// First, make a target with all the project names.
fprintf( fp, "# All projects (default target)\n" );
fprintf( fp, "all: $(CHROOT_DEPENDENCY)\n" );
fprintf( fp, "\t$(MAKE) -f $(lastword $(MAKEFILE_LIST)) -j$(MAKE_JOBS) all-targets\n\n" );
fprintf( fp, "all-targets : " );
CUtlVector<CUtlString> projNames;
GenerateProjectNames( projNames, projects );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "%s ", projNames[i].String() );
}
fprintf( fp, "\n\n\n# Individual projects + dependencies\n\n" );
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
CUtlVector<CDependency_Project*> additionalProjectDependencies;
ResolveAdditionalProjectDependencies( pCurProject, projects, additionalProjectDependencies );
fprintf( fp, "%s : ", projNames[i].String() );
for ( int iTestProject=0; iTestProject < projects.Count(); iTestProject++ )
{
if ( i == iTestProject )
continue;
CDependency_Project *pTestProject = projects[iTestProject];
int dependsOnFlags = k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagRecurse;
if ( pCurProject->DependsOn( pTestProject, dependsOnFlags ) || additionalProjectDependencies.Find( pTestProject ) != additionalProjectDependencies.InvalidIndex() )
{
fprintf( fp, "%s ", projNames[iTestProject].String() );
}
}
// Now add the code to build this thing.
CUtlPathStringHolder fileDir( pCurProject->m_Filename );
fileDir.StripFilename();
fileDir.FixSlashes( '/' );
const char *pFilename = pCurProject->GetProjectFileName();
fprintf( fp, "\n\t@$(ECHO) \"Building: %s\"", projNames[i].String());
fprintf( fp, "\n\t@+$(MAKE) -C %s -f %s $(CLEANPARAM) SHELL=$(SHELL)", fileDir.Get(), pFilename );
fprintf( fp, "\n\n" );
}
fprintf( fp, "# this is a bit over-inclusive, but the alternative (actually adding each referenced c/cpp/h file to\n" );
fprintf( fp, "# the tags file) seems like more work than it's worth. feel free to fix that up if it bugs you. \n" );
fprintf( fp, "TAGS:\n" );
fprintf( fp, "\t@$(TOOL_PATH)rm -f TAGS\n" );
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
CUtlPathStringHolder fileDir( pCurProject->GetProjectFileName() );
fileDir.StripFilename();
fileDir.FixSlashes( '/' );
fprintf( fp, "\t@$(FIND) %s -name \'*.cpp\' -print0 | $(XARGS) -r0 $(ETAGS) --declarations --ignore-indentation --append\n", fileDir.Get() );
fprintf( fp, "\t@$(FIND) %s -name \'*.h\' -print0 | $(XARGS) -r0 $(ETAGS) --language=c++ --declarations --ignore-indentation --append\n", fileDir.Get() );
fprintf( fp, "\t@$(FIND) %s -name \'*.c\' -print0 | $(XARGS) -r0 $(ETAGS) --declarations --ignore-indentation --append\n", fileDir.Get() );
}
fprintf( fp, "\n\n" );
fprintf( fp, "\n# Mark all the projects as phony or else make will see the directories by the same name and think certain targets \n\n" );
fprintf( fp, ".PHONY: TAGS all all-targets showtargets regen showregen clean cleantargets cleanandremove relink " );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "%s ", projNames[i].String() );
}
fprintf( fp, "\n\n\n" );
fprintf( fp, "\n# The standard clean command to clean it all out.\n" );
fprintf( fp, "\nclean: \n" );
fprintf( fp, "\t@$(MAKE) -f $(lastword $(MAKEFILE_LIST)) -j$(MAKE_JOBS) all-targets CLEANPARAM=clean\n\n\n" );
fprintf( fp, "\n# clean targets, so we re-link next time.\n" );
fprintf( fp, "\ncleantargets: \n" );
fprintf( fp, "\t@$(MAKE) -f $(lastword $(MAKEFILE_LIST)) -j$(MAKE_JOBS) all-targets CLEANPARAM=cleantargets\n\n\n" );
fprintf( fp, "\n# p4 edit and remove targets, so we get an entirely clean build.\n" );
fprintf( fp, "\ncleanandremove: \n" );
fprintf( fp, "\t@$(MAKE) -f $(lastword $(MAKEFILE_LIST)) -j$(MAKE_JOBS) all-targets CLEANPARAM=cleanandremove\n\n\n" );
fprintf( fp, "\n#relink\n" );
fprintf( fp, "\nrelink: cleantargets \n" );
fprintf( fp, "\t@$(MAKE) -f $(lastword $(MAKEFILE_LIST)) -j$(MAKE_JOBS) all-targets\n\n\n" );
// Create the showtargets target.
fprintf( fp, "\n# Here's a command to list out all the targets\n\n" );
fprintf( fp, "\nshowtargets: \n" );
fprintf( fp, "\t@$(ECHO) '-------------------' && \\\n" );
fprintf( fp, "\t$(ECHO) '----- TARGETS -----' && \\\n" );
fprintf( fp, "\t$(ECHO) '-------------------' && \\\n" );
fprintf( fp, "\t$(ECHO) 'clean' && \\\n" );
fprintf( fp, "\t$(ECHO) 'regen' && \\\n" );
fprintf( fp, "\t$(ECHO) 'showregen' && \\\n" );
for ( int i=0; i < projects.Count(); i++ )
{
fprintf( fp, "\t$(ECHO) '%s'", projNames[i].String() );
if ( i != projects.Count()-1 )
fprintf( fp, " && \\" );
fprintf( fp, "\n" );
}
fprintf( fp, "\n\n" );
// Create the regen target.
fprintf( fp, "\n# Here's a command to regenerate this makefile\n\n" );
fprintf( fp, "\nregen: \n" );
fprintf( fp, "\t" );
ICommandLine *pCommandLine = CommandLine();
for ( int i=0; i < pCommandLine->ParmCount(); i++ )
{
fprintf( fp, "%s ", pCommandLine->GetParm( i ) );
}
fprintf( fp, "\n\n" );
// Create the showregen target.
fprintf( fp, "\n# Here's a command to list out all the targets\n\n" );
fprintf( fp, "\nshowregen: \n" );
fprintf( fp, "\t@$(ECHO) " );
for ( int i=0; i < pCommandLine->ParmCount(); i++ )
{
fprintf( fp, "%s ", pCommandLine->GetParm( i ) );
}
fprintf( fp, "\n\n" );
// Warn if the chroot is out of date.
fprintf( fp, "ifdef CHROOT_DEPENDENCY\n"
"$(CHROOT_DEPENDENCY): $(CHROOT_TIMESTAMP_FILE)\n"
"$(CHROOT_TIMESTAMP_FILE): $(CHROOT_TARBALL)\n"
"\t@echo \"chroot ${CHROOT_NAME} at $(CHROOT_DIR) is out of date\"\n"
"\t@echo You need to re-run sudo src/tools/runtime/linux/configure_runtime.sh ${CHROOT_NAME}\n"
"endif\n");
fclose( fp );
}
virtual const char *GetSolutionFileExtension() { return "mak"; }
virtual SolutionType_t GetSolutionType( void ) { return ST_MAKEFILE; }
void ResolveAdditionalProjectDependencies(
CDependency_Project *pCurProject,
CUtlVector<CDependency_Project*> &projects,
CUtlVector<CDependency_Project*> &additionalProjectDependencies )
{
for ( int i=0; i < pCurProject->m_AdditionalProjectDependencies.Count(); i++ )
{
const char *pLookingFor = pCurProject->m_AdditionalProjectDependencies[i].String();
int j;
for ( j=0; j < projects.Count(); j++ )
{
if ( V_stricmp_fast( projects[j]->m_ProjectName.String(), pLookingFor ) == 0 )
break;
}
// If we can't resolve the dependency just ignore it.
// This fits a common usage pattern where something
// may depend on tier0 (or whatever) but you don't want
// to have tier0 in the solution since you aren't
// changing it and will just used the checked-in lib.
if ( j < projects.Count() )
{
additionalProjectDependencies.AddToTail( projects[j] );
}
}
}
const char* FindInFile( const char *pFilename, const char *pFileData, const char *pSearchFor )
{
const char *pPos = V_stristr( pFileData, pSearchFor );
if ( !pPos )
g_pVPC->VPCError( "Can't find ProjectGUID in %s.", pFilename );
return pPos + V_strlen( pSearchFor );
}
};
static CSolutionGenerator_Makefile g_SolutionGenerator_Makefile;
IBaseSolutionGenerator* GetMakefileSolutionGenerator()
{
return &g_SolutionGenerator_Makefile;
}
+642
View File
@@ -0,0 +1,642 @@
//===================== Copyright (c) Valve Corporation. All Rights Reserved. ======================
//
// Purpose:
//
//==================================================================================================
#include "vpc.h"
#include "dependencies.h"
#include "tier1/checksum_md5.h"
struct SolutionFolderData_t
{
CUtlString strAbsPath;
CUtlString strFolderName;
CUtlString strGUID;
CUtlString strParentGUID;
CUtlString strSearchPattern;
CUtlVector< CUtlString > files;
};
class CSolutionGenerator_Win32 : public IBaseSolutionGenerator
{
public:
void GetVCPROJSolutionGUID( const char *szProjectExtension, char (&szSolutionGUID)[256] )
{
#if defined( PLATFORM_WINDOWS )
HKEY hKey;
int firstVer = 8;
const int lastVer = 14; // Handle up to VS 14, AKA VS 2015
if ( g_pVPC->Is2010() )
{
firstVer = 10;
}
// Handle both VisualStudio and VCExpress (used by some SourceSDK customers)
const char* productName[] =
{
"VisualStudio",
"VCExpress",
};
for ( int nLocationIter = 0; nLocationIter < 2; ++nLocationIter ) //for some reason I don't care to investigate there are more keys available at HKEY_CURRENT_USER\\Software\\Microsoft\\%s\\%d.0_Config\\Projects (androidproj support)
{
for ( int vsVer = firstVer; vsVer <= lastVer; ++vsVer )
{
for ( int productNumber = 0; productNumber < ARRAYSIZE(productName); ++productNumber )
{
LONG ret;
if ( nLocationIter == 0 )
{
#if defined( _WIN64 )
#define WOW6432NODESTR "Software\\Wow6432Node"
#else
#define WOW6432NODESTR "Software"
#endif
ret = RegOpenKeyEx( HKEY_LOCAL_MACHINE, CFmtStrN<1024>( WOW6432NODESTR "\\Microsoft\\%s\\%d.0\\Projects", productName[ productNumber ], vsVer ).Get(), 0, KEY_READ, &hKey );
}
else if ( nLocationIter == 1 )
{
ret = RegOpenKeyEx( HKEY_CURRENT_USER, CFmtStrN<1024>( "Software\\Microsoft\\%s\\%d.0_Config\\Projects", productName[ productNumber ], vsVer ).Get(), 0, KEY_READ, &hKey );
}
else
{
UNREACHABLE();
}
if ( ret != ERROR_SUCCESS )
continue;
int nEnumKey = 0;
do
{
char szKeyName[MAX_FIXED_PATH];
DWORD dwKeyNameSize = sizeof( szKeyName );
ret = RegEnumKeyEx( hKey, nEnumKey++, szKeyName, &dwKeyNameSize, NULL, NULL, NULL, NULL );
if ( ret == ERROR_NO_MORE_ITEMS )
break;
HKEY hSubKey;
ret = RegOpenKeyEx( hKey, szKeyName, 0, KEY_READ, &hSubKey );
if ( ret == ERROR_SUCCESS )
{
DWORD dwType;
char ext[MAX_BASE_FILENAME];
DWORD dwExtLen = sizeof( ext );
ret = RegQueryValueEx( hSubKey, "DefaultProjectExtension", NULL, &dwType, (BYTE*)ext, &dwExtLen );
RegCloseKey( hSubKey );
// VS 2012 and beyond has the DefaultProjectExtension as vcxproj instead of vcproj
if ( (ret == ERROR_SUCCESS) && (dwType == REG_SZ) && V_stricmp_fast( ext, szProjectExtension ) == 0 )
{
V_strncpy( szSolutionGUID, szKeyName, ARRAYSIZE(szSolutionGUID) );
RegCloseKey( hKey );
return;
}
}
}
while( true );
RegCloseKey( hKey );
}
}
}
#endif
g_pVPC->VPCError( "Unable to find RegKey for .%s files in solutions.", szProjectExtension );
}
const char *UpdateProjectFilename( const char *pProjectFilename, CUtlPathStringHolder *pUpdateBuffer )
{
const char *pExt = V_GetFileExtension( pProjectFilename );
// We may be generating a makefile wrapper solution,
// in which case we need to look at the wrapper
// project instead of the base project.
const char *pProjectExt = "vcproj";
if ( g_pVPC->Is2010() )
{
pProjectExt = "vcxproj";
}
if ( pExt == NULL ||
V_stricmp_fast( pExt, "mak" ) == 0 )
{
pUpdateBuffer->Set( pProjectFilename, ".", pProjectExt );
return pUpdateBuffer->Get();
}
return pProjectFilename;
}
virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
{
// Default extension.
CUtlPathStringHolder tmpSolutionFilename;
if ( !V_GetFileExtension( pSolutionFilename ) )
{
tmpSolutionFilename.Set( pSolutionFilename, ".sln" );
pSolutionFilename = tmpSolutionFilename.Get();
}
CUtlVector<CUtlString> allProjectPlatforms;
{
CUtlVector<CUtlString> platformCollect;
for ( int i = 0; i < projects.Count(); i++ )
{
//collect all the platforms supported by this project
platformCollect.RemoveAll();
projects[i]->m_pProjectGenerator->EnumerateSupportedVPCTargetPlatforms( platformCollect );
//add each supported platform to the final list if it's not already in there
for ( int j = 0; j < platformCollect.Count(); ++j )
{
if ( !allProjectPlatforms.IsValidIndex( allProjectPlatforms.Find( platformCollect[j] ) ) )
{
allProjectPlatforms.AddToTail( platformCollect[j] );
}
}
}
}
g_pVPC->VPCStatus( true, "\nWriting solution file %s.", pSolutionFilename );
// Write the file.
FILE *fp = fopen( pSolutionFilename, "wt" );
if ( !fp )
g_pVPC->VPCError( "Can't open %s for writing.", pSolutionFilename );
if ( g_pVPC->Is2015() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 14.00\n" );
fprintf( fp, "# Visual Studio 2015\n" );
}
else if ( g_pVPC->Is2013() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 12.00\n" ); // Format didn't change from VS 2012 to VS 2013
fprintf( fp, "# Visual Studio 2013\n" );
}
else if ( g_pVPC->Is2012() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 12.00\n" );
fprintf( fp, "# Visual Studio 2012\n" );
}
else if ( g_pVPC->Is2010() )
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 11.00\n" );
fprintf( fp, "# Visual Studio 2010\n" );
}
else
{
fprintf( fp, "\xef\xbb\xbf\nMicrosoft Visual Studio Solution File, Format Version 9.00\n" );
fprintf( fp, "# Visual Studio 2005\n" );
}
fprintf( fp, "#\n" );
fprintf( fp, "# Automatically generated solution:\n" );
fprintf( fp, "# devtools\\bin\\vpc " );
#if defined( PLATFORM_WINDOWS )
for ( int k = 1; k < __argc; ++ k )
fprintf( fp, "%s ", __argv[k] );
#endif
fprintf( fp, "\n" );
fprintf( fp, "#\n" );
fprintf( fp, "#\n" );
if ( !g_pVPC->Is2010() )
{
// if /slnItems <filename> is passed on the command line, build a Solution Items project
const char *pSolutionItemsFilename = g_pVPC->GetSolutionItemsFilename();
if ( pSolutionItemsFilename[0] != '\0' )
{
fprintf( fp, "Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{AAAAAAAA-8B4A-11D0-8D11-90A07D6D6F7D}\"\n" );
fprintf( fp, "\tProjectSection(SolutionItems) = preProject\n" );
WriteSolutionItems( fp );
fprintf( fp, "\tEndProjectSection\n" );
fprintf( fp, "EndProject\n" );
}
}
//Write the data for all the solution folders
CUtlVector< SolutionFolderData_t > solutionFolderData;
WriteSolutionFolders( fp, solutionFolderData );
for ( int i=0; i < projects.Count(); i++ )
{
CDependency_Project *pCurProject = projects[i];
char szBasePath[MAX_PATH];
V_strncpy( szBasePath, pCurProject->m_Filename, ARRAYSIZE( szBasePath ) );
V_StripFilename( szBasePath );
char szOutputFilePath[MAX_PATH];
V_ComposeFileName( szBasePath, pCurProject->GetProjectFileName(), szOutputFilePath, ARRAYSIZE( szOutputFilePath ) );
// Get a relative filename for the vcproj file.
CUtlPathStringHolder updatedFilename;
const char *pFullProjectFilename = UpdateProjectFilename( szOutputFilePath,
&updatedFilename );
char szRelativeFilename[MAX_FIXED_PATH];
if ( !V_MakeRelativePath( pFullProjectFilename, g_pVPC->GetSourcePath(), szRelativeFilename, sizeof( szRelativeFilename ) ) )
g_pVPC->VPCError( "Can't make a relative path (to the base source directory) for %s.", pFullProjectFilename );
char szSolutionGUID[256];
GetVCPROJSolutionGUID( V_GetFileExtension( szRelativeFilename ), szSolutionGUID );
if ( g_pVPC->Is2010() )
{
char *pLastDot;
char pProjectName[MAX_BASE_FILENAME];
// It looks like Incredibuild 3.6 looks to build projects using the full project name
// with _x360 or _win64 attached to the end. Basically, the full project filename with
// the path and .vcxproj extension removed.
Sys_StripPath( pFullProjectFilename, pProjectName, sizeof( pProjectName ) );
pLastDot = V_strrchr( pProjectName, '.' );
if (pLastDot)
{
*pLastDot = 0;
}
fprintf( fp, "Project(\"%s\") = \"%s\", \"%s\", \"{%s}\"\n", szSolutionGUID, pProjectName, szRelativeFilename, pCurProject->GetProjectGUIDString() );
}
else
{
fprintf( fp, "Project(\"%s\") = \"%s\", \"%s\", \"{%s}\"\n", szSolutionGUID, pCurProject->GetName(), szRelativeFilename, pCurProject->GetProjectGUIDString() );
}
bool bHasDependencies = false;
for ( int iTestProject=0; iTestProject < projects.Count(); iTestProject++ )
{
if ( i == iTestProject )
continue;
CDependency_Project *pTestProject = projects[iTestProject];
if ( pCurProject->DependsOn( pTestProject, k_EDependsOnFlagCheckNormalDependencies | k_EDependsOnFlagTraversePastLibs | k_EDependsOnFlagRecurse ) ||
pCurProject->DependsOn( pTestProject, k_EDependsOnFlagCheckAdditionalDependencies | k_EDependsOnFlagTraversePastLibs ) )
{
if ( !bHasDependencies )
{
fprintf( fp, "\tProjectSection(ProjectDependencies) = postProject\n" );
bHasDependencies = true;
}
fprintf( fp, "\t\t{%s} = {%s}\n", projects[iTestProject]->GetProjectGUIDString(), projects[iTestProject]->GetProjectGUIDString() );
}
}
if ( bHasDependencies )
fprintf( fp, "\tEndProjectSection\n" );
fprintf( fp, "EndProject\n" );
}
if ( g_pVPC->Is2010() )
{
fprintf( fp, "Global\n" );
fprintf( fp, " GlobalSection(SolutionConfigurationPlatforms) = preSolution\n" );
for ( int nPlatformIter = 0; nPlatformIter < allProjectPlatforms.Count(); ++nPlatformIter )
{
const char *szVPCPlatformName = allProjectPlatforms[nPlatformIter].Get();
fprintf( fp, " Debug|%s = Debug|%s\n", szVPCPlatformName, szVPCPlatformName );
fprintf( fp, " Release|%s = Release|%s\n", szVPCPlatformName, szVPCPlatformName );
}
fprintf( fp, " EndGlobalSection\n" );
fprintf( fp, " GlobalSection(ProjectConfigurationPlatforms) = postSolution\n" );
for ( int nPlatformIter = 0; nPlatformIter < allProjectPlatforms.Count(); ++nPlatformIter )
{
const char *szVPCPlatformName = allProjectPlatforms[nPlatformIter].Get();
for ( int i=0; i < projects.Count(); i++ )
{
const char *ProjectGUID = projects[i]->GetProjectGUIDString();
IBaseProjectGenerator *pProjectGenerator = projects[i]->m_pProjectGenerator;
bool bBuilds = pProjectGenerator->BuildsForTargetPlatform( szVPCPlatformName );
bool bDeploys = pProjectGenerator->DeploysForVPCTargetPlatform( szVPCPlatformName );
if ( bBuilds || bDeploys )
{
CUtlString sPlatformAlias = pProjectGenerator->GetSolutionPlatformAlias( szVPCPlatformName, this );
const char *szVisualStudioPlatformName = sPlatformAlias.Get();
fprintf( fp, " {%s}.Debug|%s.ActiveCfg = Debug|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
if ( bBuilds )
{
fprintf( fp, " {%s}.Debug|%s.Build.0 = Debug|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
}
if ( bDeploys )
{
fprintf( fp, " {%s}.Debug|%s.Deploy.0 = Debug|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
}
fprintf( fp, " {%s}.Release|%s.ActiveCfg = Release|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
if ( bBuilds )
{
fprintf( fp, " {%s}.Release|%s.Build.0 = Release|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
}
if ( bDeploys )
{
fprintf( fp, " {%s}.Release|%s.Deploy.0 = Release|%s\n", ProjectGUID, szVPCPlatformName, szVisualStudioPlatformName );
}
}
}
}
fprintf( fp, " EndGlobalSection\n" );
fprintf( fp, " GlobalSection(SolutionProperties) = preSolution\n" );
fprintf( fp, " HideSolutionNode = FALSE\n" );
fprintf( fp, " EndGlobalSection\n" );
if ( solutionFolderData.Count() > 0 )
{
//Add the nested solution folders
fprintf( fp, " GlobalSection(NestedProjects) = preSolution\n" );
FOR_EACH_VEC( solutionFolderData, i )
{
if ( !solutionFolderData[i].strParentGUID.IsEmpty() && ShouldWriteSolutionFolder( solutionFolderData[i], solutionFolderData ) )
{
fprintf( fp, "\t\t%s = %s\n", solutionFolderData[i].strGUID.Get(), solutionFolderData[i].strParentGUID.Get() );
}
}
fprintf( fp, " EndGlobalSection\n" );
}
fprintf( fp, "EndGlobal\n" );
}
fclose( fp );
Sys_CopyToMirror( pSolutionFilename );
}
virtual const char *GetSolutionFileExtension() { return "sln"; }
virtual SolutionType_t GetSolutionType( void ) OVERRIDE { return ST_VISUALSTUDIO; }
const char* FindInFile( const char *pFilename, const char *pFileData, const char *pSearchFor )
{
const char *pPos = V_stristr( pFileData, pSearchFor );
if ( !pPos )
{
g_pVPC->VPCError( "Can't find %s in %s.", pSearchFor, pFilename );
}
return pPos + V_strlen( pSearchFor );
}
// Parse g_SolutionItemsFilename, reading in filenames (including wildcards),
// and add them to the Solution Items project we're already writing.
void WriteSolutionItems( FILE *fp )
{
#if defined( PLATFORM_WINDOWS )
CUtlPathStringHolder fullSolutionItemsPath;
if ( V_IsAbsolutePath( g_pVPC->GetSolutionItemsFilename() ) )
fullSolutionItemsPath.Set( g_pVPC->GetSolutionItemsFilename() );
else
fullSolutionItemsPath.ComposeFileName( g_pVPC->GetStartDirectory(), g_pVPC->GetSolutionItemsFilename() );
g_pVPC->GetScript().PushScript( fullSolutionItemsPath );
int numSolutionItems = 0;
while ( g_pVPC->GetScript().GetData() )
{
// read a line
const char *pToken = g_pVPC->GetScript().GetToken( false );
// strip out \r\n chars
char *end = V_strstr( pToken, "\n" );
if ( end )
{
*end = '\0';
}
end = V_strstr( pToken, "\r" );
if ( end )
{
*end = '\0';
}
// bail on strings too small to be paths
if ( V_strlen( pToken ) < 3 )
continue;
// compose an absolute path w/o any ../
CUtlPathStringHolder fullPath;
if ( V_IsAbsolutePath( pToken ) )
fullPath.Set( pToken );
else
fullPath.ComposeFileName( g_pVPC->GetStartDirectory(), pToken );
fullPath.FixSlashesAndDotSlashes();
if ( V_strstr( fullPath, "*" ) != NULL )
{
// wildcard!
CUtlPathStringHolder wildcardPath( fullPath );
wildcardPath.StripFilename();
struct _finddata32_t data;
intptr_t handle = _findfirst32( fullPath, &data );
if ( handle != -1L )
{
do
{
if ( ( data.attrib & _A_SUBDIR ) == 0 )
{
// not a dir, just a filename - add it
fullPath.ComposeFileName( wildcardPath, data.name );
fullPath.FixSlashesAndDotSlashes();
fprintf( fp, "\t\t%s = %s\n", fullPath.Get(), fullPath.Get() );
++numSolutionItems;
}
} while ( _findnext32( handle, &data ) == 0 );
_findclose( handle );
}
}
else
{
// just a file - add it
fprintf( fp, "\t\t%s = %s\n", fullPath.Get(), fullPath.Get() );
++numSolutionItems;
}
}
g_pVPC->GetScript().PopScript();
Msg( "Found %d solution files in %s\n", numSolutionItems, g_pVPC->GetSolutionItemsFilename() );
#endif
}
void AddSolutionFolder( CUtlString strAbsPath, CUtlString strSearchPattern, CUtlVector< SolutionFolderData_t > &solutionFolders )
{
solutionFolders.AddToTail();
SolutionFolderData_t &folder = solutionFolders.Tail();
folder.strAbsPath = strAbsPath;
folder.strAbsPath.StripTrailingSlash();
folder.strSearchPattern = strSearchPattern;
//Get the name of the folder that will be added to the solution
int nPathLength = folder.strAbsPath.Length();
while ( nPathLength > 0 )
{
//Find the last path separator in the path
if ( PATHSEPARATOR( folder.strAbsPath[nPathLength-1] ) )
{
break;
}
nPathLength--;
}
folder.strFolderName = folder.strAbsPath.Slice( nPathLength );
folder.strFolderName.ToLower();
//Get the GUID of the folder
MD5Context_t ctx;
unsigned char digest[MD5_DIGEST_LENGTH];
V_memset( &ctx, 0, sizeof( ctx ) );
V_memset( digest, 0, sizeof( digest ) );
MD5Init( &ctx );
MD5Update( &ctx, (unsigned char *)folder.strAbsPath.Get(), folder.strAbsPath.Length() );
MD5Final( digest, &ctx );
char szMD5[64];
V_binarytohex( digest, MD5_DIGEST_LENGTH, szMD5, sizeof( szMD5 ) );
V_strupper_fast( szMD5 );
char szGUID[100];
V_snprintf( szGUID, sizeof( szGUID ), "{%8.8s-%4.4s-%4.4s-%4.4s-%12.12s}", szMD5, &szMD5[8], &szMD5[12], &szMD5[16], &szMD5[20] );
folder.strGUID = szGUID;
}
void AddFilesToSolutionFolder( CUtlVector< SolutionFolderData_t > &folders, int nIndex )
{
#if defined( PLATFORM_WINDOWS )
CUtlString strSearchPattern = folders[nIndex].strSearchPattern;
bool bAllFiles = strSearchPattern == "*.*";
const char *pszSearchExtension = V_GetFileExtensionSafe( strSearchPattern );
CUtlString strSearchPath = CUtlString::PathJoin( folders[nIndex].strAbsPath, "*.*" );
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile( strSearchPath, &findFileData );
if ( hFind != INVALID_HANDLE_VALUE )
{
do
{
//FindFirstFile and FindNextFile find "." and ".." as files when searched using "*.*"
//we don't want these to be added to our lists
if ( findFileData.cFileName[0] != '.' )
{
//If the found file is actually a directory
if ( findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
{
//Found a sub-dir, add it to the list of folders and add all the files in the sub-dir
CUtlString strSubDirPath = CUtlString::PathJoin( folders[nIndex].strAbsPath, findFileData.cFileName );
AddSolutionFolder( strSubDirPath, folders[nIndex].strSearchPattern, folders );
//Set the parent GUID for the sub-directory
int nSubDirIndex = folders.Count() - 1;
folders[nSubDirIndex].strParentGUID = folders[nIndex].strGUID;
//Recursively add the files from the sub-dir
AddFilesToSolutionFolder( folders, nSubDirIndex );
}
else
{
//Add this file to the list if we are adding all files or if this files extension matches the search pattern
const char *pszExtension = V_GetFileExtensionSafe( findFileData.cFileName );
if ( bAllFiles || !V_stricmp_fast( pszExtension, pszSearchExtension ) )
{
folders[nIndex].files.AddToTail( CUtlString::PathJoin( folders[nIndex].strAbsPath, findFileData.cFileName ) );
}
}
}
} while ( FindNextFile( hFind, &findFileData ) != 0 );
FindClose( hFind );
}
#endif
}
bool ShouldWriteSolutionFolder( SolutionFolderData_t &folder, CUtlVector< SolutionFolderData_t > &solutionFolderData )
{
if ( folder.files.Count() > 0 )
{
//Write the folder if it has files
return true;
}
else
{
//Only write empty folders if they are the parent of another folder that has files or children that have files
FOR_EACH_VEC( solutionFolderData, i )
{
if ( folder.strGUID == solutionFolderData[i].strParentGUID && ShouldWriteSolutionFolder( solutionFolderData[i], solutionFolderData ) )
{
return true;
}
}
}
return false;
}
void WriteSolutionFolders( FILE *fp, CUtlVector< SolutionFolderData_t > &solutionFolderData )
{
const CUtlVector< CUtlString > &solutionFolderNames = g_pVPC->GetSolutionFolderNames();
char szOldPath[MAX_FIXED_PATH];
V_GetCurrentDirectory( szOldPath, ARRAYSIZE( szOldPath ) );
V_SetCurrentDirectory( g_pVPC->GetSourcePath() );
FOR_EACH_VEC( solutionFolderNames, x )
{
//Get the path and search pattern for the folder
CUtlString strAbsPath, strSearchPattern;
if ( solutionFolderNames[x].GetExtension().IsEmpty() )
{
//No search pattern provided, assume "*.*" (all files)
strAbsPath = solutionFolderNames[x].AbsPath( NULL, k_bVPCForceLowerCase );
strSearchPattern = "*.*";
}
else
{
//Separate the path and search pattern
strAbsPath = solutionFolderNames[x].StripFilename().AbsPath( NULL, k_bVPCForceLowerCase );
strSearchPattern = solutionFolderNames[x].UnqualifiedFilename();
}
AddSolutionFolder( strAbsPath, strSearchPattern, solutionFolderData );
AddFilesToSolutionFolder( solutionFolderData, solutionFolderData.Count() - 1 );
}
V_SetCurrentDirectory( szOldPath );
//Write out each solution folder
FOR_EACH_VEC( solutionFolderData, i )
{
if ( ShouldWriteSolutionFolder( solutionFolderData[i], solutionFolderData ) )
{
fprintf( fp, "Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"%s\", \"%s\", \"%s\"\n", solutionFolderData[i].strFolderName.Get(), solutionFolderData[i].strFolderName.Get(), solutionFolderData[i].strGUID.Get() );
if ( solutionFolderData[i].files.Count() > 0 )
{
fprintf( fp, "\tProjectSection(SolutionItems) = preProject\n" );
FOR_EACH_VEC( solutionFolderData[i].files, j )
{
fprintf( fp, "\t\t%s = %s\n", solutionFolderData[i].files[j].Get(), solutionFolderData[i].files[j].Get() );
}
fprintf( fp, "\tEndProjectSection\n" );
}
fprintf( fp, "EndProject\n" );
}
}
}
};
static CSolutionGenerator_Win32 g_SolutionGenerator_Win32;
IBaseSolutionGenerator* GetSolutionGenerator_Win32()
{
return &g_SolutionGenerator_Win32;
}
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More