Example #1
0
        public static BuildResult Build(
            string solutionFile, string buildConfiguration = null,
            string buildPlatform = null, string buildTarget = "Build",
            string logVerbosity  = null, bool?inProcess     = null
            )
        {
            bool defaultInProcess = Debugger.IsAttached;

#if WINDOWS
            if (!inProcess.GetValueOrDefault(defaultInProcess))
            {
                var argsDict = new Dictionary <string, object> {
                    { "solutionFile", solutionFile },
                    { "buildConfiguration", buildConfiguration },
                    { "buildPlatform", buildPlatform },
                    { "buildTarget", buildTarget },
                    { "logVerbosity", logVerbosity }
                };
                return(OutOfProcessBuild(argsDict));
            }

            string configString = String.Format("{0}|{1}", buildConfiguration ?? "<default>", buildPlatform ?? "<default>");

            if ((buildConfiguration ?? buildPlatform) != null)
            {
                Console.Error.WriteLine("// Running target '{2}' of '{0}' ({1}) ...", JSIL.Compiler.Program.ShortenPath(solutionFile), configString, buildTarget);
            }
            else
            {
                Console.Error.WriteLine("// Running target '{1}' of '{0}' ...", JSIL.Compiler.Program.ShortenPath(solutionFile), buildTarget);
            }

            var pc               = new ProjectCollection();
            var parms            = new BuildParameters(pc);
            var globalProperties = new Dictionary <string, string> {
                { "JSIL", "building" },
                { "JSILVersion", Assembly.GetExecutingAssembly().GetName().ToString() }
            };

            var             hostServices  = new HostServices();
            var             eventRecorder = new BuildEventRecorder();
            LoggerVerbosity _logVerbosity;

            if ((logVerbosity == null) || !Enum.TryParse(logVerbosity, out _logVerbosity))
            {
                _logVerbosity = LoggerVerbosity.Quiet;
            }

            parms.Loggers = new ILogger[] {
                new ConsoleLogger(_logVerbosity), eventRecorder
            };

            var manager = BuildManager.DefaultBuildManager;

            Console.Error.Write("// Generating MSBuild projects for solution '{0}'...", Path.GetFileName(solutionFile));
            // Begin a fake build so the manager has a logger available.
            manager.BeginBuild(parms);

            var projects = ParseSolutionFile(
                solutionFile, buildConfiguration, buildPlatform,
                globalProperties, manager
                );

            manager.EndBuild();
            Console.Error.WriteLine(" {0} project(s) generated.", projects.Length);

            if (File.ReadAllText(solutionFile).Contains("ProjectSection(ProjectDependencies)"))
            {
                Console.Error.WriteLine("// WARNING: Your solution file contains project dependencies. MSBuild ignores these, so your build may fail. If it does, try building it in Visual Studio first to resolve the dependencies.");
            }

            var allItemsBuilt = new List <BuiltItem>();
            var resultFiles   = new HashSet <string>();

            foreach (var project in projects)
            {
                // Save out the generated msbuild project for each solution, to aid debugging.
                try {
                    project.ToProjectRootElement().Save(project.FullPath, Encoding.UTF8);
                } catch (Exception exc) {
                    Console.Error.WriteLine("// Failed to save generated project '{0}': {1}", Path.GetFileName(project.FullPath), exc.Message);
                }
            }

            foreach (var project in projects)
            {
                Console.Error.WriteLine("// Building project '{0}'...", project.FullPath);

                var request = new BuildRequestData(
                    project,
                    new string[] { buildTarget },
                    hostServices, BuildRequestDataFlags.None
                    );

                Microsoft.Build.Execution.BuildResult result;
                try {
                    result = manager.Build(parms, request);
                } catch (Exception exc) {
                    Console.Error.WriteLine("// Compilation failed: {0}", exc.Message);
                    continue;
                }

                allItemsBuilt.AddRange(ExtractChildProjectResults(manager));

                foreach (var kvp in result.ResultsByTarget)
                {
                    var targetResult = kvp.Value;

                    if ((targetResult.Exception != null) || (targetResult.ResultCode == TargetResultCode.Failure))
                    {
                        string errorMessage = "Unknown error";
                        if (targetResult.Exception != null)
                        {
                            errorMessage = targetResult.Exception.Message;
                        }
                        Console.Error.WriteLine("// Compilation failed for target '{0}': {1}", kvp.Key, errorMessage);
                    }
                }
            }

            // ResultsByTarget doesn't reliably produce all the output executables, so we must
            //  extract them by hand.
            foreach (var builtItem in allItemsBuilt)
            {
                if (builtItem.TargetName != "Build")
                {
                    continue;
                }

                if (!File.Exists(builtItem.OutputPath))
                {
                    Console.Error.WriteLine("// Ignoring nonexistent build output '" + Path.GetFileName(builtItem.OutputPath) + "'.");
                    continue;
                }

                var extension = Path.GetExtension(builtItem.OutputPath).ToLowerInvariant();

                switch (extension)
                {
                case ".exe":
                case ".dll":
                    resultFiles.Add(builtItem.OutputPath);
                    break;

                default:
                    Console.Error.WriteLine("// Ignoring build output '" + Path.GetFileName(builtItem.OutputPath) + "' due to unknown file type.");
                    break;
                }
            }

            return(new BuildResult(
                       Path.GetFullPath(solutionFile),
                       resultFiles.ToArray(),
                       eventRecorder.ProjectsById.Values.ToArray(),
                       eventRecorder.TargetFiles.ToArray(),
                       allItemsBuilt.ToArray()
                       ));
#else // !WINDOWS
            throw new NotImplementedException("Solution building is only supported on Windows when JSILc is compiled using MSBuild/Visual Studio.");
#endif
        }
Example #2
0
        public static BuildResult Build (
            string solutionFile, string buildConfiguration = null, 
            string buildPlatform = null, string buildTarget = "Build", 
            string logVerbosity = null, bool? inProcess = null
        ) {
            bool defaultInProcess = Debugger.IsAttached;

#if WINDOWS
            if (!inProcess.GetValueOrDefault(defaultInProcess)) {
                var argsDict = new Dictionary<string, object> {
                    {"solutionFile", solutionFile},
                    {"buildConfiguration", buildConfiguration},
                    {"buildPlatform", buildPlatform},
                    {"buildTarget", buildTarget},
                    {"logVerbosity", logVerbosity}
                };
                return OutOfProcessBuild(argsDict);
            }

            string configString = String.Format("{0}|{1}", buildConfiguration ?? "<default>", buildPlatform ?? "<default>");

            if ((buildConfiguration ?? buildPlatform) != null)
                Console.Error.WriteLine("// Running target '{2}' of '{0}' ({1}) ...", JSIL.Compiler.Program.ShortenPath(solutionFile), configString, buildTarget);
            else
                Console.Error.WriteLine("// Running target '{1}' of '{0}' ...", JSIL.Compiler.Program.ShortenPath(solutionFile), buildTarget);

            var pc = new ProjectCollection();
            var parms = new BuildParameters(pc);
            var globalProperties = new Dictionary<string, string> {
                {"JSIL", "building"},
                {"JSILVersion", Assembly.GetExecutingAssembly().GetName().ToString() }
            };

            var hostServices = new HostServices();
            var eventRecorder = new BuildEventRecorder();
            LoggerVerbosity _logVerbosity;

            if ((logVerbosity == null) || !Enum.TryParse(logVerbosity, out _logVerbosity))
                _logVerbosity = LoggerVerbosity.Quiet;

            parms.Loggers = new ILogger[] { 
                new ConsoleLogger(_logVerbosity), eventRecorder
            };

            var manager = BuildManager.DefaultBuildManager;

            Console.Error.Write("// Generating MSBuild projects for solution '{0}'...", Path.GetFileName(solutionFile));
            // Begin a fake build so the manager has a logger available.
            manager.BeginBuild(parms);

            var projects = ParseSolutionFile(
                solutionFile, buildConfiguration, buildPlatform,
                globalProperties, manager
            );

            manager.EndBuild();
            Console.Error.WriteLine(" {0} project(s) generated.", projects.Length);

            if (File.ReadAllText(solutionFile).Contains("ProjectSection(ProjectDependencies)")) {
                Console.Error.WriteLine("// WARNING: Your solution file contains project dependencies. MSBuild ignores these, so your build may fail. If it does, try building it in Visual Studio first to resolve the dependencies.");
            }

            var allItemsBuilt = new List<BuiltItem>();
            var resultFiles = new HashSet<string>();

            foreach (var project in projects) {
                // Save out the generated msbuild project for each solution, to aid debugging.
                try {
                    project.ToProjectRootElement().Save(project.FullPath, Encoding.UTF8);
                } catch (Exception exc) {
                    Console.Error.WriteLine("// Failed to save generated project '{0}': {1}", Path.GetFileName(project.FullPath), exc.Message);
                }
            }

            foreach (var project in projects) {
                Console.Error.WriteLine("// Building project '{0}'...", project.FullPath);

                var request = new BuildRequestData(
                    project, 
                    new string[] { buildTarget }, 
                    hostServices, BuildRequestDataFlags.None
                );

                Microsoft.Build.Execution.BuildResult result;
                try {
                    result = manager.Build(parms, request);
                } catch (Exception exc) {
                    Console.Error.WriteLine("// Compilation failed: {0}", exc.Message);
                    continue;
                }

                allItemsBuilt.AddRange(ExtractChildProjectResults(manager));

                foreach (var kvp in result.ResultsByTarget) {
                    var targetResult = kvp.Value;

                    if ((targetResult.Exception != null) || (targetResult.ResultCode == TargetResultCode.Failure)) {
                        string errorMessage = "Unknown error";
                        if (targetResult.Exception != null)
                            errorMessage = targetResult.Exception.Message;
                        Console.Error.WriteLine("// Compilation failed for target '{0}': {1}", kvp.Key, errorMessage);
                    }
                }
            }

            // ResultsByTarget doesn't reliably produce all the output executables, so we must
            //  extract them by hand.
            foreach (var builtItem in allItemsBuilt) {
                if (builtItem.TargetName != "Build")
                    continue;

                if (!File.Exists(builtItem.OutputPath)) {
                    Console.Error.WriteLine("// Ignoring nonexistent build output '" + Path.GetFileName(builtItem.OutputPath) + "'.");
                    continue;
                }

                var extension = Path.GetExtension(builtItem.OutputPath).ToLowerInvariant();

                switch (extension) {
                    case ".exe":
                    case ".dll":
                        resultFiles.Add(builtItem.OutputPath);
                        break;

                    default:
                        Console.Error.WriteLine("// Ignoring build output '" + Path.GetFileName(builtItem.OutputPath) + "' due to unknown file type.");
                        break;
                }
            }

            return new BuildResult(
                Path.GetFullPath(solutionFile),
                resultFiles.ToArray(),
                eventRecorder.ProjectsById.Values.ToArray(),
                eventRecorder.TargetFiles.ToArray(),
                allItemsBuilt.ToArray()
            );
#else // !WINDOWS
            throw new NotImplementedException("Solution building is only supported on Windows when JSILc is compiled using MSBuild/Visual Studio.");
#endif
        }