Counter Strike : Global Offensive Source Code
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

  1. //========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: VPC
  4. //
  5. //=====================================================================================//
  6. #pragma once
  7. // Exclude rarely-used stuff from Windows headers
  8. #define WIN32_LEAN_AND_MEAN
  9. #ifndef VC_EXTRALEAN
  10. #define VC_EXTRALEAN
  11. #endif
  12. #include "utlstring.h"
  13. #include "utlrbtree.h"
  14. #include "utlvector.h"
  15. #include "utlbuffer.h"
  16. #include "utlstack.h"
  17. #include "utldict.h"
  18. #include "utlsortvector.h"
  19. #include "checksum_crc.h"
  20. #include "checksum_md5.h"
  21. #include "fmtstr.h"
  22. #include "exprevaluator.h"
  23. #include "tier1/interface.h"
  24. #include "p4lib/ip4.h"
  25. #include "scriptsource.h"
  26. #include "logging.h"
  27. #ifdef STEAM
  28. #include "vstdlib/strtools.h"
  29. #else
  30. #include "tier1/strtools.h"
  31. #endif
  32. #include "sys_utils.h"
  33. #include "keyvalues.h"
  34. #include "generatordefinition.h"
  35. DECLARE_LOGGING_CHANNEL( LOG_VPC );
  36. #if defined( WIN32 )
  37. #include <atlbase.h>
  38. #include <io.h>
  39. #endif // WIN32
  40. struct KeywordName_t
  41. {
  42. const char *m_pName;
  43. configKeyword_e m_Keyword;
  44. };
  45. typedef bool (*procptr_t)( const char *pPropertyName );
  46. typedef bool (*GetSymbolProc_t)( const char *pKey );
  47. #define INVALID_INDEX -1
  48. struct property_t
  49. {
  50. const char *pName;
  51. procptr_t handler;
  52. int platformMask;
  53. };
  54. enum conditionalType_e
  55. {
  56. CONDITIONAL_NULL,
  57. CONDITIONAL_PLATFORM,
  58. CONDITIONAL_GAME,
  59. CONDITIONAL_CUSTOM
  60. };
  61. struct conditional_t
  62. {
  63. conditional_t()
  64. {
  65. type = CONDITIONAL_NULL;
  66. m_bDefined = false;
  67. m_bGameConditionActive = false;
  68. }
  69. CUtlString name;
  70. CUtlString upperCaseName;
  71. conditionalType_e type;
  72. // a conditional can be present in the table but not defined
  73. // e.g. default conditionals that get set by command line args
  74. bool m_bDefined;
  75. // only used during multiple game iterations for game conditionals as each 'defined' game becomes active
  76. bool m_bGameConditionActive;
  77. };
  78. struct macro_t
  79. {
  80. macro_t()
  81. {
  82. m_bSetupDefineInProjectFile = false;
  83. m_bInternalCreatedMacro = false;
  84. }
  85. CUtlString name;
  86. CUtlString value;
  87. // If set to true, then VPC will add this as a -Dname=value parameter to the compiler's command line.
  88. bool m_bSetupDefineInProjectFile;
  89. // VPC created this macro itself rather than the macro being created from a script file.
  90. bool m_bInternalCreatedMacro;
  91. };
  92. typedef int scriptIndex_t;
  93. struct script_t
  94. {
  95. CUtlString name;
  96. CUtlString m_condition;
  97. };
  98. typedef int projectIndex_t;
  99. struct project_t
  100. {
  101. CUtlString name;
  102. CUtlVector< script_t > scripts;
  103. };
  104. typedef int groupIndex_t;
  105. struct group_t
  106. {
  107. CUtlVector< projectIndex_t > projects;
  108. };
  109. typedef int groupTagIndex_t;
  110. struct groupTag_t
  111. {
  112. groupTag_t()
  113. {
  114. bSameAsProject = false;
  115. }
  116. CUtlString name;
  117. CUtlVector< groupIndex_t > groups;
  118. // this tag is an implicit definition of the project
  119. bool bSameAsProject;
  120. };
  121. struct scriptList_t
  122. {
  123. scriptList_t()
  124. {
  125. m_crc = 0;
  126. }
  127. CUtlString m_scriptName;
  128. CRC32_t m_crc;
  129. };
  130. class IProjectIterator
  131. {
  132. public:
  133. // iProject indexes g_projectList.
  134. virtual bool VisitProject( projectIndex_t iProject, const char *szScriptPath ) = 0;
  135. };
  136. #include "ibasesolutiongenerator.h"
  137. #include "ibaseprojectgenerator.h"
  138. #if defined( WIN32 )
  139. #include "baseprojectdatacollector.h"
  140. #include "projectgenerator_vcproj.h"
  141. #include "projectgenerator_win32.h"
  142. #include "projectgenerator_win32_2010.h"
  143. #include "projectgenerator_xbox360.h"
  144. #include "projectgenerator_xbox360_2010.h"
  145. #include "projectgenerator_ps3.h"
  146. #endif
  147. // This just calls through to both the makefile and any platform specific solution generators.
  148. class CPosixSolutionGenerator : public IBaseSolutionGenerator
  149. {
  150. public:
  151. virtual void GenerateSolutionFile( const char *pSolutionFilename, CUtlVector<CDependency_Project*> &projects )
  152. {
  153. extern IBaseSolutionGenerator* GetSolutionGenerator_Makefile();
  154. GetSolutionGenerator_Makefile()->GenerateSolutionFile( pSolutionFilename, projects );
  155. #ifdef OSX
  156. extern IBaseSolutionGenerator* GetSolutionGenerator_XCode();
  157. GetSolutionGenerator_XCode()->GenerateSolutionFile( pSolutionFilename, projects );
  158. #endif
  159. }
  160. };
  161. class CVPC
  162. {
  163. public:
  164. CVPC();
  165. ~CVPC();
  166. bool Init( int argc, char **argv );
  167. void Shutdown( bool bHasError = false );
  168. void VPCError( const char *pFormat, ... );
  169. void VPCWarning( const char *pFormat, ... );
  170. void VPCStatus( bool bAlwaysSpew, const char *pFormat, ... );
  171. void VPCSyntaxError( const char *pFormat = NULL, ... );
  172. bool IsProjectCurrent( const char *pVCProjFilename );
  173. bool HasCommandLineParameter( const char *pParamName );
  174. bool HasP4SLNCommand();
  175. CScript &GetScript() { return m_Script; }
  176. bool IsVerbose() { return m_bVerbose; }
  177. bool IsQuiet() { return m_bQuiet; }
  178. bool IsShowDependencies() { return m_bShowDeps; }
  179. bool IsForceGenerate() { return m_bForceGenerate; }
  180. bool IsForceIterate() { return m_bForceIterate; }
  181. bool IsDecorateProject() { return m_bDecorateProject; }
  182. bool IsCheckFiles() { return m_bCheckFiles; }
  183. bool Is2010() { return m_bUse2010; }
  184. bool Is2012() { return m_bUse2012; } // When this returns true so does Is2010() because of the file format similarities
  185. bool Is2013() { return m_bUse2013; } // When this returns true so does Is2010() because of the file format similarities
  186. bool IsShowCaseIssues() { return m_bShowCaseIssues; }
  187. bool IsIgnoreRedundancyWarning() { return m_bIgnoreRedundancyWarning; }
  188. void SetIgnoreRedundancyWarning( bool bSet ) { m_bIgnoreRedundancyWarning = bSet; }
  189. const char *GetStartDirectory() { return m_StartDirectory.Get(); }
  190. const char *GetSourcePath() { return m_SourcePath.Get(); }
  191. const char *GetCRCString() { return m_SupplementalCRCString.Get(); }
  192. const char *GetSolutionItemsFilename() { return m_SolutionItemsFilename.Get(); }
  193. const char *GetOutputFilename() { return m_OutputFilename.Get(); }
  194. void SetOutputFilename( const char *pOutputFilename ) { m_OutputFilename = pOutputFilename; }
  195. const char *GetProjectName() { return m_ProjectName.Get(); }
  196. void SetProjectName( const char *pProjectName ) { m_ProjectName = pProjectName; }
  197. const char *GetLoadAddressName() { return m_LoadAddressName.Get(); }
  198. void SetLoadAddressName( const char *pLoadAddressName ) { m_LoadAddressName = pLoadAddressName; }
  199. int ProcessCommandLine();
  200. // Returns the mask identifying what platforms whould be built
  201. bool IsPlatformDefined( const char *pName );
  202. const char *GetTargetPlatformName();
  203. IBaseProjectGenerator *GetProjectGenerator() { return m_pProjectGenerator; }
  204. void SetProjectGenerator( IBaseProjectGenerator *pGenerator ) { m_pProjectGenerator = pGenerator; }
  205. IBaseSolutionGenerator *GetSolutionGenerator() { return m_pSolutionGenerator; }
  206. // Conditionals
  207. conditional_t *FindOrCreateConditional( const char *pName, bool bCreate, conditionalType_e type );
  208. bool ResolveConditionalSymbol( const char *pSymbol );
  209. bool EvaluateConditionalExpression( const char *pExpression );
  210. bool ConditionHasDefinedType( const char* pCondition, conditionalType_e type );
  211. void SetConditional( const char *pName, bool bSet = true );
  212. // Macros
  213. macro_t *FindOrCreateMacro( const char *pName, bool bCreate, const char *pValue );
  214. void ResolveMacrosInString( char const *pString, char *pOutBuff, int outBuffSize );
  215. int GetMacrosMarkedForCompilerDefines( CUtlVector< macro_t* > &macroDefines );
  216. void RemoveScriptCreatedMacros();
  217. const char *GetMacroValue( const char *pName );
  218. void SetMacro( const char *pName, const char *pValue, bool bSetupDefineInProjectFile );
  219. // Iterates all the projects in the specified list, checks their conditionals, and calls pIterator->VisitProject for
  220. // each one that passes the conditional tests.
  221. //
  222. // If bForce is false, then it does a CRC check before visiting any project to see if the target project file is
  223. // already up-to-date with its .vpc file.
  224. void IterateTargetProjects( CUtlVector<projectIndex_t> &projectList, IProjectIterator *pIterator );
  225. bool ParseProjectScript( const char *pScriptName, int depth, bool bQuiet, bool bWriteCRCCheckFile );
  226. void AddScriptToCRCCheck( const char *pScriptName, CRC32_t crc );
  227. const char *KeywordToName( configKeyword_e keyword );
  228. configKeyword_e NameToKeyword( const char *pKeywordName );
  229. private:
  230. void SpewUsage( void );
  231. bool LoadPerforceInterface();
  232. void UnloadPerforceInterface();
  233. void InProcessCRCCheck();
  234. void CheckForInstalledXDK();
  235. void CheckForInstalledPS3SDK();
  236. void DetermineSourcePath();
  237. void SetDefaultSourcePath();
  238. void SetupGenerators();
  239. void SetupDefaultConditionals();
  240. void SetMacrosAndConditionals();
  241. void HandleSingleCommandLineArg( const char *pArg );
  242. void ParseBuildOptions( int argc, char *argv[] );
  243. bool CheckBinPath( char *pOutBinPath, int outBinPathSize );
  244. bool RestartFromCorrectLocation( bool *pIsChild );
  245. void GenerateOptionsCRCString();
  246. void CreateOutputFilename( project_t *pProject, const char *pchPlatform, const char *pGameName, const char *pchExtension );
  247. void FindProjectFromVCPROJ( const char *pScriptNameVCProj );
  248. const char *BuildTempGroupScript( const char *pScriptName );
  249. bool HandleP4SLN( IBaseSolutionGenerator *pSolutionGenerator );
  250. void HandleMKSLN( IBaseSolutionGenerator *pSolutionGenerator, CProjectDependencyGraph &dependencyGraph );
  251. void GenerateBuildSet( CProjectDependencyGraph &dependencyGraph );
  252. bool BuildTargetProjects();
  253. bool BuildTargetProject( IProjectIterator *pIterator, projectIndex_t projectIndex, script_t *pProjectScript, const char *pGameName );
  254. bool m_bVerbose;
  255. bool m_bQuiet;
  256. bool m_bUsageOnly;
  257. bool m_bHelp;
  258. bool m_bSpewPlatforms;
  259. bool m_bSpewGames;
  260. bool m_bSpewGroups;
  261. bool m_bSpewProjects;
  262. bool m_bIgnoreRedundancyWarning;
  263. bool m_bSpewProperties;
  264. bool m_bTestMode;
  265. bool m_bForceGenerate;
  266. bool m_bForceIterate;
  267. bool m_bEnableVpcGameMacro;
  268. bool m_bCheckFiles;
  269. bool m_bDecorateProject;
  270. bool m_bShowDeps;
  271. bool m_bP4AutoAdd;
  272. bool m_bP4SlnCheckEverything;
  273. bool m_bDedicatedBuild;
  274. bool m_bAnyProjectQualified;
  275. bool m_bUse2010;
  276. bool m_bWants2010;
  277. bool m_bUse2012;
  278. bool m_bWants2012;
  279. bool m_bUse2013;
  280. bool m_bWants2013;
  281. bool m_bPS3SDKPresent;
  282. bool m_bXDKPresent;
  283. bool m_bShowCaseIssues;
  284. int m_nArgc;
  285. char **m_ppArgv;
  286. CColorizedLoggingListener m_LoggingListener;
  287. CSysModule *m_pP4Module;
  288. CSysModule *m_pFilesystemModule;
  289. CScript m_Script;
  290. // Path where vpc was started from
  291. CUtlString m_StartDirectory;
  292. // Root path to the sources (i.e. the directory where the vpc_scripts directory can be found in).
  293. CUtlString m_SourcePath;
  294. // strings derived from command-line commands which is checked alongside project CRCs:
  295. CUtlString m_SupplementalCRCString;
  296. CUtlString m_ExtraOptionsCRCString;
  297. CUtlString m_MKSolutionFilename;
  298. CUtlString m_SolutionItemsFilename; // For /slnitems
  299. CUtlString m_P4SolutionFilename; // For /p4sln
  300. CUtlVector< int > m_iP4Changelists;
  301. CUtlString m_OutputFilename;
  302. CUtlString m_ProjectName;
  303. CUtlString m_LoadAddressName;
  304. CUtlString m_TempGroupScriptFilename;
  305. // This abstracts the differences between different output methods.
  306. IBaseProjectGenerator *m_pProjectGenerator;
  307. IBaseSolutionGenerator *m_pSolutionGenerator;
  308. CUtlVector< CUtlString > m_BuildCommands;
  309. public:
  310. CUtlVector< conditional_t > m_Conditionals;
  311. CUtlVector< macro_t > m_Macros;
  312. CUtlVector< scriptList_t > m_ScriptList;
  313. CUtlVector< project_t > m_Projects;
  314. CUtlVector< projectIndex_t > m_TargetProjects;
  315. CUtlVector< group_t > m_Groups;
  316. CUtlVector< groupTag_t > m_GroupTags;
  317. CUtlVector< CUtlString > m_SchemaFiles;
  318. CUtlDict< CUtlString, int > m_CustomBuildSteps;
  319. bool m_bGeneratedProject;
  320. };
  321. extern CVPC *g_pVPC;
  322. extern const char *g_pOption_ImportLibrary; // "$ImportLibrary";
  323. extern const char *g_pOption_OutputFile; // "$OutputFile";
  324. extern const char *g_pOption_AdditionalIncludeDirectories; // "$AdditionalIncludeDirectories"
  325. extern const char *g_pOption_AdditionalProjectDependencies; // "$AdditionalProjectDependencies"
  326. extern const char *g_pOption_AdditionalOutputFiles; // "$AdditionalOutputFiles"
  327. extern const char *g_pOption_PreprocessorDefinitions; // "$PreprocessorDefinitions"
  328. extern char *g_IncludeSeparators[2];
  329. extern void VPC_ParseGroupScript( const char *pScriptName );
  330. extern groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate );
  331. extern void VPC_Keyword_Configuration();
  332. extern void VPC_Keyword_FileConfiguration();
  333. extern void VPC_Config_SpewProperties( configKeyword_e keyword );
  334. extern bool VPC_Config_IgnoreOption( const char *pPropertyName );
  335. extern void VPC_FakeKeyword_SchemaFolder( class CBaseProjectDataCollector *pDataCollector );