Package org.eclipse.cdt.managedbuilder.llvm.ui

Source Code of org.eclipse.cdt.managedbuilder.llvm.ui.LlvmEnvironmentVariableSupplier

/*******************************************************************************
* Copyright (c) 2010-2013 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
*      Leo Hippelainen - Initial implementation
*      Petri Tuononen - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.llvm.ui;

import java.io.File;
import java.util.HashMap;

import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
import org.eclipse.cdt.managedbuilder.gnu.cygwin.GnuCygwinConfigurationEnvironmentSupplier;
import org.eclipse.cdt.managedbuilder.gnu.mingw.MingwEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.llvm.ui.preferences.LlvmPreferenceStore;
import org.eclipse.cdt.managedbuilder.llvm.util.Separators;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

/**
* Contains LLVM environment variables.
*
* @noextend This class is not intended to be subclassed by clients.
*/
public class LlvmEnvironmentVariableSupplier implements
    IConfigurationEnvironmentVariableSupplier {

  //toggle for preference changes
  private static boolean preferencesChanged = true;
  //LLVM environment variable data structure
  private static HashMap<String, LlvmBuildEnvironmentVariable> llvmEnvironmentVariables =
    new HashMap<String, LlvmBuildEnvironmentVariable>(6);
  //Environment variables for HashMap usage
  private static final String ENV_VAR_NAME_LLVM_BIN     = "LLVM_BIN_PATH"; //$NON-NLS-1$
  private static final String ENV_VAR_NAME_LLVMINTERP   = "LLVMINTERP"; //$NON-NLS-1$
  private static final String ENV_VAR_NAME_PATH       = "PATH"; //$NON-NLS-1$
  private static final String ENV_VAR_NAME_INCLUDE_PATH   = "INCLUDE_PATH"; //$NON-NLS-1$
  private static final String ENV_VAR_NAME_LIBRARY_PATH   = "LLVM_LIB_SEARCH_PATH"; //$NON-NLS-1$
  private static final String ENV_VAR_NAME_LIBRARIES     = "LIBRARIES"; //$NON-NLS-1$
 
  /**
   * Initializes llvm environment variable paths from the system environment variables.
   */
  public static void initializePaths() { //TODO: Is this actually called anywhere?
    //get bin path
    String binPath = getBinPath();
    //set LLVM bin path environment variable
    setLlvmEnvironmentVariableReplace(ENV_VAR_NAME_LLVM_BIN, binPath);
    //if bin path exists
    if (binPath != null && binPath.length()!=0) {
      String pathStr = binPath;
      //if OS is Windows (Windows specific settings)
      if (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) { //$NON-NLS-1$ //$NON-NLS-2$
        try {
          //try to find mingw or cygwin path from PATH environment variable
          IBuildEnvironmentVariable envPath = llvmEnvironmentVariables
              .get(ENV_VAR_NAME_PATH);
          IBuildEnvironmentVariable mingwPath=null, cygwinPath=null;
          //if path is empty
          if (envPath == null) {
            //try to find mingw path from MingwEnvironmentVariableSupplier
            IConfigurationEnvironmentVariableSupplier mingwEnvironmentVariables =
              new MingwEnvironmentVariableSupplier();
            mingwPath = mingwEnvironmentVariables.getVariable(
                ENV_VAR_NAME_PATH, null, null);
            //try to find cygwin path from GnuCygwinConfigurationEnvironmentSupplier
            IConfigurationEnvironmentVariableSupplier cygwinEnvironmentVariables =
              new GnuCygwinConfigurationEnvironmentSupplier();
            cygwinPath = cygwinEnvironmentVariables.getVariable(
                ENV_VAR_NAME_PATH, null, null);

          }
          //if mingw found
          if (mingwPath != null) {
            //form full path
            pathStr = pathStr + System.getProperty("path.separator") + mingwPath.getValue(); //$NON-NLS-1$
          }
          //if cygwin found
          if (cygwinPath != null) {
            //form full path
            pathStr = pathStr + System.getProperty("path.separator") + cygwinPath.getValue(); //$NON-NLS-1$
          }
        } catch (Exception e) {
          //TODO: Emit proper error message and enter it to Eclipse error log.
          e.printStackTrace();
        }
      }
      //initialize environment variable cache values
      setLlvmEnvironmentVariable(ENV_VAR_NAME_PATH, pathStr);
      setLlvmEnvironmentVariable(ENV_VAR_NAME_LLVMINTERP, binPath + Separators.getFileSeparator() + "lli"); //$NON-NLS-1$
      setLlvmEnvironmentVariable(ENV_VAR_NAME_INCLUDE_PATH, getSysEnvPath(ENV_VAR_NAME_INCLUDE_PATH));
      setLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARY_PATH, getSysEnvPath(ENV_VAR_NAME_LIBRARY_PATH));
      setLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARIES, getSysEnvPath(ENV_VAR_NAME_LIBRARIES));
      preferencesChanged = false;
    }
  }
 
  /**
   * Get LLVM bin path
   *
   * @return LLVM bin path
   */
  public static String getBinPath() {
    return findBinDir(ENV_VAR_NAME_LLVM_BIN, "bin"); //$NON-NLS-1$
  }

  /**
   * Get LLVM include paths
   *
   * @return LLVM include paths
   */
  public static String getIncludePath() {
    return getLlvmEnvironmentVariable(ENV_VAR_NAME_INCLUDE_PATH).getValue();
  }

  /**
   * Get LLVM library paths
   *
   * @return LLVM library paths
   */
  public static String getLibraryPath() {
    return getLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARY_PATH).getValue();
  }

  /**
   * Get LLVM libraries
   *
   * @return LLVM libraries
   */
  public static String getLibraries() {
    return getLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARIES).getValue();
   
  }
 
  /**
   * Set path to LLVM bin.
   *
   * @param path Path to LLVM bin location.
   */
  public static void setBinPath(String path) {
    setLlvmEnvironmentVariableReplace(ENV_VAR_NAME_LLVM_BIN, path);
  }
 
  /**
   * Append a new include path.
   *
   * @param path Include path
   */
  public static void addIncludePath(String path) {
    String existingIncPaths = getIncludePath();
    //add the include path only if it doesn't already exists
    if (!existingIncPaths.contains(path)) {
      appendLlvmEnvironmentVariable(ENV_VAR_NAME_INCLUDE_PATH, existingIncPaths, path);     
    }
  }
 
  /**
   * Append a new library path.
   *
   * @param path Library path
   */
  public static void addLibraryPath(String path) {
    String existingLibPaths = getLibraryPath();
    //add the library path only if it doesn't already exists
    if (!existingLibPaths.contains(path)) {
      appendLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARY_PATH, existingLibPaths, path);     
    }
  }
 
  /**
   * Append a new library.
   *
   * @param lib Library file
   */
  public static void addLibrary(String lib) {
    String existingLibs = getLibraries();
    //add the library only if it doesn't already exists
    if (!existingLibs.contains(lib)) {
      appendLlvmEnvironmentVariable(ENV_VAR_NAME_LIBRARIES, existingLibs, lib);     
    }
  }
 
  /**
   * This is to be called if some of the preference paths have changed.
   */
  public static void notifyPreferenceChange() { //TODO: Change
    preferencesChanged = true;
  }

  /**
   * Get a specific path for given parameters.
   *
   * @param pathKey Path for specific location
   * @param subDirName Additional sub-path
   * @return bin path
   */
  private static String findBinDir(String pathKey, String subDirName) {
    String resultPath = null;
    //if preferences haven't been changed
    //try to find the bin path from the LLVM environment variable HashMap
    if (!preferencesChanged) { //TODO: Change
      //get current path
      LlvmBuildEnvironmentVariable earlierValue = llvmEnvironmentVariables
          .get(pathKey);
      //if earlier LlvmBuildEnvironmentVariable exists
      if (null != earlierValue) {
        //return current path
        return earlierValue.getValue();
      }
    } else {
      // Try if the path is set in the LLVM plug-in preferences
      String preferenceLocation = LlvmPreferenceStore.getBinPath();
      //if preference exists
      if (null != preferenceLocation) {
        //remove white spaces from preference location
        preferenceLocation = preferenceLocation.trim();
        //if preference location is not empty
        if (preferenceLocation.length()!=0) {
          //get path for LLVM executable
          resultPath = getDirIfLlvmFound(preferenceLocation, null);
          //if LLVM executable path doesn't exist
          if (null == resultPath) {
            // If no luck check next with sub directory name appended
            resultPath = getDirIfLlvmFound(preferenceLocation,
                subDirName);
          }
        }
      }
      if (null == resultPath) {
        // If still no luck try all folders listed in PATH
        String pathVariable = System.getenv(ENV_VAR_NAME_PATH);
        //split paths to String array
        String[] paths = pathVariable.split(Separators.getPathSeparator());
        //check every path if LLVM executable is found
        for (String pathStr : paths) {
          resultPath = getDirIfLlvmFound(pathStr, null);
          //stop loop if LLVM executable path is found
          if (null != resultPath) {
            break;
          }
        }
      }
      //return found path
      return resultPath;     
    }
    return null;
  }

  /**
   * Get LLVM executable path.
   *
   * @param candidatePath Suggestion for LLVM executable path
   * @param subPath Additional sub-path for LLVM executable path
   * @return Full path for LLVM executable if valid, otherwise null
   */
  private static String getDirIfLlvmFound(String candidatePath, String subPath) {
    String llvmPath = null;
    // If there is a trailing / or \, remove it
    if (candidatePath.endsWith(Separators.getFileSeparator()) && candidatePath.length() > 1) {
      llvmPath = candidatePath.substring(0, candidatePath.length() - 1);
    }
    //if subPath exists and is not empty -> append it to candidatePath
    if ((null != subPath) && (subPath.length()!=0)) {
      //form full path
      llvmPath = candidatePath + Separators.getFileSeparator() + subPath;
    }
    //return a full path for LLVM executable if it's valid, otherwise null
    return getBinDirIfLlvm_ar(llvmPath);
  }

  /**
   * Get the full path for llvm executable if the bin path given
   * as a parameter is found and executable exists in that path.
   *
   * @param binPathTemp User provided bin directory path
   * @return bin path where llvm-ar is located if executable exists
   */
  private static String getBinDirIfLlvm_ar(String binPathTemp) {
    //if given directory is found
    if (new Path(binPathTemp).toFile().isDirectory()) {
      String llvm_executable = "llvm-ar"; //$NON-NLS-1$
      File arFileFullPath = null;
      //if OS is Windows -> add .exe to the executable name
      if (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) {  //$NON-NLS-1$//$NON-NLS-2$
        llvm_executable = llvm_executable + ".exe"; //$NON-NLS-1$
      }
      //form full executable path
      arFileFullPath = new File(binPathTemp + Separators.getFileSeparator()
          + llvm_executable);
      //check if file exists -> proper LLVM installation exists
      if (arFileFullPath.isFile()) {
        //return path where llvm-ar exists
        return binPathTemp;
      }
    }     
    return null;
  }
 
  /**
   * Get stdc++ library path located in MinGW installation.
   *
   * @return stdc++ library path for MinGW
   */
  public static String getMinGWStdLib() {
    //get mingw bin path
    IPath mingwBinPath = MingwEnvironmentVariableSupplier.getBinDir();
    StringBuilder sB = new StringBuilder(mingwBinPath.toOSString());
    //drop bin
    sB.delete(sB.length()-3, sB.length());
    //append mingw lib subdir
    sB.append("lib\\gcc\\mingw32\\"); //$NON-NLS-1$
    //get all files in the directory
    File f = new File(sB.toString());
    //append the first dir
    sB.append(f.list()[0])
    return sB.toString();
  }
 
  /**
   *
   * Get LLVM environment variable.
   *
   * @param envName Name of the environment variable
   */
  public static LlvmBuildEnvironmentVariable getLlvmEnvironmentVariable(String envName) {
    return llvmEnvironmentVariables.get(envName);
  }
 
  /**
   * Set LLVM environment variable.
   *
   * @param name Name for the environment variable
   * @param path Path for the environment variable
   */
  private static void setLlvmEnvironmentVariable(String name, String path) {
    //appends a new path in front of the the old path in HashMap that contains
    //the specific LLVM environment variable
    llvmEnvironmentVariables.put(name, new LlvmBuildEnvironmentVariable(
        name, path, IBuildEnvironmentVariable.ENVVAR_APPEND));
  }
 
  /**
   * Set LLVM environment variable by replacing the existing paths.
   *
   * @param name Name for the environment variable
   * @param path Path for the environment variable
   */
  public static void setLlvmEnvironmentVariableReplace(String name, String path) {
    //replaces the old path in HashMap that contains the specific LLVM environment variable
    llvmEnvironmentVariables.put(name, new LlvmBuildEnvironmentVariable(
        name, path, IBuildEnvironmentVariable.ENVVAR_REPLACE));
  }
 
  /**
   * Append a new LLVM environment variable to existing list.
   *
   * @param name Name of the preference
   * @param oldPath Old paths/preference values
   * @param path New path to be added to the environment variable
   */
  public static void appendLlvmEnvironmentVariable(String name, String oldPath, String path) {
    String newPath = null;
    boolean ok = false;
    //if oldPath exists
    if (oldPath!=null) {
      //if the oldPath isn't empty
      if((oldPath.trim()).length()!=0) {
        StringBuffer sB = new StringBuffer();
        //append old path
        sB.append(oldPath);
        //append a path separator
        sB.append(Separators.getPathSeparator());
        //append the new path
        sB.append(path);
        //construct a new full path
        newPath = sB.toString();
        ok=true;
      }
    }
    if (!ok) {
      newPath=path;     
    }
    //set new path to the HashMap that contains
    //the specific LLVM environment variable
    //if newPath exists
    if (newPath!=null) {
      //if the newPath isn't empty
      if((newPath.trim()).length()!=0) {
        //add new values to the LLVM environment variable
        llvmEnvironmentVariables.put(name, new LlvmBuildEnvironmentVariable(
            name, newPath, IBuildEnvironmentVariable.ENVVAR_APPEND));       
      }
    }
  }
 
  /**
   * Returns a system environment variable path
   *
   * @param envName Environment variable name
   * @return system environment variable path
   */
  private static String getSysEnvPath(String envName) {
    String path = System.getenv(envName);
    if(path != null) {
      return path;
    }
    return ""; //$NON-NLS-1$
  }
 
  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.cdt.managedbuilder.envvar.
   * IConfigurationEnvironmentVariableSupplier#getVariable(java.lang.String,
   * org.eclipse.cdt.managedbuilder.core.IConfiguration,
   * org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider)
   */
  public IBuildEnvironmentVariable getVariable(String variableName,
      IConfiguration configuration, IEnvironmentVariableProvider provider) {
    return llvmEnvironmentVariables.get(variableName);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.cdt.managedbuilder.envvar.
   * IConfigurationEnvironmentVariableSupplier
   * #getVariables(org.eclipse.cdt.managedbuilder.core.IConfiguration,
   * org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider)
   */
  public IBuildEnvironmentVariable[] getVariables(
      IConfiguration configuration, IEnvironmentVariableProvider provider) {
    return llvmEnvironmentVariables.values().toArray(
        new IBuildEnvironmentVariable[0]);
  }

}
TOP

Related Classes of org.eclipse.cdt.managedbuilder.llvm.ui.LlvmEnvironmentVariableSupplier

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.