1 import java.io.File; 2 import java.io.FileNotFoundException; 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.io.UnsupportedEncodingException; 6 import java.util.Hashtable; 7 import java.util.Iterator; 8 import java.util.TreeSet; 9 import java.util.UUID; 10 import java.util.Vector; 11 12 public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 { 13 14 @Override 15 protected String getProjectExt() { 16 return ".vcxproj"; 17 } 18 19 @Override 20 public void writeProjectFile(String projectFileName, String projectName, 21 Vector<BuildConfig> allConfigs) throws IOException { 22 System.out.println(); 23 System.out.print(" Writing .vcxproj file: " + projectFileName); 24 25 String projDir = Util.normalize(new File(projectFileName).getParent()); 26 27 printWriter = new PrintWriter(projectFileName, "UTF-8"); 28 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 29 startTag("Project", 30 "DefaultTargets", "Build", 31 "ToolsVersion", "4.0", 32 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 33 startTag("ItemGroup", 34 "Label", "ProjectConfigurations"); 35 for (BuildConfig cfg : allConfigs) { 36 startTag("ProjectConfiguration", 37 "Include", cfg.get("Name")); 38 tagData("Configuration", cfg.get("Id")); 39 tagData("Platform", cfg.get("PlatformName")); 40 endTag("ProjectConfiguration"); 41 } 42 endTag("ItemGroup"); 43 44 startTag("PropertyGroup", "Label", "Globals"); 45 tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}"); 46 tag("SccProjectName"); 47 tag("SccLocalPath"); 48 endTag("PropertyGroup"); 49 50 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); 51 52 for (BuildConfig cfg : allConfigs) { 53 startTag(cfg, "PropertyGroup", "Label", "Configuration"); 54 tagData("ConfigurationType", "DynamicLibrary"); 55 tagData("UseOfMfc", "false"); 56 endTag("PropertyGroup"); 57 } 58 59 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); 60 startTag("ImportGroup", "Label", "ExtensionSettings"); 61 endTag("ImportGroup"); 62 for (BuildConfig cfg : allConfigs) { 63 startTag(cfg, "ImportGroup", "Label", "PropertySheets"); 64 tag("Import", 65 "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props", 66 "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')", 67 "Label", "LocalAppDataPlatform"); 68 endTag("ImportGroup"); 69 } 70 71 tag("PropertyGroup", "Label", "UserMacros"); 72 73 startTag("PropertyGroup"); 74 tagData("_ProjectFileVersion", "10.0.30319.1"); 75 for (BuildConfig cfg : allConfigs) { 76 tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep); 77 tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep); 78 tagData(cfg, "LinkIncremental", "false"); 79 } 80 for (BuildConfig cfg : allConfigs) { 81 tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset"); 82 tag(cfg, "CodeAnalysisRules"); 83 tag(cfg, "CodeAnalysisRuleAssemblies"); 84 } 85 endTag("PropertyGroup"); 86 87 for (BuildConfig cfg : allConfigs) { 88 startTag(cfg, "ItemDefinitionGroup"); 89 startTag("ClCompile"); 90 tagV(cfg.getV("CompilerFlags")); 91 endTag("ClCompile"); 92 93 startTag("Link"); 94 tagV(cfg.getV("LinkerFlags")); 95 endTag("Link"); 96 97 startTag("PostBuildEvent"); 98 tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription")); 99 tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n"))); 100 endTag("PostBuildEvent"); 101 102 startTag("PreLinkEvent"); 103 tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription")); 104 tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n"))); 105 endTag("PreLinkEvent"); 106 107 endTag("ItemDefinitionGroup"); 108 } 109 110 writeFiles(allConfigs, projDir); 111 112 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); 113 startTag("ImportGroup", "Label", "ExtensionTargets"); 114 endTag("ImportGroup"); 115 116 endTag("Project"); 117 printWriter.close(); 118 System.out.println(" Done."); 119 120 writeFilterFile(projectFileName, projectName, allConfigs, projDir); 121 writeUserFile(projectFileName, allConfigs); 122 } 123 124 125 private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException { 126 String userFileName = projectFileName + ".user"; 127 if (new File(userFileName).exists()) { 128 return; 129 } 130 System.out.print(" Writing .vcxproj.user file: " + userFileName); 131 printWriter = new PrintWriter(userFileName, "UTF-8"); 132 133 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 134 startTag("Project", 135 "ToolsVersion", "4.0", 136 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 137 138 for (BuildConfig cfg : allConfigs) { 139 startTag(cfg, "PropertyGroup"); 140 tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe"); 141 endTag("PropertyGroup"); 142 } 143 144 endTag("Project"); 145 printWriter.close(); 146 System.out.println(" Done."); 147 } 148 149 private void writeFilterFile(String projectFileName, String projectName, 150 Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException { 151 String filterFileName = projectFileName + ".filters"; 152 System.out.print(" Writing .vcxproj.filters file: " + filterFileName); 153 printWriter = new PrintWriter(filterFileName, "UTF-8"); 154 155 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 156 startTag("Project", 157 "ToolsVersion", "4.0", 158 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 159 160 Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs); 161 TreeSet<FileInfo> sortedFiles = sortFiles(allFiles); 162 Vector<NameFilter> filters = makeFilters(sortedFiles); 163 164 // first all filters 165 startTag("ItemGroup"); 166 for (NameFilter filter : filters) { 167 doWriteFilter(filter, ""); 168 } 169 startTag("Filter", "Include", "Resource Files"); 170 UUID uuid = UUID.randomUUID(); 171 tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); 172 tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"); 173 endTag("Filter"); 174 endTag("ItemGroup"); 175 176 // then all cpp files 177 startTag("ItemGroup"); 178 for (NameFilter filter : filters) { 179 doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() { 180 public boolean pick(FileInfo fi) { 181 return fi.isCpp(); 182 } 183 }, base); 184 } 185 endTag("ItemGroup"); 186 187 // then all header files 188 startTag("ItemGroup"); 189 for (NameFilter filter : filters) { 190 doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() { 191 public boolean pick(FileInfo fi) { 192 return fi.isHeader(); 193 } 194 }, base); 195 } 196 endTag("ItemGroup"); 197 198 // then all other files 199 startTag("ItemGroup"); 200 for (NameFilter filter : filters) { 201 doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() { 202 public boolean pick(FileInfo fi) { 203 return true; 204 } 205 }, base); 206 } 207 endTag("ItemGroup"); 208 209 endTag("Project"); 210 printWriter.close(); 211 System.out.println(" Done."); 212 } 213 214 215 private void doWriteFilter(NameFilter filter, String start) { 216 startTag("Filter", "Include", start + filter.fname); 217 UUID uuid = UUID.randomUUID(); 218 tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); 219 endTag("Filter"); 220 if (filter instanceof ContainerFilter) { 221 Iterator i = ((ContainerFilter)filter).babies(); 222 while (i.hasNext()) { 223 doWriteFilter((NameFilter)i.next(), start + filter.fname + "\\"); 224 } 225 } 226 } 227 228 interface Evaluator { 229 boolean pick(FileInfo fi); 230 } 231 232 private void doWriteFiles(TreeSet<FileInfo> allFiles, NameFilter filter, String start, String tool, Evaluator eval, String base) { 233 if (filter instanceof ContainerFilter) { 234 Iterator i = ((ContainerFilter)filter).babies(); 235 while (i.hasNext()) { 236 doWriteFiles(allFiles, (NameFilter)i.next(), start + filter.fname + "\\", tool, eval, base); 237 } 238 } 239 else { 240 Iterator i = allFiles.iterator(); 241 while (i.hasNext()) { 242 FileInfo fi = (FileInfo)i.next(); 243 244 if (!filter.match(fi)) { 245 continue; 246 } 247 if (eval.pick(fi)) { 248 startTag(tool, "Include", rel(fi.full, base)); 249 tagData("Filter", start + filter.fname); 250 endTag(tool); 251 252 // we not gonna look at this file anymore (sic!) 253 i.remove(); 254 } 255 } 256 } 257 } 258 259 260 void writeFiles(Vector<BuildConfig> allConfigs, String projDir) { 261 Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs); 262 TreeSet<FileInfo> sortedFiles = sortFiles(allFiles); 263 264 // first cpp-files 265 startTag("ItemGroup"); 266 for (FileInfo fi : sortedFiles) { 267 if (!fi.isCpp()) { 268 continue; 269 } 270 writeFile("ClCompile", allConfigs, fi, projDir); 271 } 272 endTag("ItemGroup"); 273 274 // then header-files 275 startTag("ItemGroup"); 276 for (FileInfo fi : sortedFiles) { 277 if (!fi.isHeader()) { 278 continue; 279 } 280 writeFile("ClInclude", allConfigs, fi, projDir); 281 } 282 endTag("ItemGroup"); 283 284 // then others 285 startTag("ItemGroup"); 286 for (FileInfo fi : sortedFiles) { 287 if (fi.isHeader() || fi.isCpp()) { 288 continue; 289 } 290 writeFile("None", allConfigs, fi, projDir); 291 } 292 endTag("ItemGroup"); 293 } 294 295 /** 296 * Make "path" into a relative path using "base" as the base. 297 * 298 * path and base are assumed to be normalized with / as the file separator. 299 * returned path uses "\\" as file separator 300 */ 301 private String rel(String path, String base) 302 { 303 if(!base.endsWith("/")) { 304 base += "/"; 305 } 306 String[] pathTok = path.split("/"); 307 String[] baseTok = base.split("/"); 308 int pi = 0; 309 int bi = 0; 310 StringBuilder newPath = new StringBuilder(); 311 312 // first step past all path components that are the same 313 while (pi < pathTok.length && 314 bi < baseTok.length && 315 pathTok[pi].equals(baseTok[bi])) { 316 pi++; 317 bi++; 318 } 319 320 // for each path component left in base, add "../" 321 while (bi < baseTok.length) { 322 bi++; 323 newPath.append("..\\"); 324 } 325 326 // now add everything left in path 327 while (pi < pathTok.length) { 328 newPath.append(pathTok[pi]); 329 pi++; 330 if (pi != pathTok.length) { 331 newPath.append("\\"); 332 } 333 } 334 return newPath.toString(); 335 } 336 337 private void writeFile(String tool, Vector<BuildConfig> allConfigs, FileInfo fi, String base) { 338 if (fi.attr.configs == null && fi.attr.pchRoot == false && fi.attr.noPch == false) { 339 tag(tool, "Include", rel(fi.full, base)); 340 } 341 else { 342 startTag(tool, "Include", rel(fi.full, base)); 343 for (BuildConfig cfg : allConfigs) { 344 if (fi.attr.configs != null && !fi.attr.configs.contains(cfg.get("Name"))) { 345 tagData(cfg, "ExcludedFromBuild", "true"); 346 } 347 if (fi.attr.pchRoot) { 348 tagData(cfg, "PrecompiledHeader", "Create"); 349 } 350 if (fi.attr.noPch) { 351 startTag(cfg, "PrecompiledHeader"); 352 endTag("PrecompiledHeader"); 353 } 354 } 355 endTag(tool); 356 } 357 } 358 359 String buildCond(BuildConfig cfg) { 360 return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'"; 361 } 362 363 364 void tagV(Vector<String> v) { 365 Iterator<String> i = v.iterator(); 366 while(i.hasNext()) { 367 String name = i.next(); 368 String data = i.next(); 369 tagData(name, data); 370 } 371 } 372 373 void tagData(BuildConfig cfg, String name, String data) { 374 tagData(name, data, "Condition", buildCond(cfg)); 375 } 376 377 void tag(BuildConfig cfg, String name, String... attrs) { 378 String[] ss = new String[attrs.length + 2]; 379 ss[0] = "Condition"; 380 ss[1] = buildCond(cfg); 381 System.arraycopy(attrs, 0, ss, 2, attrs.length); 382 383 tag(name, ss); 384 } 385 386 void startTag(BuildConfig cfg, String name, String... attrs) { 387 String[] ss = new String[attrs.length + 2]; 388 ss[0] = "Condition"; 389 ss[1] = buildCond(cfg); 390 System.arraycopy(attrs, 0, ss, 2, attrs.length); 391 392 startTag(name, ss); 393 } 394 } 395 396 class CompilerInterfaceVC10 extends CompilerInterface { 397 398 @Override 399 Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) { 400 Vector rv = new Vector(); 401 402 addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes)); 403 addAttr(rv, "PreprocessorDefinitions", 404 Util.join(";", defines).replace("\\\"", "\"")); 405 addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp"); 406 addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch"); 407 addAttr(rv, "AssemblerListingLocation", outDir); 408 addAttr(rv, "ObjectFileName", outDir+Util.sep); 409 addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb"); 410 // Set /nologo option 411 addAttr(rv, "SuppressStartupBanner", "true"); 412 // Surpass the default /Tc or /Tp. 413 addAttr(rv, "CompileAs", "Default"); 414 // Set /W3 option. 415 addAttr(rv, "WarningLevel", "Level3"); 416 // Set /WX option, 417 addAttr(rv, "TreatWarningAsError", "true"); 418 // Set /GS option 419 addAttr(rv, "BufferSecurityCheck", "false"); 420 // Set /Zi option. 421 addAttr(rv, "DebugInformationFormat", "ProgramDatabase"); 422 // Set /Yu option. 423 addAttr(rv, "PrecompiledHeader", "Use"); 424 // Set /EHsc- option 425 addAttr(rv, "ExceptionHandling", ""); 426 427 addAttr(rv, "MultiProcessorCompilation", "true"); 428 429 return rv; 430 } 431 432 @Override 433 Vector getDebugCompilerFlags(String opt) { 434 Vector rv = new Vector(); 435 436 // Set /On option 437 addAttr(rv, "Optimization", opt); 438 // Set /FR option. 439 addAttr(rv, "BrowseInformation", "true"); 440 addAttr(rv, "BrowseInformationFile", "$(IntDir)"); 441 // Set /MD option. 442 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 443 // Set /Oy- option 444 addAttr(rv, "OmitFramePointers", "false"); 445 446 return rv; 447 } 448 449 @Override 450 Vector getProductCompilerFlags() { 451 Vector rv = new Vector(); 452 453 // Set /O2 option. 454 addAttr(rv, "Optimization", "MaxSpeed"); 455 // Set /Oy- option 456 addAttr(rv, "OmitFramePointers", "false"); 457 // Set /Ob option. 1 is expandOnlyInline 458 addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline"); 459 // Set /GF option. 460 addAttr(rv, "StringPooling", "true"); 461 // Set /MD option. 2 is rtMultiThreadedDLL 462 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 463 // Set /Gy option 464 addAttr(rv, "FunctionLevelLinking", "true"); 465 466 return rv; 467 } 468 469 @Override 470 Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) { 471 Vector rv = new Vector(); 472 473 addAttr(rv, "AdditionalOptions", 474 "/export:JNI_GetDefaultJavaVMInitArgs " + 475 "/export:JNI_CreateJavaVM " + 476 "/export:JVM_FindClassFromBootLoader "+ 477 "/export:JNI_GetCreatedJavaVMs "+ 478 "/export:jio_snprintf /export:jio_printf "+ 479 "/export:jio_fprintf /export:jio_vfprintf "+ 480 "/export:jio_vsnprintf "+ 481 "/export:JVM_GetVersionInfo "+ 482 "/export:JVM_GetThreadStateNames "+ 483 "/export:JVM_GetThreadStateValues "+ 484 "/export:JVM_InitAgentProperties"); 485 addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib"); 486 addAttr(rv, "OutputFile", outDll); 487 addAttr(rv, "SuppressStartupBanner", "true"); 488 addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); 489 addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb"); 490 addAttr(rv, "SubSystem", "Windows"); 491 addAttr(rv, "BaseAddress", "0x8000000"); 492 addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); 493 494 if(platformName.equals("Win32")) { 495 addAttr(rv, "TargetMachine", "MachineX86"); 496 } else { 497 addAttr(rv, "TargetMachine", "MachineX64"); 498 } 499 500 // We always want the /DEBUG option to get full symbol information in the pdb files 501 addAttr(rv, "GenerateDebugInformation", "true"); 502 503 return rv; 504 } 505 506 @Override 507 Vector getDebugLinkerFlags() { 508 Vector rv = new Vector(); 509 510 // Empty now that /DEBUG option is used by all configs 511 512 return rv; 513 } 514 515 @Override 516 Vector getProductLinkerFlags() { 517 Vector rv = new Vector(); 518 519 // Set /OPT:REF option. 520 addAttr(rv, "OptimizeReferences", "true"); 521 // Set /OPT:ICF option. 522 addAttr(rv, "EnableCOMDATFolding", "true"); 523 524 return rv; 525 } 526 527 @Override 528 void getAdditionalNonKernelLinkerFlags(Vector rv) { 529 extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace"); 530 } 531 532 @Override 533 String getOptFlag() { 534 return "MaxSpeed"; 535 } 536 537 @Override 538 String getNoOptFlag() { 539 return "Disabled"; 540 } 541 542 @Override 543 String makeCfgName(String flavourBuild, String platform) { 544 return flavourBuild + "|" + platform; 545 } 546 547 }