Ejemplo n.º 1
0
 public Resource(ManagedProjectBase project, FileInfo resourceSourceFile, string resourceSourceFileRelativePath, string dependentFile, SolutionTask solutionTask, GacCache gacCache)
 {
     _project                        = project;
     _resourceSourceFile             = resourceSourceFile;
     _resourceSourceFileRelativePath = resourceSourceFileRelativePath;
     _dependentFile                  = dependentFile;
     _solutionTask                   = solutionTask;
     _culture                        = CompilerBase.GetResourceCulture(resourceSourceFile.FullName,
                                                                       dependentFile);
 }
Ejemplo n.º 2
0
        public static string LoadGuid(string fileName)
        {
            // check if a project with specified file is already cached
            if (_cachedProjects.ContainsKey(fileName))
            {
                // return the guid of the cached project
                return(((ProjectBase)_cachedProjects[fileName]).Guid);
            }

            string projectFileName = ProjectFactory.GetProjectFileName(fileName);
            string projectExt      = Path.GetExtension(projectFileName).ToLower(
                CultureInfo.InvariantCulture);

            // check if GUID of project is already cached
            if (!_cachedProjectGuids.Contains(fileName))
            {
                if (projectExt == ".vbproj" || projectExt == ".csproj" || projectExt == ".vjsproj")
                {
                    // add project GUID to cache
                    _cachedProjectGuids[fileName] = ManagedProjectBase.LoadGuid(fileName);
                }
                else if (projectExt == ".vcproj")
                {
                    // add project GUID to cache
                    _cachedProjectGuids[fileName] = VcProject.LoadGuid(fileName);
                }
                else
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Unknown project file extension '{0}'.", projectExt,
                                                           Location.UnknownLocation));
                }
            }

            // return project GUID from cache
            return((string)_cachedProjectGuids[fileName]);
        }
Ejemplo n.º 3
0
        public Solution(string solutionContent, SolutionTask solutionTask, TempFileCollection tfc, GacCache gacCache, ReferencesResolver refResolver) : base(solutionTask, tfc, gacCache, refResolver)
        {
            Regex           reProjects     = new Regex(@"Project\(\""(?<package>\{.*?\})\"".*?\""(?<name>.*?)\"".*?\""(?<project>.*?)\"".*?\""(?<guid>.*?)\""(?<all>[\s\S]*?)EndProject", RegexOptions.Multiline);
            MatchCollection projectMatches = reProjects.Matches(solutionContent);

            Hashtable explicitProjectDependencies = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (Match projectMatch in projectMatches)
            {
                string project = projectMatch.Groups["project"].Value;
                string guid    = projectMatch.Groups["guid"].Value;

                // translate partial project path or URL to absolute path
                string fullProjectPath = TranslateProjectPath(solutionTask.SolutionFile.DirectoryName,
                                                              project);

                // check if project file actually exists
                if (!System.IO.File.Exists(fullProjectPath))
                {
                    throw CreateProjectDoesNotExistException(fullProjectPath);
                }

                if (ManagedProjectBase.IsEnterpriseTemplateProject(fullProjectPath))
                {
                    RecursiveLoadTemplateProject(fullProjectPath);
                }
                else
                {
                    // add project path to collection
                    ProjectEntries.Add(new ProjectEntry(guid, fullProjectPath));
                }

                // set-up project dependencies
                Regex           reDependencies    = new Regex(@"^\s+" + guid + @"\.[0-9]+ = (?<dep>\{\S*\}?)\s*$", RegexOptions.Multiline);
                MatchCollection dependencyMatches = reDependencies.Matches(solutionContent);

                foreach (Match dependencyMatch in dependencyMatches)
                {
                    string dependency = dependencyMatch.Groups["dep"].Value;

                    if (!explicitProjectDependencies.ContainsKey(guid))
                    {
                        explicitProjectDependencies[guid] = CollectionsUtil.CreateCaseInsensitiveHashtable();
                    }
                    ((Hashtable)explicitProjectDependencies[guid])[dependency] = null;
                }

                // set-up project configuration
                Regex           reProjectBuildConfig = new Regex(@"^\s+" + guid + @"\.(?<solutionConfiguration>[^|]+)\.Build\.0\s*=\s*(?<projectConfiguration>[^|]+)\|\s*\S*", RegexOptions.Multiline);
                MatchCollection projectBuildMatches  = reProjectBuildConfig.Matches(solutionContent);

                // initialize hashtable that will hold the project build configurations
                Hashtable projectBuildConfiguration = CollectionsUtil.CreateCaseInsensitiveHashtable();

                if (projectBuildMatches.Count > 0)
                {
                    foreach (Match projectBuildMatch in projectBuildMatches)
                    {
                        string solutionConfiguration = projectBuildMatch.Groups["solutionConfiguration"].Value;
                        string projectConfiguration  = projectBuildMatch.Groups["projectConfiguration"].Value;
                        projectBuildConfiguration[solutionConfiguration] = projectConfiguration;
                    }
                }

                // add project build configuration, this signals that project was
                // loaded in context of solution file
                ProjectBuildConfigurations[guid] = projectBuildConfiguration;
            }

            LoadProjectGuids(new ArrayList(solutionTask.Projects.FileNames), false);
            LoadProjectGuids(new ArrayList(solutionTask.ReferenceProjects.FileNames), true);
            LoadProjects(gacCache, refResolver, explicitProjectDependencies);
        }
Ejemplo n.º 4
0
        public ConfigurationSettings(ManagedProjectBase project, XmlElement elemConfig, DirectoryInfo outputDir) : base(project)
        {
            _settings = new ArrayList();
            if (outputDir == null)
            {
                _relativeOutputDir = elemConfig.Attributes["OutputPath"].Value;
                if (!_relativeOutputDir.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture)))
                {
                    _relativeOutputDir = _relativeOutputDir + Path.DirectorySeparatorChar;
                }
                _outputDir = new DirectoryInfo(FileUtils.CombinePaths(
                                                   project.ProjectDirectory.FullName,
                                                   _relativeOutputDir));
            }
            else
            {
                _relativeOutputDir = outputDir.FullName;
                if (!_relativeOutputDir.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture)))
                {
                    _relativeOutputDir = _relativeOutputDir + Path.DirectorySeparatorChar;
                }
                _outputDir = outputDir;
            }

            _name = elemConfig.GetAttribute("Name");

            string documentationFile = elemConfig.GetAttribute("DocumentationFile");

            if (!StringUtils.IsNullOrEmpty(documentationFile))
            {
                // to match VS.NET, the XML Documentation file will be output
                // in the project directory, and only later copied to the output
                // directory
                string xmlDocBuildFile = FileUtils.CombinePaths(project.ProjectDirectory.FullName,
                                                                documentationFile);

                // add compiler option to build XML Documentation file
                _settings.Add(@"/doc:""" + xmlDocBuildFile + @"""");

                // make sure the output directory for the doc file exists
                if (!Directory.Exists(Path.GetDirectoryName(xmlDocBuildFile)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(xmlDocBuildFile));
                }

                // add built documentation file as extra output file
                ExtraOutputFiles[xmlDocBuildFile] = Path.GetFileName(xmlDocBuildFile);
            }

            // determine whether we need to register project output for use with
            // COM components
            _registerForComInterop = string.Compare(elemConfig.GetAttribute("RegisterForComInterop"),
                                                    "true", true, CultureInfo.InvariantCulture) == 0;

            SolutionTask.Log(Level.Debug, "Project: {0} Relative Output Path: {1} Output Path: {2} Documentation Path: {3}",
                             Project.Name, _relativeOutputDir, _outputDir.FullName, documentationFile);

            Hashtable htStringSettings  = new Hashtable();
            Hashtable htBooleanSettings = new Hashtable();

            htStringSettings["BaseAddress"] = "/baseaddress:{0}";

            // is only supported by csc (all versions) and vbc (2.0 or higher)
            htStringSettings["FileAlignment"] = "/filealign:{0}";

            htStringSettings["DefineConstants"] = "/define:{0}";

            switch (project.Type)
            {
            case ProjectType.CSharp:
                htStringSettings["WarningLevel"]               = "/warn:{0}";
                htStringSettings["NoWarn"]                     = "/nowarn:{0}";
                htBooleanSettings["IncrementalBuild"]          = "/incremental";
                htBooleanSettings["AllowUnsafeBlocks"]         = "/unsafe";
                htBooleanSettings["CheckForOverflowUnderflow"] = "/checked";
                break;

            case ProjectType.JSharp:
                htStringSettings["WarningLevel"]      = "/warn:{0}";
                htStringSettings["NoWarn"]            = "/nowarn:{0}";
                htBooleanSettings["IncrementalBuild"] = "/incremental";
                break;

            case ProjectType.VB:
                htStringSettings["DefineDebug"]          = "/d:DEBUG={0}";
                htStringSettings["DefineTrace"]          = "/d:TRACE={0}";
                htBooleanSettings["RemoveIntegerChecks"] = "/removeintchecks";
                break;
            }

            htBooleanSettings["DebugSymbols"]          = "/debug";
            htBooleanSettings["TreatWarningsAsErrors"] = "/warnaserror";
            htBooleanSettings["Optimize"] = "/optimize";

            foreach (DictionaryEntry de in htStringSettings)
            {
                string value = elemConfig.GetAttribute(de.Key.ToString());
                if (!StringUtils.IsNullOrEmpty(value))
                {
                    switch (de.Key.ToString())
                    {
                    case "BaseAddress":
                        // vbc and vjs expect the base address to be specified
                        // as a hexadecimal number, csc supports decimal,
                        // hexadecimal, or octal number
                        //
                        // so use hexadecimal as all compiler support this
                        uint intvalue = Convert.ToUInt32(value, CultureInfo.InvariantCulture);
                        value = "0x" + intvalue.ToString("x", CultureInfo.InvariantCulture);
                        break;

                    case "DefineConstants":
                        // vbc fails when the symbol contains spaces
                        value = value.Replace(" ", string.Empty);
                        break;
                    }
                    _settings.Add(string.Format(CultureInfo.InvariantCulture, de.Value.ToString(), value));
                }
            }

            foreach (DictionaryEntry de in htBooleanSettings)
            {
                string value = elemConfig.GetAttribute(de.Key.ToString());
                if (string.Compare(value, "true", true, CultureInfo.InvariantCulture) == 0)
                {
                    _settings.Add(de.Value.ToString() + "+");
                }
                else if (string.Compare(value, "false", true, CultureInfo.InvariantCulture) == 0)
                {
                    _settings.Add(de.Value.ToString() + "-");
                }
            }

            _settings.Add(string.Format(CultureInfo.InvariantCulture, "/out:\"{0}\"", BuildPath));
        }
Ejemplo n.º 5
0
        public WhidbeySolution(string solutionContent, SolutionTask solutionTask, TempFileCollection tfc, GacCache gacCache, ReferencesResolver refResolver)
            : base(solutionTask, tfc, gacCache, refResolver)
        {
            Regex           reProjects     = new Regex(@"Project\(\""(?<package>\{.*?\})\"".*?\""(?<name>.*?)\"".*?\""(?<project>.*?)\"".*?\""(?<guid>.*?)\""(?<all>[\s\S]*?)EndProject", RegexOptions.Multiline);
            MatchCollection projectMatches = reProjects.Matches(solutionContent);

            Hashtable explicitProjectDependencies = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (Match projectMatch in projectMatches)
            {
                string project = projectMatch.Groups["project"].Value;
                string guid    = projectMatch.Groups["guid"].Value;
                string package = projectMatch.Groups["package"].Value;

                // bug #1732361: skip solution folders
                if (package == SolutionFolder_GUID)
                {
                    continue;
                }

                // translate partial project path or URL to absolute path
                string fullProjectPath = TranslateProjectPath(solutionTask.SolutionFile.DirectoryName,
                                                              project);

                if (ManagedProjectBase.IsEnterpriseTemplateProject(fullProjectPath))
                {
                    RecursiveLoadTemplateProject(fullProjectPath);
                }
                else
                {
                    // add project entry to collection
                    ProjectEntries.Add(new ProjectEntry(guid, fullProjectPath));
                }

                // set-up project dependencies
                Regex           reDependencies    = new Regex(@"^\s+(?<guid>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})\s+=\s+(?<dep>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})", RegexOptions.Multiline);
                MatchCollection dependencyMatches = reDependencies.Matches(projectMatch.Value);

                foreach (Match dependencyMatch in dependencyMatches)
                {
                    string dependency = dependencyMatch.Groups["dep"].Value;

                    if (!explicitProjectDependencies.ContainsKey(guid))
                    {
                        explicitProjectDependencies[guid] = CollectionsUtil.CreateCaseInsensitiveHashtable();
                    }
                    ((Hashtable)explicitProjectDependencies[guid])[dependency] = null;
                }

                // set-up project configuration
                Regex           reProjectBuildConfig = new Regex(@"^\s+" + Regex.Escape(guid) + @"\.(?<solutionConfiguration>[^|]+)\|(?<solutionPlatform>[^.]+)\.Build\.0\s*=\s*(?<projectConfiguration>[^|]+)\|(?<projectPlatform>[\.\w ]+)\s*", RegexOptions.Multiline);
                MatchCollection projectBuildMatches  = reProjectBuildConfig.Matches(solutionContent);

                ProjectEntry projectEntry = ProjectEntries [guid];
                if (projectEntry == null)
                {
                    // TODO: determine if we should report an error if a build
                    // configuration is defined for a project that does not
                    // exist in the solution
                    continue;
                }

                // holds mapping between project configuration(s) and solution(s)
                ConfigurationMap buildConfigurations = new ConfigurationMap(
                    projectBuildMatches.Count);

                for (int i = 0; i < projectBuildMatches.Count; i++)
                {
                    Match         projectBuildMatch  = projectBuildMatches [i];
                    string        solutionConfigName = projectBuildMatch.Groups["solutionConfiguration"].Value;
                    string        solutionPlatform   = projectBuildMatch.Groups["solutionPlatform"].Value;
                    string        projectConfigName  = projectBuildMatch.Groups["projectConfiguration"].Value;
                    string        projectPlatform    = projectBuildMatch.Groups["projectPlatform"].Value;
                    Configuration solutionConfig     = new Configuration(
                        solutionConfigName, solutionPlatform);
                    Configuration projectConfig = new Configuration(
                        projectConfigName, projectPlatform);
                    buildConfigurations [solutionConfig] = projectConfig;
                }

                // add map to corresponding project entry
                projectEntry.BuildConfigurations = buildConfigurations;
            }

            LoadProjectGuids(new ArrayList(solutionTask.Projects.FileNames), false);
            LoadProjectGuids(new ArrayList(solutionTask.ReferenceProjects.FileNames), true);
            LoadProjects(gacCache, refResolver, explicitProjectDependencies);
        }
Ejemplo n.º 6
0
        public Solution(string solutionContent, SolutionTask solutionTask, TempFileCollection tfc, GacCache gacCache, ReferencesResolver refResolver) : base(solutionTask, tfc, gacCache, refResolver)
        {
            Regex           reProjects     = new Regex(@"Project\(\""(?<package>\{.*?\})\"".*?\""(?<name>.*?)\"".*?\""(?<project>.*?)\"".*?\""(?<guid>.*?)\""(?<all>[\s\S]*?)EndProject", RegexOptions.Multiline);
            MatchCollection projectMatches = reProjects.Matches(solutionContent);

            Hashtable explicitProjectDependencies = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (Match projectMatch in projectMatches)
            {
                string project = projectMatch.Groups["project"].Value;
                string guid    = projectMatch.Groups["guid"].Value;

                // translate partial project path or URL to absolute path
                string fullProjectPath = TranslateProjectPath(solutionTask.SolutionFile.DirectoryName,
                                                              project);

                // check if project file actually exists
                if (!System.IO.File.Exists(fullProjectPath))
                {
                    throw CreateProjectDoesNotExistException(fullProjectPath);
                }

                bool isEnterpriseTemplateProject = ManagedProjectBase.IsEnterpriseTemplateProject(fullProjectPath);
                if (isEnterpriseTemplateProject)
                {
                    RecursiveLoadTemplateProject(fullProjectPath);
                }
                else
                {
                    // add project entry to collection
                    ProjectEntries.Add(new ProjectEntry(guid, fullProjectPath));
                }

                // set-up project dependencies
                Regex           reDependencies    = new Regex(@"^\s+(?<guid>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})\s+=\s+(?<dep>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})", RegexOptions.Multiline);
                MatchCollection dependencyMatches = reDependencies.Matches(projectMatch.Value);

                foreach (Match dependencyMatch in dependencyMatches)
                {
                    string dependency = dependencyMatch.Groups["dep"].Value;
                    // bug #1534864: an Enterprise Template project actually
                    // defines dependencies for the projects it contains, and
                    // is not added as a project itself
                    //
                    // Note: for non-ET projects both the "guid" and "dep" group
                    // have the same value, which is the guid of the project
                    // that the project containing the dependencies section
                    // depends upon
                    string projectGuid = isEnterpriseTemplateProject ?
                                         dependencyMatch.Groups["guid"].Value : guid;

                    if (!explicitProjectDependencies.ContainsKey(projectGuid))
                    {
                        explicitProjectDependencies[projectGuid] = CollectionsUtil.CreateCaseInsensitiveHashtable();
                    }
                    ((Hashtable)explicitProjectDependencies[projectGuid])[dependency] = null;
                }

                // set-up project configuration
                Regex           reProjectBuildConfig = new Regex(@"^\s+" + guid + @"\.(?<solutionConfiguration>[^|]+)\|?(?<solutionPlatform>[^\.]?)\.Build\.0\s*=\s* (?<projectConfiguration>[^|]+)\|(?<projectPlatform>[\.\w ]+)\s*", RegexOptions.Multiline);
                MatchCollection projectBuildMatches  = reProjectBuildConfig.Matches(solutionContent);

                ProjectEntry projectEntry = ProjectEntries [guid];
                if (projectEntry == null)
                {
                    // TODO: determine if we should report an error if a build
                    // configuration is defined for a project that does not
                    // exist in the solution
                    continue;
                }

                // holds mapping between project configuration(s) and solution(s)
                ConfigurationMap buildConfigurations = new ConfigurationMap(
                    projectBuildMatches.Count);

                for (int i = 0; i < projectBuildMatches.Count; i++)
                {
                    Match         projectBuildMatch  = projectBuildMatches [i];
                    string        solutionConfigName = projectBuildMatch.Groups["solutionConfiguration"].Value;
                    string        solutionPlatform   = projectBuildMatch.Groups["solutionPlatform"].Value;
                    string        projectConfigName  = projectBuildMatch.Groups["projectConfiguration"].Value;
                    string        projectPlatform    = projectBuildMatch.Groups["projectPlatform"].Value;
                    Configuration solutionConfig     = new Configuration(
                        solutionConfigName, solutionPlatform);
                    Configuration projectConfig = new Configuration(
                        projectConfigName, projectPlatform);
                    buildConfigurations [solutionConfig] = projectConfig;
                }

                // add map to corresponding project entry
                projectEntry.BuildConfigurations = buildConfigurations;
            }

            LoadProjectGuids(new ArrayList(solutionTask.Projects.FileNames), false);
            LoadProjectGuids(new ArrayList(solutionTask.ReferenceProjects.FileNames), true);
            LoadProjects(gacCache, refResolver, explicitProjectDependencies);
        }
Ejemplo n.º 7
0
        public void RecursiveLoadTemplateProject(string fileName)
        {
            XmlDocument doc = _solutionTask.ProjectFactory.LoadProjectXml(fileName);

            foreach (XmlNode node in doc.SelectNodes("//Reference"))
            {
                XmlNode projectGuidNode = node.SelectSingleNode("GUIDPROJECTID");
                XmlNode fileNode        = node.SelectSingleNode("FILE");

                if (fileNode == null)
                {
                    Log(Level.Warning, "Reference with missing <FILE> node. Skipping.");
                    continue;
                }

                // check if we're dealing with project or assembly reference
                if (projectGuidNode != null)
                {
                    string subProjectFilename = node.SelectSingleNode("FILE").InnerText;
                    string fullPath;

                    // translate URLs to physical paths if using a webmap
                    string map = _webMaps.FindBestMatch(subProjectFilename);
                    if (map != null)
                    {
                        Log(Level.Debug, "Found webmap match '{0}' for '{1}.",
                            map, subProjectFilename);
                        subProjectFilename = map;
                    }

                    try {
                        Uri uri = new Uri(subProjectFilename);
                        if (uri.Scheme == Uri.UriSchemeFile)
                        {
                            fullPath = FileUtils.GetFullPath(FileUtils.CombinePaths(
                                                                 Path.GetDirectoryName(fileName), uri.LocalPath));
                        }
                        else
                        {
                            fullPath = subProjectFilename;

                            if (!_solutionTask.EnableWebDav)
                            {
                                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                                       "Cannot build web project '{0}'.  Please use"
                                                                       + " <webmap> to map the given URL to a project-relative"
                                                                       + " path, or specify enablewebdav=\"true\" on the"
                                                                       + " <solution> task element to use WebDAV.", fullPath));
                            }
                        }
                    } catch (UriFormatException) {
                        fullPath = FileUtils.GetFullPath(FileUtils.CombinePaths(
                                                             Path.GetDirectoryName(fileName), subProjectFilename));
                    }

                    // check if project file actually exists
                    if (!System.IO.File.Exists(fullPath))
                    {
                        throw CreateProjectDoesNotExistException(fullPath);
                    }

                    if (ManagedProjectBase.IsEnterpriseTemplateProject(fullPath))
                    {
                        RecursiveLoadTemplateProject(fullPath);
                    }
                    else
                    {
                        ProjectEntries.Add(new ProjectEntry(projectGuidNode.InnerText, fullPath));
                    }
                }
                else
                {
                    Log(Level.Verbose, "Skipping file reference '{0}'.",
                        fileNode.InnerText);
                }
            }
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        public ProjectSettings(XmlElement elemRoot, XmlElement elemSettings, ManagedProjectBase project)
        {
            _project  = project;
            _settings = new ArrayList();

            // check whether build file is valid
            if (elemRoot.FirstChild == null)
            {
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       "Project file '{0}' is not valid.", Project.ProjectPath),
                                         Location.UnknownLocation);
            }

            _guid = ProjectSettings.GetProjectGuid(project.ProjectPath,
                                                   elemRoot);

            // determine output type of this project
            _outputType = GetOutputType(elemSettings);

            // initialize hashtable for holding string settings
            Hashtable htStringSettings = new Hashtable();

            switch (_outputType)
            {
            case ManagedOutputType.Library:
                _settings.Add("/target:library");
                break;

            case ManagedOutputType.Executable:
                _settings.Add("/target:exe");
                // startup object only makes sense for executable assemblies
                htStringSettings["StartupObject"] = @"/main:""{0}""";
                break;

            case ManagedOutputType.WindowsExecutable:
                _settings.Add("/target:winexe");
                // startup object only makes sense for executable assemblies
                htStringSettings["StartupObject"] = @"/main:""{0}""";
                break;
            }

            // suppresses display of Microsoft startup banner
            _settings.Add("/nologo");

            _assemblyName = elemSettings.Attributes["AssemblyName"].Value;

            // the key file to use to sign ActiveX/COM wrappers
            _assemblyOriginatorKeyFile = StringUtils.ConvertEmptyToNull(
                elemSettings.Attributes["AssemblyOriginatorKeyFile"].Value);

            // the key container to use to sign ActiveX/COM wrappers
            _assemblyKeyContainerName = StringUtils.ConvertEmptyToNull(
                elemSettings.Attributes["AssemblyKeyContainerName"].Value);

            // pre and post build events are VS .NET 2003 specific, so do not
            // assume they are there
            if (elemSettings.Attributes["RunPostBuildEvent"] != null)
            {
                _runPostBuildEvent = StringUtils.ConvertEmptyToNull(
                    elemSettings.Attributes["RunPostBuildEvent"].Value);
            }

            if (elemSettings.Attributes["PreBuildEvent"] != null)
            {
                _preBuildEvent = StringUtils.ConvertEmptyToNull(
                    elemSettings.Attributes["PreBuildEvent"].Value);
            }

            if (elemSettings.Attributes["PostBuildEvent"] != null)
            {
                _postBuildEvent = StringUtils.ConvertEmptyToNull(
                    elemSettings.Attributes["PostBuildEvent"].Value);
            }

            if (elemSettings.Attributes["RootNamespace"] != null)
            {
                _rootNamespace = StringUtils.ConvertEmptyToNull(
                    elemSettings.Attributes["RootNamespace"].Value);
                if (RootNamespace != null && Project.Type == ProjectType.VB)
                {
                    _settings.Add("/rootnamespace:" + _rootNamespace);
                }
            }

            if (elemSettings.Attributes["ApplicationIcon"] != null)
            {
                string value = StringUtils.ConvertEmptyToNull(
                    elemSettings.Attributes["ApplicationIcon"].Value);
                if (value != null)
                {
                    _applicationIcon = new FileInfo(FileUtils.CombinePaths(
                                                        Project.ProjectDirectory.FullName, value));
                }
            }

            // process VB.NET specific project settings
            if (Project.Type == ProjectType.VB)
            {
                if (elemSettings.Attributes["OptionExplicit"] != null)
                {
                    if (elemSettings.Attributes ["OptionExplicit"].Value == "Off")
                    {
                        _settings.Add("/optionexplicit-");
                    }
                    else
                    {
                        _settings.Add("/optionexplicit+");
                    }
                }

                if (elemSettings.Attributes["OptionStrict"] != null)
                {
                    if (elemSettings.Attributes ["OptionStrict"].Value == "Off")
                    {
                        _settings.Add("/optionstrict-");
                    }
                    else
                    {
                        _settings.Add("/optionstrict+");
                    }
                }

                if (elemSettings.Attributes["OptionCompare"] != null)
                {
                    if (elemSettings.Attributes ["OptionCompare"].Value == "Text")
                    {
                        _settings.Add("/optioncompare:text");
                    }
                    else
                    {
                        _settings.Add("/optioncompare:binary");
                    }
                }
            }

            foreach (DictionaryEntry de in htStringSettings)
            {
                string value = elemSettings.GetAttribute(de.Key.ToString());
                if (String.IsNullOrEmpty(value))
                {
                    // skip empty values
                    continue;
                }
                _settings.Add(string.Format(de.Value.ToString(), value));
            }
        }