Ejemplo n.º 1
0
        private void RunLinker(Configuration solutionConfiguration)
        {
            const string noinherit = "$(noinherit)";

            // obtain project configuration (corresponding with solution configuration)
            VcProjectConfiguration projectConfig = (VcProjectConfiguration) BuildConfigurations[solutionConfiguration];

            // check if linking needs to be performed
            if (projectConfig.ObjFiles.Count == 0) {
                Log(Level.Debug, "No files to link.");
                return;
            }

            // create instance of Link task
            LinkTask linkTask = new LinkTask();

            // inherit project from solution task
            linkTask.Project = SolutionTask.Project;

            // inherit namespace manager from solution task
            linkTask.NamespaceManager = SolutionTask.NamespaceManager;

            // parent is solution task
            linkTask.Parent = SolutionTask;

            // inherit verbose setting from solution task
            linkTask.Verbose = SolutionTask.Verbose;

            // make sure framework specific information is set
            linkTask.InitializeTaskConfiguration();

            // set parent of child elements
            linkTask.Sources.Parent = linkTask;
            linkTask.LibDirs.Parent = linkTask;
            linkTask.Modules.Parent = linkTask;
            linkTask.EmbeddedResources.Project = linkTask.Project;

            // inherit project from solution task for child elements
            linkTask.Sources.Project = linkTask.Project;
            linkTask.LibDirs.Project = linkTask.Project;
            linkTask.Modules.Project = linkTask.Project;
            linkTask.EmbeddedResources.Project = linkTask.Project;

            // inherit namespace manager from parent
            linkTask.Sources.NamespaceManager = linkTask.NamespaceManager;
            linkTask.LibDirs.NamespaceManager = linkTask.NamespaceManager;
            linkTask.Modules.NamespaceManager = linkTask.NamespaceManager;
            linkTask.EmbeddedResources.NamespaceManager = linkTask.NamespaceManager;

            // set base directory of filesets
            linkTask.Sources.BaseDirectory = ProjectDirectory;
            linkTask.LibDirs.BaseDirectory = ProjectDirectory;
            linkTask.Modules.BaseDirectory = ProjectDirectory;
            linkTask.EmbeddedResources.BaseDirectory = ProjectDirectory;

            string addDeps = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "AdditionalDependencies");
            if (!String.IsNullOrEmpty(addDeps)) {
                // only include default libraries if noinherit is not set
                if (addDeps.ToLower(CultureInfo.InvariantCulture).IndexOf(noinherit) == -1) {
                    foreach (string defaultLib in _defaultLibraries) {
                        linkTask.Sources.FileNames.Add(defaultLib);
                    }
                } else {
                    addDeps = addDeps.Remove(addDeps.ToLower(CultureInfo.InvariantCulture).IndexOf(noinherit), noinherit.Length);
                }
                foreach (string addDep in addDeps.Split(' ')) {
                    if (Path.GetExtension(addDep) == ".obj") {
                        // skip obj files are these are handled in
                        // VcProjectConfiguration
                        continue;
                    }
                    linkTask.Sources.FileNames.Add(addDep);
                }
            } else {
                // always include default libraries if no additional dependencies
                // are specified
                foreach (string defaultLib in _defaultLibraries) {
                    linkTask.Sources.FileNames.Add(defaultLib);
                }
            }

            string delayLoadedDlls = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "DelayLoadDLLs");
            if (!String.IsNullOrEmpty(delayLoadedDlls)) {
                foreach (string dll in delayLoadedDlls.Split(';')) {
                    linkTask.DelayLoadedDlls.FileNames.Add(dll);
                }
            }

            foreach (string objFile in projectConfig.ObjFiles) {
                linkTask.Sources.FileNames.Add(objFile);
            }

            // add output generated by referenced projects and explicit project
            // dependencies
            ProjectBaseCollection projectDependencies = GetVcProjectDependencies();
            foreach (VcProject vcProject in projectDependencies) {
                VcProjectConfiguration vcProjectConfig = vcProject.BuildConfigurations[
                    solutionConfiguration] as VcProjectConfiguration;

                switch (vcProjectConfig.Type) {
                    case VcProjectConfiguration.ConfigurationType.Application:
                    case VcProjectConfiguration.ConfigurationType.DynamicLibrary:
                        FileInfo dependencyImportLibrary = vcProjectConfig.LinkerConfiguration.ImportLibrary;
                        if (dependencyImportLibrary != null) {
                            linkTask.Sources.FileNames.Add(
                                dependencyImportLibrary.FullName);
                        }
                        break;
                    case VcProjectConfiguration.ConfigurationType.StaticLibrary:
                        linkTask.Sources.FileNames.Add(vcProjectConfig.OutputPath);
                        break;
                }
            }

            linkTask.OutputFile = new FileInfo(projectConfig.OutputPath);

            // ensure directory exists
            if (!linkTask.OutputFile.Directory.Exists) {
                linkTask.OutputFile.Directory.Create();
                linkTask.OutputFile.Directory.Refresh();
            }

            // generation of debug information
            linkTask.Debug = bool.Parse(projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "GenerateDebugInformation", "FALSE"));

            string pdbFile = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "ProgramDatabaseFile");
            // use default value if pdb was not explicitly disabled (by setting it to empty string)
            if (pdbFile == null && linkTask.Debug) {
                pdbFile = projectConfig.ExpandMacros("$(OutDir)/$(ProjectName).pdb");
            }
            if (!String.IsNullOrEmpty(pdbFile)) {
                if (OutputDir != null) {
                    pdbFile = FileUtils.CombinePaths(OutputDir.FullName, Path.GetFileName(pdbFile));
                } else {
                    pdbFile = FileUtils.CombinePaths(ProjectDirectory.FullName, pdbFile);
                }
                linkTask.ProgramDatabaseFile = new FileInfo(pdbFile);

                // ensure directory exists
                if (!linkTask.ProgramDatabaseFile.Directory.Exists) {
                    linkTask.ProgramDatabaseFile.Directory.Create();
                    linkTask.ProgramDatabaseFile.Directory.Refresh();
                }
            }

            // generation of import library
            FileInfo importLibrary = projectConfig.LinkerConfiguration.ImportLibrary;
            if (importLibrary != null) {
                Argument importLibraryArg = new Argument();
                importLibraryArg.Line = "/IMPLIB:" + LinkTask.QuoteArgumentValue(
                    importLibrary.FullName);
                linkTask.Arguments.Add(importLibraryArg);

                // ensure directory exists
                if (!importLibrary.Directory.Exists) {
                    importLibrary.Directory.Create();
                    importLibrary.Directory.Refresh();
                }
            }

            // Ignore Specific Libraries
            string ignoreDefaultLibraries = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool,
                "IgnoreDefaultLibraryNames");
            if (!String.IsNullOrEmpty(ignoreDefaultLibraries)) {
                foreach (string ignoreLibrary in ignoreDefaultLibraries.Split(';')) {
                    linkTask.IgnoreLibraries.Add(new Library(ignoreLibrary));
                }
            }

            // Forced Symbol References
            string symbolReferences = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool,
                "ForceSymbolReferences");
            if (!String.IsNullOrEmpty(symbolReferences)) {
                foreach (string symbol in symbolReferences.Split(';')) {
                    linkTask.Symbols.Add(new Symbol(symbol));
                }
            }

            // generation of map file during linking
            bool generateMapFile = bool.Parse(projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "GenerateMapFile", "FALSE"));
            if (generateMapFile) {
                Argument mapArg = new Argument();

                string mapFileName = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "MapFileName");
                if (!String.IsNullOrEmpty(mapFileName)) {
                    mapArg.Line = "/MAP:" + LinkTask.QuoteArgumentValue(mapFileName);;
                } else {
                    mapArg.Line = "/MAP";
                }

                linkTask.Arguments.Add(mapArg);
            }

            // total heap allocation size
            string heapReserveSize = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "HeapReserveSize");
            if (!String.IsNullOrEmpty(heapReserveSize)) {
                Argument heapArg = new Argument();

                string heapCommitSize = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "HeapCommitSize");
                if (!String.IsNullOrEmpty(heapCommitSize)) {
                    heapArg.Line = string.Format(CultureInfo.InvariantCulture,
                        "/HEAP:{0},{1}", heapReserveSize, heapCommitSize);
                } else {
                    heapArg.Line = "/HEAP:" + heapReserveSize;
                }

                linkTask.Arguments.Add(heapArg);
            }

            // total stack allocation size
            string stackReserveSize = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "StackReserveSize");
            if (!String.IsNullOrEmpty(stackReserveSize)) {
                Argument stackArg = new Argument();

                string stackCommitSize = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "StackCommitSize");
                if (!String.IsNullOrEmpty(stackCommitSize)) {
                    stackArg.Line = string.Format(CultureInfo.InvariantCulture,
                        "/STACK:{0},{1}", stackReserveSize, stackCommitSize);
                } else {
                    stackArg.Line = "/STACK:" + stackReserveSize;
                }

                linkTask.Arguments.Add(stackArg);
            }

            if (projectConfig.Type == VcProjectConfiguration.ConfigurationType.DynamicLibrary) {
                linkTask.Arguments.Add(new Argument("/DLL"));
            }

            string addLibDirs = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "AdditionalLibraryDirectories");
            if (!String.IsNullOrEmpty(addLibDirs)) {
                foreach (string addLibDir in addLibDirs.Split(',', ';')) {
                    if (addLibDir.Length == 0) {
                        continue;
                    }
                    linkTask.LibDirs.DirectoryNames.Add(addLibDir);
                }
            }

            // links to modules
            string modules = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "AddModuleNamesToAssembly");
            if (!String.IsNullOrEmpty(modules)) {
                foreach (string module in modules.Split(';')) {
                    linkTask.Modules.FileNames.Add(module);
                }
            }

            // embedded resources
            string embeddedResources = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "EmbedManagedResourceFile");
            if (!String.IsNullOrEmpty(embeddedResources)) {
                foreach (string embeddedResource in embeddedResources.Split(';')) {
                    linkTask.EmbeddedResources.FileNames.Add(embeddedResource);
                }
            }

            Hashtable linkerArgs = projectConfig.GetToolArguments(VcConfigurationBase.LinkerTool, _linkerArgMap);
            foreach (string arg in linkerArgs.Values) {
                Argument linkArg = new Argument();
                linkArg.Line = (string) arg;
                linkTask.Arguments.Add(linkArg);
            }

            string addOptions = projectConfig.GetToolSetting(VcConfigurationBase.LinkerTool, "AdditionalOptions");
            if (!String.IsNullOrEmpty(addOptions)) {
                using (StringReader reader = new StringReader(addOptions)) {
                    string addOptionsLine = reader.ReadLine();
                    while (addOptionsLine != null) {
                        foreach (string addOption in addOptionsLine.Split(' ')) {
                            linkTask.Arguments.Add(new Argument(addOption));
                        }
                        addOptionsLine = reader.ReadLine();
                    }
                }
            }

            if (projectConfig.WholeProgramOptimization) {
                linkTask.Arguments.Add(new Argument("/LTCG"));
            }

            // execute the task
            ExecuteInProjectDirectory(linkTask);
        }
Ejemplo n.º 2
0
        public void Test_LibDirsContainingSpaces() {
            if (!CanCompileAndLink) {
                Assert.Ignore ("Compiler, linker or header files are not available"
                    + " or do not match the expected version.");
            }

            CleanAllObjs();
            CleanAllBins();

            Project project = CreateFilebasedProject(_test_compile_only);
            ExecuteProject(project);

            LinkTask lt = new LinkTask();
            lt.Project = project;
            lt.Options = "-debug";
            lt.OutputFile = new FileInfo(Path.Combine(this.TempDirectory.FullName,
                "bin/HelloWorld.exe"));

            lt.LibDirs.BaseDirectory = this.TempDirectory;
            lt.LibDirs.DirectoryNames.Add("\"whatever you want\"");
            lt.LibDirs.DirectoryNames.Add("whatever you want");

            lt.Sources.BaseDirectory = this.TempDirectory;
            lt.Sources.Includes.Add("objs\\*.obj");

            ExecuteTask(lt);
        }