/// <summary> /// Updates library paths from config settings. /// </summary> private void updateLibraryPaths(ProjectConfigurationInfo_CPP configuration) { MakeItSoConfig_Project projectSettings = MakeItSoConfig.Instance.getProjectConfig(configuration.ParentProjectInfo.Name); ProjectInfo projectInfo = configuration.ParentProjectInfo; string projectRootFolder = projectInfo.RootFolderAbsolute; // We check if any library paths should be removed... List <string> libraryPaths = new List <string>(configuration.getLibraryPaths()); foreach (string libraryPath in libraryPaths) { // We remove the library (and re-add it if we need to, but // with the name changed)... configuration.removeLibraryPath(libraryPath); // We find the full path, and add it if we are not // configured to remove it... string fullPath = Path.Combine(projectRootFolder, libraryPath); if (projectSettings.libraryPathShouldBeRemoved(fullPath) == false) { string prefix = MakeItSoConfig.Instance.getProjectConfig(projectInfo.Name).CPPFolderPrefix; string gccPath = Utils.addPrefixToFolderPath(libraryPath, prefix); configuration.addLibraryPath(gccPath); } } // We add any new paths... List <ProjectPath> pathsToAdd = projectSettings.getConfiguration(configuration.Name).getLibraryPathsToAdd(); foreach (ProjectPath pathToAdd in pathsToAdd) { string relativePath; if (!pathToAdd.Absolute) { relativePath = Utils.makeRelativePath(projectRootFolder, pathToAdd.Path); } else { relativePath = pathToAdd.Path; } configuration.addLibraryPath(relativePath); } }
/// <summary> /// Finds the library path for the configuration passed in. /// </summary> private void parseLinkerSettings_LibraryPath(VCConfiguration vcConfiguration, VCLinkerTool linkerTool, ProjectConfigurationInfo_CPP configurationInfo) { // We: // 1. Read the additional library paths (which are in a semi-colon-delimited string) // 2. Split it into separate paths // 3. Resolve any symbols // 4. Make sure all paths are relative to the project root folder // 1 & 2... string strAdditionalLibraryDirectories = Utils.call(() => (linkerTool.AdditionalLibraryDirectories)); if (strAdditionalLibraryDirectories == null) { return; } List<string> additionalLibraryDirectories = Utils.split(strAdditionalLibraryDirectories, ';', ','); foreach (string additionalLibraryDirectory in additionalLibraryDirectories) { // The string may be quoted. We need to remove the quotes... string unquotedLibraryDirectory = additionalLibraryDirectory.Trim('"'); if (unquotedLibraryDirectory == "") { continue; } // 3 & 4... string resolvedPath = Utils.call(() => (vcConfiguration.Evaluate(unquotedLibraryDirectory))); if (resolvedPath != "") { string relativePath = Utils.makeRelativePath(m_projectInfo.RootFolderAbsolute, resolvedPath); configurationInfo.addLibraryPath(relativePath); } } }
/// <summary> /// Updates library paths from config settings. /// </summary> private void updateLibraryPaths(ProjectConfigurationInfo_CPP configuration) { MakeItSoConfig_Project projectSettings = MakeItSoConfig.Instance.getProjectConfig(configuration.ParentProjectInfo.Name); ProjectInfo projectInfo = configuration.ParentProjectInfo; string projectRootFolder = projectInfo.RootFolderAbsolute; // We check if any library paths should be removed... List<string> libraryPaths = new List<string>(configuration.getLibraryPaths()); foreach (string libraryPath in libraryPaths) { // We remove the library (and re-add it if we need to, but // with the name changed)... configuration.removeLibraryPath(libraryPath); // We find the full path, and add it if we are not // configured to remove it... string fullPath = Path.Combine(projectRootFolder, libraryPath); if (projectSettings.libraryPathShouldBeRemoved(fullPath) == false) { string prefix = MakeItSoConfig.Instance.getProjectConfig(projectInfo.Name).CPPFolderPrefix; string gccPath = Utils.addPrefixToFolderPath(libraryPath, prefix); configuration.addLibraryPath(gccPath); } } // We add any new paths... List<string> pathsToAdd = projectSettings.getConfiguration(configuration.Name).getLibraryPathsToAdd().ToList(); foreach (string pathToAdd in pathsToAdd) { string relativePath = Utils.makeRelativePath(projectRootFolder, pathToAdd); configuration.addLibraryPath(relativePath); } }
/// <summary> /// Sets up implicit linking for this project. /// </summary> public void setupImplicitLinking() { // Implicit linking can be a bit tricky, and works differently // depending on whether the project is an executable or a // library. // Executables // ----------- // 1. We check if the project is set to link dependencies. // If so, we: // 2. Find the libraries that the executable depends and link // them in. // 3. If the libraries themselves depend on other libraries, // we need to link them in as well. We recurse through the // chain of dependencies, to find all the libraries that // the executable depends on. (Subject to rule 4, below.) // 4. If any library is set to link its dependencies, we // link it, but we do not link any of the libraries it // depends on (as they are already linked into the // library itself). // Libraries // --------- // 1. We check if the library is set to link dependencies. // If so, we: // 2. Find the libraries that the project depends on. // We find the list of object files that these libraries // are made up from, and add them to the collection to // create the main library from. // 3. We recurse through any libraries that the libraries // from step 2 depend on. We add their files to this // library as well. // We check if this project should implicitly link the projects // it depends on... if (LinkLibraryDependencies == false) { return; } // We want to link projects we depend on... switch (ProjectType) { case ProjectInfo.ProjectTypeEnum.CPP_EXECUTABLE: { // We find the libraries that this executable depends on... List <ImplicitLinkInfo> infos = new List <ImplicitLinkInfo>(); // Commented as it generates wrong and not needed additional informations. // Is it really needed if project properties are correctly filled? //findImplicitlyLinkedLibraries(infos); // And add them to the library path... foreach (ImplicitLinkInfo info in infos) { // We find the configuration for this info and add // the library to it... ProjectConfigurationInfo_CPP configuration = getConfigurationInfo(info.ConfigurationName); if (configuration == null) { // We should only fail to find a configuration is the // project has no configurations. So really, this should // not happen... Log.log(String.Format("Project {0} could not implicitly link {1}. Could not find the {2} configuration.", Name, info.LibraryRawName, info.ConfigurationName)); continue; } // We add the library and the library path... configuration.addLibraryRawName(info.LibraryRawName); string libraryPath = Utils.makeRelativePath(RootFolderAbsolute, info.OutputFolderAbsolute); configuration.addLibraryPath(libraryPath); } } break; case ProjectInfo_CPP.ProjectTypeEnum.CPP_STATIC_LIBRARY: { // We find the collection of object files used by any // libraries this library depends on... List <ImplicitLinkInfo> infos = new List <ImplicitLinkInfo>(); findImplicitlyLinkedObjectFiles(infos); // We add the files to the configurations... foreach (ImplicitLinkInfo info in infos) { // We find the configuration for this info... ProjectConfigurationInfo_CPP configuration = getConfigurationInfos().Find((cfg) => (cfg.Name == info.ConfigurationName)); // We add the collection of object files to the configuration... string prefix = MakeItSoConfig.Instance.getProjectConfig(Name).CPPFolderPrefix; string intermediateFolderAbsolute = Utils.addPrefixToFolderPath(info.IntermediateFolderAbsolute, prefix); foreach (string objectFile in info.ObjectFileNames) { string absolutePath = intermediateFolderAbsolute + "/" + objectFile; string relativePath = Utils.makeRelativePath(RootFolderAbsolute, absolutePath); configuration.addImplicitlyLinkedObjectFile(relativePath); } } } break; } }
/// <summary> /// Finds the library path for the configuration passed in. /// </summary> private void parseLinkerSettings_LibraryPath(VCConfiguration vcConfiguration, ProjectConfigurationInfo_CPP configurationInfo) { // Get the library paths across all property sheets List<string> libraryPaths = ToolPropertyCollector.Get(vcConfiguration, "VCLinkerTool", (tool) => { var linkerTool = tool as VCLinkerTool; string str = Utils.call(() => (linkerTool.AdditionalLibraryDirectories)); if (str == null) return null; // The string may be quoted. We need to remove the quotes. // (TODO: We might need to handle quotes in a smarter manner.) return Utils.split(str, ';').Select(s => s.Trim('"')).ToList(); } ); // Process the library paths foreach (string libraryPath in libraryPaths) { if (libraryPath == "") continue; string resolvedPath = Utils.call(() => (vcConfiguration.Evaluate(libraryPath))); if (resolvedPath == "") continue; string relativePath = Utils.makeRelativePath(m_projectInfo.RootFolderAbsolute, resolvedPath); configurationInfo.addLibraryPath(relativePath); } }