From caa20b4d376cad914de08e8a73b27becef3dcd39 Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Thu, 4 Mar 2010 17:51:55 +0000 Subject: bug 303900: Cygwin 1.7 is Not detected on the CDT system. Patch from Marc-Andre Laperle --- .../gnu/cygwin/CygwinPathResolver.java | 151 +++++++++++++-------- .../gnu/cygwin/IsGnuCygwinToolChainSupported.java | 58 +++++--- 2 files changed, 131 insertions(+), 78 deletions(-) (limited to 'build/org.eclipse.cdt.managedbuilder.gnu.ui/src') 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 dbbf28bf7d8..2fda30fbfc4 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 @@ -8,6 +8,7 @@ * Contributors: * Intel Corporation - Initial API and implementation * Enrico Ehrich - http://bugs.eclipse.org/233866 + * Marc-Andre Laperle - fix for Cygwin GCC is Not detected (bug 303900) *******************************************************************************/ package org.eclipse.cdt.managedbuilder.gnu.cygwin; @@ -31,18 +32,22 @@ import org.eclipse.cdt.utils.spawner.ProcessFactory; * @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 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 SP = " "; //$NON-NLS-1$ - private static final String REGISTRY_KEY = "SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\"; //$NON-NLS-1$ + // note that in Cygwin 1.7 the mount point storage has been moved out of the registry + private static final String REGISTRY_KEY_MOUNTS = "SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\"; //$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$ private static final String PATH_NAME = "native"; //$NON-NLS-1$ - private static final String EMPTY = ""; //$NON-NLS-1$ private static final String SSLASH = "/"; //$NON-NLS-1$ private static final String BSLASH = "\\\\"; //$NON-NLS-1$ private static final String BINPATTERN = "/usr/bin"; //$NON-NLS-1$ + private static final String BINPATTERN_ALTERNATE = "/bin"; //$NON-NLS-1$ private static final String ETCPATTERN = "/etc"; //$NON-NLS-1$ private static final String ROOTPATTERN = SSLASH; private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$ @@ -88,7 +93,7 @@ public class CygwinPathResolver implements IBuildPathResolver { * returns "/etc" path in Windows format */ public static String getEtcPath() { - if (!checked) checkRegistry(); + if (!checked) findPaths(); return etcCygwin; } @@ -96,7 +101,7 @@ public class CygwinPathResolver implements IBuildPathResolver { * returns "/usr/bin" path in Windows format */ public static String getBinPath() { - if (!checked) checkRegistry(); + if (!checked) findPaths(); return binCygwin; } /* @@ -104,7 +109,7 @@ public class CygwinPathResolver implements IBuildPathResolver { */ public static String getRootPath() { - if (!checked) checkRegistry(); + if (!checked) findPaths(); return rootCygwin; } @@ -113,70 +118,104 @@ public class CygwinPathResolver implements IBuildPathResolver { } /** - * Reads required value from registry. + * Reads required value from registry. Looks in both + * HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE * - * If there's no such key, tries to read "parent" key - * and forms resulting path from parent path and - * key suffix. - * - * For example, if there's no key for "/etc", - * reads key for "/" (has value "c:/cygwin") - * and forms result "c:/cygwin/etc". - * - * @param user - * if true, reads from HKEY_CURRENT_USER - * if false, reads from HKEY_LOCAL_MACHINE - * @param pattern - * specific registry key value (last segment) - * @return - * corresponding string value - * or null if nothing found + * @param key Registry key + * @param name Registry value to read + * @return corresponding string value or null if nothing found */ - private static String read(boolean user, String pattern) { - String tail = EMPTY; - while (pattern.length() > 0) { - String key = REGISTRY_KEY + pattern; - WindowsRegistry registry = WindowsRegistry.getRegistry(); - if (null != registry) { - String s = user ? - registry.getCurrentUserValue(key, PATH_NAME) : - registry.getLocalMachineValue(key, PATH_NAME); + private static String readValueFromRegistry(String key, String name) { + WindowsRegistry registry = WindowsRegistry.getRegistry(); + if (null != registry) { + String s = registry.getCurrentUserValue(key, name); + if(s == null) + s = registry.getLocalMachineValue(key, name); - if (s != null) - return (s.concat(tail).replaceAll(BSLASH, SSLASH)); - } - if (pattern.equals(ROOTPATTERN)) - break; // no other paths to search - int pos = pattern.lastIndexOf(SLASH); - if (pos < 0) break; - tail = pattern.substring(pos, pattern.length()) + tail; - if (pos == 0) - pattern = ROOTPATTERN; // leave leading slash - else - pattern = pattern.substring(0, pos); + if (s != null) + return (s.replaceAll(BSLASH, SSLASH)); } - return null; + return null; + } + /** + * Returns the absolute path of the pattern by + * simply appending the pattern to the root + * + * @param pattern The pattern to find + * @return The absolute path to the pattern or null if pattern is not found + */ + private static String getValueFromRoot(String pattern) { + if (rootCygwin != null) { + String path = rootCygwin + pattern; + File file = new File(path); + 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 rootValue = null; + + // 1. Try to find the root dir in SOFTWARE\Cygnus Solutions + rootValue = readValueFromRegistry(REGISTRY_KEY_MOUNTS+ROOTPATTERN, PATH_NAME); + + // 2. 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 + if(rootValue == null) { + rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP_WIN64, "rootdir"); //$NON-NLS-1$ + } + + // 4. Try the default Cygwin install dir + if(rootValue == null) { + File file = new File(DEFAULT_ROOT); + if (file.exists() && file.isDirectory()) + rootValue = DEFAULT_ROOT; + } + + if(rootValue != null) + rootValue = rootValue.replaceAll(BSLASH, SSLASH); + + return rootValue; } /** - * reads once data from registry (for Win32 only) - * and sets corresponding properties; + * Finds Cygwin's paths and sets corresponding properties */ - private static synchronized void checkRegistry() { + private static synchronized void findPaths() { if (checked) return; etcCygwin = null; binCygwin = null; rootCygwin = null; if (!isWindows()) return; - for (int i=0; i<2; i++) { - if (etcCygwin == null) - etcCygwin = read((i==0), ETCPATTERN); - if (binCygwin == null) - binCygwin = read((i==0), BINPATTERN); - if (rootCygwin == null) - rootCygwin = read((i==0), ROOTPATTERN); - } - checked = true; + + rootCygwin = findRoot(); + + // 1. Try to find the paths in SOFTWARE\\Cygnus Solutions + etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME); + binCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + BINPATTERN, PATH_NAME); + + // 2. Try to find the paths by appending the patterns to the root dir + if(etcCygwin == null) + etcCygwin = getValueFromRoot(ETCPATTERN); + if(binCygwin == null) + binCygwin = getValueFromRoot(BINPATTERN); + if(binCygwin == null) + binCygwin = getValueFromRoot(BINPATTERN_ALTERNATE); + + checked = true; } private static String[] exec(String cmd, IConfiguration cfg) { diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java index baf1dea5978..f5f4c183b89 100644 --- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java +++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/src/org/eclipse/cdt/managedbuilder/gnu/cygwin/IsGnuCygwinToolChainSupported.java @@ -40,8 +40,9 @@ public class IsGnuCygwinToolChainSupported implements static boolean suppChecked = false; static boolean toolchainIsSupported = false; - /* - * returns support status + + /* (non-Javadoc) + * @see org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported#isSupported(org.eclipse.cdt.managedbuilder.core.IToolChain, org.eclipse.core.runtime.PluginVersionIdentifier, java.lang.String) */ public boolean isSupported(IToolChain toolChain, PluginVersionIdentifier version, String instance) { @@ -50,30 +51,43 @@ public class IsGnuCygwinToolChainSupported implements String etcCygwin = CygwinPathResolver.getEtcPath(); if (etcCygwin != null) { - File file = new File(etcCygwin + "/setup/installed.db"); //$NON-NLS-1$ - try { - BufferedReader data = new BufferedReader(new FileReader(file)); - - // all required package names should be found - boolean[] found = new boolean[CHECKED_NAMES.length]; - String s; - while ((s = data.readLine()) != null ) { - for (int j = 0; j < CHECKED_NAMES.length; j++) { - if (s.startsWith(CHECKED_NAMES[j])) {found[j] = true;} - } - } - toolchainIsSupported = true; - for (int j = 0; j < CHECKED_NAMES.length; j++) { - toolchainIsSupported &= found[j]; - } - data.close(); - } catch (FileNotFoundException e) { - } catch (IOException e) { - } + toolchainIsSupported = arePackagesInstalled(etcCygwin); } suppChecked = true; return toolchainIsSupported; + } + + /** + * Returns true if all required packages are installed, see CHECKED_NAMES for a list of packages. Cygwin + * maintains a list of packages in /etc/setup/installed.db so we look for packages in this file. + * + * @param etcCygwin the absolute path of /etc containing /setup/installed.db + * @return true if the packages specified in CHECKED_NAMES are installed + */ + private boolean arePackagesInstalled(String etcCygwin) { + boolean arePackagesInstalled = false; + File file = new File(etcCygwin + "/setup/installed.db"); //$NON-NLS-1$ + try { + BufferedReader data = new BufferedReader(new FileReader(file)); + + // All required package names should be found + boolean[] found = new boolean[CHECKED_NAMES.length]; + String s; + while ((s = data.readLine()) != null ) { + for (int j = 0; j < CHECKED_NAMES.length; j++) { + if (s.startsWith(CHECKED_NAMES[j])) {found[j] = true;} + } + } + arePackagesInstalled = true; + for (int j = 0; j < CHECKED_NAMES.length; j++) { + arePackagesInstalled &= found[j]; + } + data.close(); + } catch (FileNotFoundException e) { + } catch (IOException e) { + } + return arePackagesInstalled; } } -- cgit v1.2.3