Beispiel #1
0
        internal void Link(Builder builder)
        {
            if (_dependenciesResolved)
            {
                return;
            }

            bool hasFastBuildProjectConf = false;

            foreach (Solution.Configuration solutionConfiguration in Configurations)
            {
                // Build SolutionFilesMapping
                string configurationFile = Path.Combine(solutionConfiguration.SolutionPath, solutionConfiguration.SolutionFileName);

                var fileConfigurationList = SolutionFilesMapping.GetValueOrAdd(configurationFile, new List <Solution.Configuration>());
                fileConfigurationList.Add(solutionConfiguration);

                // solutionConfiguration.IncludedProjectInfos will be appended
                // while iterating, but with projects that we already have resolved,
                // so no need to parse them again
                int origCount = solutionConfiguration.IncludedProjectInfos.Count;
                for (int i = 0; i < origCount; ++i)
                {
                    Configuration.IncludedProjectInfo configurationProject = solutionConfiguration.IncludedProjectInfos[i];
                    bool projectIsInactive = configurationProject.InactiveProject;

                    Project project = builder.GetProject(configurationProject.Type);
                    Project.Configuration projectConfiguration = project.GetConfiguration(configurationProject.Target);

                    if (projectConfiguration == null)
                    {
                        throw new Error(
                                  "Solution {0} for target '{1}' contains project {2} with invalid target '{3}'",
                                  GetType().FullName, solutionConfiguration.Target, project.GetType().FullName, configurationProject.Target
                                  );
                    }

                    if (configurationProject.Project == null)
                    {
                        configurationProject.Project = project;
                    }
                    else if (configurationProject.Project != project)
                    {
                        throw new Error("Tried to match more than one project to Project type.");
                    }

                    if (configurationProject.Configuration == null)
                    {
                        configurationProject.Configuration = projectConfiguration;
                    }
                    else if (configurationProject.Configuration != projectConfiguration)
                    {
                        throw new Error("Tried to match more than one Project Configuration to a solution configuration.");
                    }

                    hasFastBuildProjectConf |= projectConfiguration.IsFastBuild;

                    bool build = !projectConfiguration.IsExcludedFromBuild && !configurationProject.InactiveProject;
                    if (build && solutionConfiguration.IncludeOnlyFilterProject && (configurationProject.Project.SourceFilesFiltersCount == 0 || configurationProject.Project.SkipProjectWhenFiltersActive))
                    {
                        build = false;
                    }

                    if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                    {
                        if (build)
                        {
                            configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.Yes;
                        }
                        else if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                        {
                            configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                        }
                    }

                    var dependenciesConfiguration = configurationProject.Configuration.GetRecursiveDependencies();
                    foreach (Project.Configuration dependencyConfiguration in dependenciesConfiguration)
                    {
                        Project dependencyProject     = dependencyConfiguration.Project;
                        Type    dependencyProjectType = dependencyProject.GetType();

                        if (dependencyProjectType.IsDefined(typeof(Export), false))
                        {
                            continue;
                        }

                        ITarget dependencyProjectTarget = dependencyConfiguration.Target;
                        hasFastBuildProjectConf |= dependencyConfiguration.IsFastBuild;

                        Configuration.IncludedProjectInfo configurationProjectDependency = solutionConfiguration.GetProject(dependencyProjectType);

                        // if that project was not explicitely added to the solution configuration, add it ourselves, as it is needed
                        if (configurationProjectDependency == null)
                        {
                            configurationProjectDependency = new Configuration.IncludedProjectInfo
                            {
                                Type            = dependencyProjectType,
                                Project         = dependencyProject,
                                Configuration   = dependencyConfiguration,
                                Target          = dependencyProjectTarget,
                                InactiveProject = projectIsInactive // inherit from the parent: no reason to mark dependencies for build if parent is inactive
                            };
                            solutionConfiguration.IncludedProjectInfos.Add(configurationProjectDependency);
                        }
                        else if (!projectIsInactive && configurationProjectDependency.InactiveProject)
                        {
                            // if the project we found in the solutionConfiguration is inactive, and the current is not, replace its settings
                            configurationProjectDependency.Type            = dependencyProjectType;
                            configurationProjectDependency.Project         = dependencyProject;
                            configurationProjectDependency.Configuration   = dependencyConfiguration;
                            configurationProjectDependency.Target          = dependencyProjectTarget;
                            configurationProjectDependency.InactiveProject = false;
                        }
                        else if (projectIsInactive)
                        {
                            // if the current project is inactive, ignore
                        }
                        else
                        {
                            if (!configurationProjectDependency.Target.IsEqualTo(dependencyProjectTarget))
                            {
                                throw new Error("In solution configuration (solution: {3}, config: {4}) the parent project {5} generates multiple dependency targets for the same child project {0}: {1} and {2}. Look for all AddPublicDependency() and AddPrivateDependency() calls for the child project and follow the dependency chain.",
                                                configurationProjectDependency.Project?.GetType().ToString(),
                                                configurationProjectDependency.Target,
                                                dependencyProjectTarget,
                                                solutionConfiguration.SolutionFileName,
                                                solutionConfiguration.Target,
                                                project.Name);
                            }

                            if (configurationProjectDependency.Project == null)
                            {
                                configurationProjectDependency.Project = dependencyProject;
                            }
                            else if (configurationProjectDependency.Project != dependencyProject)
                            {
                                throw new Error("Tried to match more than one project to Project type.");
                            }

                            if (configurationProjectDependency.Configuration == null)
                            {
                                configurationProjectDependency.Configuration = dependencyConfiguration;
                            }
                            else if (configurationProjectDependency.Configuration != dependencyConfiguration)
                            {
                                throw new Error("Tried to match more than one Project Configuration to a solution configuration.");
                            }
                        }

                        bool depBuild = !projectIsInactive && !dependencyConfiguration.IsExcludedFromBuild && !configurationProjectDependency.InactiveProject;
                        if (depBuild && solutionConfiguration.IncludeOnlyFilterProject && (dependencyProject.SourceFilesFiltersCount == 0 || dependencyProject.SkipProjectWhenFiltersActive))
                        {
                            depBuild = false;
                        }

                        if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                        {
                            if (depBuild)
                            {
                                if (projectConfiguration.Output == Project.Configuration.OutputType.Dll || projectConfiguration.Output == Project.Configuration.OutputType.Exe)
                                {
                                    configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency;
                                }
                                else
                                {
                                    configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.Yes;
                                }
                            }
                            else if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                            {
                                configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                            }
                        }
                    }
                }
            }

            if (hasFastBuildProjectConf)
            {
                MakeFastBuildAllProjectIfNeeded(builder);
            }

            _dependenciesResolved = true;
        }
Beispiel #2
0
        internal void Link(Builder builder)
        {
            if (_dependenciesResolved)
            {
                return;
            }

            bool hasFastBuildProjectConf = false;
            var  unlinkedConfigurations  = new Dictionary <Solution.Configuration, List <Project.Configuration> >(); // This will hold MSBuild -> Fastbuild refs

            using (builder.CreateProfilingScope("Solution.Link:confs", Configurations.Count))
            {
                foreach (Solution.Configuration solutionConfiguration in Configurations)
                {
                    // Build SolutionFilesMapping
                    string configurationFile = Path.Combine(solutionConfiguration.SolutionPath, solutionConfiguration.SolutionFileName);

                    var fileConfigurationList = SolutionFilesMapping.GetValueOrAdd(configurationFile, new List <Solution.Configuration>());
                    fileConfigurationList.Add(solutionConfiguration);

                    var unlinkedList = unlinkedConfigurations.GetValueOrAdd(solutionConfiguration, new List <Project.Configuration>());

                    // solutionConfiguration.IncludedProjectInfos will be appended
                    // while iterating, but with projects that we already have resolved,
                    // so no need to parse them again
                    int origCount = solutionConfiguration.IncludedProjectInfos.Count;
                    for (int i = 0; i < origCount; ++i)
                    {
                        Configuration.IncludedProjectInfo configurationProject = solutionConfiguration.IncludedProjectInfos[i];
                        bool projectIsInactive = configurationProject.InactiveProject;

                        Project project = builder.GetProject(configurationProject.Type);
                        Project.Configuration projectConfiguration = project.GetConfiguration(configurationProject.Target);

                        if (projectConfiguration == null)
                        {
                            var messageBuilder = new System.Text.StringBuilder();
                            messageBuilder.AppendFormat("Resolving dependencies for solution {0}, target '{1}': cannot find target '{3}' in project {2}",
                                                        GetType().FullName, solutionConfiguration.Target, project.GetType().FullName, configurationProject.Target);
                            messageBuilder.AppendLine();

                            if (project.Configurations.Any())
                            {
                                messageBuilder.AppendLine("Project configurations are:");
                                int confNum = 0;
                                foreach (var conf in project.Configurations)
                                {
                                    messageBuilder.AppendLine(++confNum + "/" + project.Configurations.Count + " " + conf.ToString());
                                }
                            }
                            else
                            {
                                messageBuilder.AppendLine("The project does not contain any configurations!");
                            }

                            Trace.WriteLine(messageBuilder.ToString());
                            Debugger.Break();

                            throw new Error(messageBuilder.ToString());
                        }

                        if (configurationProject.Project == null)
                        {
                            configurationProject.Project = project;
                        }
                        else if (configurationProject.Project != project)
                        {
                            throw new Error("Tried to match more than one project to Project type.");
                        }

                        if (configurationProject.Configuration == null)
                        {
                            configurationProject.Configuration = projectConfiguration;
                        }
                        else if (configurationProject.Configuration != projectConfiguration)
                        {
                            throw new Error("Tried to match more than one Project Configuration to a solution configuration.");
                        }

                        hasFastBuildProjectConf |= projectConfiguration.IsFastBuild;
                        if (projectConfiguration.IsFastBuild)
                        {
                            projectConfiguration.AddMasterBff(solutionConfiguration.MasterBffFilePath);
                        }

                        bool build = !projectConfiguration.IsExcludedFromBuild && !configurationProject.InactiveProject;
                        if (build && solutionConfiguration.IncludeOnlyFilterProject && (configurationProject.Project.SourceFilesFiltersCount == 0 || configurationProject.Project.SkipProjectWhenFiltersActive))
                        {
                            build = false;
                        }

                        if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                        {
                            if (build)
                            {
                                configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.Yes;
                            }
                            else if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                            {
                                configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                            }
                        }

                        var dependenciesConfiguration = configurationProject.Configuration.GetRecursiveDependencies();
                        // TODO: Slow LINQ? May be better to create this list as part of GetRecursiveDependencies
                        if (!configurationProject.Configuration.IsFastBuild && configurationProject.Configuration.ResolvedDependencies.Any(d => d.IsFastBuild))
                        {
                            unlinkedList.Add(configurationProject.Configuration);
                        }
                        unlinkedList.AddRange(dependenciesConfiguration.Where(c => !c.IsFastBuild && c.ResolvedDependencies.Any(d => d.IsFastBuild)));
                        foreach (Project.Configuration dependencyConfiguration in dependenciesConfiguration)
                        {
                            Project dependencyProject = dependencyConfiguration.Project;
                            if (dependencyProject.SharpmakeProjectType == Project.ProjectTypeAttribute.Export)
                            {
                                continue;
                            }

                            Type    dependencyProjectType   = dependencyProject.GetType();
                            ITarget dependencyProjectTarget = dependencyConfiguration.Target;

                            hasFastBuildProjectConf |= dependencyConfiguration.IsFastBuild;
                            if (dependencyConfiguration.IsFastBuild)
                            {
                                dependencyConfiguration.AddMasterBff(solutionConfiguration.MasterBffFilePath);
                            }

                            Configuration.IncludedProjectInfo configurationProjectDependency = solutionConfiguration.GetProject(dependencyProjectType);

                            // if that project was not explicitly added to the solution configuration, add it ourselves, as it is needed
                            if (configurationProjectDependency == null)
                            {
                                configurationProjectDependency = new Configuration.IncludedProjectInfo
                                {
                                    Type            = dependencyProjectType,
                                    Project         = dependencyProject,
                                    Configuration   = dependencyConfiguration,
                                    Target          = dependencyProjectTarget,
                                    InactiveProject = projectIsInactive // inherit from the parent: no reason to mark dependencies for build if parent is inactive
                                };
                                solutionConfiguration.IncludedProjectInfos.Add(configurationProjectDependency);
                            }
                            else if (!projectIsInactive && configurationProjectDependency.InactiveProject)
                            {
                                // if the project we found in the solutionConfiguration is inactive, and the current is not, replace its settings
                                configurationProjectDependency.Type            = dependencyProjectType;
                                configurationProjectDependency.Project         = dependencyProject;
                                configurationProjectDependency.Configuration   = dependencyConfiguration;
                                configurationProjectDependency.Target          = dependencyProjectTarget;
                                configurationProjectDependency.InactiveProject = false;
                            }
                            else if (projectIsInactive)
                            {
                                // if the current project is inactive, ignore
                            }
                            else
                            {
                                if (!configurationProjectDependency.Target.IsEqualTo(dependencyProjectTarget))
                                {
                                    throw new Error("In solution configuration (solution: {3}, config: {4}) the parent project {5} generates multiple dependency targets for the same child project {0}: {1} and {2}. Look for all AddPublicDependency() and AddPrivateDependency() calls for the child project and follow the dependency chain.",
                                                    configurationProjectDependency.Project?.GetType().ToString(),
                                                    configurationProjectDependency.Target,
                                                    dependencyProjectTarget,
                                                    solutionConfiguration.SolutionFileName,
                                                    solutionConfiguration.Target,
                                                    project.Name
                                                    );
                                }

                                if (configurationProjectDependency.Project == null)
                                {
                                    configurationProjectDependency.Project = dependencyProject;
                                }
                                else if (configurationProjectDependency.Project != dependencyProject)
                                {
                                    throw new Error("Tried to match more than one project to Project type.");
                                }

                                if (configurationProjectDependency.Configuration == null)
                                {
                                    configurationProjectDependency.Configuration = dependencyConfiguration;
                                }
                                else if (configurationProjectDependency.Configuration != dependencyConfiguration)
                                {
                                    throw new Error("Tried to match more than one Project Configuration to a solution configuration.");
                                }
                            }

                            if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                            {
                                // If we're finding a Fastbuild dependency of an MSBuild project, we know that it'll need re-linking if the All project is generated.
                                var needsFastbuildRelink = (dependencyConfiguration.IsFastBuild && !configurationProject.Configuration.IsFastBuild && GenerateFastBuildAllProject);

                                var isExcludedSinceNoFilter = solutionConfiguration.IncludeOnlyFilterProject &&
                                                              (configurationProjectDependency.Project.SourceFilesFiltersCount == 0 || configurationProjectDependency.Project.SkipProjectWhenFiltersActive);

                                var skipBuild = dependencyConfiguration.IsExcludedFromBuild ||
                                                projectIsInactive ||
                                                configurationProjectDependency.InactiveProject ||
                                                needsFastbuildRelink ||
                                                isExcludedSinceNoFilter;

                                if (!skipBuild)
                                {
                                    if (projectConfiguration.Output == Project.Configuration.OutputType.Dll || projectConfiguration.Output == Project.Configuration.OutputType.Exe)
                                    {
                                        configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency;
                                    }
                                    else
                                    {
                                        configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.Yes;
                                    }
                                }
                                else if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                                {
                                    configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                                }
                            }
                        }
                    }
                }

                if (hasFastBuildProjectConf)
                {
                    MakeFastBuildAllProjectIfNeeded(builder, unlinkedConfigurations);
                }

                _dependenciesResolved = true;
            }
        }
Beispiel #3
0
        internal void Link(Builder builder)
        {
            if (_dependenciesResolved)
            {
                return;
            }

            foreach (Solution.Configuration solutionConfiguration in Configurations)
            {
                // Build SolutionFilesMapping
                string configurationFile = Path.Combine(solutionConfiguration.SolutionPath, solutionConfiguration.SolutionFileName);

                var fileConfigurationList = SolutionFilesMapping.GetValueOrAdd(configurationFile, new List <Solution.Configuration>());
                fileConfigurationList.Add(solutionConfiguration);

                // solutionConfiguration.IncludedProjectInfos will be appended
                // while iterating, but with projects that we already have resolved,
                // so no need to parse them again
                int origCount = solutionConfiguration.IncludedProjectInfos.Count;
                for (int i = 0; i < origCount; ++i)
                {
                    Configuration.IncludedProjectInfo configurationProject = solutionConfiguration.IncludedProjectInfos[i];

                    Project project = builder.GetProject(configurationProject.Type);
                    Project.Configuration projectConfiguration = project.GetConfiguration(configurationProject.Target);

                    if (projectConfiguration == null)
                    {
                        throw new Error(
                                  "Solution {0} for target '{1}' contains project {2} with invalid target '{3}'",
                                  GetType().FullName, solutionConfiguration.Target, project.GetType().FullName, configurationProject.Target
                                  );
                    }

                    configurationProject.Project       = project;
                    configurationProject.Configuration = projectConfiguration;

                    bool build = !projectConfiguration.IsExcludedFromBuild && !configurationProject.InactiveProject;
                    if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                    {
                        if (build)
                        {
                            configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.Yes;
                        }
                        else if (configurationProject.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                        {
                            configurationProject.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                        }
                    }

                    var dependenciesConfiguration = configurationProject.Configuration.GetRecursiveDependencies();
                    foreach (Project.Configuration dependencyConfiguration in dependenciesConfiguration)
                    {
                        Type dependencyProjectType = dependencyConfiguration.Project.GetType();

                        if (dependencyProjectType.IsDefined(typeof(Export), false))
                        {
                            continue;
                        }

                        ITarget dependencyProjectTarget = dependencyConfiguration.Target;

                        Configuration.IncludedProjectInfo configurationProjectDependency = solutionConfiguration.GetProject(dependencyProjectType);

                        if (configurationProjectDependency == null)
                        {
                            var dependencyProject = builder.GetProject(dependencyProjectType);
                            configurationProjectDependency = new Configuration.IncludedProjectInfo
                            {
                                Type            = dependencyProjectType,
                                Project         = dependencyProject,
                                Configuration   = dependencyProject.GetConfiguration(dependencyProjectTarget),
                                Target          = dependencyProjectTarget,
                                InactiveProject = configurationProject.InactiveProject // inherit from the parent: no reason to mark dependencies for build if parent is inactive
                            };
                            solutionConfiguration.IncludedProjectInfos.Add(configurationProjectDependency);
                        }
                        else
                        {
                            if (!configurationProjectDependency.Target.IsEqualTo(dependencyProjectTarget))
                            {
                                throw new Error("In solution configuration (solution: {3}, config: {4}) the parent project {5} generates multiple dependency targets for the same child project {0}: {1} and {2}. Look for all AddPublicDependency() and AddPrivateDependency() calls for the child project and follow the dependency chain.",
                                                configurationProjectDependency.Project.GetType().ToString(),
                                                configurationProjectDependency.Target,
                                                dependencyProjectTarget,
                                                solutionConfiguration.SolutionFileName,
                                                solutionConfiguration.Target,
                                                project.Name);
                            }
                        }

                        bool depBuild = !dependencyConfiguration.IsExcludedFromBuild && !configurationProjectDependency.InactiveProject;
                        if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.YesThroughDependency)
                        {
                            if (depBuild)
                            {
                                configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.YesThroughDependency;
                            }
                            else if (configurationProjectDependency.ToBuild != Configuration.IncludedProjectInfo.Build.Yes)
                            {
                                configurationProjectDependency.ToBuild = Configuration.IncludedProjectInfo.Build.No;
                            }
                        }
                    }
                }
            }
            _dependenciesResolved = true;
        }