You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
426 lines
13 KiB
426 lines
13 KiB
//========= 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* > ¯oDefines );
|
|
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 );
|