示例#1
0
        private void MakeFastBuildAllProjectIfNeeded(Builder builder, Dictionary <Solution.Configuration, List <Project.Configuration> > unlinkedConfigurations)
        {
            if (!GenerateFastBuildAllProject)
            {
                return;
            }

            foreach (var solutionFile in SolutionFilesMapping)
            {
                var solutionConfigurations = solutionFile.Value;

                bool generateFastBuildAll             = false;
                var  projectsToBuildPerSolutionConfig = new List <Tuple <Solution.Configuration, List <Solution.Configuration.IncludedProjectInfo> > >();
                foreach (var solutionConfiguration in solutionConfigurations)
                {
                    var configProjects = solutionConfiguration.IncludedProjectInfos;

                    var fastBuildProjectConfsToBuild = configProjects.Where(
                        configProject => (
                            configProject.Configuration.IsFastBuild &&
                            configProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.Yes
                            )
                        ).ToList();

                    if (fastBuildProjectConfsToBuild.Count == 0)
                    {
                        continue;
                    }

                    // if there's only one project to build, no need for the FastBuildAll
                    generateFastBuildAll |= fastBuildProjectConfsToBuild.Count > 1;
                    projectsToBuildPerSolutionConfig.Add(Tuple.Create(solutionConfiguration, fastBuildProjectConfsToBuild));
                }

                if (!generateFastBuildAll)
                {
                    continue;
                }

                builder.LogWriteLine("    extra FastBuildAll project added to solution " + Path.GetFileName(solutionFile.Key));

                // Use the target type from the first solution configuration, as they all should have the same anyway
                var firstSolutionConf = projectsToBuildPerSolutionConfig.First().Item1;

                Project fastBuildAllProject = null;
                foreach (var projectsToBuildInSolutionConfig in projectsToBuildPerSolutionConfig)
                {
                    var solutionConf          = projectsToBuildInSolutionConfig.Item1;
                    var projectConfigsToBuild = projectsToBuildInSolutionConfig.Item2;

                    if (GenerateFastBuildAllOnlyForConfThatNeedIt && projectConfigsToBuild.Count == 1)
                    {
                        continue;
                    }

                    var solutionTarget = solutionConf.Target;
                    if (fastBuildAllProject == null)
                    {
                        var firstProject = projectConfigsToBuild.First();

                        // Use the target type from the current solution configuration, as they all should have the same anyway
                        fastBuildAllProject = new FastBuildAllProject(solutionConf.Target.GetType())
                        {
                            Name                 = FastBuildAllProjectName,
                            RootPath             = firstProject.Project.RootPath,
                            SourceRootPath       = firstProject.Project.RootPath,
                            IsFileNameToLower    = firstProject.Project.IsFileNameToLower,
                            SharpmakeProjectType = Project.ProjectTypeAttribute.Generate
                        };
                    }
                    else
                    {
                        // validate the assumption made above
                        if (fastBuildAllProject.Targets.TargetType != firstSolutionConf.Target.GetType())
                        {
                            throw new Error("Target type must match between all solution configurations");
                        }
                    }

                    fastBuildAllProject.AddTargets(solutionTarget);
                }

                fastBuildAllProject.Targets.BuildTargets();
                fastBuildAllProject.InvokeConfiguration(builder.Context);

                // we need to iterate again after invoking the configure of all the projects so we can tweak their conf
                foreach (var projectsToBuildInSolutionConfig in projectsToBuildPerSolutionConfig)
                {
                    var solutionConf          = projectsToBuildInSolutionConfig.Item1;
                    var projectConfigsToBuild = projectsToBuildInSolutionConfig.Item2;

                    if (GenerateFastBuildAllOnlyForConfThatNeedIt && projectConfigsToBuild.Count == 1)
                    {
                        continue;
                    }

                    var solutionTarget = solutionConf.Target;
                    var projectConf    = fastBuildAllProject.GetConfiguration(solutionTarget);

                    // Re-link projects to the new All project
                    // TODO: We should do something to detect and avoid any circular references that this project can now theoretically create.
                    List <Project.Configuration> projectConfigsToRelink;
                    if (unlinkedConfigurations.TryGetValue(solutionConf, out projectConfigsToRelink))
                    {
                        foreach (Project.Configuration config in projectConfigsToRelink.Distinct())
                        {
                            ProjectsDependingOnFastBuildAllForThisSolution.Add(config.Project);
                        }
                    }

                    projectConf.IsFastBuild = true;

                    projectConf.AddMasterBff(solutionConf.MasterBffFilePath);

                    // output the project in the same folder as the solution, and the same name
                    projectConf.ProjectPath = solutionConf.SolutionPath;
                    if (string.IsNullOrWhiteSpace(FastBuildAllProjectFileSuffix))
                    {
                        throw new Error("FastBuildAllProjectFileSuffix cannot be left empty in solution " + solutionFile);
                    }
                    projectConf.ProjectFileName = solutionFile.Key + FastBuildAllProjectFileSuffix;
                    projectConf.SolutionFolder  = FastBuildAllSolutionFolder;

                    // the project doesn't output anything
                    projectConf.Output = Project.Configuration.OutputType.None;

                    // get some settings that are usually global from the first project
                    // we could expose those, if we need to set them specifically for FastBuildAllProject
                    var firstProject = projectConfigsToBuild.First();
                    projectConf.FastBuildCustomArgs = firstProject.Configuration.FastBuildCustomArgs;
                    projectConf.FastBuildCustomActionsBeforeBuildCommand = firstProject.Configuration.FastBuildCustomActionsBeforeBuildCommand;

                    // add all the projects to build as private dependencies, and OnlyBuildOrder
                    foreach (Configuration.IncludedProjectInfo projectConfigToBuild in projectConfigsToBuild)
                    {
                        // update the ToBuild, as now it is built through the "FastBuildAll" dependency
                        projectConfigToBuild.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency;

                        // Relink any build-order dependencies
                        projectConf.GenericBuildDependencies.AddRange(projectConfigToBuild.Configuration.GenericBuildDependencies);
                        projectConf.GenericBuildDependencies.AddRange(projectConfigToBuild.Configuration.DotNetPublicDependencies.Select(d => d.Configuration).Where(c => !c.IsFastBuild));
                        projectConf.GenericBuildDependencies.AddRange(projectConfigToBuild.Configuration.DotNetPrivateDependencies.Select(d => d.Configuration).Where(c => !c.IsFastBuild));

                        projectConf.AddPrivateDependency(projectConfigToBuild.Target, projectConfigToBuild.Project.GetType(), DependencySetting.OnlyBuildOrder);
                    }

                    // add the newly generated project to the solution config
                    solutionConf.IncludedProjectInfos.Add(
                        new Configuration.IncludedProjectInfo
                    {
                        Project       = fastBuildAllProject,
                        Configuration = projectConf,
                        Target        = solutionTarget,
                        Type          = fastBuildAllProject.GetType(),
                        ToBuild       = Configuration.IncludedProjectInfo.Build.Yes
                    }
                        );
                }

                fastBuildAllProject.Resolve(builder, false);
                fastBuildAllProject.Link(builder);

                builder.RegisterGeneratedProject(fastBuildAllProject);
            }
        }
示例#2
0
        private void MakeFastBuildAllProjectIfNeeded(Builder builder)
        {
            foreach (var solutionFile in SolutionFilesMapping)
            {
                var solutionConfigurations = solutionFile.Value;

                bool generateFastBuildAll             = false;
                var  projectsToBuildPerSolutionConfig = new List <Tuple <Solution.Configuration, List <Solution.Configuration.IncludedProjectInfo> > >();
                foreach (var solutionConfiguration in solutionConfigurations)
                {
                    var configProjects = solutionConfiguration.IncludedProjectInfos;

                    var fastBuildProjectConfsToBuild = configProjects.Where(
                        configProject => (
                            configProject.Configuration.IsFastBuild &&
                            configProject.ToBuild == Solution.Configuration.IncludedProjectInfo.Build.Yes
                            )
                        ).ToList();

                    if (fastBuildProjectConfsToBuild.Count == 0)
                    {
                        continue;
                    }

                    // if there's only one project to build, no need for the FastBuildAll
                    generateFastBuildAll |= fastBuildProjectConfsToBuild.Count > 1;
                    projectsToBuildPerSolutionConfig.Add(Tuple.Create(solutionConfiguration, fastBuildProjectConfsToBuild));
                }

                if (!generateFastBuildAll)
                {
                    continue;
                }

                builder.LogWriteLine("    extra FastBuildAll project added to solution " + Path.GetFileName(solutionFile.Key));

                // Use the target type from the first solution configuration, as they all should have the same anyway
                var firstSolutionConf = projectsToBuildPerSolutionConfig.First().Item1;

                Project fastBuildAllProject = null;
                foreach (var projectsToBuildInSolutionConfig in projectsToBuildPerSolutionConfig)
                {
                    var solutionConf          = projectsToBuildInSolutionConfig.Item1;
                    var projectConfigsToBuild = projectsToBuildInSolutionConfig.Item2;

                    var solutionTarget = solutionConf.Target;
                    if (fastBuildAllProject == null)
                    {
                        var firstProject = projectConfigsToBuild.First();

                        // Use the target type from the current solution configuration, as they all should have the same anyway
                        fastBuildAllProject = new FastBuildAllProject(solutionConf.Target.GetType())
                        {
                            Name              = FastBuildAllProjectName,
                            RootPath          = firstProject.Project.RootPath,
                            SourceRootPath    = firstProject.Project.RootPath,
                            IsFileNameToLower = firstProject.Project.IsFileNameToLower
                        };
                    }
                    else
                    {
                        // validate the asumption made above
                        if (fastBuildAllProject.Targets.TargetType != firstSolutionConf.Target.GetType())
                        {
                            throw new Error("Target type must match between all solution configurations");
                        }
                    }

                    fastBuildAllProject.AddTargets(solutionTarget);
                }

                fastBuildAllProject.Targets.BuildTargets();
                fastBuildAllProject.InvokeConfiguration(builder.Context);

                foreach (var projectsToBuildInSolutionConfig in projectsToBuildPerSolutionConfig)
                {
                    var solutionConf          = projectsToBuildInSolutionConfig.Item1;
                    var projectConfigsToBuild = projectsToBuildInSolutionConfig.Item2;

                    var solutionTarget = solutionConf.Target;
                    var projectConf    = fastBuildAllProject.GetConfiguration(solutionTarget);

                    projectConf.IsFastBuild = true;

                    // output the project in the same folder as the solution, and the same name
                    projectConf.ProjectPath = solutionConf.SolutionPath;
                    if (string.IsNullOrWhiteSpace(FastBuildAllProjectFileSuffix))
                    {
                        throw new Error("FastBuildAllProjectFileSuffix cannot be left emtpy in solution " + solutionFile);
                    }
                    projectConf.ProjectFileName = solutionFile.Key + FastBuildAllProjectFileSuffix;
                    projectConf.SolutionFolder  = FastBuildAllSolutionFolder;

                    // the project doesn't output anything
                    projectConf.Output = Project.Configuration.OutputType.None;

                    // get some settings that are usually global from the first project
                    // we could expose those, if we need to set them specifically for FastBuildAllProject
                    var firstProject = projectConfigsToBuild.First();
                    projectConf.FastBuildCustomArgs = firstProject.Configuration.FastBuildCustomArgs;
                    projectConf.FastBuildCustomActionsBeforeBuildCommand = firstProject.Configuration.FastBuildCustomActionsBeforeBuildCommand;

                    // add all the projects to build as private dependencies, and OnlyBuildOrder
                    foreach (Configuration.IncludedProjectInfo projectConfigToBuild in projectConfigsToBuild)
                    {
                        // update the ToBuild, as now it is built through the "FastBuildAll" dependency
                        projectConfigToBuild.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency;

                        projectConf.AddPrivateDependency(projectConfigToBuild.Target, projectConfigToBuild.Project.GetType(), DependencySetting.OnlyBuildOrder);
                    }

                    // add the newly generated project to the solution config
                    solutionConf.IncludedProjectInfos.Add(
                        new Configuration.IncludedProjectInfo
                    {
                        Project       = fastBuildAllProject,
                        Configuration = projectConf,
                        Target        = solutionTarget,
                        Type          = fastBuildAllProject.GetType(),
                        ToBuild       = Configuration.IncludedProjectInfo.Build.Yes
                    }
                        );
                }

                fastBuildAllProject.Resolve(builder, false);
                fastBuildAllProject.Link(builder);

                builder.RegisterGeneratedProject(fastBuildAllProject);
            }
        }