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:
parent
d84ca549b2
commit
caa20b4d37
2 changed files with 131 additions and 78 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue