protected LinkerBase( C.EBit depth) { var meta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC"); var discovery = meta as C.IToolchainDiscovery; discovery.discover(depth); this.Macros.Add("InstallPath", meta.InstallDir); this.EnvironmentVariables = meta.Environment(depth); var fullLinkExePath = this.getLinkerPath(depth); this.Macros.Add("LinkerPath", Bam.Core.TokenizedString.CreateVerbatim(fullLinkExePath)); this.Macros.AddVerbatim("exeext", ".exe"); this.Macros.AddVerbatim("dynamicprefix", string.Empty); this.Macros.AddVerbatim("dynamicext", ".dll"); this.Macros.AddVerbatim("pluginprefix", string.Empty); this.Macros.AddVerbatim("pluginext", ".dll"); this.Macros.AddVerbatim("libprefix", string.Empty); this.Macros.AddVerbatim("libext", ".lib"); this.Macros.AddVerbatim("pdbext", ".pdb"); this.InheritedEnvironmentVariables.Add("TEMP"); this.InheritedEnvironmentVariables.Add("TMP"); }
VisualCCommon.IRuntimeLibraryPathMeta.CxxRuntimePaths( C.EBit depth) { var redistdir = new Bam.Core.TokenizedStringArray(this.Environment(depth)["VCToolsRedistDir"]); var dynamicLibPaths = new Bam.Core.TokenizedStringArray(); switch (depth) { case C.EBit.ThirtyTwo: dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/x86/Microsoft.VC141.CRT/msvcp140.dll", null, redistdir ) ); break; case C.EBit.SixtyFour: dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/x64/Microsoft.VC141.CRT/msvcp140.dll", null, redistdir ) ); break; default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } return(dynamicLibPaths); }
getLinkerPath( C.EBit depth) { const string executable = "link.exe"; foreach (var path in this.EnvironmentVariables["PATH"]) { var installLocation = Bam.Core.OSUtilities.GetInstallLocation( executable, path.ToString(), this.GetType().Name, throwOnFailure: false ); if (null != installLocation) { return(installLocation.First()); } } var message = new System.Text.StringBuilder(); message.AppendFormat("Unable to locate {0} for {1}-bit on these search locations:", executable, (int)depth); message.AppendLine(); foreach (var path in this.EnvironmentVariables["PATH"]) { message.AppendFormat("\t{0}", path.ToString()); message.AppendLine(); } throw new Bam.Core.Exception(message.ToString()); }
VisualCCommon.IRuntimeLibraryPathMeta.CRuntimePaths( C.EBit depth) { // only redist the VisualC specific version runtime, and the universal CRT // don't redist the api-ms-win-crt-*-l1-1-0.dll files from the WindowsSDK, as I can find no reference // to needing to do so var windowsSDKMeta = Bam.Core.Graph.Instance.PackageMetaData <WindowsSDK.MetaData>("WindowsSDK"); var dynamicLibPaths = new Bam.Core.TokenizedStringArray(); switch (depth) { case C.EBit.ThirtyTwo: { dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/VC/redist/x86/Microsoft.VC140.CRT/vcruntime140.dll", null, new Bam.Core.TokenizedStringArray(this.InstallDir))); dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/Redist/ucrt/DLLs/x86/ucrtbase.dll", null, new Bam.Core.TokenizedStringArray(windowsSDKMeta.InstallDirSDK10))); } break; case C.EBit.SixtyFour: { dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/VC/redist/x64/Microsoft.VC140.CRT/vcruntime140.dll", null, new Bam.Core.TokenizedStringArray(this.InstallDir))); dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/Redist/ucrt/DLLs/x64/ucrtbase.dll", null, new Bam.Core.TokenizedStringArray(windowsSDKMeta.InstallDirSDK10))); } break; default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } return(dynamicLibPaths); }
VisualCCommon.IRuntimeLibraryPathMeta.CRuntimePaths( C.EBit depth) { // only redist the VisualC specific version runtime, and the universal CRT // vcvarsall.bat defines UniversalCRTSdkDir which is suitable for use with both WinSDK8.1 and 10.x // don't redist the api-ms-win-crt-*-l1-1-0.dll files from the WindowsSDK, as I can find no reference // to needing to do so var env = this.Environment(depth); var redistdir = new Bam.Core.TokenizedStringArray(env["VCToolsRedistDir"]); var winsdkdir = env["UniversalCRTSdkDir"]; var dynamicLibPaths = new Bam.Core.TokenizedStringArray(); switch (depth) { case C.EBit.ThirtyTwo: { dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/x86/Microsoft.VC141.CRT/vcruntime140.dll", null, redistdir ) ); dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/Redist/ucrt/DLLs/x86/ucrtbase.dll", null, new Bam.Core.TokenizedStringArray(winsdkdir) ) ); } break; case C.EBit.SixtyFour: { dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/x64/Microsoft.VC141.CRT/vcruntime140.dll", null, redistdir ) ); dynamicLibPaths.Add( Bam.Core.TokenizedString.Create( "$(0)/Redist/ucrt/DLLs/x64/ucrtbase.dll", null, new Bam.Core.TokenizedStringArray(winsdkdir) ) ); } break; default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } return(dynamicLibPaths); }
report_WindowsSDK( System.Collections.Generic.Dictionary <string, Bam.Core.TokenizedStringArray> env, C.EBit depth) { // only need to report it once, not for each environment if (report_WindowsSDK_done) { return; } report_WindowsSDK_done = true; var report = new System.Text.StringBuilder(); report.Append("Using WindowsSDK "); if (env.ContainsKey("WindowsSDKVersion")) { // the WindowsSDKVersion environment variable has a trailing back slash var version = env["WindowsSDKVersion"].ToString(); version = version.TrimEnd(System.IO.Path.DirectorySeparatorChar); report.AppendFormat("version {0} ", version); } var winsdk_installdir = System.String.Empty; if (env.ContainsKey("WindowsSdkDir")) { // WindowsSDK 7.0A, 8.1 has this form winsdk_installdir = env["WindowsSdkDir"].ToString(); } else if (env.ContainsKey("WindowsSDKDir")) { // WindowsSDK 7.1 has this form winsdk_installdir = env["WindowsSDKDir"].ToString(); } else { throw new Bam.Core.Exception("Unable to locate WindowsSDK installation directory environment variable for {0}-bit builds", (int)depth); } report.AppendFormat("installed at {0} ", winsdk_installdir); if (env.ContainsKey("UniversalCRTSdkDir") && env.ContainsKey("UCRTVersion")) { var ucrt_installdir = env["UniversalCRTSdkDir"].ToString(); if (ucrt_installdir != winsdk_installdir) { report.AppendFormat("with UniversalCRT SDK {0} installed at {1} ", env["UCRTVersion"].ToString(), ucrt_installdir ); } } Bam.Core.Log.Info(report.ToString()); }
Bam.Core.TokenizedString VisualCCommon.IRuntimeLibraryPathMeta.MSVCP(C.EBit depth) { switch (depth) { case C.EBit.ThirtyTwo: return(Bam.Core.TokenizedString.CreateVerbatim(this.Meta["InstallDir"] + @"\VC\redist\x86\Microsoft.VC120.CRT\msvcp120.dll")); case C.EBit.SixtyFour: return(Bam.Core.TokenizedString.CreateVerbatim(this.Meta["InstallDir"] + @"\VC\redist\x64\Microsoft.VC120.CRT\msvcp120.dll")); default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } }
protected AssemblerBase( C.EBit depth, string basename) { var meta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC"); var discovery = meta as C.IToolchainDiscovery; discovery.discover(depth); this.EnvironmentVariables = meta.Environment(depth); this.Macros.Add("InstallPath", meta.InstallDir); var fullAsmExePath = this.getAssemblerPath(basename, depth); this.Macros.Add("AssemblerPath", Bam.Core.TokenizedString.CreateVerbatim(fullAsmExePath)); this.Macros.AddVerbatim("objext", ".obj"); }
protected LibrarianBase( C.EBit depth) { var meta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC"); var discovery = meta as C.IToolchainDiscovery; discovery.discover(depth); this.Macros.Add("InstallPath", meta.InstallDir); this.EnvironmentVariables = meta.Environment(depth); var fullLibExePath = this.getLibrarianPath(depth); this.Macros.Add("ArchiverPath", Bam.Core.TokenizedString.CreateVerbatim(fullLibExePath)); this.Macros.AddVerbatim("libprefix", string.Empty); this.Macros.AddVerbatim("libext", ".lib"); }
EnvironmentKey( C.EBit depth) { switch (depth) { case C.EBit.ThirtyTwo: return("Environment32"); case C.EBit.SixtyFour: return("Environment64"); default: throw new Bam.Core.Exception("Unknown bit depth, {0}", depth.ToString()); } }
VisualCCommon.IRuntimeLibraryPathMeta.CxxRuntimePaths( C.EBit depth) { var dynamicLibPaths = new Bam.Core.TokenizedStringArray(); switch (depth) { case C.EBit.ThirtyTwo: dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/VC/redist/x86/Microsoft.VC110.CRT/msvcp110.dll", null, new Bam.Core.TokenizedStringArray(this.InstallDir))); break; case C.EBit.SixtyFour: dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("$(0)/VC/redist/x64/Microsoft.VC110.CRT/msvcp110.dll", null, new Bam.Core.TokenizedStringArray(this.InstallDir))); break; default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } return(dynamicLibPaths); }
get_tool_environment_variables( C.EBit depth, bool has64bithost_32bitcross, bool hasNative64BitTools, Bam.Core.StringArray inherited_envvars = null, System.Collections.Generic.Dictionary <string, Bam.Core.StringArray> required_envvars = null) { // for 'reg' used in vcvarsall subroutines if (null == required_envvars) { required_envvars = new System.Collections.Generic.Dictionary <string, Bam.Core.StringArray>(); } if (required_envvars.ContainsKey("PATH")) { var existing = required_envvars["PATH"]; existing.AddUnique("%WINDIR%\\System32"); required_envvars["PATH"] = existing; } else { required_envvars.Add("PATH", new Bam.Core.StringArray { "%WINDIR%\\System32" }); } // for WindowsSDK-7.1 if (null == inherited_envvars) { inherited_envvars = new Bam.Core.StringArray(); } inherited_envvars.AddUnique("PROCESSOR_ARCHITECTURE"); var env = this.execute_vcvars( depth, has64bithost_32bitcross, hasNative64BitTools, inherited_envvars, required_envvars ); this.Meta.Add(EnvironmentKey(depth), env); }
protected CompilerBase( C.EBit depth) { var meta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC"); var discovery = meta as C.IToolchainDiscovery; discovery.discover(depth); this.MajorVersion = meta.CompilerMajorVersion; this.MinorVersion = meta.CompilerMinorVersion; this.Macros.Add("InstallPath", meta.InstallDir); this.EnvironmentVariables = meta.Environment(depth); var fullCompilerExePath = this.getCompilerPath(depth); this.Macros.Add("CompilerPath", Bam.Core.TokenizedString.CreateVerbatim(fullCompilerExePath)); this.Macros.AddVerbatim("objext", ".obj"); this.InheritedEnvironmentVariables.Add("SystemRoot"); // temp environment variables avoid generation of _CL_<hex> temporary files in the current directory this.InheritedEnvironmentVariables.Add("TEMP"); this.InheritedEnvironmentVariables.Add("TMP"); }
VisualCCommon.IRuntimeLibraryPathMeta.CxxRuntimePaths( C.EBit depth) { // https://social.msdn.microsoft.com/Forums/en-US/7b703997-e0d2-4b25-bb3a-c6a00141221d/visual-studio-2010-missing-mscvr100dll?forum=Vsexpressvcs var dynamicLibPaths = new Bam.Core.TokenizedStringArray(); if (Bam.Core.OSUtilities.Is64BitHosting) { switch (depth) { case C.EBit.ThirtyTwo: dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("C:/Windows/SysWOW64/msvcp100.dll", null)); break; case C.EBit.SixtyFour: dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("C:/Windows/System32/msvcp100.dll", null)); break; default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } } else { switch (depth) { case C.EBit.ThirtyTwo: dynamicLibPaths.Add(Bam.Core.TokenizedString.Create("C:/Windows/System32/msvcp100.dll", null)); break; case C.EBit.SixtyFour: throw new Bam.Core.Exception("64-bit CRT is not available on 32-bit operating systems."); default: throw new Bam.Core.Exception("Unrecognized bit depth, {0}", depth); } } return(dynamicLibPaths); }
Environment( C.EBit depth) { return(this.Meta[EnvironmentKey(depth)] as System.Collections.Generic.Dictionary <string, Bam.Core.TokenizedStringArray>); }
execute_vcvars( C.EBit depth, bool has64bithost_32bitcross, bool hasNative64BitTools, Bam.Core.StringArray inherited_envvars, System.Collections.Generic.Dictionary <string, Bam.Core.StringArray> required_envvars ) { var startinfo = new System.Diagnostics.ProcessStartInfo(); startinfo.FileName = @"c:\Windows\System32\cmd.exe"; startinfo.EnvironmentVariables.Clear(); if (null != inherited_envvars) { foreach (var inherited in inherited_envvars) { startinfo.EnvironmentVariables.Add(inherited, System.Environment.GetEnvironmentVariable(inherited)); } } if (null != required_envvars) { foreach (System.Collections.Generic.KeyValuePair <string, Bam.Core.StringArray> required in required_envvars) { if (startinfo.EnvironmentVariables.ContainsKey(required.Key)) { var existing_value = startinfo.EnvironmentVariables[required.Key]; var updated_value = System.String.Format( "{0};{1}", System.Environment.ExpandEnvironmentVariables(required.Value.ToString(';')), existing_value ); startinfo.EnvironmentVariables[required.Key] = updated_value; } else { startinfo.EnvironmentVariables.Add(required.Key, System.Environment.ExpandEnvironmentVariables(required.Value.ToString(';'))); } } } startinfo.UseShellExecute = false; startinfo.RedirectStandardInput = true; startinfo.RedirectStandardOutput = true; startinfo.RedirectStandardError = true; System.Func <string> vcvarsall_command = () => { var command_and_args = new System.Text.StringBuilder(); command_and_args.Append("vcvarsall.bat "); switch (depth) { case C.EBit.ThirtyTwo: { if (Bam.Core.OSUtilities.Is64BitHosting && has64bithost_32bitcross) { command_and_args.Append("amd64_x86 "); } else { command_and_args.Append("x86 "); } } break; case C.EBit.SixtyFour: { if (Bam.Core.OSUtilities.Is64BitHosting && hasNative64BitTools) { command_and_args.Append("amd64 "); } else { command_and_args.Append("x86_amd64 "); } } break; } // VisualC packages define their 'default' WindowsSDK package to function with // if this is different to what is being used, append the version fo the vcvarsall.bat command var visualC = Bam.Core.Graph.Instance.Packages.First(item => item.Name == "VisualC"); var defaultWindowsSDKVersion = visualC.Dependents.First(item => item.Item1 == "WindowsSDK").Item2; var windowsSDK = Bam.Core.Graph.Instance.Packages.FirstOrDefault(item => item.Name == "WindowsSDK"); if (null != windowsSDK) { if (windowsSDK.Version != defaultWindowsSDKVersion) { command_and_args.Append(System.String.Format("{0} ", windowsSDK.Version)); } else { var option_type = System.Type.GetType("WindowsSDK.Options.WindowsSDK10Version", throwOnError: false); if (null != option_type) { var option_type_instance = System.Activator.CreateInstance(option_type) as Bam.Core.IStringCommandLineArgument; if (null != option_type_instance) { var win10Option = Bam.Core.CommandLineProcessor.Evaluate(option_type_instance); if (null != win10Option) { command_and_args.Append(System.String.Format("{0} ", win10Option)); } } } } } return(command_and_args.ToString()); }; var environment_generator_cmdline = System.String.Empty; // allow the WindowsSDK to provide an alternative mechanism for generating // and environment in which to execute VisualC and WindowsSDK tools var windowssdk_meta = Bam.Core.Graph.Instance.PackageMetaData <WindowsSDK.MetaData>("WindowsSDK"); if (windowssdk_meta.Contains("setenvdir") && windowssdk_meta.Contains("setenvcmd")) { startinfo.WorkingDirectory = windowssdk_meta["setenvdir"] as string; environment_generator_cmdline = windowssdk_meta["setenvcmd"] as string; switch (depth) { case C.EBit.ThirtyTwo: environment_generator_cmdline += " /x86"; break; case C.EBit.SixtyFour: environment_generator_cmdline += " /x64"; break; } } else { startinfo.WorkingDirectory = System.IO.Path.Combine(this.InstallDir.ToString(), subpath_to_vcvars); environment_generator_cmdline = vcvarsall_command(); } // allow the WindowsSDK to override the VisualStudio project's PlatformToolset if (windowssdk_meta.Contains("PlatformToolset")) { var vc_meta = Bam.Core.Graph.Instance.PackageMetaData <VisualC.MetaData>("VisualC"); vc_meta.PlatformToolset = windowssdk_meta["PlatformToolset"] as string; } var arguments = new System.Text.StringBuilder(); arguments.AppendFormat("/C {0} && SET", environment_generator_cmdline); startinfo.Arguments = arguments.ToString(); var process = new System.Diagnostics.Process(); process.StartInfo = startinfo; // if you don't async read the output, then the process will never finish // as the buffer is filled up // EOLs will also be trimmed from these, so always append whole lines var stdout = new System.Text.StringBuilder(); process.OutputDataReceived += (sender, args) => stdout.AppendLine(args.Data); var stderr = new System.Text.StringBuilder(); process.ErrorDataReceived += (sender, args) => stderr.AppendLine(args.Data); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.StandardInput.Close(); process.WaitForExit(); if (process.ExitCode != 0) { throw new Bam.Core.Exception("{0} failed: {1}", environment_generator_cmdline, stderr.ToString()); } var env = new System.Collections.Generic.Dictionary <string, Bam.Core.TokenizedStringArray>(); var lines = stdout.ToString().Split( new[] { System.Environment.NewLine }, System.StringSplitOptions.RemoveEmptyEntries ); foreach (var line in lines) { Bam.Core.Log.DebugMessage("{0}->{1}", environment_generator_cmdline, line); var equals_index = line.IndexOf('='); if (-1 == equals_index) { continue; } var key = line.Remove(equals_index); var value = line.Remove(0, equals_index + 1); if (System.String.IsNullOrEmpty(key) || System.String.IsNullOrEmpty(value)) { continue; } var splitValue = value.Split(new[] { ';' }); var valueArray = new Bam.Core.TokenizedStringArray(); foreach (var v in splitValue) { valueArray.Add(Bam.Core.TokenizedString.CreateVerbatim(v)); } env.Add(key, valueArray); } Bam.Core.Log.Info(@"Generating {0}-bit build environment using '{1}\{2}'", (int)depth, startinfo.WorkingDirectory, environment_generator_cmdline.TrimEnd() ); foreach (System.Collections.Generic.KeyValuePair <string, Bam.Core.TokenizedStringArray> entry in env) { Bam.Core.Log.DebugMessage("\t{0} = {1}", entry.Key, entry.Value.ToString(';')); } return(env); }