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