| /******************************************************************************* |
| * Copyright (c) 2010, 2016 Nokia Siemens Networks Oyj, Finland. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Nokia Siemens Networks - initial implementation |
| * Petri Tuononen - Initial implementation |
| *******************************************************************************/ |
| package org.eclipse.cdt.managedbuilder.llvm.util; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.resources.RefreshScopeManager; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescription; |
| import org.eclipse.cdt.managedbuilder.core.BuildException; |
| import org.eclipse.cdt.managedbuilder.core.IConfiguration; |
| import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; |
| import org.eclipse.cdt.managedbuilder.core.IManagedProject; |
| import org.eclipse.cdt.managedbuilder.core.IOption; |
| import org.eclipse.cdt.managedbuilder.core.ITool; |
| import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; |
| import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; |
| import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier; |
| import org.eclipse.cdt.managedbuilder.gnu.mingw.MingwEnvironmentVariableSupplier; |
| import org.eclipse.cdt.managedbuilder.llvm.ui.LlvmEnvironmentVariableSupplier; |
| import org.eclipse.cdt.managedbuilder.llvm.ui.preferences.LlvmPreferenceStore; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| |
| /** |
| * The main purpose of this class is to add include paths and libraries and library search paths |
| * for LLVM compiler and linker Tools which are added in Preferences->LLVM to all projects |
| * and build configurations that use LLVM ToolChain. Values added in Preferences->LLVM will |
| * show in Project->Properties->C/C++ General->Paths and Symbols tabs. |
| * |
| */ |
| public class LlvmToolOptionPathUtil { |
| |
| //tool input extensions |
| private static final String linkerInputType = "bc"; //$NON-NLS-1$ |
| private static final String[] inputTypes = {"cpp", "c"}; //$NON-NLS-1$ //$NON-NLS-2$ |
| //tool option values |
| public static final int INCLUDE = 1; |
| public static final int LIB = 2; |
| public static final int LIB_PATH = 3; |
| |
| /** |
| * Adds new include path to LLVM front-end's Include path option for every project |
| * in the workspace that uses LLVM Toolchain and for for every build configuration. |
| * |
| * @param includePath Include path for LLVM front-end's Include Option |
| */ |
| public static void addLlvmIncludePath(String includePath) { |
| addPathToToolOption(includePath, INCLUDE); |
| } |
| |
| /** |
| * Removes an include path from LLVM front-end's Include path option for every project |
| * in the workspace that uses LLVM Toolchain and for for every build configuration. |
| * |
| * @param includePath Include path for LLVM front-end's Include Option |
| */ |
| public static void removeLlvmIncludePath(String includePath) { |
| removePathFromToolOption(includePath, INCLUDE); |
| } |
| |
| /** |
| * Adds a new Library to LLVM linker's Libraries Option for every project |
| * in the workspace that use LLVM Toolchain and for for every build configuration. |
| * |
| * @param lib Library name for the LLVM linker's Libraries Option |
| */ |
| public static void addLlvmLib(String lib) { |
| addPathToToolOption(lib, LIB); |
| } |
| |
| /** |
| * Removes a Library to LLVM linker's Libraries Option for every project |
| * in the workspace that use LLVM Toolchain and for for every build configuration. |
| * |
| * @param lib Library name for the LLVM linker's Libraries Option |
| */ |
| public static void removeLlvmLib(String lib) { |
| removePathFromToolOption(lib, LIB); |
| } |
| |
| /** |
| * Adds a new Library search path directory to LLVM linker's Library search path Option |
| * for every project in the workspace that use LLVM Toolchain and for for every |
| * build configuration. |
| * |
| * @param libDir Library search path directory for LLVM linker's Library search path Option |
| */ |
| public static void addLlvmLibraryPath(String libDir) { |
| addPathToToolOption(libDir, LIB_PATH); |
| } |
| |
| /** |
| * Removes a Library search path directory from LLVM linker's Library search path Option |
| * for every project in the workspace that use LLVM Toolchain and for for every |
| * build configuration. |
| * |
| * @param libDir Library search path directory for LLVM linker's Library search path Option |
| */ |
| public static void removeLlvmLibraryPath(String libDir) { |
| removePathFromToolOption(libDir, LIB_PATH); |
| } |
| |
| /** |
| * Adds a path to Tool option. |
| * |
| * @param path Path to add to Tool option |
| * @param var Tool option's value |
| */ |
| private static void addPathToToolOption(String path, int var) { |
| //check if the given path exists |
| if (path.length()>0 && (pathExists(path) || var==LIB)) { |
| boolean success = false; |
| //get all projects in the workspace |
| IProject[] projects = getProjectsInWorkspace(); |
| IConfiguration[] configs; |
| for (IProject proj : projects) { |
| |
| //get all build configurations of the IProject |
| configs = getAllBuildConfigs(proj); |
| //if build configurations found |
| if (configs.length>0) { |
| for (IConfiguration cf : configs) { |
| //Add path for the Tool's option |
| if (addPathToSelectedToolOptionBuildConf(cf, path, var)) { |
| success = true; |
| } else { |
| success = false; |
| } |
| } |
| //if the path was added successfully |
| if (success) { |
| //save project build info |
| ManagedBuildManager.saveBuildInfo(proj, true); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Adds a path to Tool option. Only for C++ projects. |
| * |
| * @param path Path to add to Tool option |
| * @param var Tool option's value |
| */ |
| private static void addPathToToolOptionCppProjects(String path, int var) { |
| //check if the given path exists |
| if (path.length()>0 && (pathExists(path) || var==LIB)) { |
| boolean success = false; |
| //get all projects in the workspace |
| IProject[] projects = getProjectsInWorkspace(); |
| IConfiguration[] configs; |
| String projectPath = null; |
| for (IProject proj : projects) { |
| projectPath = proj.getLocation().toOSString(); |
| if (projectPath!=null) { |
| //only apply to C++ projects |
| if (FileUtil.containsCppFile(new File(projectPath))) { |
| //get all build configurations of the IProject |
| configs = getAllBuildConfigs(proj); |
| //if build configurations found |
| if (configs.length>0) { |
| for (IConfiguration cf : configs) { |
| //Add path for the Tool's option |
| if (addPathToSelectedToolOptionBuildConf(cf, path, var)) { |
| success = true; |
| } else { |
| success = false; |
| } |
| } |
| //if the path was added successfully |
| if (success) { |
| //save project build info |
| ManagedBuildManager.saveBuildInfo(proj, true); |
| ICProjectDescription projectDescription = CoreModel.getDefault().getProjectDescription(proj); |
| try { |
| CoreModel.getDefault().setProjectDescription(proj, projectDescription); |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| //use refresh scope manager to refresh |
| RefreshScopeManager manager = RefreshScopeManager.getInstance(); |
| IWorkspaceRunnable runnable = manager.getRefreshRunnable(proj); |
| try { |
| ResourcesPlugin.getWorkspace().run(runnable, null, IWorkspace.AVOID_UPDATE, new NullProgressMonitor()); |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| //rebuilt the project index |
| ProjectIndex.rebuiltIndex(proj); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Removes a path from Tool option. |
| * |
| * @param path Path to remove from Tool option |
| * @param var Tool option's value |
| */ |
| private static void removePathFromToolOption(String path, int var) { |
| //check if the given path exists |
| if (path.length()>0 && pathExists(path) || var==LIB) { |
| boolean success = false; |
| //get all projects in the workspace |
| IProject[] projects = getProjectsInWorkspace(); |
| IConfiguration[] configs; |
| for (IProject proj : projects) { |
| //get all build configurations of the IProject |
| configs = getAllBuildConfigs(proj); |
| //if build configurations found |
| if (configs.length>0) { |
| for (IConfiguration cf : configs) { |
| //remove a path from the Tool's option |
| if (removePathFromSelectedToolOptionBuildConf(cf, path, var)) { |
| success = true; |
| } else { |
| success = false; |
| } |
| } |
| //if the path was removed successfully |
| if (success) { |
| //save project build info |
| ManagedBuildManager.saveBuildInfo(proj, true); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Add a path to specific build configuration's Tool option. |
| * |
| * @param cf Build configuration |
| * @param path Path or file name to add |
| * @param var Value of the option type |
| * @return boolean True if path was added successfully |
| */ |
| private static boolean addPathToSelectedToolOptionBuildConf(IConfiguration cf, String path, int var) { |
| switch (var) { |
| case INCLUDE: |
| return addLlvmIncludePathToToolOption(cf, path); |
| case LIB: |
| return addLlvmLibToToolOption(cf, path); |
| case LIB_PATH: |
| return addLlvmLibSearchPathToToolOption(cf, path); |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Removes a path from specific build configuration's Tool option. |
| * |
| * @param cf Build configuration |
| * @param path Path or file name to remove |
| * @param var Value of the option type |
| * @return boolean True if path was removed successfully |
| */ |
| private static boolean removePathFromSelectedToolOptionBuildConf(IConfiguration cf, String path, int var) { |
| switch (var) { |
| case INCLUDE: |
| return removeLlvmIncludePathFromToolOption(cf, path); |
| case LIB: |
| return removeLlvmLibFromToolOption(cf, path); |
| case LIB_PATH: |
| return removeLlvmLibSearchPathFromToolOption(cf, path); |
| default: |
| return false; |
| } |
| } |
| |
| /** |
| * Returns all projects in the workspace. |
| * |
| * @return IProject[] |
| */ |
| public static IProject[] getProjectsInWorkspace() { |
| //get workspace |
| IWorkspace root = ResourcesPlugin.getWorkspace(); |
| //get all projects in the workspace |
| return root.getRoot().getProjects(); |
| } |
| |
| /** |
| * Returns all build configurations of the project. |
| * |
| * @param proj IProject Project |
| * @return IConfiguration[] Build configurations |
| */ |
| private static IConfiguration[] getAllBuildConfigs(IProject proj) { |
| IConfiguration[] configurations = new IConfiguration[] {}; |
| IManagedBuildInfo info = null; |
| //try to get Managed build info |
| try { |
| info = ManagedBuildManager.getBuildInfo(proj); //null if doesn't exists |
| } catch (Exception e) { //if not a managed build project |
| //print error |
| e.printStackTrace(); |
| return configurations; |
| } |
| //info can be null for projects without build info. For example, when creating a project |
| //from Import > C/C++ Executable |
| if(info == null) { |
| return configurations; |
| } |
| //get ManagedProject associated with build info |
| IManagedProject mProj = info.getManagedProject(); |
| |
| //get all build configurations of the project |
| configurations = mProj.getConfigurations(); |
| return configurations; |
| } |
| |
| /** |
| * Adds an include path to LLVM front-end's include path option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param newIncludePath Include path to be added to LLVM front-end's Include path option |
| */ |
| private static boolean addLlvmIncludePathToToolOption(IConfiguration cf, String newIncludePath) { |
| //get LLVM front-end |
| ITool llvmFrontEnd = getLlvmFrontEnd(cf); |
| //If the LLVM front-end is found from the given build configuration |
| if (llvmFrontEnd != null) { |
| //get LLVM front-end Include paths option. |
| IOption llvmFrontEndIncPathOption = getLlvmFrontEndIncludePathOption(cf); |
| //add a new include path to front-end's Include paths option. |
| boolean val = addIncludePathToToolOption(cf, llvmFrontEnd, llvmFrontEndIncPathOption, newIncludePath); |
| return val; |
| } |
| return false; |
| } |
| |
| /** |
| * Removes an include path from LLVM front-end's include path option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param removeIncludePath Include path to be removed from LLVM front-end's Include path option |
| */ |
| private static boolean removeLlvmIncludePathFromToolOption(IConfiguration cf, String removeIncludePath) { |
| //get LLVM front-end |
| ITool llvmFrontEnd = getLlvmFrontEnd(cf); |
| //If the LLVM front-end is found from the given build configuration |
| if (llvmFrontEnd != null) { |
| //get LLVM front-end Include paths option. |
| IOption llvmFrontEndIncPathOption = getLlvmFrontEndIncludePathOption(cf); |
| //remove an include path from front-end's Include paths option. |
| removeIncludePathFromToolOption(cf, llvmFrontEnd, llvmFrontEndIncPathOption, removeIncludePath); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Adds a Library to LLVM linker's Libraries Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param lib Library name |
| * @return boolean Returns true if Library Option was added successfully for the LLVM Linker. |
| */ |
| private static boolean addLlvmLibToToolOption(IConfiguration cf, String lib) { |
| //get LLVM linker |
| ITool llvmLinker = getLlvmLinker(cf); |
| //If the LLVM linker is found from the given build configuration |
| if (llvmLinker != null) { |
| //get LLVM Linker Libraries option |
| IOption librariesOption = getLlvmLinkerLibrariesOption(cf); |
| //add library to LLVM linker's Libraries Option type |
| boolean val = addLibraryToToolOption(cf, llvmLinker, librariesOption, lib); |
| return val; |
| } |
| //adding the library failed |
| return false; |
| } |
| |
| /** |
| * Removes a Library from LLVM linker's Libraries Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param removeLib Library name |
| * @return boolean Returns true if Library Option was removed successfully from the LLVM Linker. |
| */ |
| private static boolean removeLlvmLibFromToolOption(IConfiguration cf, String removeLib) { |
| //get LLVM linker |
| ITool llvmLinker = getLlvmLinker(cf); |
| //If the LLVM linker is found from the given build configuration |
| if (llvmLinker != null) { |
| //get LLVM Linker Libraries option |
| IOption librariesOption = getLlvmLinkerLibrariesOption(cf); |
| //remove a library from LLVM linker's Libraries Option type |
| removeLibraryFromToolOption(cf, llvmLinker, librariesOption, removeLib); |
| return true; |
| } |
| //removing the library failed |
| return false; |
| } |
| |
| /** |
| * Adds a Library search path to LLVM linker's Library search path Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param libDir Library search path |
| * @return boolean Returns true if Library search path Option was added successfully for the LLVM Linker. |
| */ |
| private static boolean addLlvmLibSearchPathToToolOption(IConfiguration cf, String libDir) { |
| //get LLVM linker |
| ITool llvmLinker = getLlvmLinker(cf); |
| //If the LLVM linker is found from the given build configuration |
| if (llvmLinker != null) { |
| //get LLVM Linker Library search path option |
| IOption libDirOption = getLlvmLinkerLibrarySearchPathOption(cf); |
| //add library search path to LLVM linker's Library Search Path Option type |
| boolean val = addLibrarySearchPathToToolOption(cf, llvmLinker, libDirOption, libDir); |
| return val; |
| } |
| //adding library failed |
| return false; |
| } |
| |
| /** |
| * Removes a Library search path from LLVM linker's Library search path Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param removeLibDir Library search path |
| * @return boolean Returns true if Library search path Option was removed successfully from the LLVM Linker. |
| */ |
| private static boolean removeLlvmLibSearchPathFromToolOption(IConfiguration cf, String removeLibDir) { |
| //get LLVM linker |
| ITool llvmLinker = getLlvmLinker(cf); |
| //If the LLVM linker is found from the given build configuration |
| if (llvmLinker != null) { |
| //get LLVM Linker Library search path option |
| IOption libDirOption = getLlvmLinkerLibrarySearchPathOption(cf); |
| //remove a library search path from LLVM linker's Library Search Path Option type |
| removeLibrarySearchPathFromToolOption(cf, llvmLinker, libDirOption, removeLibDir); |
| return true; |
| } |
| //removing the library search path failed |
| return false; |
| } |
| |
| /** |
| * Adds include path for given Build configuration's Tool's Include path Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param newIncludePath Include path to be added to Tool's Include path option |
| */ |
| private static boolean addIncludePathToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newIncludePath) { |
| try { |
| //add path only if it does not exists |
| String[] incPaths = option.getIncludePaths(); |
| for (String inc : incPaths) { |
| if (inc.equalsIgnoreCase(newIncludePath)) { |
| return false; |
| } |
| } |
| //add a new include path to linker's Include paths option. |
| addInputToToolOption(cf, cfTool, option, newIncludePath, incPaths); |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| return true; |
| } |
| |
| /** |
| * Removes an include path from given Build configuration's Tool's Include path Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param removeIncludePath Include path to be removed from Tool's Include path option |
| */ |
| private static void removeIncludePathFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeIncludePath) { |
| try { |
| //remove an include path from linker's Include paths option. |
| removeInputFromToolOption(cf, cfTool, option, removeIncludePath, option.getIncludePaths()); |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Adds new Library for the Linker's Libraries Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param newLibrary Library |
| */ |
| private static boolean addLibraryToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newLibrary) { |
| try { |
| if(option != null) { |
| //add library only if it does not exists |
| String[] libraries = option.getLibraries(); |
| for (String lib : libraries) { |
| if (lib.equalsIgnoreCase(newLibrary)) { |
| return false; |
| } |
| } |
| //add a new library to linker's Libraries option. |
| addInputToToolOption(cf, cfTool, option, newLibrary, libraries); |
| } |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| return true; |
| } |
| |
| /** |
| * Removes a new Library from the Linker's Libraries Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param removeLibrary Library |
| */ |
| private static void removeLibraryFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeLibrary) { |
| try { |
| //remove a library from linker's Libraries option. |
| removeInputFromToolOption(cf, cfTool, option, removeLibrary, option.getLibraries()); |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| } |
| |
| //Works only if Eclipse Bugzilla Bug 321040 fix is applied |
| /** |
| * Adds new Library search path for the Linker's Library search path Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param newLibraryPath Library search path |
| */ |
| private static boolean addLibrarySearchPathToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newLibraryPath) { |
| try { |
| if(option != null) { |
| //add path only if it does not exists |
| String[] libPaths = option.getLibraryPaths(); |
| for (String libPath : libPaths) { |
| if (libPath.equalsIgnoreCase(newLibraryPath)) { |
| return false; |
| } |
| } |
| //add a new library path to linker's Library search path option. |
| addInputToToolOption(cf, cfTool, option, newLibraryPath, libPaths); |
| } |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| return true; |
| } |
| |
| /** |
| * Removes a Library search path from the Linker's Library search path Option. |
| * Since CDT 8.0 (Bugzilla Bug 321040) |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param removeSearchPath Library search path |
| */ |
| private static void removeLibrarySearchPathFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeSearchPath) { |
| try { |
| //remove a library path from linker's Library search path option. |
| removeInputFromToolOption(cf, cfTool, option, removeSearchPath, option.getLibraryPaths()); |
| } catch (BuildException e) { |
| //show error |
| e.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Adds a new value to specific Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param newValue New value to be added to the Option type |
| * @param existingValues Existing Option type values |
| */ |
| private static void addInputToToolOption(IConfiguration cf, ITool cfTool, IOption option, String newValue, String[] existingValues) { |
| //if Option type is found |
| if (option != null) { |
| //append new value with existing values |
| String[] newValues = addNewPathToExistingPathList(existingValues, newValue); |
| //set new values array for the option for the given build configuration |
| ManagedBuildManager.setOption(cf, cfTool, option, newValues); |
| } |
| else{ |
| //log error |
| } |
| } |
| |
| /** |
| * Removes a value from a specific Option. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param cfTool ITool Tool |
| * @param option Tool Option type |
| * @param removeValue Value to be removed from the Option type |
| * @param existingValues Existing Option type values |
| */ |
| private static void removeInputFromToolOption(IConfiguration cf, ITool cfTool, IOption option, String removeValue, String[] existingValues) { |
| //if Option type is found |
| if (option != null) { |
| //check that list has values |
| if(existingValues.length>0) { |
| //remove value from existing values |
| String[] newValues = removePathFromExistingPathList(existingValues, removeValue); |
| //set new values array for the option for the given build configuration |
| ManagedBuildManager.setOption(cf, cfTool, option, newValues); |
| } |
| } |
| else{ |
| //log error |
| } |
| } |
| |
| /** |
| * Return LLVM front-end according to the input type. |
| * @param cf IConfiguration Build configuration |
| * @return ITool LLVM front-end |
| */ |
| private static ITool getLlvmFrontEnd(IConfiguration cf) { |
| //get LLVM front-end according to the input type |
| for(int i=0; i<inputTypes.length; i++) { |
| ITool tool = getIToolByInputType(cf, inputTypes[i]); |
| if (tool != null) { |
| return tool; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns LLVM linker. |
| * |
| * @param cf IConfiguration Build configuration |
| * @return ITool LLVM linker |
| */ |
| private static ITool getLlvmLinker(IConfiguration cf) { |
| //get LLVM linker |
| return getIToolByInputType(cf, linkerInputType); |
| } |
| |
| /** |
| * Returns ITool associated with the input extension. |
| * |
| * @param cf IConfiguration Build configuration |
| * @param ext input extension associated with ITool |
| * @return ITool Tool that matches input extension |
| */ |
| private static ITool getIToolByInputType(IConfiguration cf, String ext) { |
| //get ITool associated with the input extension |
| return cf.getToolFromInputExtension(ext); |
| } |
| |
| /** |
| * Returns LLVM front-end Include path Option type. |
| * |
| * @param cf IConfiguration Project build configuration |
| * @return IOption Tool option type |
| */ |
| private static IOption getLlvmFrontEndIncludePathOption(IConfiguration cf) { |
| //get llvm front-end |
| ITool cfTool = getLlvmFrontEnd(cf); |
| //get option id for include paths |
| String includeOptionId = getOptionId(cfTool, IOption.INCLUDE_PATH); |
| return getIToolPathOption(cfTool, includeOptionId); |
| } |
| |
| /** |
| * Returns LLVM Linker Libraries Option type. |
| * |
| * @param cf IConfiguration Project build configuration |
| * @return IOption Tool option type |
| */ |
| private static IOption getLlvmLinkerLibrariesOption(IConfiguration cf) { |
| //get llvm linker |
| ITool cfTool = getLlvmLinker(cf); |
| //get option id for libraries |
| String libOptionId = getOptionId(cfTool, IOption.LIBRARIES); |
| return getIToolPathOption(cfTool, libOptionId); |
| } |
| |
| /** |
| * Returns LLVM Linker Library search path Option type. |
| * |
| * @param cf IConfiguration Project build configuration |
| * @return IOption Tool option type |
| */ |
| private static IOption getLlvmLinkerLibrarySearchPathOption(IConfiguration cf) { |
| //get ITool associated with the input extension |
| ITool cfTool = cf.getToolFromInputExtension(linkerInputType); |
| //get option id for library paths |
| String libDirOptionId = getOptionId(cfTool, IOption.LIBRARY_PATHS); |
| return getIToolPathOption(cfTool, libDirOptionId); |
| } |
| |
| /** |
| * Returns Tool's option id. |
| * |
| * @param cfTool ITool Tool |
| * @param optionValueType Option's value type. |
| * @return optionId Tool's option id. |
| */ |
| private static String getOptionId(ITool cfTool, int optionValueType) { |
| String optionId = null; |
| //get all Tool options. |
| IOption[] options = cfTool.getOptions(); |
| for (IOption opt : options) { |
| try { |
| //try to match option value type |
| if(opt.getValueType()==optionValueType) { |
| //get option id |
| optionId = opt.getId(); |
| break; |
| } |
| } catch (BuildException e) { |
| //log error |
| } |
| } |
| return optionId; |
| } |
| |
| /** |
| * Returns Tool's Option type by Id. |
| * |
| * @param cfTool ITool Tool |
| * @param optionId String Tool option type id |
| * @return IOption Tool option type |
| */ |
| private static IOption getIToolPathOption(ITool cfTool, String optionId) { |
| //get path option with specific id for the ITool |
| return cfTool.getOptionById(optionId); |
| } |
| |
| /** |
| * Adds one or more paths to the list of paths. |
| * |
| * @param existingPaths Existing list of paths to add to |
| * @param newPath New path to add. May include multiple directories with a path delimiter java.io.File.pathSeparator |
| * (usually semicolon (Win) or colon (Linux/Mac), OS specific) |
| * @return String[] List that includes existing paths as well as new paths. |
| */ |
| public static String[] addNewPathToExistingPathList(String[] existingPaths, String newPath) { |
| String pathSep = java.io.File.pathSeparator; // semicolon for windows, colon for Linux/Mac |
| List<String> newPathList = new ArrayList<>(); |
| String path; |
| //adds existing paths to new paths list |
| for (int i = 0; i < existingPaths.length; i++) { |
| path = existingPaths[i]; |
| newPathList.add(path); |
| } |
| //separates new path if it has multiple paths separated by a path separator |
| String[] newPathArray = newPath.split(pathSep); |
| for (int i = 0; i < newPathArray.length; i++) { |
| path = newPathArray[i]; |
| newPathList.add(path); |
| } |
| //creates a new list that includes all existing paths as well as new paths |
| String[] newArray = newPathList.toArray(new String[0]); |
| return newArray; |
| } |
| |
| /** |
| * Removes one path from the list of paths. |
| * |
| * @param existingPaths Existing list of paths to remove from |
| * @param removePath Path to be removed. |
| * @return String[] List that includes existing paths without the path that was removed. |
| */ |
| public static String[] removePathFromExistingPathList(String[] existingPaths, String removePath) { |
| List<String> newPathList = new ArrayList<>(); |
| String path; |
| //adds existing paths to new paths list |
| for (int i = 0; i < existingPaths.length; i++) { |
| path = existingPaths[i]; |
| newPathList.add(path); |
| } |
| newPathList.remove(removePath); |
| //creates a new list that includes all existing paths except the removed path |
| String[] newArray = newPathList.toArray(new String[0]); |
| return newArray; |
| } |
| |
| /** |
| * Split paths to a String array. |
| * |
| * @param str String of paths separated by a path separator. |
| * @return String array containing multiple paths. |
| */ |
| public static String[] stringToArray(String str) { |
| return str.split(System.getProperty("path.separator")); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Append an array of Strings to a String separated by a path separator. |
| * |
| * @param array An array of Strings. |
| * @return string which contains all indexes of |
| * a String array separated by a path separator. |
| */ |
| public static String arrayToString(String[] array) { |
| StringBuilder sB = new StringBuilder(); |
| //if array isn't empty and doesn't contain an empty String |
| if (array.length>0 /*&& !array[0].isEmpty()*/) { |
| for (String i : array) { |
| sB.append(i); |
| sB.append(System.getProperty("path.separator")); //$NON-NLS-1$ |
| } |
| } |
| return sB.toString(); |
| } |
| |
| /** |
| * Checks if a file path exists. |
| * |
| * @return boolean True if the file exists. |
| */ |
| private static boolean pathExists(String path) { |
| //return true if path exists. |
| return new File(path).exists(); |
| } |
| |
| /** |
| * Get all include paths in a String array. |
| * |
| * @return String[] A String array of include paths |
| */ |
| private static String[] getAllIncludePaths() { |
| //get all include paths |
| String includePathList = LlvmPreferenceStore.getIncludePath(); |
| //split paths to String array |
| String[] incPaths = includePathList.split(Separators.getPathSeparator()); |
| return incPaths; |
| } |
| |
| /** |
| * Get all libraries in a String array. |
| * |
| * @return String[] A String array of libraries |
| */ |
| private static String[] getAllLibraries() { |
| //get all libraries |
| String libList = LlvmPreferenceStore.getLibraries(); |
| //split values to String array |
| String[] libs = libList.split(Separators.getPathSeparator()); |
| return libs; |
| } |
| |
| /** |
| * Get all library paths in a String array. |
| * |
| * @return String[] A String array of library paths |
| */ |
| private static String[] getAllLibraryPaths() { |
| //get all library paths |
| String libPathList = LlvmPreferenceStore.getLibraryPath(); |
| //split paths to String array |
| String[] libPaths = libPathList.split(Separators.getPathSeparator()); |
| return libPaths; |
| } |
| |
| /** |
| * Add all include paths found in LLVM preference page to |
| * every project's build configurations. |
| */ |
| public static void addAllIncludesToBuildConf() { |
| String[] includes = getAllIncludePaths(); |
| for(String inc : includes) { |
| addLlvmIncludePath(inc); |
| } |
| } |
| |
| /** |
| * Add all libraries found in LLVM preference page to |
| * every project's build configurations. |
| */ |
| public static void addAllLibsToBuildConf() { |
| String[] libs = getAllLibraries(); |
| for(String lib : libs) { |
| // if (!lib.equalsIgnoreCase("stdc++")) { //$NON-NLS-1$ //C++ specific |
| addLlvmLib(lib); |
| // } |
| } |
| } |
| |
| /** |
| * Add all library paths found in LLVM preference page to |
| * every project's build configurations. |
| */ |
| public static void addAllLibPathsToBuildConf() { |
| String[] libPaths = getAllLibraryPaths(); |
| for(String libPath : libPaths) { |
| // if (!libPath.equalsIgnoreCase(LlvmEnvironmentVariableSupplier.getMinGWStdLib())) { //C++ specific |
| addLlvmLibraryPath(libPath); |
| // } |
| } |
| } |
| |
| //temporary hack until scanner discovery works |
| public static void addMissingCppIncludesForMingw() { |
| //try to find mingw path from MingwEnvironmentVariableSupplier |
| IConfigurationEnvironmentVariableSupplier mingwEnvironmentVariables = |
| new MingwEnvironmentVariableSupplier(); |
| IBuildEnvironmentVariable mingwPath = mingwEnvironmentVariables.getVariable( |
| "PATH", null, null); //$NON-NLS-1$ |
| //may contain multiple paths therefore must be separated |
| String[] mingwPaths = mingwPath.getValue().split(Separators.getPathSeparator()); |
| //bin folder is appended so it must be removed |
| for(int i=0; i<mingwPaths.length; i++) { |
| if(mingwPaths[i].contains("bin")) { //$NON-NLS-1$ |
| mingwPaths[i] = mingwPaths[i].replace("bin", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| //find the correct path |
| File f1 = null; |
| String rightPath = null; |
| findPath: for(int i=0; i<mingwPaths.length; i++) { |
| f1 = new File(mingwPaths[i]+"lib/gcc/mingw32"); //$NON-NLS-1$ |
| if (f1.exists()) { |
| rightPath = f1.getAbsolutePath(); |
| break findPath; |
| } |
| } |
| if (rightPath!=null && f1!=null) { |
| //get the first directory (mingw version) |
| f1 = f1.listFiles()[0]; |
| //add three includes if they exist |
| File testFile = new File(f1.getAbsolutePath()+"/include/c++"); //$NON-NLS-1$ |
| if (testFile.exists()) { |
| LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath()); |
| addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE); |
| } |
| testFile = new File(f1.getAbsolutePath()+"/include/c++/mingw32"); //$NON-NLS-1$ |
| if (testFile.exists()) { |
| LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath()); |
| addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE); |
| } |
| testFile = new File(f1.getAbsolutePath()+"/include/c++/backward"); //$NON-NLS-1$ |
| if (testFile.exists()) { |
| LlvmPreferenceStore.appendIncludePath(testFile.getAbsolutePath()); |
| addPathToToolOptionCppProjects(testFile.getAbsolutePath(), INCLUDE); |
| } |
| //inform LLVM environment variable supplier that there has been a change |
| LlvmEnvironmentVariableSupplier.notifyPreferenceChange(); |
| } |
| } |
| |
| } |