1 /* 2 * Copyright (c) 2011, 2013, 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 import java.io.File; 26 import java.io.FileNotFoundException; 27 import java.io.IOException; 28 import java.io.PrintWriter; 29 import java.io.UnsupportedEncodingException; 30 import java.nio.file.FileSystems; 31 import java.util.Iterator; 32 import java.util.LinkedList; 33 import java.util.UUID; 34 import java.util.Vector; 35 36 public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 { 37 38 39 LinkedList <String>filters = new LinkedList<String>(); 40 LinkedList <String[]>filterDeps = new LinkedList<String[]>(); 41 42 @Override 43 protected String getProjectExt() { 44 return ".vcxproj"; 45 } 46 47 @Override 48 public void writeProjectFile(String projectFileName, String projectName, 49 Vector<BuildConfig> allConfigs) throws IOException { 50 System.out.println(); 51 System.out.println(" Writing .vcxproj file: " + projectFileName); 52 53 String projDir = Util.normalize(new File(projectFileName).getParent()); 54 55 printWriter = new PrintWriter(projectFileName, "UTF-8"); 56 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 57 startTag("Project", 58 "DefaultTargets", "Build", 59 "ToolsVersion", "4.0", 60 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 61 startTag("ItemGroup", 62 "Label", "ProjectConfigurations"); 63 for (BuildConfig cfg : allConfigs) { 64 startTag("ProjectConfiguration", 65 "Include", cfg.get("Name")); 66 tagData("Configuration", cfg.get("Id")); 67 tagData("Platform", cfg.get("PlatformName")); 68 endTag(); 69 } 70 endTag(); 71 72 startTag("PropertyGroup", "Label", "Globals"); 73 tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}"); 74 tag("SccProjectName"); 75 tag("SccLocalPath"); 76 endTag(); 77 78 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props"); 79 80 for (BuildConfig cfg : allConfigs) { 81 startTag(cfg, "PropertyGroup", "Label", "Configuration"); 82 tagData("ConfigurationType", "DynamicLibrary"); 83 tagData("UseOfMfc", "false"); 84 endTag(); 85 } 86 87 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props"); 88 startTag("ImportGroup", "Label", "ExtensionSettings"); 89 endTag(); 90 for (BuildConfig cfg : allConfigs) { 91 startTag(cfg, "ImportGroup", "Label", "PropertySheets"); 92 tag("Import", 93 "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props", 94 "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')", 95 "Label", "LocalAppDataPlatform"); 96 endTag(); 97 } 98 99 tag("PropertyGroup", "Label", "UserMacros"); 100 101 startTag("PropertyGroup"); 102 tagData("_ProjectFileVersion", "10.0.30319.1"); 103 for (BuildConfig cfg : allConfigs) { 104 tagData(cfg, "OutDir", cfg.get("OutputDir") + Util.sep); 105 tagData(cfg, "IntDir", cfg.get("OutputDir") + Util.sep); 106 tagData(cfg, "LinkIncremental", "false"); 107 } 108 for (BuildConfig cfg : allConfigs) { 109 tagData(cfg, "CodeAnalysisRuleSet", "AllRules.ruleset"); 110 tag(cfg, "CodeAnalysisRules"); 111 tag(cfg, "CodeAnalysisRuleAssemblies"); 112 } 113 endTag(); 114 115 for (BuildConfig cfg : allConfigs) { 116 startTag(cfg, "ItemDefinitionGroup"); 117 startTag("ClCompile"); 118 tagV(cfg.getV("CompilerFlags")); 119 endTag(); 120 121 startTag("Link"); 122 tagV(cfg.getV("LinkerFlags")); 123 endTag(); 124 125 startTag("PreLinkEvent"); 126 tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription")); 127 tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n"))); 128 endTag(); 129 130 endTag(); 131 } 132 133 writeFiles(allConfigs, projDir); 134 135 tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets"); 136 startTag("ImportGroup", "Label", "ExtensionTargets"); 137 endTag(); 138 139 endTag(); 140 printWriter.close(); 141 System.out.println(" Done writing .vcxproj file."); 142 143 writeFilterFile(projectFileName, projectName, allConfigs, projDir); 144 writeUserFile(projectFileName, allConfigs); 145 } 146 147 148 private void writeUserFile(String projectFileName, Vector<BuildConfig> allConfigs) throws FileNotFoundException, UnsupportedEncodingException { 149 String userFileName = projectFileName + ".user"; 150 if (new File(userFileName).exists()) { 151 return; 152 } 153 System.out.print(" Writing .vcxproj.user file: " + userFileName); 154 printWriter = new PrintWriter(userFileName, "UTF-8"); 155 156 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 157 startTag("Project", 158 "ToolsVersion", "4.0", 159 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 160 161 for (BuildConfig cfg : allConfigs) { 162 startTag(cfg, "PropertyGroup"); 163 tagData("LocalDebuggerCommand", cfg.get("JdkTargetRoot") + "\\bin\\java.exe"); 164 tagData("LocalDebuggerCommandArguments", "-XXaltjvm=$(TargetDir) -Dsun.java.launcher=gamma"); 165 tagData("LocalDebuggerEnvironment", "JAVA_HOME=" + cfg.get("JdkTargetRoot")); 166 endTag(); 167 } 168 169 endTag(); 170 printWriter.close(); 171 System.out.println(" Done."); 172 } 173 174 public void addFilter(String rPath) { 175 filters.add(rPath); 176 } 177 178 public void addFilterDependency(String fileLoc, String filter) { 179 filterDeps.add(new String[] {fileLoc, filter}); 180 } 181 182 private void writeFilterFile(String projectFileName, String projectName, 183 Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException { 184 String filterFileName = projectFileName + ".filters"; 185 System.out.print(" Writing .vcxproj.filters file: " + filterFileName); 186 printWriter = new PrintWriter(filterFileName, "UTF-8"); 187 188 printWriter.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 189 startTag("Project", 190 "ToolsVersion", "4.0", 191 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003"); 192 193 startTag("ItemGroup"); 194 for (String filter : filters) { 195 startTag("Filter", "Include",filter); 196 UUID uuid = UUID.randomUUID(); 197 tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); 198 endTag(); 199 } 200 startTag("Filter", "Include", "Resource Files"); 201 UUID uuid = UUID.randomUUID(); 202 tagData("UniqueIdentifier", "{" + uuid.toString() + "}"); 203 tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"); 204 endTag(); 205 endTag(); 206 207 //TODO - do I need to split cpp and hpp files? 208 209 // then all files 210 startTag("ItemGroup"); 211 for (String[] dep : filterDeps) { 212 String tagName = getFileTagFromSuffix(dep[0]); 213 214 startTag(tagName, "Include", dep[0]); 215 tagData("Filter", dep[1]); 216 endTag(); 217 } 218 endTag(); 219 220 endTag(); 221 printWriter.close(); 222 System.out.println(" Done."); 223 } 224 225 public String getFileTagFromSuffix(String fileName) { 226 if (fileName.endsWith(".cpp")) { 227 return"ClCompile"; 228 } else if (fileName.endsWith(".c")) { 229 return "ClCompile"; 230 } else if (fileName.endsWith(".hpp")) { 231 return"ClInclude"; 232 } else if (fileName.endsWith(".h")) { 233 return "ClInclude"; 234 } else { 235 return"None"; 236 } 237 } 238 239 void writeFiles(Vector<BuildConfig> allConfigs, String projDir) { 240 // This code assummes there are no config specific includes. 241 startTag("ItemGroup"); 242 243 String sourceBase = BuildConfig.getFieldString(null, "SourceBase"); 244 245 // Use first config for all global absolute includes. 246 BuildConfig baseConfig = allConfigs.firstElement(); 247 Vector<String> rv = new Vector<String>(); 248 249 // Then use first config for all relative includes 250 Vector<String> ri = new Vector<String>(); 251 baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude"); 252 for (String f : ri) { 253 rv.add(sourceBase + Util.sep + f); 254 } 255 256 baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude"); 257 258 handleIncludes(rv, allConfigs); 259 260 endTag(); 261 } 262 263 // Will visit file tree for each include 264 private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) { 265 for (String path : includes) { 266 FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this); 267 try { 268 ftc.writeFileTree(); 269 } catch (IOException e) { 270 e.printStackTrace(); 271 } 272 } 273 } 274 275 String buildCond(BuildConfig cfg) { 276 return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'"; 277 } 278 279 void tagV(Vector<String> v) { 280 Iterator<String> i = v.iterator(); 281 while(i.hasNext()) { 282 String name = i.next(); 283 String data = i.next(); 284 tagData(name, data); 285 } 286 } 287 288 void tagData(BuildConfig cfg, String name, String data) { 289 tagData(name, data, "Condition", buildCond(cfg)); 290 } 291 292 void tag(BuildConfig cfg, String name, String... attrs) { 293 String[] ss = new String[attrs.length + 2]; 294 ss[0] = "Condition"; 295 ss[1] = buildCond(cfg); 296 System.arraycopy(attrs, 0, ss, 2, attrs.length); 297 298 tag(name, ss); 299 } 300 301 void startTag(BuildConfig cfg, String name, String... attrs) { 302 String[] ss = new String[attrs.length + 2]; 303 ss[0] = "Condition"; 304 ss[1] = buildCond(cfg); 305 System.arraycopy(attrs, 0, ss, 2, attrs.length); 306 307 startTag(name, ss); 308 } 309 310 } 311 312 class CompilerInterfaceVC10 extends CompilerInterface { 313 314 @Override 315 Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) { 316 Vector rv = new Vector(); 317 318 addAttr(rv, "AdditionalIncludeDirectories", Util.join(";", includes)); 319 addAttr(rv, "PreprocessorDefinitions", 320 Util.join(";", defines).replace("\\\"", "\"")); 321 addAttr(rv, "PrecompiledHeaderFile", "precompiled.hpp"); 322 addAttr(rv, "PrecompiledHeaderOutputFile", outDir+Util.sep+"vm.pch"); 323 addAttr(rv, "AssemblerListingLocation", outDir); 324 addAttr(rv, "ObjectFileName", outDir+Util.sep); 325 addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb"); 326 // Set /nologo option 327 addAttr(rv, "SuppressStartupBanner", "true"); 328 // Surpass the default /Tc or /Tp. 329 addAttr(rv, "CompileAs", "Default"); 330 // Set /W3 option. 331 addAttr(rv, "WarningLevel", "Level3"); 332 // Set /WX option, 333 addAttr(rv, "TreatWarningAsError", "true"); 334 // Set /GS option 335 addAttr(rv, "BufferSecurityCheck", "false"); 336 // Set /Zi option. 337 addAttr(rv, "DebugInformationFormat", "ProgramDatabase"); 338 // Set /Yu option. 339 addAttr(rv, "PrecompiledHeader", "Use"); 340 // Set /EHsc- option 341 addAttr(rv, "ExceptionHandling", ""); 342 343 addAttr(rv, "MultiProcessorCompilation", "true"); 344 345 return rv; 346 } 347 348 @Override 349 Vector getDebugCompilerFlags(String opt) { 350 Vector rv = new Vector(); 351 352 // Set /On option 353 addAttr(rv, "Optimization", opt); 354 // Set /FR option. 355 addAttr(rv, "BrowseInformation", "true"); 356 addAttr(rv, "BrowseInformationFile", "$(IntDir)"); 357 // Set /MD option. 358 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 359 // Set /Oy- option 360 addAttr(rv, "OmitFramePointers", "false"); 361 362 return rv; 363 } 364 365 @Override 366 Vector getProductCompilerFlags() { 367 Vector rv = new Vector(); 368 369 // Set /O2 option. 370 addAttr(rv, "Optimization", "MaxSpeed"); 371 // Set /Oy- option 372 addAttr(rv, "OmitFramePointers", "false"); 373 // Set /Ob option. 1 is expandOnlyInline 374 addAttr(rv, "InlineFunctionExpansion", "OnlyExplicitInline"); 375 // Set /GF option. 376 addAttr(rv, "StringPooling", "true"); 377 // Set /MD option. 2 is rtMultiThreadedDLL 378 addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); 379 // Set /Gy option 380 addAttr(rv, "FunctionLevelLinking", "true"); 381 382 return rv; 383 } 384 385 @Override 386 Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) { 387 Vector rv = new Vector(); 388 389 addAttr(rv, "AdditionalOptions", 390 "/export:JNI_GetDefaultJavaVMInitArgs " + 391 "/export:JNI_CreateJavaVM " + 392 "/export:JVM_FindClassFromBootLoader "+ 393 "/export:JNI_GetCreatedJavaVMs "+ 394 "/export:jio_snprintf /export:jio_printf "+ 395 "/export:jio_fprintf /export:jio_vfprintf "+ 396 "/export:jio_vsnprintf "+ 397 "/export:JVM_GetVersionInfo "+ 398 "/export:JVM_GetThreadStateNames "+ 399 "/export:JVM_GetThreadStateValues "+ 400 "/export:JVM_InitAgentProperties"); 401 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"); 402 addAttr(rv, "OutputFile", outDll); 403 addAttr(rv, "SuppressStartupBanner", "true"); 404 addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def"); 405 addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb"); 406 addAttr(rv, "SubSystem", "Windows"); 407 addAttr(rv, "BaseAddress", "0x8000000"); 408 addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib"); 409 410 if(platformName.equals("Win32")) { 411 addAttr(rv, "TargetMachine", "MachineX86"); 412 } else { 413 addAttr(rv, "TargetMachine", "MachineX64"); 414 } 415 416 // We always want the /DEBUG option to get full symbol information in the pdb files 417 addAttr(rv, "GenerateDebugInformation", "true"); 418 419 return rv; 420 } 421 422 @Override 423 Vector getDebugLinkerFlags() { 424 Vector rv = new Vector(); 425 426 // Empty now that /DEBUG option is used by all configs 427 428 return rv; 429 } 430 431 @Override 432 Vector getProductLinkerFlags() { 433 Vector rv = new Vector(); 434 435 // Set /OPT:REF option. 436 addAttr(rv, "OptimizeReferences", "true"); 437 // Set /OPT:ICF option. 438 addAttr(rv, "EnableCOMDATFolding", "true"); 439 440 return rv; 441 } 442 443 @Override 444 void getAdditionalNonKernelLinkerFlags(Vector rv) { 445 extAttr(rv, "AdditionalOptions", " /export:AsyncGetCallTrace"); 446 } 447 448 @Override 449 String getOptFlag() { 450 return "MaxSpeed"; 451 } 452 453 @Override 454 String getNoOptFlag() { 455 return "Disabled"; 456 } 457 458 @Override 459 String makeCfgName(String flavourBuild, String platform) { 460 return flavourBuild + "|" + platform; 461 } 462 463 }