From 459437b14db546d194971b945114d650913676de Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Wed, 11 Jul 2012 17:56:33 -0400 Subject: [PATCH] bug 357442: Added $CYGWIN_HOME to cygwin toolchain detection algorithm --- .../gnu/cygwin/CygwinPathResolver.java | 88 +++++++++++-------- ...ygwinConfigurationEnvironmentSupplier.java | 48 ++++++---- .../MingwEnvironmentVariableSupplier.java | 21 ++++- 3 files changed, 100 insertions(+), 57 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java index 8f2b5b7e781..0d0dd542361 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/CygwinPathResolver.java @@ -30,17 +30,19 @@ import org.eclipse.cdt.utils.PathUtil; import org.eclipse.cdt.utils.WindowsRegistry; import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; /** * @noextend This class is not intended to be subclassed by clients. */ public class CygwinPathResolver implements IBuildPathResolver { private static final String DEFAULT_ROOT = "C:\\cygwin"; //$NON-NLS-1$ + private static final String CYGWIN_DLL = "cygwin1.dll"; //$NON-NLS-1$ private static final String TOOL = "/cygpath -w -p "; //$NON-NLS-1$ private static final char BS = '\\'; private static final char SLASH = '/'; private static final String PROPERTY_OS_NAME = "os.name"; //$NON-NLS-1$ - private static final String PROPERTY_OS_VALUE = "windows";//$NON-NLS-1$ + private static final String OS_WINDOWS = "windows";//$NON-NLS-1$ private static final String SP = " "; //$NON-NLS-1$ private static final String REGISTRY_KEY_SETUP = "SOFTWARE\\Cygwin\\setup"; //$NON-NLS-1$ private static final String REGISTRY_KEY_SETUP_WIN64 = "SOFTWARE\\Wow6432Node\\Cygwin\\setup"; //$NON-NLS-1$ @@ -59,7 +61,10 @@ public class CygwinPathResolver implements IBuildPathResolver { private static final String MINGW_SPECIAL = "mingw "; //$NON-NLS-1$ private static final String CYGWIN_SPECIAL = "cygwin "; //$NON-NLS-1$ + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ + private static String envPathValueCached = null; + private static String envCygwinHomeValueCached = null; private static String binCygwin = null; private static String rootCygwin = null; private static String etcCygwin = null; @@ -90,40 +95,40 @@ public class CygwinPathResolver implements IBuildPathResolver { } /** - * returns "/etc" path in Windows format + * @return "/etc" path in Windows format. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ public static String getEtcPath() { - findPaths(); + locateCygwin(); return etcCygwin; } /** - * returns "/usr/bin" path in Windows format + * @return "/usr/bin" path in Windows format. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ public static String getBinPath() { - findPaths(); + locateCygwin(); return binCygwin; } /** - * returns Cygwin root ("/") path in Windows format + * @return Cygwin root ("/") path in Windows format. * * If you use this do not cache results to ensure user preferences are accounted for. * Please rely on internal caching. */ public static String getRootPath() { - findPaths(); + locateCygwin(); return rootCygwin; } public static boolean isWindows() { - return (System.getProperty(PROPERTY_OS_NAME).toLowerCase().startsWith(PROPERTY_OS_VALUE)); + return (System.getProperty(PROPERTY_OS_NAME).toLowerCase().startsWith(OS_WINDOWS)); } /** @@ -148,55 +153,63 @@ public class CygwinPathResolver implements IBuildPathResolver { } /** - * Returns the absolute path of the pattern by - * simply appending the pattern to the root + * Returns the absolute path of the pattern by simply appending the relativePath to the root. * - * @param pattern The pattern to find - * @return The absolute path to the pattern or null if pattern is not found + * @param relativePath - the pattern to find. + * @return The absolute path to the pattern or {@code null} if path does not exist. */ - private static String getValueFromRoot(String pattern) { + private static String getPathFromRoot(String relativePath) { if (rootCygwin != null) { - String path = rootCygwin + pattern; + String path = rootCygwin + relativePath; File file = new File(path); - if (file.exists() && file.isDirectory()) + if (file.exists() && file.isDirectory()) { return (path.replaceAll(BSLASH, SSLASH)); - else - return null; + } } return null; } /** - * Returns the absolute path to cygwin's root - * * @return The absolute path to cygwin's root or null if not found */ private static String findRoot(String paths) { String rootValue = null; - // 1. Look in PATH values. Look for bin\cygwin1.dll - IPath location = PathUtil.findProgramLocation("cygwin1.dll", paths); //$NON-NLS-1$ - if (location!=null) { - rootValue = location.removeLastSegments(2).toOSString(); + // Check $CYGWIN_HOME + if (envCygwinHomeValueCached != null && !envCygwinHomeValueCached.isEmpty()) { + IPath location = new Path(envCygwinHomeValueCached + "/bin/" + CYGWIN_DLL); + if (location.toFile().exists()) { + // deduct rootValue from "rootValue\bin\cygwin1.dll" + rootValue = location.removeLastSegments(2).toOSString(); + } } - // 2. Try to find the root dir in SOFTWARE\Cygwin\setup + // Look in PATH values. Look for cygwin1.dll + if(rootValue == null) { + IPath location = PathUtil.findProgramLocation(CYGWIN_DLL, paths); + if (location != null) { + // deduct rootValue from "rootValue\bin\cygwin1.dll" + rootValue = location.removeLastSegments(2).toOSString(); + } + } + + // Try to find the root dir in SOFTWARE\Cygwin\setup if(rootValue == null) { rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP, "rootdir"); //$NON-NLS-1$ } - // 3. Try to find the root dir in SOFTWARE\Wow6432Node\Cygwin\setup + // Try to find the root dir in SOFTWARE\Wow6432Node\Cygwin\setup if(rootValue == null) { rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP_WIN64, "rootdir"); //$NON-NLS-1$ } - // 4. Try to find the root dir in SOFTWARE\Cygnus Solutions + // Try to find the root dir in SOFTWARE\Cygnus Solutions if (rootValue == null) { rootValue = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ROOTPATTERN, PATH_NAME); } - // 5. Try the default Cygwin install dir + // Try the default Cygwin install dir if(rootValue == null) { File file = new File(DEFAULT_ROOT); if (file.exists() && file.isDirectory()) @@ -212,31 +225,36 @@ public class CygwinPathResolver implements IBuildPathResolver { /** * Finds Cygwin's paths and sets corresponding properties. */ - private static synchronized void findPaths() { + private static synchronized void locateCygwin() { if (!isWindows()) { return; } - IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable("PATH", null, true); //$NON-NLS-1$ + IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true); String envPathValue = varPath != null ? varPath.getValue() : null; + IEnvironmentVariable varCygwinHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable("CYGWIN_HOME", null, true); //$NON-NLS-1$ + String envCygwinHomeValue = varCygwinHome != null ? varCygwinHome.getValue() : null; - if (CDataUtil.objectsEqual(envPathValue, envPathValueCached)) { + if (CDataUtil.objectsEqual(envPathValue, envPathValueCached) && CDataUtil.objectsEqual(envCygwinHomeValue, envCygwinHomeValueCached)) { return; } + envPathValueCached = envPathValue; + envCygwinHomeValueCached = envCygwinHomeValue; + etcCygwin = null; binCygwin = null; rootCygwin = null; rootCygwin = findRoot(envPathValue); - // 1. Try to find the paths by appending the patterns to the root dir - etcCygwin = getValueFromRoot(ETCPATTERN); - binCygwin = getValueFromRoot(BINPATTERN); + // Try to find the paths by appending the patterns to the root dir + etcCygwin = getPathFromRoot(ETCPATTERN); + binCygwin = getPathFromRoot(BINPATTERN); if(binCygwin == null) - binCygwin = getValueFromRoot(BINPATTERN_ALTERNATE); + binCygwin = getPathFromRoot(BINPATTERN_ALTERNATE); - // 2. Try to find the paths in SOFTWARE\\Cygnus Solutions + // Try to find the paths in SOFTWARE\\Cygnus Solutions if(etcCygwin == null) etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME); if(binCygwin == null) diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java index ae08fcf841d..b3c553a0515 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/GnuCygwinConfigurationEnvironmentSupplier.java @@ -15,20 +15,22 @@ 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.internal.envvar.BuildEnvVar; +import org.eclipse.core.runtime.Path; /** * @noextend This class is not intended to be subclassed by clients. */ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfigurationEnvironmentVariableSupplier { - private static final String PATH = "PATH"; //$NON-NLS-1$ + private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ + private static final String ENV_CYGWIN_HOME = "CYGWIN_HOME"; //$NON-NLS-1$ + private static final String ENV_LANG = "LANG"; //$NON-NLS-1$ + private static final String ENV_LC_ALL = "LC_ALL"; //$NON-NLS-1$ + private static final String ENV_LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$ + private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ private static final String PROPERTY_DELIMITER = "path.separator"; //$NON-NLS-1$ private static final String PROPERTY_OSNAME = "os.name"; //$NON-NLS-1$ - private static final String LANG = "LANG"; //$NON-NLS-1$ - private static final String LC_ALL = "LC_ALL"; //$NON-NLS-1$ - private static final String LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$ - @Override public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration, IEnvironmentVariableProvider provider) { if (variableName == null) { @@ -39,19 +41,28 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration return null; } - if (variableName.equalsIgnoreCase(PATH)) { - String p = CygwinPathResolver.getBinPath(); - if (p != null) { - return new BuildEnvVar(PATH, p.replace('/','\\'), IBuildEnvironmentVariable.ENVVAR_PREPEND, System.getProperty(PROPERTY_DELIMITER, DELIMITER_UNIX)); + if (variableName.equalsIgnoreCase(ENV_PATH)) { + String path = CygwinPathResolver.getBinPath(); + if (path != null) { + path = new Path(path).toOSString(); + return new BuildEnvVar(ENV_PATH, path, IBuildEnvironmentVariable.ENVVAR_PREPEND, System.getProperty(PROPERTY_DELIMITER, DELIMITER_UNIX)); } - } else if (variableName.equalsIgnoreCase(LANG)) { + } else if (variableName.equals(ENV_CYGWIN_HOME)) { + String home = CygwinPathResolver.getRootPath(); + if (home == null) { + home = ""; //$NON-NLS-1$ + } else { + home = new Path(home).toOSString(); + } + return new BuildEnvVar(ENV_CYGWIN_HOME, home); + } else if (variableName.equalsIgnoreCase(ENV_LANG)) { // Workaround for not being able to select encoding for CDT console -> change codeset to Latin1 - String langValue = System.getenv(LANG); + String langValue = System.getenv(ENV_LANG); if (langValue == null || langValue.length() == 0) { - langValue = System.getenv(LC_ALL); + langValue = System.getenv(ENV_LC_ALL); } if (langValue == null || langValue.length() == 0) { - langValue = System.getenv(LC_MESSAGES); + langValue = System.getenv(ENV_LC_MESSAGES); } if (langValue != null && langValue.length() > 0) { // langValue is [language[_territory][.codeset][@modifier]], i.e. "en_US.UTF-8@dict" @@ -62,20 +73,21 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration langValue = "C.ISO-8859-1"; //$NON-NLS-1$ } - return new BuildEnvVar(LANG, langValue); + return new BuildEnvVar(ENV_LANG, langValue); } return null; } @Override public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration, IEnvironmentVariableProvider provider) { - IBuildEnvironmentVariable varLang = getVariable(LANG, configuration, provider); - IBuildEnvironmentVariable varPath = getVariable(PATH, configuration, provider); + IBuildEnvironmentVariable varHome = getVariable(ENV_CYGWIN_HOME, configuration, provider); + IBuildEnvironmentVariable varLang = getVariable(ENV_LANG, configuration, provider); + IBuildEnvironmentVariable varPath = getVariable(ENV_PATH, configuration, provider); if (varPath != null) { - return new IBuildEnvironmentVariable[] {varLang, varPath}; + return new IBuildEnvironmentVariable[] {varHome, varLang, varPath}; } else { - return new IBuildEnvironmentVariable[] {varLang}; + return new IBuildEnvironmentVariable[] {varHome, varLang}; } } } diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/mingw/MingwEnvironmentVariableSupplier.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/mingw/MingwEnvironmentVariableSupplier.java index c5dcb3c01a0..c05926bc240 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/mingw/MingwEnvironmentVariableSupplier.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/mingw/MingwEnvironmentVariableSupplier.java @@ -29,6 +29,7 @@ import org.eclipse.core.runtime.Platform; * @noextend This class is not intended to be subclassed by clients. */ public class MingwEnvironmentVariableSupplier implements IConfigurationEnvironmentVariableSupplier { + private static final String ENV_MINGW_HOME = "MINGW_HOME"; //$NON-NLS-1$ private static final String ENV_PATH = "PATH"; //$NON-NLS-1$ private static String envPathValueCached = null; @@ -98,7 +99,7 @@ public class MingwEnvironmentVariableSupplier implements IConfigurationEnvironme private static void locateMingw() { IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true); String envPathValue = varPath != null ? varPath.getValue() : null; - IEnvironmentVariable varMingwHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable("MINGW_HOME", null, true); //$NON-NLS-1$ + IEnvironmentVariable varMingwHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_MINGW_HOME, null, true); String envMingwHomeValue = varMingwHome != null ? varMingwHome.getValue() : null; if (CDataUtil.objectsEqual(envPathValue, envPathValueCached) && CDataUtil.objectsEqual(envMingwHomeValue, envMingwHomeValueCached)) { @@ -181,7 +182,18 @@ public class MingwEnvironmentVariableSupplier implements IConfigurationEnvironme @Override public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration, IEnvironmentVariableProvider provider) { - if (variableName.equals(ENV_PATH)) { + if (variableName.equals(ENV_MINGW_HOME)) { + locateMingw(); + String home = envMingwHomeValueCached; + if (home == null) { + if (binDir != null) { + home = binDir.removeLastSegments(1).toOSString(); + } else { + home = ""; //$NON-NLS-1$ + } + } + return new MingwBuildEnvironmentVariable(ENV_MINGW_HOME, home, IBuildEnvironmentVariable.ENVVAR_REPLACE); + } else if (variableName.equals(ENV_PATH)) { locateMingw(); if (binDir != null) { String pathStr = binDir.toOSString(); @@ -197,10 +209,11 @@ public class MingwEnvironmentVariableSupplier implements IConfigurationEnvironme @Override public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration, IEnvironmentVariableProvider provider) { + IBuildEnvironmentVariable home = getVariable(ENV_MINGW_HOME, configuration, provider); IBuildEnvironmentVariable path = getVariable(ENV_PATH, configuration, provider); return path != null - ? new IBuildEnvironmentVariable[] { path } - : new IBuildEnvironmentVariable[0]; + ? new IBuildEnvironmentVariable[] { home, path } + : new IBuildEnvironmentVariable[] { home }; } }