1 /* 2 * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package build.tools.projectcreator; 26 27 import java.io.File; 28 import java.io.FileNotFoundException; 29 import java.io.IOException; 30 import java.io.PrintWriter; 31 import java.io.UnsupportedEncodingException; 32 import java.nio.file.FileSystems; 33 import java.util.Iterator; 34 import java.util.LinkedList; 35 import java.util.UUID; 36 import java.util.Vector; 37 38 public class WinGammaPlatformVC10 extends WinGammaPlatform { 39 40 41 LinkedList <String>filters = new LinkedList<String>(); 42 LinkedList <String[]>filterDeps = new LinkedList<String[]>(); 43 44 @Override 45 protected String getProjectExt() { 46 return ".vcxproj"; 47 } 48 49 @Override 50 public void writeProjectFile(String projectFileName, String projectName, 51 Vector<BuildConfig> allConfigs) throws IOException { 52 System.out.println(); 53 System.out.println(" Writing .vcxproj file: " + projectFileName); 54 55 String projDir = Util.normalize(new File(projectFileName).getParent()); 56 57 printWriter = new PrintWriter(projectFileName, "UTF-8"); 58 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 59 startTag("Project", 60 "DefaultTargets", "Build", 61 "ToolsVersion", "4.0", 62 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 63 startTag("ItemGroup", 64 "Label", "ProjectConfigurations"); 65 for (BuildConfig cfg : allConfigs) { 66 startTag("ProjectConfiguration", 67 "Include", cfg.get("Name")); 68 tagData("Configuration", cfg.get("Id")); 69 tagData("Platform", cfg.get("PlatformName")); 70 endTag(); 71 } 72 endTag(); 73 74 startTag("PropertyGroup", "Label", "Globals"); 75 tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}"); 76 tagData("Keyword", "MakeFileProj"); 77 tag("SccProjectName"); 78 tag("SccLocalPath"); 79 endTag(); 80 81 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); 82 83 for (BuildConfig cfg : allConfigs) { 84 startTag(cfg, "PropertyGroup", "Label", "Configuration"); 85 tagData("ConfigurationType", "Makefile"); 86 tagData("UseDebugLibraries", "true"); 87 endTag(); 88 } 89 90 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); 91 startTag("ImportGroup", "Label", "ExtensionSettings"); 92 endTag(); 93 for (BuildConfig cfg : allConfigs) { 94 startTag(cfg, "ImportGroup", "Label", "PropertySheets"); 95 tag("Import", 96 "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props", 97 "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')", 98 "Label", "LocalAppDataPlatform"); 99 endTag(); 100 } 101 102 tag("PropertyGroup", "Label", "UserMacros"); 103 104 startTag("PropertyGroup"); 105 tagData("_ProjectFileVersion", "10.0.30319.1"); 106 for (BuildConfig cfg : allConfigs) { 107 tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep); 108 tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep); 109 tagData(cfg, "LinkIncremental", "false"); 110 } 111 for (BuildConfig cfg : allConfigs) { 112 tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset"); 113 tag(cfg, "CodeAnalysisRules"); 114 tag(cfg, "CodeAnalysisRuleAssemblies"); 115 } 116 for (BuildConfig cfg : allConfigs) { 117 tagData(cfg, "NMakeBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile hotspot LOG=info"); 118 tagData(cfg, "NMakeReBuildCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot hotspot LOG=info"); 119 tagData(cfg, "NMakeCleanCommandLine", cfg.get("MakeBinary") + " -f ../../Makefile clean-hotspot LOG=info"); 120 tagData(cfg, "NMakeOutput", cfg.get("MakeOutput") + Util.sep + "jvm.dll"); 121 tagData(cfg, "NMakePreprocessorDefinitions", Util.join(";", cfg.getDefines())); 122 tagData(cfg, "NMakeIncludeSearchPath", Util.join(";", cfg.getIncludes())); 123 } 124 endTag(); 125 126 for (BuildConfig cfg : allConfigs) { 127 startTag(cfg, "ItemDefinitionGroup"); 128 startTag("ClCompile"); 129 tagV(cfg.getV("CompilerFlags")); 130 endTag(); 131 132 startTag("Link"); 133 tagV(cfg.getV("LinkerFlags")); 134 endTag(); 135 136 endTag(); 137 } 138 139 writeFiles(allConfigs, projDir); 140 141 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); 142 startTag("ImportGroup", "Label", "ExtensionTargets"); 143 endTag(); 144 145 endTag(); 146 printWriter.close(); 147 System.out.println(" Done writing .vcxproj file."); 148 149 writeFilterFile(projectFileName, projectName, allConfigs, projDir); 150 writeUserFile(projectFileName, allConfigs); 151 } 152 153 154 private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException { 155 String userFileName = projectFileName + ".user"; 156 if (new File(userFileName).exists()) { 157 return; 158 } 159 System.out.print(" Writing .vcxproj.user file: " + userFileName); 160 printWriter = new PrintWriter(userFileName, "UTF-8"); 161 162 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 163 startTag("Project", 164 "ToolsVersion", "4.0", 165 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 166 167 for (BuildConfig cfg : allConfigs) { 168 startTag(cfg, "PropertyGroup"); 169 tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe"); 170 // Since we run "make hotspot-import", we get the correct jvm.dll by java.exe. 171 // The '-XX:+PauseAtExit' option 172 // causes the VM to wait for key press before exiting; this 173 // allows any stdout or stderr messages to be seen before 174 // the cmdtool exits. 175 tagData("LocalDebuggerCommandArguments", 176 "-XX:+UnlockDiagnosticVMOptions -XX:+PauseAtExit"); 177 tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot")); 178 endTag(); 179 } 180 181 endTag(); 182 printWriter.close(); 183 System.out.println(" Done."); 184 } 185 186 public void addFilter(String rPath) { 187 filters.add(rPath); 188 } 189 190 public void addFilterDependency(String fileLoc, String filter) { 191 filterDeps.add(new String[] {fileLoc, filter}); 192 } 193 194 private void writeFilterFile(String projectFileName, String projectName, 195 Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException { 196 String filterFileName = projectFileName + ".filters"; 197 System.out.print(" Writing .vcxproj.filters file: " + filterFileName); 198 printWriter = new PrintWriter(filterFileName, "UTF-8"); 199 200 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 201 startTag("Project", 202 "ToolsVersion", "4.0", 203 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 204 205 startTag("ItemGroup"); 206 for (String filter : filters) { 207 startTag("Filter", "Include",filter); 208 UUID uuid = UUID.randomUUID(); 209 tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); 210 endTag(); 211 } 212 endTag(); 213 214 //TODO - do I need to split cpp and hpp files? 215 216 // then all files 217 startTag("ItemGroup"); 218 for (String[] dep : filterDeps) { 219 String tagName = getFileTagFromSuffix(dep[0]); 220 221 startTag(tagName, "Include", dep[0]); 222 tagData("Filter", dep[1]); 223 endTag(); 224 } 225 endTag(); 226 227 endTag(); 228 printWriter.close(); 229 System.out.println(" Done."); 230 } 231 232 public String getFileTagFromSuffix(String fileName) { 233 if (fileName.endsWith(".cpp")) { 234 return"ClCompile"; 235 } else if (fileName.endsWith(".c")) { 236 return "ClCompile"; 237 } else if (fileName.endsWith(".hpp")) { 238 return"ClInclude"; 239 } else if (fileName.endsWith(".h")) { 240 return "ClInclude"; 241 } else { 242 return"None"; 243 } 244 } 245 246 void writeFiles(Vector<BuildConfig> allConfigs, String projDir) { 247 // This code assummes there are no config specific includes. 248 startTag("ItemGroup"); 249 250 String sourceBase = BuildConfig.getFieldString(null, "SourceBase"); 251 252 // Use first config for all global absolute includes. 253 BuildConfig baseConfig = allConfigs.firstElement(); 254 Vector<String> rv = new Vector<String>(); 255 256 // Then use first config for all relative includes 257 Vector<String> ri = new Vector<String>(); 258 baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude"); 259 for (String f : ri) { 260 rv.add(sourceBase + Util.sep + f); 261 } 262 263 baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude"); 264 265 handleIncludes(rv, allConfigs); 266 267 endTag(); 268 } 269 270 // Will visit file tree for each include 271 private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) { 272 for (String path : includes) { 273 FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this); 274 try { 275 ftc.writeFileTree(); 276 } catch (IOException e) { 277 e.printStackTrace(); 278 } 279 } 280 } 281 282 String buildCond(BuildConfig cfg) { 283 return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'"; 284 } 285 286 void tagV(Vector<String> v) { 287 Iterator<String> i = v.iterator(); 288 while(i.hasNext()) { 289 String name = i.next(); 290 String data = i.next(); 291 tagData(name, data); 292 } 293 } 294 295 void tagData(BuildConfig cfg, String name, String data) { 296 tagData(name, data, "Condition", buildCond(cfg)); 297 } 298 299 void tag(BuildConfig cfg, String name, String... attrs) { 300 String[] ss = new String[attrs.length + 2]; 301 ss[0] = "Condition"; 302 ss[1] = buildCond(cfg); 303 System.arraycopy(attrs, 0, ss, 2, attrs.length); 304 305 tag(name, ss); 306 } 307 308 void startTag(BuildConfig cfg, String name, String... attrs) { 309 String[] ss = new String[attrs.length + 2]; 310 ss[0] = "Condition"; 311 ss[1] = buildCond(cfg); 312 System.arraycopy(attrs, 0, ss, 2, attrs.length); 313 314 startTag(name, ss); 315 } 316 317 } 318 319 class CompilerInterfaceVC10 extends CompilerInterface { 320 321 @Override 322 Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) { 323 Vector rv = new Vector(); 324 325 addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes)); 326 addAttr(rv, "PreprocessorDefinitions", 327 Util.join(";", defines).replace("\\\"", "\"")); 328 addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp"); 329 addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch"); 330 addAttr(rv, "AssemblerListingLocation", outDir); 331 addAttr(rv, "ObjectFileName", outDir+Util.sep); 332 addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb"); 333 // Set /nologo option 334 addAttr(rv, "SuppressStartupBanner", "true"); 335 // Surpass the default /Tc or /Tp. 336 addAttr(rv, "CompileAs", "Default"); 337 // Set /W3 option. 338 addAttr(rv, "WarningLevel", "Level3"); 339 // Set /WX option, 340 addAttr(rv, "TreatWarningAsError", "true"); 341 // Set /GS option 342 addAttr(rv, "BufferSecurityCheck", "false"); 343 // Set /Zi option. 344 addAttr(rv, "DebugInformationFormat", "ProgramDatabase"); 345 // Set /Yu option. 346 addAttr(rv, "PrecompiledHeader", "Use"); 347 // Set /EHsc- option 348 addAttr(rv, "ExceptionHandling", ""); 349 350 addAttr(rv, "MultiProcessorCompilation", "true"); 351 352 return rv; 353 } 354 355 @Override 356 Vector getDebugCompilerFlags(String opt, String platformName) { 357 Vector rv = new Vector(); 358 359 // Set /On option 360 addAttr(rv, "Optimization", opt); 361 // Set /MD option. 362 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 363 // Set /Oy- option 364 addAttr(rv, "OmitFramePointers", "false"); 365 // Set /homeparams for x64 debug builds 366 if(platformName.equals("x64")) { 367 addAttr(rv, "AdditionalOptions", "/homeparams"); 368 } 369 370 return rv; 371 } 372 373 @Override 374 Vector getProductCompilerFlags() { 375 Vector rv = new Vector(); 376 377 // Set /O2 option. 378 addAttr(rv, "Optimization", "MaxSpeed"); 379 // Set /Oy- option 380 addAttr(rv, "OmitFramePointers", "false"); 381 // Set /Ob option. 1 is expandOnlyInline 382 addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline"); 383 // Set /GF option. 384 addAttr(rv, "StringPooling", "true"); 385 // Set /MD option. 2 is rtMultiThreadedDLL 386 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 387 // Set /Gy option 388 addAttr(rv, "FunctionLevelLinking", "true"); 389 390 return rv; 391 } 392 393 @Override 394 Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) { 395 Vector rv = new Vector(); 396 397 if(platformName.equals("Win32")) { 398 addAttr(rv, "AdditionalOptions", 399 "/export:JNI_GetDefaultJavaVMInitArgs " + 400 "/export:JNI_CreateJavaVM " + 401 "/export:JVM_FindClassFromBootLoader "+ 402 "/export:JNI_GetCreatedJavaVMs "+ 403 "/export:jio_snprintf /export:jio_printf "+ 404 "/export:jio_fprintf /export:jio_vfprintf "+ 405 "/export:jio_vsnprintf "+ 406 "/export:JVM_GetVersionInfo "+ 407 "/export:JVM_InitAgentProperties"); 408 } 409 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;psapi.lib;version.lib"); 410 addAttr(rv, "OutputFile", outDll); 411 addAttr(rv, "SuppressStartupBanner", "true"); 412 addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); 413 addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb"); 414 addAttr(rv, "SubSystem", "Windows"); 415 addAttr(rv, "BaseAddress", "0x8000000"); 416 addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); 417 418 if(platformName.equals("Win32")) { 419 addAttr(rv, "TargetMachine", "MachineX86"); 420 } else { 421 addAttr(rv, "TargetMachine", "MachineX64"); 422 } 423 424 // We always want the /DEBUG option to get full symbol information in the pdb files 425 addAttr(rv, "GenerateDebugInformation", "true"); 426 427 return rv; 428 } 429 430 @Override 431 Vector getDebugLinkerFlags() { 432 Vector rv = new Vector(); 433 434 // Empty now that /DEBUG option is used by all configs 435 436 return rv; 437 } 438 439 @Override 440 Vector getProductLinkerFlags() { 441 Vector rv = new Vector(); 442 443 // Set /OPT:REF option. 444 addAttr(rv, "OptimizeReferences", "true"); 445 // Set /OPT:ICF option. 446 addAttr(rv, "EnableCOMDATFolding", "true"); 447 448 return rv; 449 } 450 451 @Override 452 void getAdditionalNonKernelLinkerFlags(Vector rv) { 453 extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace"); 454 } 455 456 @Override 457 String getOptFlag() { 458 return "MaxSpeed"; 459 } 460 461 @Override 462 String getNoOptFlag() { 463 return "Disabled"; 464 } 465 466 @Override 467 String makeCfgName(String flavourBuild, String platform) { 468 return flavourBuild + "|" + platform; 469 } 470 471 }