1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

bug 303900: Cygwin 1.7 is Not detected on the CDT system.

Patch from Marc-Andre Laperle
This commit is contained in:
Andrew Gvozdev 2010-03-04 17:51:55 +00:00
parent d84ca549b2
commit caa20b4d37
2 changed files with 131 additions and 78 deletions

View file

@ -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;
}
/**
* reads once data from registry (for Win32 only)
* and sets corresponding properties;
* Returns the absolute path to cygwin's root
*
* @return The absolute path to cygwin's root or null if not found
*/
private static synchronized void checkRegistry() {
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;
}
/**
* Finds Cygwin's paths and sets corresponding properties
*/
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) {

View file

@ -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;
}
}