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); }
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); }