Пример #1
0
        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");
        }
Пример #2
0
        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);
        }
Пример #3
0
        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());
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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());
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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");
        }
Пример #9
0
        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");
        }
Пример #10
0
        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());
            }
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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");
        }
Пример #14
0
        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);
        }
Пример #15
0
 Environment(
     C.EBit depth)
 {
     return(this.Meta[EnvironmentKey(depth)] as System.Collections.Generic.Dictionary <string, Bam.Core.TokenizedStringArray>);
 }
Пример #16
0
        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);
        }