コード例 #1
0
ファイル: SolutionBase.cs プロジェクト: thinkum-sys/nant
        /// <summary>
        /// Converts assembly references to projects to project references, adding
        /// a build dependency.c
        /// </summary>
        /// <param name="project">The <see cref="ProjectBase" /> to analyze.</param>
        /// <param name="solutionConfiguration">The solution configuration that is built.</param>
        /// <param name="builtProjects"><see cref="Hashtable" /> containing list of projects that have been built.</param>
        /// <param name="failedProjects"><see cref="Hashtable" /> containing list of projects that failed to build.</param>
        protected bool FixProjectReferences(ProjectBase project, Configuration solutionConfiguration, Hashtable builtProjects, Hashtable failedProjects)
        {
            // check if the project still has dependencies that have not been
            // built
            if (HasDirtyProjectDependency(project, builtProjects))
            {
                return(false);
            }

            ConfigurationBase projectConfig = project.BuildConfigurations[solutionConfiguration];

            // check if the project actually supports the build configuration
            if (projectConfig == null)
            {
                return(false);
            }

            Log(Level.Verbose, "Fixing up references...");

            ArrayList projectReferences = (ArrayList)
                                          project.References.Clone();

            bool referencesFailedProject = false;

            foreach (ReferenceBase reference in projectReferences)
            {
                AssemblyReferenceBase assemblyReference = reference as
                                                          AssemblyReferenceBase;
                if (assemblyReference == null)
                {
                    // project references and wrappers don't
                    // need to be fixed
                    continue;
                }

                ProjectBase projectRef = null;

                string outputFile = assemblyReference.GetPrimaryOutputFile(
                    solutionConfiguration);
                if (outputFile == null)
                {
                    continue;
                }

                if (_htOutputFiles.Contains(outputFile))
                {
                    // if the reference is an output file of
                    // another build configuration of a project
                    // and this output file wasn't built before
                    // then use the output file for the current
                    // build configuration
                    //
                    // eg. a project file might be referencing the
                    // the debug assembly of a given project as an
                    // assembly reference, but the projects are now
                    // being built in release configuration, so
                    // instead of failing the build we use the
                    // release assembly of that project

                    // Note that this was designed to intentionally
                    // deviate from VS.NET's building strategy.

                    // See "Reference Configuration Matching" at http://nant.sourceforge.net/wiki/index.php/SolutionTask
                    // for why we must always convert file references to project references

                    // If we want a different behaviour, this
                    // should be controlled by a flag

                    projectRef = ProjectEntries[(string)_htOutputFiles[outputFile]].Project;
                }
                else if (_outputDir != null)
                {
                    // if an output directory is set, then the
                    // assembly reference might not have been
                    // resolved during Reference initialization,
                    // as the output file of the project might
                    // not have existed at that time
                    //
                    // this will perform matching on file name
                    // only, so its really tricky (VS.NET does
                    // not support this)

                    string projectOutput = FileUtils.CombinePaths(
                        _outputDir.FullName, Path.GetFileName(
                            outputFile));
                    if (_htOutputFiles.Contains(projectOutput))
                    {
                        projectRef = (ProjectBase)ProjectEntries[
                            (string)_htOutputFiles[projectOutput]].Project;
                    }
                }

                // try matching assembly reference and project on assembly name
                // if the assembly file does not exist
                if (projectRef == null && !System.IO.File.Exists(outputFile))
                {
                    foreach (ProjectEntry projectEntry in ProjectEntries)
                    {
                        // we can only do this for managed projects, as we only have
                        // an assembly name for these
                        ManagedProjectBase managedProject = projectEntry.Project as ManagedProjectBase;
                        if (managedProject == null)
                        {
                            continue;
                        }
                        // check if the assembly names match
                        if (assemblyReference.Name == managedProject.ProjectSettings.AssemblyName)
                        {
                            projectRef = managedProject;
                            break;
                        }
                    }
                }

                if (projectRef != null)
                {
                    if (!referencesFailedProject && failedProjects.ContainsKey(projectRef.Guid))
                    {
                        referencesFailedProject = true;
                    }

                    ProjectReferenceBase projectReference = assemblyReference.
                                                            CreateProjectReference(projectRef);
                    Log(Level.Verbose, "Converted assembly reference to project reference: {0} -> {1}",
                        assemblyReference.Name, projectReference.Name);

                    // remove assembly reference from project
                    project.References.Remove(assemblyReference);

                    // add project reference instead
                    project.References.Add(projectReference);

                    // unless referenced project has already been build, add
                    // referenced project as project dependency
                    if (!builtProjects.Contains(projectReference.Project.Guid))
                    {
                        project.ProjectDependencies.Add(projectReference.Project);
                    }
                }
            }

            return(referencesFailedProject);
        }
コード例 #2
0
ファイル: SolutionBase.cs プロジェクト: thinkum-sys/nant
        protected void GetDependenciesFromProjects(Configuration solutionConfiguration)
        {
            Log(Level.Verbose, "Gathering additional dependencies...");

            // first get all of the output files
            foreach (ProjectEntry projectEntry in ProjectEntries)
            {
                ProjectBase project = projectEntry.Project;

                if (project == null)
                {
                    // skip projects that are not loaded/supported
                    continue;
                }

                foreach (ConfigurationBase projectConfig in project.ProjectConfigurations.Values)
                {
                    string projectOutputFile = projectConfig.OutputPath;
                    if (projectOutputFile != null)
                    {
                        _htOutputFiles[projectOutputFile] = project.Guid;
                    }
                }
            }

            // if one of output files resides in reference search path - circle began
            // we must build project with that outputFile before projects referencing it
            // (similar to project dependency) VS.NET 7.0/7.1 do not address this problem

            // build list of output which reside in such folders
            Hashtable outputsInAssemblyFolders = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (DictionaryEntry de in _htOutputFiles)
            {
                string outputfile = (string)de.Key;
                string folder     = Path.GetDirectoryName(outputfile);

                if (_solutionTask.AssemblyFolderList.Contains(folder))
                {
                    outputsInAssemblyFolders[Path.GetFileName(outputfile)] =
                        (string)de.Value;
                }
            }

            // build the dependency list
            foreach (ProjectEntry projectEntry in ProjectEntries)
            {
                ProjectBase project = projectEntry.Project;

                if (project == null)
                {
                    // skip projects that are not loaded/supported
                    continue;
                }

                // check if project actually supports the build configuration
                ConfigurationBase projectConfig = project.BuildConfigurations[solutionConfiguration];
                if (projectConfig == null)
                {
                    continue;
                }

                // ensure output directory exists. VS creates output directories
                // before it starts compiling projects
                if (!projectConfig.OutputDir.Exists)
                {
                    projectConfig.OutputDir.Create();
                    projectConfig.OutputDir.Refresh();
                }

                foreach (ReferenceBase reference in project.References)
                {
                    ProjectReferenceBase projectReference = reference as ProjectReferenceBase;
                    if (projectReference != null)
                    {
                        project.ProjectDependencies.Add(projectReference.Project);
                    }
                    else
                    {
                        string outputFile = reference.GetPrimaryOutputFile(
                            solutionConfiguration);
                        // if we reference an assembly in an AssemblyFolder
                        // that is an output directory of another project,
                        // then add dependency on that project
                        if (outputFile == null)
                        {
                            continue;
                        }

                        string dependencyGuid = (string)outputsInAssemblyFolders[Path.GetFileName(outputFile)];
                        if (dependencyGuid == null)
                        {
                            continue;
                        }

                        ProjectEntry dependencyEntry = ProjectEntries[dependencyGuid];
                        if (dependencyEntry != null && dependencyEntry.Project != null)
                        {
                            project.ProjectDependencies.Add(dependencyEntry.Project);
                        }
                    }
                }
            }
        }