mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
bug 357442: Added $CYGWIN_HOME to cygwin toolchain detection algorithm
This commit is contained in:
parent
b5807e9b29
commit
d960fff7dd
8 changed files with 815 additions and 408 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2011 IBM Corporation and others.
|
* Copyright (c) 2004, 2013 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -20,8 +20,14 @@ import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.IBinaryParser;
|
import org.eclipse.cdt.core.IBinaryParser;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariableManager;
|
||||||
import org.eclipse.cdt.core.model.CoreModelUtil;
|
import org.eclipse.cdt.core.model.CoreModelUtil;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
|
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||||
|
import org.eclipse.cdt.internal.core.Cygwin;
|
||||||
|
import org.eclipse.cdt.make.core.MakeCorePlugin;
|
||||||
import org.eclipse.cdt.utils.CygPath;
|
import org.eclipse.cdt.utils.CygPath;
|
||||||
import org.eclipse.cdt.utils.ICygwinToolsFactroy;
|
import org.eclipse.cdt.utils.ICygwinToolsFactroy;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
@ -32,125 +38,135 @@ import org.eclipse.core.runtime.Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use binary parser's 'cygpath' command to translate cygpaths to absolute paths.
|
* Use binary parser's 'cygpath' command to translate cygpaths to absolute paths.
|
||||||
|
* Note that this class does not support build configurations.
|
||||||
*
|
*
|
||||||
* @author vhirsl
|
* @author vhirsl
|
||||||
*/
|
*/
|
||||||
public class CygpathTranslator {
|
public class CygpathTranslator {
|
||||||
/** Default Cygwin root dir */
|
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
|
||||||
private static final String DEFAULT_CYGWIN_ROOT= "C:\\cygwin"; //$NON-NLS-1$
|
|
||||||
// private static final String CYGPATH_ERROR_MESSAGE = "CygpathTranslator.NotAvailableErrorMessage"; //$NON-NLS-1$
|
private CygPath cygPath = null;
|
||||||
private CygPath cygPath = null;
|
|
||||||
private boolean isAvailable = false;
|
public CygpathTranslator(IProject project) {
|
||||||
|
try {
|
||||||
public CygpathTranslator(IProject project) {
|
ICConfigExtensionReference[] parserRef = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project);
|
||||||
try {
|
for (int i = 0; i < parserRef.length; i++) {
|
||||||
ICConfigExtensionReference[] parserRef = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project);
|
try {
|
||||||
for (int i = 0; i < parserRef.length; i++) {
|
IBinaryParser parser = CoreModelUtil.getBinaryParser(parserRef[i]);
|
||||||
try {
|
ICygwinToolsFactroy cygwinToolFactory = (ICygwinToolsFactroy) parser.getAdapter(ICygwinToolsFactroy.class);
|
||||||
IBinaryParser parser = CoreModelUtil.getBinaryParser(parserRef[i]);
|
if (cygwinToolFactory != null) {
|
||||||
ICygwinToolsFactroy cygwinToolFactory = (ICygwinToolsFactroy) parser.getAdapter(ICygwinToolsFactroy.class);
|
cygPath = cygwinToolFactory.getCygPath();
|
||||||
if (cygwinToolFactory != null) {
|
}
|
||||||
cygPath = cygwinToolFactory.getCygPath();
|
} catch (ClassCastException e) {
|
||||||
if (cygPath != null) {
|
}
|
||||||
isAvailable = true;
|
}
|
||||||
break;
|
}
|
||||||
}
|
catch (CoreException e) {
|
||||||
}
|
}
|
||||||
} catch (ClassCastException e) {
|
}
|
||||||
}
|
|
||||||
}
|
public static List<String> translateIncludePaths(IProject project, List<String> sumIncludes) {
|
||||||
// No CygPath specified in BinaryParser page or not supported.
|
// first check if cygpath translation is needed at all
|
||||||
// Hoping that cygpath is on the path.
|
boolean translationNeeded = false;
|
||||||
if (cygPath == null && Platform.getOS().equals(Platform.OS_WIN32)) {
|
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||||
if (new File(DEFAULT_CYGWIN_ROOT).exists()) {
|
for (Iterator<String> i = sumIncludes.iterator(); i.hasNext(); ) {
|
||||||
cygPath = new CygPath(DEFAULT_CYGWIN_ROOT + "\\bin\\cygpath.exe"); //$NON-NLS-1$
|
|
||||||
} else {
|
|
||||||
cygPath = new CygPath("cygpath"); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
isAvailable = cygPath.getFileName("test").equals("test"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (CoreException e) {
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
isAvailable = false;
|
|
||||||
// Removing markers. if cygpath isn't in your path then you aren't using cygwin.
|
|
||||||
// Then why are we calling this....
|
|
||||||
// scMarkerGenerator.addMarker(project, -1,
|
|
||||||
// MakeMessages.getString(CYGPATH_ERROR_MESSAGE),
|
|
||||||
// IMarkerGenerator.SEVERITY_WARNING, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> translateIncludePaths(IProject project, List<String> sumIncludes) {
|
|
||||||
// first check if cygpath translation is needed at all
|
|
||||||
boolean translationNeeded = false;
|
|
||||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
|
||||||
for (Iterator<String> i = sumIncludes.iterator(); i.hasNext(); ) {
|
|
||||||
String include = i.next();
|
String include = i.next();
|
||||||
if (include.startsWith("/")) { //$NON-NLS-1$
|
if (include.startsWith("/")) { //$NON-NLS-1$
|
||||||
translationNeeded = true;
|
translationNeeded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!translationNeeded) {
|
if (!translationNeeded) {
|
||||||
return sumIncludes;
|
return sumIncludes;
|
||||||
}
|
}
|
||||||
|
|
||||||
CygpathTranslator cygpath = new CygpathTranslator(project);
|
CygpathTranslator cygpath = new CygpathTranslator(project);
|
||||||
|
boolean useCygPathExtension = cygpath.cygPath != null;
|
||||||
List<String> translatedIncludePaths = new ArrayList<String>();
|
boolean useCygwinFromPath = !useCygPathExtension;
|
||||||
for (Iterator<String> i = sumIncludes.iterator(); i.hasNext(); ) {
|
|
||||||
String includePath = i.next();
|
String envPath = null;
|
||||||
IPath realPath = new Path(includePath);
|
if (useCygwinFromPath) {
|
||||||
// only allow native pathes if they have a device prefix
|
IEnvironmentVariableManager mngr = CCorePlugin.getDefault().getBuildEnvironmentManager();
|
||||||
// to avoid matches on the current drive, e.g. /usr/bin = C:\\usr\\bin
|
ICProjectDescription prjDes = CCorePlugin.getDefault().getProjectDescription(project, false);
|
||||||
if (realPath.getDevice() != null && realPath.toFile().exists()) {
|
if (prjDes != null) {
|
||||||
translatedIncludePaths.add(includePath);
|
// we don't know for sure which configuration needs to be used here, so betting on "DefaultSettingConfiguration"
|
||||||
}
|
// considering that scanner discovery uses "DefaultSettingConfiguration" rather than "Active" configuration,
|
||||||
else {
|
// see org.eclipse.cdt.build.core.scannerconfig.ScannerConfigBuilder.build(CfgInfoContext context, ...)
|
||||||
String translatedPath = includePath;
|
ICConfigurationDescription cfgDes = prjDes.getDefaultSettingConfiguration();
|
||||||
if (cygpath.isAvailable) {
|
IEnvironmentVariable envVar = mngr.getVariable(ENV_PATH, cfgDes, true);
|
||||||
try {
|
if (envVar != null) {
|
||||||
translatedPath = cygpath.cygPath.getFileName(includePath);
|
envPath = envVar.getValue();
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
}
|
||||||
TraceUtil.outputError("CygpathTranslator unable to translate path: ", includePath); //$NON-NLS-1$
|
if (envPath == null) {
|
||||||
}
|
IEnvironmentVariable envVar = mngr.getVariable(ENV_PATH, null, true);
|
||||||
} else if (realPath.segmentCount() >= 2) {
|
if (envVar != null) {
|
||||||
// try default conversions
|
envPath = envVar.getValue();
|
||||||
// /cygdrive/x/ --> X:\
|
}
|
||||||
if ("cygdrive".equals(realPath.segment(0))) { //$NON-NLS-1$
|
}
|
||||||
String drive= realPath.segment(1);
|
|
||||||
if (drive.length() == 1) {
|
useCygwinFromPath = Cygwin.isAvailable(envPath);
|
||||||
translatedPath= realPath.removeFirstSegments(2).makeAbsolute().setDevice(drive.toUpperCase() + ':').toOSString();
|
}
|
||||||
}
|
|
||||||
}
|
List<String> translatedIncludePaths = new ArrayList<String>();
|
||||||
}
|
for (Iterator<String> i = sumIncludes.iterator(); i.hasNext(); ) {
|
||||||
if (!translatedPath.equals(includePath)) {
|
String includePath = i.next();
|
||||||
// Check if the translated path exists
|
IPath realPath = new Path(includePath);
|
||||||
if (new File(translatedPath).exists()) {
|
// only allow native pathes if they have a device prefix
|
||||||
translatedIncludePaths.add(translatedPath);
|
// to avoid matches on the current drive, e.g. /usr/bin = C:\\usr\\bin
|
||||||
}
|
if (realPath.getDevice() != null && realPath.toFile().exists()) {
|
||||||
else if (cygpath.isAvailable) {
|
translatedIncludePaths.add(includePath);
|
||||||
// TODO VMIR for now add even if it does not exist
|
}
|
||||||
translatedIncludePaths.add(translatedPath);
|
else {
|
||||||
}
|
String translatedPath = includePath;
|
||||||
else {
|
|
||||||
translatedIncludePaths.add(includePath);
|
if (useCygPathExtension) {
|
||||||
}
|
try {
|
||||||
}
|
translatedPath = cygpath.cygPath.getFileName(includePath);
|
||||||
else {
|
}
|
||||||
// TODO VMIR for now add even if it does not exist
|
catch (IOException e) {
|
||||||
translatedIncludePaths.add(translatedPath);
|
TraceUtil.outputError("CygpathTranslator unable to translate path: ", includePath); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
}
|
} else if (useCygwinFromPath) {
|
||||||
}
|
try {
|
||||||
if (cygpath.cygPath != null) {
|
translatedPath = Cygwin.cygwinToWindowsPath(includePath, envPath);
|
||||||
cygpath.cygPath.dispose();
|
} catch (Exception e) {
|
||||||
}
|
MakeCorePlugin.log(e);
|
||||||
return translatedIncludePaths;
|
}
|
||||||
}
|
} else if (realPath.segmentCount() >= 2) {
|
||||||
|
// try default conversions
|
||||||
|
// /cygdrive/x/ --> X:\
|
||||||
|
if ("cygdrive".equals(realPath.segment(0))) { //$NON-NLS-1$
|
||||||
|
String drive= realPath.segment(1);
|
||||||
|
if (drive.length() == 1) {
|
||||||
|
translatedPath= realPath.removeFirstSegments(2).makeAbsolute().setDevice(drive.toUpperCase() + ':').toOSString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!translatedPath.equals(includePath)) {
|
||||||
|
// Check if the translated path exists
|
||||||
|
if (new File(translatedPath).exists()) {
|
||||||
|
translatedIncludePaths.add(translatedPath);
|
||||||
|
}
|
||||||
|
else if (useCygPathExtension || useCygwinFromPath) {
|
||||||
|
// TODO VMIR for now add even if it does not exist
|
||||||
|
translatedIncludePaths.add(translatedPath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
translatedIncludePaths.add(includePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// TODO VMIR for now add even if it does not exist
|
||||||
|
translatedIncludePaths.add(translatedPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (useCygPathExtension) {
|
||||||
|
cygpath.cygPath.dispose();
|
||||||
|
}
|
||||||
|
return translatedIncludePaths;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2012, 2012 Andrew Gvozdev and others.
|
||||||
|
* 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:
|
||||||
|
* Andrew Gvozdev - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.envvar;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.cdtvariables.ICdtVariable;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
|
import org.eclipse.cdt.internal.core.cdtvariables.DefaultVariableContextInfo;
|
||||||
|
import org.eclipse.cdt.internal.core.cdtvariables.EnvironmentVariableSupplier;
|
||||||
|
import org.eclipse.cdt.internal.core.cdtvariables.ICoreVariableContextInfo;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.DefaultEnvironmentContextInfo;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.EnvVarDescriptor;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.EnvironmentVariableManager;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.ICoreEnvironmentVariableSupplier;
|
||||||
|
import org.eclipse.cdt.internal.core.envvar.IEnvironmentContextInfo;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IToolChain;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||||
|
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
|
||||||
|
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
|
||||||
|
import org.eclipse.cdt.utils.cdtvariables.ICdtVariableSupplier;
|
||||||
|
import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to resolve environment variables directly from toolchain. The intention is
|
||||||
|
* to use that in New Project Wizard scenarios when no configuration is available yet.
|
||||||
|
*/
|
||||||
|
public class EnvironmentVariableManagerToolChain extends EnvironmentVariableManager {
|
||||||
|
private static EnvironmentVariableManagerToolChain fInstance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basically, converter from IEnvironmentVariable to ICdtVariable (build macros) which
|
||||||
|
* is used by EnvironmentVariableManager implementation to resolve variables/macros.
|
||||||
|
*/
|
||||||
|
private final class CoreVariableContextInfoToolChain implements ICoreVariableContextInfo {
|
||||||
|
public final static int CONTEXT_TOOLCHAIN = 1009; // arbitrary value different from ICoreVariableContextInfo.CONTEXT_XXX
|
||||||
|
|
||||||
|
private final IToolChain toolChain;
|
||||||
|
private final IConfigurationEnvironmentVariableSupplier mbsSupplier;
|
||||||
|
|
||||||
|
private CoreVariableContextInfoToolChain(IToolChain toolChain) {
|
||||||
|
this.toolChain = toolChain;
|
||||||
|
this.mbsSupplier = toolChain.getEnvironmentVariableSupplier();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICdtVariableSupplier[] getSuppliers() {
|
||||||
|
ICdtVariableSupplier sup = new ICdtVariableSupplier() {
|
||||||
|
@Override
|
||||||
|
public ICdtVariable getVariable(String macroName, IVariableContextInfo context) {
|
||||||
|
IEnvironmentVariable var = mbsSupplier.getVariable(macroName, null, ManagedBuildManager.getEnvironmentVariableProvider());
|
||||||
|
return EnvironmentVariableSupplier.getInstance().createBuildMacro(var);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public ICdtVariable[] getVariables(IVariableContextInfo context) {
|
||||||
|
IEnvironmentVariable[] vars = mbsSupplier.getVariables(null, ManagedBuildManager.getEnvironmentVariableProvider());
|
||||||
|
if (vars != null) {
|
||||||
|
ICdtVariable[] cdtVars = new ICdtVariable[vars.length];
|
||||||
|
for (int i = 0; i < vars.length; i++) {
|
||||||
|
cdtVars[i] = EnvironmentVariableSupplier.getInstance().createBuildMacro(vars[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
return new ICdtVariableSupplier[] { sup };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IVariableContextInfo getNext() {
|
||||||
|
return new DefaultVariableContextInfo(ICoreVariableContextInfo.CONTEXT_WORKSPACE, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContextType() {
|
||||||
|
return CONTEXT_TOOLCHAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getContextData() {
|
||||||
|
return toolChain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class EnvironmentContextInfoToolChain implements IEnvironmentContextInfo {
|
||||||
|
private final IToolChain toolChain;
|
||||||
|
|
||||||
|
private EnvironmentContextInfoToolChain(IToolChain toolChain) {
|
||||||
|
this.toolChain = toolChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEnvironmentContextInfo getNext() {
|
||||||
|
return new DefaultEnvironmentContextInfo(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICoreEnvironmentVariableSupplier[] getSuppliers() {
|
||||||
|
final IConfigurationEnvironmentVariableSupplier cevSupplier = toolChain.getEnvironmentVariableSupplier();
|
||||||
|
|
||||||
|
ICoreEnvironmentVariableSupplier toolchainSupplier = new ICoreEnvironmentVariableSupplier() {
|
||||||
|
@Override
|
||||||
|
public IEnvironmentVariable getVariable(String name, Object context) {
|
||||||
|
IEnvironmentVariableProvider provider = ManagedBuildManager.getEnvironmentVariableProvider();
|
||||||
|
return cevSupplier.getVariable(name, null, provider);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public IEnvironmentVariable[] getVariables(Object context) {
|
||||||
|
return cevSupplier.getVariables(null, ManagedBuildManager.getEnvironmentVariableProvider());
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean appendEnvironment(Object context) {
|
||||||
|
// Arbitrary value, it did not appear being used in tested scenarios
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new ICoreEnvironmentVariableSupplier[] { EnvironmentVariableManagerToolChain.fUserSupplier, toolchainSupplier };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getContext() {
|
||||||
|
return toolChain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EnvironmentVariableManagerToolChain getDefault() {
|
||||||
|
if (fInstance == null)
|
||||||
|
fInstance = new EnvironmentVariableManagerToolChain();
|
||||||
|
return fInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEnvironmentContextInfo getContextInfo(Object level) {
|
||||||
|
if (level instanceof IToolChain) {
|
||||||
|
return new EnvironmentContextInfoToolChain((IToolChain) level);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getContextInfo(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMacroContextTypeFromContext(Object context) {
|
||||||
|
if (context instanceof IToolChain) {
|
||||||
|
return CoreVariableContextInfoToolChain.CONTEXT_TOOLCHAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getMacroContextTypeFromContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICoreVariableContextInfo getMacroContextInfoForContext(Object context) {
|
||||||
|
if (context instanceof IToolChain) {
|
||||||
|
return new CoreVariableContextInfoToolChain((IToolChain) context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getMacroContextInfoForContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get environment variable value from toolchain definition.
|
||||||
|
*
|
||||||
|
* @param name - name of the variable.
|
||||||
|
* @param toolChain - toolchain.
|
||||||
|
* @param resolveMacros - {@code true} to expand macros, {@code false} otherwise.
|
||||||
|
*
|
||||||
|
* @return value of the variable.
|
||||||
|
*/
|
||||||
|
public IEnvironmentVariable getVariable(String name, IToolChain toolChain, boolean resolveMacros) {
|
||||||
|
if (name == null || name.isEmpty())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IEnvironmentContextInfo info = getContextInfo(toolChain);
|
||||||
|
EnvVarDescriptor var = EnvironmentVariableManagerToolChain.getVariable(name,info,true);
|
||||||
|
|
||||||
|
if (var != null && var.getOperation() != IEnvironmentVariable.ENVVAR_REMOVE) {
|
||||||
|
return resolveMacros ? calculateResolvedVariable(var,info) : var;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get environment variable value resolved in context of configuration.
|
||||||
|
* If no configuration available use toolchain definition.
|
||||||
|
*
|
||||||
|
* @param name - name of the variable.
|
||||||
|
* @param toolChain - toolchain.
|
||||||
|
* @param resolveMacros - {@code true} to expand macros, {@code false} otherwise.
|
||||||
|
*
|
||||||
|
* @return value of the variable.
|
||||||
|
*/
|
||||||
|
public String getVariableInConfigurationContext(String name, IToolChain toolChain, boolean resolveMacros) {
|
||||||
|
if (toolChain == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConfiguration cfg = toolChain.getParent();
|
||||||
|
ICConfigurationDescription cfgDescription = cfg != null ? ManagedBuildManager.getDescriptionForConfiguration(cfg) : null;
|
||||||
|
|
||||||
|
IEnvironmentVariable var = null;
|
||||||
|
if (cfgDescription != null) {
|
||||||
|
var = getVariable(name, cfgDescription, resolveMacros);
|
||||||
|
} else {
|
||||||
|
var = getVariable(name, toolChain, resolveMacros);
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = var != null ? var.getValue() : null;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2010 Intel Corporation and others.
|
* Copyright (c) 2005, 2013 Intel Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
* Intel Corporation - Initial API and implementation
|
* Intel Corporation - Initial API and implementation
|
||||||
* Enrico Ehrich - http://bugs.eclipse.org/233866
|
* Enrico Ehrich - http://bugs.eclipse.org/233866
|
||||||
* Marc-Andre Laperle - fix for Cygwin GCC is Not detected (bug 303900)
|
* Marc-Andre Laperle - fix for Cygwin GCC is Not detected (bug 303900)
|
||||||
|
* Andrew Gvozdev - changes to recognize $CYGWIN_HOME
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
||||||
|
|
||||||
|
@ -19,9 +20,8 @@ import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
import org.eclipse.cdt.internal.core.Cygwin;
|
||||||
import org.eclipse.cdt.managedbuilder.core.IBuildPathResolver;
|
import org.eclipse.cdt.managedbuilder.core.IBuildPathResolver;
|
||||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||||
|
@ -30,40 +30,35 @@ import org.eclipse.cdt.utils.PathUtil;
|
||||||
import org.eclipse.cdt.utils.WindowsRegistry;
|
import org.eclipse.cdt.utils.WindowsRegistry;
|
||||||
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @noextend This class is not intended to be subclassed by clients.
|
* @noextend This class is not intended to be subclassed by clients.
|
||||||
*/
|
*/
|
||||||
public class CygwinPathResolver implements IBuildPathResolver {
|
public class CygwinPathResolver implements IBuildPathResolver {
|
||||||
private static final String DEFAULT_ROOT = "C:\\cygwin"; //$NON-NLS-1$
|
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
|
||||||
private static final String TOOL = "/cygpath -w -p "; //$NON-NLS-1$
|
private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$
|
||||||
private static final char BS = '\\';
|
private static final String DELIMITER_WIN = ";"; //$NON-NLS-1$
|
||||||
private static final char SLASH = '/';
|
|
||||||
private static final String PROPERTY_OS_NAME = "os.name"; //$NON-NLS-1$
|
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 char SLASH = '/';
|
||||||
private static final String REGISTRY_KEY_SETUP = "SOFTWARE\\Cygwin\\setup"; //$NON-NLS-1$
|
private static final char BACKSLASH = '\\';
|
||||||
private static final String REGISTRY_KEY_SETUP_WIN64 = "SOFTWARE\\Wow6432Node\\Cygwin\\setup"; //$NON-NLS-1$
|
|
||||||
|
private static final String CYGPATH_PATH_LIST_TO_WINDOWS = "cygpath -w -p "; //$NON-NLS-1$
|
||||||
|
|
||||||
// note that in Cygwin 1.7 the mount point storage has been moved out of the registry
|
// 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_MOUNTS = "SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\"; //$NON-NLS-1$
|
||||||
private static final String PATH_NAME = "native"; //$NON-NLS-1$
|
private static final String PATH_NAME = "native"; //$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 = "/usr/bin"; //$NON-NLS-1$
|
||||||
private static final String BINPATTERN_ALTERNATE = "/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 ETCPATTERN = "/etc"; //$NON-NLS-1$
|
||||||
private static final String ROOTPATTERN = SSLASH;
|
|
||||||
private static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$
|
|
||||||
private static final String DELIMITER_WIN = ";"; //$NON-NLS-1$
|
|
||||||
private static final String GCC_VERSION_CMD = "gcc --version"; //$NON-NLS-1$
|
private static final String GCC_VERSION_CMD = "gcc --version"; //$NON-NLS-1$
|
||||||
private static final String MINGW_SPECIAL = "mingw "; //$NON-NLS-1$
|
private static final String MINGW_SPECIAL = "mingw "; //$NON-NLS-1$
|
||||||
private static final String CYGWIN_SPECIAL = "cygwin "; //$NON-NLS-1$
|
private static final String CYGWIN_SPECIAL = "cygwin "; //$NON-NLS-1$
|
||||||
|
|
||||||
private static String envPathValueCached = null;
|
|
||||||
private static String binCygwin = null;
|
|
||||||
private static String rootCygwin = null;
|
|
||||||
private static String etcCygwin = null;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] resolveBuildPaths(int pathType, String variableName, String variableValue, IConfiguration configuration) {
|
public String[] resolveBuildPaths(int pathType, String variableName, String variableValue, IConfiguration configuration) {
|
||||||
if(!isWindows()) {
|
if(!isWindows()) {
|
||||||
|
@ -72,58 +67,66 @@ public class CygwinPathResolver implements IBuildPathResolver {
|
||||||
return variableValue.split(DELIMITER_WIN);
|
return variableValue.split(DELIMITER_WIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] result = variableValue.split(DELIMITER_UNIX);
|
String[] lines = executeInConfigurationContext(CYGPATH_PATH_LIST_TO_WINDOWS + variableValue, configuration);
|
||||||
String exePath = getBinPath();
|
|
||||||
if (exePath == null) {
|
|
||||||
return result; // no changes
|
|
||||||
}
|
|
||||||
File file = new File(exePath);
|
|
||||||
if (!file.exists() || !file.isDirectory()) {
|
|
||||||
return result; // no changes
|
|
||||||
}
|
|
||||||
String s = exePath + TOOL + variableValue;
|
|
||||||
String[] lines = exec(s, configuration);
|
|
||||||
if (lines != null && lines.length > 0) {
|
if (lines != null && lines.length > 0) {
|
||||||
result = lines[0].replace(BS,SLASH).split(DELIMITER_WIN);
|
String pathList = lines[0].replace(BACKSLASH, SLASH);
|
||||||
|
return pathList.split(DELIMITER_WIN);
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
return variableValue.split(DELIMITER_UNIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns "/etc" path in Windows format
|
* @return "/etc" path in Windows format for workspace.
|
||||||
|
* @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration.
|
||||||
*
|
*
|
||||||
* If you use this do not cache results to ensure user preferences are accounted for.
|
* If you use this do not cache results to ensure user preferences are accounted for.
|
||||||
* Please rely on internal caching.
|
* Please rely on internal caching.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getEtcPath() {
|
public static String getEtcPath() {
|
||||||
findPaths();
|
String etcCygwin = getPathFromRoot(ETCPATTERN);
|
||||||
|
// Try to find the paths in SOFTWARE\\Cygnus Solutions
|
||||||
|
if(etcCygwin == null) {
|
||||||
|
etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME);
|
||||||
|
}
|
||||||
return etcCygwin;
|
return etcCygwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns "/usr/bin" path in Windows format
|
* @return "/usr/bin" path in Windows format for workspace.
|
||||||
|
* @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration.
|
||||||
*
|
*
|
||||||
* If you use this do not cache results to ensure user preferences are accounted for.
|
* If you use this do not cache results to ensure user preferences are accounted for.
|
||||||
* Please rely on internal caching.
|
* Please rely on internal caching.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getBinPath() {
|
public static String getBinPath() {
|
||||||
findPaths();
|
String binCygwin = getPathFromRoot(BINPATTERN);
|
||||||
|
if(binCygwin == null) {
|
||||||
|
binCygwin = getPathFromRoot(BINPATTERN_ALTERNATE);
|
||||||
|
}
|
||||||
|
// Try to find the paths in SOFTWARE\\Cygnus Solutions
|
||||||
|
if(binCygwin == null) {
|
||||||
|
binCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + BINPATTERN, PATH_NAME);
|
||||||
|
}
|
||||||
return binCygwin;
|
return binCygwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns Cygwin root ("/") path in Windows format
|
* @return Cygwin root ("/") path in Windows format for workspace.
|
||||||
|
* @deprecated. Deprecated as of CDT 8.2. Note that Cygwin root path in general may depend on configuration.
|
||||||
*
|
*
|
||||||
* If you use this do not cache results to ensure user preferences are accounted for.
|
* If you use this do not cache results to ensure user preferences are accounted for.
|
||||||
* Please rely on internal caching.
|
* Please rely on internal caching.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static String getRootPath() {
|
public static String getRootPath() {
|
||||||
findPaths();
|
return Cygwin.getCygwinHome();
|
||||||
return rootCygwin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isWindows() {
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,146 +139,117 @@ public class CygwinPathResolver implements IBuildPathResolver {
|
||||||
*/
|
*/
|
||||||
private static String readValueFromRegistry(String key, String name) {
|
private static String readValueFromRegistry(String key, String name) {
|
||||||
WindowsRegistry registry = WindowsRegistry.getRegistry();
|
WindowsRegistry registry = WindowsRegistry.getRegistry();
|
||||||
if (null != registry) {
|
if (registry != null) {
|
||||||
String s = registry.getCurrentUserValue(key, name);
|
String value = registry.getCurrentUserValue(key, name);
|
||||||
if(s == null)
|
if (value == null) {
|
||||||
s = registry.getLocalMachineValue(key, name);
|
value = registry.getLocalMachineValue(key, name);
|
||||||
|
|
||||||
if (s != null)
|
|
||||||
return (s.replaceAll(BSLASH, SSLASH));
|
|
||||||
}
|
|
||||||
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 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 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
|
|
||||||
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 (!isWindows()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable("PATH", null, true); //$NON-NLS-1$
|
|
||||||
String envPathValue = varPath != null ? varPath.getValue() : null;
|
|
||||||
|
|
||||||
if (CDataUtil.objectsEqual(envPathValue, envPathValueCached)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
if(binCygwin == null)
|
|
||||||
binCygwin = getValueFromRoot(BINPATTERN_ALTERNATE);
|
|
||||||
|
|
||||||
// 2. Try to find the paths in SOFTWARE\\Cygnus Solutions
|
|
||||||
if(etcCygwin == null)
|
|
||||||
etcCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ETCPATTERN, PATH_NAME);
|
|
||||||
if(binCygwin == null)
|
|
||||||
binCygwin = readValueFromRegistry(REGISTRY_KEY_MOUNTS + BINPATTERN, PATH_NAME);
|
|
||||||
|
|
||||||
envPathValueCached = envPathValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] exec(String cmd, IConfiguration cfg) {
|
|
||||||
try {
|
|
||||||
IEnvironmentVariable vars[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true);
|
|
||||||
String env[] = new String[vars.length];
|
|
||||||
for(int i = 0; i < env.length; i++) {
|
|
||||||
env[i] = vars[i].getName() + "="; //$NON-NLS-1$
|
|
||||||
String value = vars[i].getValue();
|
|
||||||
if(value != null)
|
|
||||||
env[i] += value;
|
|
||||||
}
|
}
|
||||||
Process proc = ProcessFactory.getFactory().exec(cmd.split(SP), env);
|
if (value != null) {
|
||||||
if (proc != null) {
|
return value.replace(BACKSLASH, SLASH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
InputStream ein = proc.getInputStream();
|
/**
|
||||||
BufferedReader d1 = new BufferedReader(new InputStreamReader(ein));
|
* Returns the absolute path of the pattern by simply appending the relativePath to the root.
|
||||||
ArrayList<String> ls = new ArrayList<String>(10);
|
*
|
||||||
String s;
|
* @param relativePath - the pattern to find.
|
||||||
while ((s = d1.readLine() ) != null ) {
|
* @return The absolute path to the pattern or {@code null} if path does not exist.
|
||||||
ls.add(s);
|
*/
|
||||||
|
private static String getPathFromRoot(String relativePath) {
|
||||||
|
String rootCygwin = Cygwin.getCygwinHome();
|
||||||
|
if (rootCygwin != null) {
|
||||||
|
String path = rootCygwin + relativePath;
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.exists() && file.isDirectory()) {
|
||||||
|
return path.replace(BACKSLASH, SLASH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve and return full path to program in context of configuration.
|
||||||
|
*
|
||||||
|
* @param program - program to resolve.
|
||||||
|
* @param cfg - configuration context.
|
||||||
|
* @return absolute path to program.
|
||||||
|
*/
|
||||||
|
private static String resolveProgram(String program, IConfiguration cfg) {
|
||||||
|
String envPathValue = null;
|
||||||
|
try {
|
||||||
|
IEnvironmentVariable envPathVar = ManagedBuildManager.getEnvironmentVariableProvider().getVariable(ENV_PATH, cfg, true);
|
||||||
|
if (envPathVar != null) {
|
||||||
|
envPathValue = envPathVar.getValue();
|
||||||
|
IPath progPath = PathUtil.findProgramLocation(program, envPathValue);
|
||||||
|
if (progPath != null) {
|
||||||
|
program = progPath.toOSString();
|
||||||
|
}
|
||||||
|
// this resolves cygwin symbolic links
|
||||||
|
program = Cygwin.cygwinToWindowsPath(program, envPathValue);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
GnuUIPlugin.getDefault().log(new Status(IStatus.WARNING, GnuUIPlugin.PLUGIN_ID, "Problem trying to find program [" + program + "] in $PATH=[" + envPathValue + "]", e));
|
||||||
|
}
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return environment in envp format, see {@link Runtime#exec(String, String[])}.
|
||||||
|
*
|
||||||
|
* @param cfg - configuration.
|
||||||
|
* @return environment as array of strings in format name=value.
|
||||||
|
*/
|
||||||
|
private static String[] getEnvp(IConfiguration cfg) {
|
||||||
|
IEnvironmentVariable vars[] = ManagedBuildManager.getEnvironmentVariableProvider().getVariables(cfg,true);
|
||||||
|
String envp[] = new String[vars.length];
|
||||||
|
for(int i = 0; i < envp.length; i++) {
|
||||||
|
envp[i] = vars[i].getName() +'=';
|
||||||
|
String value = vars[i].getValue();
|
||||||
|
if(value != null)
|
||||||
|
envp[i] += value;
|
||||||
|
}
|
||||||
|
return envp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute command taking in account configuration environment.
|
||||||
|
*
|
||||||
|
* @param cmd - command to execute.
|
||||||
|
* @param cfg - configuration context.
|
||||||
|
* @return command output as string array.
|
||||||
|
*/
|
||||||
|
private static String[] executeInConfigurationContext(String cmd, IConfiguration cfg) {
|
||||||
|
String[] args = cmd.split(" "); //$NON-NLS-1$
|
||||||
|
args[0] = resolveProgram(args[0], cfg);
|
||||||
|
|
||||||
|
String[] result = null;
|
||||||
|
try {
|
||||||
|
String[] envp = getEnvp(cfg);
|
||||||
|
Process proc = ProcessFactory.getFactory().exec(args, envp);
|
||||||
|
if (proc != null) {
|
||||||
|
InputStream ein = proc.getInputStream();
|
||||||
|
try {
|
||||||
|
BufferedReader d1 = new BufferedReader(new InputStreamReader(ein));
|
||||||
|
ArrayList<String> ls = new ArrayList<String>(10);
|
||||||
|
String s;
|
||||||
|
while ((s = d1.readLine()) != null ) {
|
||||||
|
ls.add(s);
|
||||||
|
}
|
||||||
|
result = ls.toArray(new String[0]);
|
||||||
|
} finally {
|
||||||
|
ein.close();
|
||||||
}
|
}
|
||||||
ein.close();
|
|
||||||
return ls.toArray(new String[0]);
|
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
GnuUIPlugin.getDefault().log(e);
|
GnuUIPlugin.getDefault().log(new Status(IStatus.ERROR, GnuUIPlugin.PLUGIN_ID, "Error executing program [" +cmd + "]", e));
|
||||||
}
|
}
|
||||||
return null;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isMinGW(IConfiguration cfg) {
|
public static boolean isMinGW(IConfiguration cfg) {
|
||||||
String versionInfo[] = exec(GCC_VERSION_CMD, cfg);
|
String versionInfo[] = executeInConfigurationContext(GCC_VERSION_CMD, cfg);
|
||||||
if(versionInfo != null) {
|
if(versionInfo != null) {
|
||||||
for(int i = 0; i < versionInfo.length; i++) {
|
for(int i = 0; i < versionInfo.length; i++) {
|
||||||
if(versionInfo[i].indexOf(MINGW_SPECIAL) != -1)
|
if(versionInfo[i].indexOf(MINGW_SPECIAL) != -1)
|
||||||
|
|
|
@ -1,33 +1,38 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2011 Intel Corporation and others.
|
* Copyright (c) 2005, 2012 Intel Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Intel Corporation - Initial API and implementation
|
* Intel Corporation - Initial API and implementation
|
||||||
|
* Andrew Gvozdev - Ability to use different Cygwin versions in different cfg
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
|
import org.eclipse.cdt.internal.core.Cygwin;
|
||||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
|
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
|
||||||
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
|
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
|
||||||
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
|
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.envvar.BuildEnvVar;
|
import org.eclipse.cdt.managedbuilder.internal.envvar.BuildEnvVar;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @noextend This class is not intended to be subclassed by clients.
|
* @noextend This class is not intended to be subclassed by clients.
|
||||||
*/
|
*/
|
||||||
public class GnuCygwinConfigurationEnvironmentSupplier implements IConfigurationEnvironmentVariableSupplier {
|
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 DELIMITER_UNIX = ":"; //$NON-NLS-1$
|
private static final String ENV_LANG = "LANG"; //$NON-NLS-1$
|
||||||
private static final String PROPERTY_DELIMITER = "path.separator"; //$NON-NLS-1$
|
private static final String ENV_LC_ALL = "LC_ALL"; //$NON-NLS-1$
|
||||||
private static final String PROPERTY_OSNAME = "os.name"; //$NON-NLS-1$
|
private static final String ENV_LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$
|
||||||
|
|
||||||
private static final String LANG = "LANG"; //$NON-NLS-1$
|
private static final String PROPERTY_OSNAME = "os.name"; //$NON-NLS-1$
|
||||||
private static final String LC_ALL = "LC_ALL"; //$NON-NLS-1$
|
private static final String BACKSLASH = java.io.File.separator;
|
||||||
private static final String LC_MESSAGES = "LC_MESSAGES"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration, IEnvironmentVariableProvider provider) {
|
public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration, IEnvironmentVariableProvider provider) {
|
||||||
|
@ -39,19 +44,33 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variableName.equalsIgnoreCase(PATH)) {
|
if (variableName.equalsIgnoreCase(ENV_PATH)) {
|
||||||
String p = CygwinPathResolver.getBinPath();
|
@SuppressWarnings("nls")
|
||||||
if (p != null) {
|
String path = "${" + Cygwin.ENV_CYGWIN_HOME + "}" + BACKSLASH + "bin";
|
||||||
return new BuildEnvVar(PATH, p.replace('/','\\'), IBuildEnvironmentVariable.ENVVAR_PREPEND, System.getProperty(PROPERTY_DELIMITER, DELIMITER_UNIX));
|
return new BuildEnvVar(ENV_PATH, path, IBuildEnvironmentVariable.ENVVAR_PREPEND);
|
||||||
|
|
||||||
|
} else if (variableName.equals(Cygwin.ENV_CYGWIN_HOME)) {
|
||||||
|
String home = Cygwin.getCygwinHome();
|
||||||
|
// If the variable is not defined still show it in the environment variables list as a hint to user
|
||||||
|
if (home == null) {
|
||||||
|
home = ""; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
} else if (variableName.equalsIgnoreCase(LANG)) {
|
IPath homePath = new Path(home);
|
||||||
|
IEnvironmentVariable varCygwinHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(Cygwin.ENV_CYGWIN_HOME, null, false);
|
||||||
|
if (varCygwinHome == null || (!homePath.equals(new Path(varCygwinHome.getValue())))) {
|
||||||
|
// Contribute if the variable does not already come from workspace environment
|
||||||
|
return new BuildEnvVar(Cygwin.ENV_CYGWIN_HOME, homePath.toOSString());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
} else if (variableName.equalsIgnoreCase(ENV_LANG)) {
|
||||||
// Workaround for not being able to select encoding for CDT console -> change codeset to Latin1
|
// 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) {
|
if (langValue == null || langValue.length() == 0) {
|
||||||
langValue = System.getenv(LC_ALL);
|
langValue = System.getenv(ENV_LC_ALL);
|
||||||
}
|
}
|
||||||
if (langValue == null || langValue.length() == 0) {
|
if (langValue == null || langValue.length() == 0) {
|
||||||
langValue = System.getenv(LC_MESSAGES);
|
langValue = System.getenv(ENV_LC_MESSAGES);
|
||||||
}
|
}
|
||||||
if (langValue != null && langValue.length() > 0) {
|
if (langValue != null && langValue.length() > 0) {
|
||||||
// langValue is [language[_territory][.codeset][@modifier]], i.e. "en_US.UTF-8@dict"
|
// langValue is [language[_territory][.codeset][@modifier]], i.e. "en_US.UTF-8@dict"
|
||||||
|
@ -61,21 +80,17 @@ public class GnuCygwinConfigurationEnvironmentSupplier implements IConfiguration
|
||||||
} else {
|
} else {
|
||||||
langValue = "C.ISO-8859-1"; //$NON-NLS-1$
|
langValue = "C.ISO-8859-1"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
return new BuildEnvVar(ENV_LANG, langValue);
|
||||||
return new BuildEnvVar(LANG, langValue);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration, IEnvironmentVariableProvider provider) {
|
public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration, IEnvironmentVariableProvider provider) {
|
||||||
IBuildEnvironmentVariable varLang = getVariable(LANG, configuration, provider);
|
IBuildEnvironmentVariable varHome = getVariable(Cygwin.ENV_CYGWIN_HOME, configuration, provider);
|
||||||
IBuildEnvironmentVariable varPath = getVariable(PATH, configuration, provider);
|
IBuildEnvironmentVariable varLang = getVariable(ENV_LANG, configuration, provider);
|
||||||
|
IBuildEnvironmentVariable varPath = getVariable(ENV_PATH, configuration, provider);
|
||||||
|
|
||||||
if (varPath != null) {
|
return new IBuildEnvironmentVariable[] {varHome, varLang, varPath};
|
||||||
return new IBuildEnvironmentVariable[] {varLang, varPath};
|
|
||||||
} else {
|
|
||||||
return new IBuildEnvironmentVariable[] {varLang};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2005, 2010 Intel Corporation and others.
|
* Copyright (c) 2005, 2013 Intel Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,85 +7,28 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Intel Corporation - Initial API and implementation
|
* Intel Corporation - Initial API and implementation
|
||||||
|
* Andrew Gvozdev - Ability to use different Cygwin versions in different configurations
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
package org.eclipse.cdt.managedbuilder.gnu.cygwin;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import org.eclipse.cdt.internal.core.Cygwin;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
|
||||||
import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported;
|
import org.eclipse.cdt.managedbuilder.core.IManagedIsToolChainSupported;
|
||||||
import org.eclipse.cdt.managedbuilder.core.IToolChain;
|
import org.eclipse.cdt.managedbuilder.core.IToolChain;
|
||||||
|
import org.eclipse.cdt.managedbuilder.internal.envvar.EnvironmentVariableManagerToolChain;
|
||||||
import org.osgi.framework.Version;
|
import org.osgi.framework.Version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements the IManagedIsToolChainSupported for the Gnu Cygwin tool-chain
|
* This class implements the IManagedIsToolChainSupported for the Gnu Cygwin tool-chain
|
||||||
* The class is NOT used currently, because currently the gnu cygwin tool-chain
|
|
||||||
* is intended to be used not only with Cygwin, but with MinGW also, and there is no
|
|
||||||
* correct way of determining whether the appropriate packages are installed for MinGW.
|
|
||||||
*
|
|
||||||
* For the future MBS/CDT versions we might create the separate tool-chain/configuration/project-type
|
|
||||||
* for the MinGW and define a set of converters using the tool-chain converter mechanism that MBS will provide,
|
|
||||||
* that would convert the CygWin to the MinGW projects/tool-chains, and vice a versa.
|
|
||||||
*
|
*
|
||||||
* @noextend This class is not intended to be subclassed by clients.
|
* @noextend This class is not intended to be subclassed by clients.
|
||||||
*/
|
*/
|
||||||
public class IsGnuCygwinToolChainSupported implements IManagedIsToolChainSupported {
|
public class IsGnuCygwinToolChainSupported implements IManagedIsToolChainSupported {
|
||||||
private static final String[] CHECKED_NAMES = {"gcc", "binutils", "make"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
|
||||||
|
|
||||||
private static String etcCygwinCached = null;
|
|
||||||
private static boolean toolchainIsSupported = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @since 8.0
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSupported(IToolChain toolChain, Version version, String instance) {
|
public boolean isSupported(IToolChain toolChain, Version version, String instance) {
|
||||||
String etcCygwin = CygwinPathResolver.getEtcPath();
|
String envPath = EnvironmentVariableManagerToolChain.getDefault().getVariableInConfigurationContext(ENV_PATH, toolChain, true);
|
||||||
if (CDataUtil.objectsEqual(etcCygwin, etcCygwinCached)) {
|
return Cygwin.isAvailable(envPath);
|
||||||
return toolchainIsSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
toolchainIsSupported = etcCygwin != null && arePackagesInstalled(etcCygwin);
|
|
||||||
etcCygwinCached = etcCygwin;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2012, 2012 Andrew Gvozdev and others.
|
* Copyright (c) 2012, 2013 Andrew Gvozdev and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -11,24 +11,74 @@
|
||||||
package org.eclipse.cdt.internal.core;
|
package org.eclipse.cdt.internal.core;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
import org.eclipse.cdt.utils.PathUtil;
|
import org.eclipse.cdt.utils.PathUtil;
|
||||||
|
import org.eclipse.cdt.utils.WindowsRegistry;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of cygwin-related utilities.
|
* A collection of cygwin-related utilities.
|
||||||
*/
|
*/
|
||||||
public class Cygwin {
|
public class Cygwin {
|
||||||
|
public static final String ENV_CYGWIN_HOME = "CYGWIN_HOME"; //$NON-NLS-1$
|
||||||
|
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
|
||||||
|
|
||||||
private static IPath findCygpathLocation(String envPath) {
|
private static final String CYGPATH = "cygpath"; //$NON-NLS-1$
|
||||||
return PathUtil.findProgramLocation("cygpath", envPath); //$NON-NLS-1$
|
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 REGISTRY_KEY_SETUP = "SOFTWARE\\Cygwin\\setup"; //$NON-NLS-1$
|
||||||
|
private static final String REGISTRY_KEY_SETUP_WIN64 = "SOFTWARE\\Wow6432Node\\Cygwin\\setup"; //$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 PATH_NAME = "native"; //$NON-NLS-1$
|
||||||
|
private static final String ROOTPATTERN = "/"; //$NON-NLS-1$
|
||||||
|
private static final char SLASH = '/';
|
||||||
|
private static final char BACKSLASH = '\\';
|
||||||
|
|
||||||
|
private static final boolean isWindowsPlatform = Platform.getOS().equals(Platform.OS_WIN32);
|
||||||
|
|
||||||
|
private static String envPathValueCached = null;
|
||||||
|
private static String envCygwinHomeValueCached = null;
|
||||||
|
private static String cygwinLocation = null;
|
||||||
|
private static boolean isCygwinLocationCached = false;
|
||||||
|
|
||||||
|
private final static Map<String/*envPath*/, String /*cygpathLocation*/> cygpathLocationCache = Collections.synchronizedMap(new LRUCache<String, String>(1,20));
|
||||||
|
private final static Map<String/*command*/, String /*translatedPath*/> translatedPathsCache = Collections.synchronizedMap(new LRUCache<String, String>(10,500));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find location of "cygpath" utility on the file system.
|
||||||
|
*/
|
||||||
|
private static String findCygpathLocation(String envPath) {
|
||||||
|
if (envPath == null) {
|
||||||
|
// $PATH from user preferences
|
||||||
|
IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true);
|
||||||
|
if (varPath != null) {
|
||||||
|
envPath = varPath.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String cygpathLocation = cygpathLocationCache.get(envPath);
|
||||||
|
if (cygpathLocation == null) {
|
||||||
|
IPath loc = PathUtil.findProgramLocation(CYGPATH, envPath);
|
||||||
|
cygpathLocation = loc != null ? loc.toOSString() : null;
|
||||||
|
cygpathLocationCache.put(envPath, cygpathLocation);
|
||||||
|
}
|
||||||
|
return cygpathLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if cygwin path conversion utilities are available in the path.
|
* Check if cygwin path conversion utilities are available in the path.
|
||||||
|
* Tells whether cygwin is installed in the path.
|
||||||
*
|
*
|
||||||
* @param envPath - list of directories to search for cygwin utilities separated
|
* @param envPath - list of directories to search for cygwin utilities separated
|
||||||
* by path separator (format of environment variable $PATH)
|
* by path separator (format of environment variable $PATH)
|
||||||
|
@ -36,22 +86,60 @@ public class Cygwin {
|
||||||
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isAvailable(String envPath) {
|
public static boolean isAvailable(String envPath) {
|
||||||
return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(envPath) != null;
|
return isWindowsPlatform && findCygpathLocation(envPath) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if cygwin path conversion utilities are available in $PATH.
|
* Check if cygwin path conversion utilities are available in $PATH.
|
||||||
|
* Tells whether cygwin is installed in the path.
|
||||||
*
|
*
|
||||||
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
* @return {@code true} if cygwin is available, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isAvailable() {
|
public static boolean isAvailable() {
|
||||||
return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(null) != null;
|
return isWindowsPlatform && findCygpathLocation(null) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run program (assuming cygpath) and return the translated path which is the first line of output.
|
||||||
|
*/
|
||||||
|
private static String runCygpath(String[] args) throws IOException {
|
||||||
|
String command = getCommand(args);
|
||||||
|
String translatedPath = translatedPathsCache.get(command);
|
||||||
|
if (translatedPath == null) {
|
||||||
|
Process cygpathProcess = Runtime.getRuntime().exec(args);
|
||||||
|
BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpathProcess.getInputStream()));
|
||||||
|
String firstLine = null;
|
||||||
|
try {
|
||||||
|
firstLine = stdout.readLine();
|
||||||
|
} finally {
|
||||||
|
stdout.close();
|
||||||
|
}
|
||||||
|
if (firstLine == null) {
|
||||||
|
throw new IOException("Unable read output from command=[" + command + "]"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
translatedPath = firstLine.trim();
|
||||||
|
translatedPathsCache.put(command, translatedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return translatedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a command from arguments array.
|
||||||
|
*/
|
||||||
|
private static String getCommand(String[] args) {
|
||||||
|
String command = ""; //$NON-NLS-1$
|
||||||
|
for (String arg : args) {
|
||||||
|
command = command + arg + ' ';
|
||||||
|
}
|
||||||
|
return command.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversion from Cygwin path to Windows path.
|
* Conversion from Cygwin path to Windows path.
|
||||||
|
* Note that there is no need to cache results, they are already cached internally.
|
||||||
*
|
*
|
||||||
* @param cygwinPath - Cygwin path.
|
* @param cygwinPath - cygwin path.
|
||||||
* @param envPath - list of directories to search for cygwin utilities separated
|
* @param envPath - list of directories to search for cygwin utilities separated
|
||||||
* by path separator (format of environment variable $PATH).
|
* by path separator (format of environment variable $PATH).
|
||||||
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
|
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
|
||||||
|
@ -63,31 +151,24 @@ public class Cygwin {
|
||||||
if (cygwinPath == null || cygwinPath.trim().length() == 0)
|
if (cygwinPath == null || cygwinPath.trim().length() == 0)
|
||||||
return cygwinPath;
|
return cygwinPath;
|
||||||
|
|
||||||
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
|
if (!isWindowsPlatform) {
|
||||||
// Don't run this on non-windows platforms
|
|
||||||
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
|
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
IPath cygpathLocation = findCygpathLocation(envPath);
|
String cygpathLocation = findCygpathLocation(envPath);
|
||||||
if (cygpathLocation == null) {
|
if (cygpathLocation == null) {
|
||||||
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$
|
throw new UnsupportedOperationException(CYGPATH + " is not in the system search path."); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] args = {cygpathLocation.toOSString(), "-w", cygwinPath}; //$NON-NLS-1$
|
String windowsPath = runCygpath(new String[] {cygpathLocation, "-w", cygwinPath}); //$NON-NLS-1$
|
||||||
Process cygpathProcess = Runtime.getRuntime().exec(args);
|
return windowsPath;
|
||||||
BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpathProcess.getInputStream()));
|
|
||||||
|
|
||||||
String windowsPath = stdout.readLine();
|
|
||||||
if (windowsPath == null) {
|
|
||||||
throw new IOException("Unexpected output from Cygwin utility cygpath."); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
return windowsPath.trim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversion from Cygwin path to Windows path.
|
* Conversion from Cygwin path to Windows path.
|
||||||
|
* Note that there is no need to cache results, they are already cached internally.
|
||||||
*
|
*
|
||||||
* @param cygwinPath - Cygwin path.
|
* @param cygwinPath - cygwin path.
|
||||||
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
|
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
|
||||||
*
|
*
|
||||||
* @throws UnsupportedOperationException if Cygwin is unavailable.
|
* @throws UnsupportedOperationException if Cygwin is unavailable.
|
||||||
|
@ -99,6 +180,7 @@ public class Cygwin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversion from Windows path to Cygwin path.
|
* Conversion from Windows path to Cygwin path.
|
||||||
|
* Note that there is no need to cache results, they are already cached internally.
|
||||||
*
|
*
|
||||||
* @param windowsPath - Windows path.
|
* @param windowsPath - Windows path.
|
||||||
* @param envPath - list of directories to search for cygwin utilities (value of environment variable $PATH).
|
* @param envPath - list of directories to search for cygwin utilities (value of environment variable $PATH).
|
||||||
|
@ -111,28 +193,22 @@ public class Cygwin {
|
||||||
if (windowsPath == null || windowsPath.trim().length() == 0)
|
if (windowsPath == null || windowsPath.trim().length() == 0)
|
||||||
return windowsPath;
|
return windowsPath;
|
||||||
|
|
||||||
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
|
if (!isWindowsPlatform) {
|
||||||
// Don't run this on non-windows platforms
|
|
||||||
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
|
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
IPath cygpathLocation = findCygpathLocation(envPath);
|
|
||||||
|
String cygpathLocation = findCygpathLocation(envPath);
|
||||||
if (cygpathLocation == null) {
|
if (cygpathLocation == null) {
|
||||||
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$
|
throw new UnsupportedOperationException(CYGPATH + " is not in the system search path."); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] args = {cygpathLocation.toOSString(), "-u", windowsPath}; //$NON-NLS-1$
|
String cygwinPath = runCygpath(new String[] {cygpathLocation, "-u", windowsPath}); //$NON-NLS-1$
|
||||||
Process cygpath = Runtime.getRuntime().exec(args);
|
return cygwinPath;
|
||||||
BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpath.getInputStream()));
|
|
||||||
|
|
||||||
String cygwinPath = stdout.readLine();
|
|
||||||
if (cygwinPath == null) {
|
|
||||||
throw new IOException("Unexpected output from Cygwin utility cygpath."); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
return cygwinPath.trim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conversion from Windows path to Cygwin path.
|
* Conversion from Windows path to Cygwin path.
|
||||||
|
* Note that there is no need to cache results, they are already cached internally.
|
||||||
*
|
*
|
||||||
* @param windowsPath - Windows path.
|
* @param windowsPath - Windows path.
|
||||||
* @return Cygwin style converted path.
|
* @return Cygwin style converted path.
|
||||||
|
@ -143,4 +219,114 @@ public class Cygwin {
|
||||||
public static String windowsToCygwinPath(String windowsPath) throws IOException, UnsupportedOperationException {
|
public static String windowsToCygwinPath(String windowsPath) throws IOException, UnsupportedOperationException {
|
||||||
return windowsToCygwinPath(windowsPath, null);
|
return windowsToCygwinPath(windowsPath, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find location where Cygwin is installed. A number of locations is being checked,
|
||||||
|
* such as environment variable $CYGWIN_HOME, $PATH, Windows registry et al.
|
||||||
|
* <br><br>
|
||||||
|
* If you use this do not cache results to ensure user preferences are accounted for.
|
||||||
|
* Please rely on internal caching.
|
||||||
|
*
|
||||||
|
* @return Location of Cygwin root folder "/" on file system in Windows format.
|
||||||
|
*/
|
||||||
|
public static String getCygwinHome() {
|
||||||
|
if (!isWindowsPlatform) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnvironmentVariable varPath = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_PATH, null, true);
|
||||||
|
String envPathValue = varPath != null ? varPath.getValue() : null;
|
||||||
|
IEnvironmentVariable varCygwinHome = CCorePlugin.getDefault().getBuildEnvironmentManager().getVariable(ENV_CYGWIN_HOME, null, true);
|
||||||
|
String envCygwinHomeValue = varCygwinHome != null ? varCygwinHome.getValue() : null;
|
||||||
|
|
||||||
|
// isCygwinLocationCached is used to figure fact of caching when all cached objects are null
|
||||||
|
if (isCygwinLocationCached && CDataUtil.objectsEqual(envPathValue, envPathValueCached) && CDataUtil.objectsEqual(envCygwinHomeValue, envCygwinHomeValueCached)) {
|
||||||
|
return cygwinLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
cygwinLocation = findCygwinRoot(envPathValue, envCygwinHomeValue);
|
||||||
|
|
||||||
|
envPathValueCached = envPathValue;
|
||||||
|
envCygwinHomeValueCached = envCygwinHomeValue;
|
||||||
|
isCygwinLocationCached = true;
|
||||||
|
|
||||||
|
return cygwinLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads required value from registry. Looks in both
|
||||||
|
* HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE
|
||||||
|
*
|
||||||
|
* @param key Registry key
|
||||||
|
* @param name Registry value to read
|
||||||
|
* @return corresponding string value or null if nothing found
|
||||||
|
*/
|
||||||
|
private static String readValueFromRegistry(String key, String name) {
|
||||||
|
WindowsRegistry registry = WindowsRegistry.getRegistry();
|
||||||
|
if (registry != null) {
|
||||||
|
String s = registry.getCurrentUserValue(key, name);
|
||||||
|
if(s == null) {
|
||||||
|
s = registry.getLocalMachineValue(key, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s != null) {
|
||||||
|
return (s.replace(BACKSLASH, SLASH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The absolute path to cygwin's root or null if not found
|
||||||
|
*/
|
||||||
|
private static String findCygwinRoot(String envPathValue, String envCygwinHomeValue) {
|
||||||
|
String rootValue = null;
|
||||||
|
|
||||||
|
// Check $CYGWIN_HOME
|
||||||
|
if (envCygwinHomeValue != null && !envCygwinHomeValue.isEmpty()) {
|
||||||
|
IPath location = new Path(envCygwinHomeValue + "/bin/" + CYGWIN_DLL); //$NON-NLS-1$
|
||||||
|
if (location.toFile().exists()) {
|
||||||
|
// get rootValue from "rootValue\bin\cygwin1.dll"
|
||||||
|
rootValue = location.removeLastSegments(2).toOSString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look in PATH values. Look for cygwin1.dll
|
||||||
|
if(rootValue == null) {
|
||||||
|
IPath location = PathUtil.findProgramLocation(CYGWIN_DLL, envPathValue);
|
||||||
|
if (location != null) {
|
||||||
|
// get 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$
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the root dir in SOFTWARE\Wow6432Node\Cygwin\setup
|
||||||
|
if(rootValue == null) {
|
||||||
|
rootValue = readValueFromRegistry(REGISTRY_KEY_SETUP_WIN64, "rootdir"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the root dir in SOFTWARE\Cygnus Solutions
|
||||||
|
if (rootValue == null) {
|
||||||
|
rootValue = readValueFromRegistry(REGISTRY_KEY_MOUNTS + ROOTPATTERN, PATH_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.replace(BACKSLASH, SLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootValue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013 Andrew Gvozdev and others.
|
||||||
|
* 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:
|
||||||
|
* Andrew Gvozdev - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.core;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple cache with limited number of items in the cache. LRUCache discards the Least Recently Used items first.
|
||||||
|
* Based on {@link LinkedHashMap}. Note that {@link LinkedHashMap} has built-in facility to support cache like that
|
||||||
|
* which is described in its JavaDoc.
|
||||||
|
*/
|
||||||
|
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
|
||||||
|
private int fLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an empty LRUCache with the specified limit on the number of items in the cache.
|
||||||
|
*
|
||||||
|
* @param limit - the maximum number of items to keep in the cache.
|
||||||
|
*/
|
||||||
|
public LRUCache(int limit) {
|
||||||
|
super(limit, 0.75f, true);
|
||||||
|
fLimit= limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an empty LRUCache with the specified initial capacity and limit on the number of items in the cache.
|
||||||
|
*
|
||||||
|
* @param initialCapacity - initial capacity.
|
||||||
|
* @param limit - the maximum number of items to keep in the cache.
|
||||||
|
*/
|
||||||
|
public LRUCache(int initialCapacity, int limit) {
|
||||||
|
super(initialCapacity, 0.75f, true);
|
||||||
|
fLimit= limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Entry<K, V> eldest) {
|
||||||
|
return size() >= fLimit;
|
||||||
|
}
|
||||||
|
}
|
|
@ -979,8 +979,11 @@ implements
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void cfgChanged(ICConfigurationDescription _cfgd) {
|
protected void cfgChanged(ICConfigurationDescription _cfgd) {
|
||||||
|
|
||||||
CConfigurationStatus st = _cfgd.getConfigurationStatus();
|
CConfigurationStatus st = _cfgd.getConfigurationStatus();
|
||||||
|
if (st.getCode() == CConfigurationStatus.TOOLCHAIN_NOT_SUPPORTED) {
|
||||||
|
// Re-check, maybe user got the problem fixed
|
||||||
|
st = _cfgd.getConfigurationData().getStatus();
|
||||||
|
}
|
||||||
if (errPane != null && errMessage != null) {
|
if (errPane != null && errMessage != null) {
|
||||||
if (st.isOK()) {
|
if (st.isOK()) {
|
||||||
errPane.setVisible(false);
|
errPane.setVisible(false);
|
||||||
|
|
Loading…
Add table
Reference in a new issue