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.

367 lines
11 KiB

  1. //====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "vpc.h"
  7. #include "projectgenerator_xcode.h"
  8. #ifdef WIN32
  9. #include <direct.h>
  10. #define mkdir(dir, mode) _mkdir(dir)
  11. #define getcwd _getcwd
  12. #endif
  13. static const char *k_pchSource = "Source Files";
  14. static const char *k_pchHeaders = "Header Files";
  15. static const char *k_pchResources = "Resources";
  16. static const char *k_pchVPCFiles = "VPC Files";
  17. static const char *k_pchFrameworksAndLibs = "VPC Files";
  18. void CProjectGenerator_XCode::GenerateXCodeProject( CBaseProjectDataCollector *pCollector, const char *pOutFilename, const char *pMakefileFilename )
  19. {
  20. char sPbxProjFile[MAX_PATH];
  21. sprintf( sPbxProjFile, "%s.xcodeproj", pOutFilename );
  22. mkdir( sPbxProjFile, 0777 );
  23. g_pVPC->VPCStatus( true, "Saving XCode project for: '%s' File: '%s'", pCollector->GetProjectName().String(), sPbxProjFile );
  24. sprintf( sPbxProjFile, "%s.xcodeproj/project.pbxproj", pOutFilename );
  25. m_fp = fopen( sPbxProjFile, "wt" );
  26. m_nIndent = 0;
  27. m_pCollector = pCollector;
  28. m_pMakefileFilename = pMakefileFilename;
  29. WriteHeader();
  30. WriteFileReferences();
  31. WriteFiles();
  32. WriteProject( pMakefileFilename );
  33. //WriteBuildFiles();
  34. WriteBuildConfigurations();
  35. // Write the files list.
  36. WriteTrailer();
  37. fclose( m_fp );
  38. m_fp = NULL;
  39. }
  40. void CProjectGenerator_XCode::Write( const char *pMsg, ... )
  41. {
  42. char sOut[8192];
  43. va_list marker;
  44. va_start( marker, pMsg );
  45. V_vsnprintf( sOut, sizeof( sOut ), pMsg, marker );
  46. va_end( marker );
  47. for ( int i=0; i < m_nIndent; i++ )
  48. fprintf( m_fp, "\t" );
  49. fprintf( m_fp, "%s", sOut );
  50. }
  51. void CProjectGenerator_XCode::WriteHeader()
  52. {
  53. // preamble
  54. Write( "// !$*UTF8*$!\n{\n" );
  55. ++m_nIndent;
  56. Write( "archiveVersion = 1;\n" );
  57. Write( "classes = {\n" );
  58. Write( "};\n" );
  59. Write( "objectVersion = 42;\n" );
  60. Write( "objects = {\n" );
  61. }
  62. void CProjectGenerator_XCode::WriteProject( const char *pMakefileFilename )
  63. {
  64. ++m_nIndent;
  65. Write( "%024X = {\n", m_pCollector );
  66. ++m_nIndent;
  67. Write( "isa = PBXGroup;\n" );
  68. Write( "children = (\n" );
  69. ++m_nIndent;
  70. Write( "%024X /* %s */,\n", k_pchSource, k_pchSource );
  71. Write( "%024X /* %s */,\n", k_pchHeaders, k_pchHeaders );
  72. Write( "%024X /* %s */,\n", k_pchResources, k_pchResources );
  73. Write( "%024X /* %s */,\n", k_pchVPCFiles, k_pchVPCFiles );
  74. --m_nIndent;
  75. Write( ");\n" );
  76. Write( "sourceTree = \"<group>\";\n" );
  77. --m_nIndent;
  78. Write( "};" );
  79. --m_nIndent;
  80. Write( "\n/* End PBXGroup section */\n" );
  81. WriteLegacyTargets( pMakefileFilename );
  82. Write( "\n/* Begin PBXProject section */\n" );
  83. Write( "%024X /* Project object */ = {\n", this );
  84. ++m_nIndent;
  85. Write( "isa = PBXProject;\n" );
  86. Write( "buildConfigurationList = %024X /* Build configuration list for PBXProject \"%s\" */;\n", &(m_pCollector->m_BaseConfigData), m_pCollector->GetProjectName().String() );
  87. Write( "compatibilityVersion = \"Xcode 2.4\";\n" );
  88. Write( "hasScannedForEncodings = 0;\n" );
  89. Write( "mainGroup = %024X;\n", m_pCollector );
  90. Write( "projectDirPath = \"\";\n" );
  91. char sSrcRootRelative[MAX_PATH];
  92. g_pVPC->ResolveMacrosInString( "$SRCDIR", sSrcRootRelative, sizeof( sSrcRootRelative ) );
  93. V_FixSlashes( sSrcRootRelative, '/' );
  94. Write( "projectRoot = \"%s\";\n", sSrcRootRelative );
  95. Write( "targets = (\n" );
  96. ++m_nIndent;
  97. Write( "%024X /* build with make */, \n", &CProjectGenerator_XCode::WriteLegacyTargets );
  98. --m_nIndent;
  99. Write( ");\n" );
  100. --m_nIndent;
  101. Write( "};" );
  102. Write( "\n/* End PBXProject section */\n" );
  103. }
  104. void CProjectGenerator_XCode::WriteBuildFiles()
  105. {
  106. Write( "\n/* Begin PBXBuildFile section */\n" );
  107. for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
  108. {
  109. const char *pFilename = m_pCollector->m_Files[i]->GetName();
  110. Write( "%024X /* %s */ = {isa = PBXBuildFile; fileRef = %024X /* %s */;};\n",
  111. m_pCollector->m_Files[i],
  112. pFilename, m_pCollector->m_Files[i]->GetName(),
  113. pFilename, m_pCollector->m_Files[i]->GetName() );
  114. }
  115. Write( "\n/* End PBXBuildFile section */\n" );
  116. }
  117. void CProjectGenerator_XCode::WriteBuildConfigurations()
  118. {
  119. ++m_nIndent;
  120. CUtlVector< CUtlString > configNames;
  121. m_pCollector->GetAllConfigurationNames( configNames );
  122. Write( "\n/* Begin XCBuildConfiguration section */\n" );
  123. FOR_EACH_VEC( configNames, iConfig )
  124. {
  125. Write( "%024X /* %s */ = {\n", &(configNames[iConfig]), configNames[iConfig].String() );
  126. ++m_nIndent;
  127. Write( "isa = XCBuildConfiguration;\n" );
  128. Write( "buildSettings = {\n" );
  129. ++m_nIndent;
  130. Write( "COPY_PHASE_STRIP = %s;\n", ( V_strstr( configNames[iConfig].String(), "release" ) ? "YES" : "NO" ) );
  131. --m_nIndent;
  132. Write( "};\n" );
  133. Write( "name = %s;\n", configNames[iConfig].String() );
  134. --m_nIndent;
  135. Write( "};\n" );
  136. }
  137. FOR_EACH_VEC( configNames, iConfig )
  138. {
  139. Write( "%024X /* %s */ = {\n", (byte*)&(configNames[iConfig])+1, configNames[iConfig].String() );
  140. ++m_nIndent;
  141. Write( "isa = XCBuildConfiguration;\n" );
  142. Write( "buildSettings = {\n" );
  143. ++m_nIndent;
  144. Write( "PRODUCT_NAME = \"build with make\";\n" );
  145. Write( "CFG = %s;\n", configNames[iConfig].String() );
  146. --m_nIndent;
  147. Write( "};\n" );
  148. Write( "name = %s;\n", configNames[iConfig].String() );
  149. --m_nIndent;
  150. Write( "};\n" );
  151. }
  152. Write( "\n/* End XCBuildConfiguration section */\n" );
  153. Write( "\n/* Begin XCBuildConfigurationList section */\n" );
  154. Write( "%024X /* Build configuration list for PBXProject \"%s\" */ = {\n", &(m_pCollector->m_BaseConfigData), m_pCollector->GetProjectName().String() );
  155. ++m_nIndent;
  156. Write( "isa = XCConfigurationList;\n" );
  157. Write( "buildConfigurations = (\n" );
  158. ++m_nIndent;
  159. FOR_EACH_VEC( configNames, iConfig )
  160. {
  161. Write( "%024X /* %s */,\n", &(configNames[iConfig]), configNames[iConfig].String() );
  162. }
  163. --m_nIndent;
  164. Write( ");\n" );
  165. Write( "defaultConfigurationIsVisible = 0;\n" );
  166. Write( "defaultConfigurationName = %s;\n", configNames[0].String() );
  167. --m_nIndent;
  168. Write( "};\n" );
  169. Write( "%024X /* Build configuration list for PBXLegacyTarget \"build with make\" */ = {\n", (byte*)&(m_pCollector->m_BaseConfigData)+1 );
  170. ++m_nIndent;
  171. Write( "isa = XCConfigurationList;\n" );
  172. Write( "buildConfigurations = (\n" );
  173. ++m_nIndent;
  174. FOR_EACH_VEC( configNames, iConfig )
  175. {
  176. Write( "%024X /* %s */,\n", (byte*)&(configNames[iConfig])+1, configNames[iConfig].String() );
  177. }
  178. --m_nIndent;
  179. Write( ");\n" );
  180. Write( "defaultConfigurationIsVisible = 0;\n" );
  181. Write( "defaultConfigurationName = %s;\n", configNames[0].String() );
  182. --m_nIndent;
  183. Write( "};" );
  184. Write( "\n/* End XCBuildConfigurationList section */\n" );
  185. --m_nIndent;
  186. }
  187. void CProjectGenerator_XCode::WriteLegacyTargets( const char *pchMakefileName )
  188. {
  189. Write( "\n/* Begin PBXLegacyTarget section */\n" );
  190. ++m_nIndent;
  191. Write( "%024X /* build with make */ = {\n", &CProjectGenerator_XCode::WriteLegacyTargets );
  192. ++m_nIndent;
  193. Write( "isa = PBXLegacyTarget;\n");
  194. Write( "buildArgumentsString = \"-f %s $(ACTION) MAKE_VERBOSE=1\";\n", pchMakefileName );
  195. Write( "buildConfigurationList = %024X /* Build configuration list for PBXLegacyTarget \"build with make\" */;\n", (byte*)&(m_pCollector->m_BaseConfigData)+1 );
  196. Write( "buildPhases = (\n" );
  197. Write( ");\n" );
  198. Write( "buildToolPath = /usr/bin/make;\n" );
  199. char rgchCurDir[MAX_PATH];
  200. getcwd( rgchCurDir, MAX_PATH );
  201. Write( "buildWorkingDirectory = %s;\n", rgchCurDir );
  202. Write( "dependencies = (\n" );
  203. Write( ");\n");
  204. Write( "name = \"build with make\";\n" );
  205. Write( "passBuildSettingsInEnvironment = 1;\n" );
  206. Write( "productName = \"build with make\";\n" );
  207. --m_nIndent;
  208. Write( "};\n" );
  209. --m_nIndent;
  210. Write( "\n/* End PBXLegacyTarget section */\n" );
  211. }
  212. void CProjectGenerator_XCode::WriteFileReferences()
  213. {
  214. Write( "\n/* Begin PBXFileReference section */\n" );
  215. ++m_nIndent;
  216. for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
  217. {
  218. const char *pchExtension = V_GetFileExtension( m_pCollector->m_Files[i]->GetName() );
  219. char rgchFileType[MAX_PATH];
  220. if ( pchExtension && ( !Q_stricmp( pchExtension, "cpp" ) || !Q_stricmp( pchExtension, "h" ) || !Q_stricmp( pchExtension, "c" ) || !Q_stricmp( pchExtension, "cc" ) ) )
  221. sprintf( rgchFileType, "sourcecode.cpp.%s", pchExtension );
  222. else
  223. sprintf( rgchFileType, "text.plain" );
  224. char rgchFilePath[MAX_PATH];
  225. Q_strncpy( rgchFilePath, m_pCollector->m_Files[i]->GetName(), sizeof( rgchFilePath ) );
  226. Q_RemoveDotSlashes( rgchFilePath );
  227. Write( "%024X /* %s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = %s; path = \"%s\"; sourceTree = \"<group>\"; };\n",
  228. m_pCollector->m_Files[i],
  229. rgchFilePath,
  230. rgchFileType,
  231. rgchFilePath
  232. );
  233. }
  234. --m_nIndent;
  235. Write( "\n/* End PBXFileReference section */\n" );
  236. }
  237. void CProjectGenerator_XCode::WriteTrailer()
  238. {
  239. Write( "};\n" );
  240. Write( "rootObject = %024X /* project object */;\n", this );
  241. --m_nIndent;
  242. Write( "}\n" );
  243. }
  244. void CProjectGenerator_XCode::WriteConfig( CSpecificConfig *pConfig )
  245. {
  246. }
  247. void CProjectGenerator_XCode::WriteTarget_Build( CSpecificConfig *pConfig )
  248. {
  249. }
  250. void CProjectGenerator_XCode::WriteTarget_Compile( CSpecificConfig *pConfig )
  251. {
  252. }
  253. void CProjectGenerator_XCode::WriteTarget_Rebuild( CSpecificConfig *pConfig )
  254. {
  255. }
  256. void CProjectGenerator_XCode::WriteTarget_Link( CSpecificConfig *pConfig )
  257. {
  258. }
  259. void CProjectGenerator_XCode::WriteTarget_Debug( CSpecificConfig *pConfig )
  260. {
  261. }
  262. void CProjectGenerator_XCode::WriteIncludes( CSpecificConfig *pConfig )
  263. {
  264. }
  265. void CProjectGenerator_XCode::WriteFilesFolder( const char *pFolderName, const char *pExtensions )
  266. {
  267. CUtlVector<char*> extensions;
  268. V_SplitString( pExtensions, ";", extensions );
  269. Write( "%024X /* %s */ = {\n", pFolderName, pFolderName );
  270. ++m_nIndent;
  271. Write( "isa = PBXGroup;\n" );
  272. Write( "children = (\n" );
  273. ++m_nIndent;
  274. for ( int i=m_pCollector->m_Files.First(); i != m_pCollector->m_Files.InvalidIndex(); i=m_pCollector->m_Files.Next( i ) )
  275. {
  276. const char *pFilename = m_pCollector->m_Files[i]->GetName();
  277. // Make sure this file's extension is one of the extensions they're asking for.
  278. bool bValidExt = false;
  279. const char *pFileExtension = V_GetFileExtension( pFilename );
  280. if ( pFileExtension )
  281. {
  282. for ( int iExt=0; iExt < extensions.Count(); iExt++ )
  283. {
  284. const char *pTestExt = extensions[iExt];
  285. if ( pTestExt[0] == '*' && pTestExt[1] == '.' && V_stricmp( pTestExt+2, pFileExtension ) == 0 )
  286. {
  287. bValidExt = true;
  288. break;
  289. }
  290. }
  291. }
  292. if ( bValidExt )
  293. {
  294. char sFixedSlashes[MAX_PATH];
  295. V_strncpy( sFixedSlashes, pFilename, sizeof( sFixedSlashes ) );
  296. Write( "%024X /* %s */,\n", m_pCollector->m_Files[i], sFixedSlashes );
  297. }
  298. }
  299. --m_nIndent;
  300. Write( ");\n" );
  301. Write( "name = \"%s\";\n", pFolderName );
  302. Write( "sourceTree = \"<group>\";\n" );
  303. --m_nIndent;
  304. Write( "};\n" );
  305. }
  306. void CProjectGenerator_XCode::WriteFiles()
  307. {
  308. Write( "\n/* Begin PBXGroup section */\n" );
  309. ++m_nIndent;
  310. 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" );
  311. WriteFilesFolder( k_pchHeaders, "*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if" );
  312. WriteFilesFolder( k_pchResources, "*.plist;*.strings;*.xib" );
  313. WriteFilesFolder( k_pchVPCFiles, "*.vpc" );
  314. --m_nIndent;
  315. }