1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 03:05:39 +02:00

bug 364733: Internal Builder does not work with Cygwin toolchain

This commit is contained in:
Andrew Gvozdev 2012-03-13 13:25:14 -04:00
parent 863ac9d61b
commit dc01366f97
9 changed files with 244 additions and 230 deletions

View file

@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.internal.buildmodel;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
@ -21,12 +20,14 @@ import java.util.Set;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
/**
@ -41,56 +42,28 @@ import org.eclipse.core.runtime.SubProgressMonitor;
*/
public class CommandBuilder implements IBuildModelBuilder {
private static final String PATH_ENV = "PATH"; //$NON-NLS-1$
private static final String PROPERTY_DELIMITER = "path.separator"; //$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$
static final String DELIMITER_UNIX = ":"; //$NON-NLS-1$
static final String DELIMITER_WINDOWS = ";"; //$NON-NLS-1$
private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
private IBuildCommand fCmd;
private Process fProcess;
private String fErrMsg;
private static final String BUILDER_MSG_HEADER = "InternalBuilder.msg.header"; //$NON-NLS-1$
private static final String NEWLINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
/*
* no need in this for now, Spawner is always used
*
protected class SpawnerfreeLauncher extends CommandLauncher{
public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory) {
try {
// add platform specific arguments (shell invocation)
fCommandArgs = constructCommandArray(commandPath.toOSString(), args);
fProcess = Runtime.getRuntime().exec(fCommandArgs, env, changeToDirectory.toFile());
// ProcessFactory.getFactory().exec(fCommandArgs, env, changeToDirectory.toFile());
fErrorMessage = ""; //$NON-NLS-1$
} catch (IOException e) {
setErrorMessage(e.getMessage());
fProcess = null;
}
return fProcess;
}
}
*/
/*
* a temporary work-around to resolve the bug#145099
* (https://bugs.eclipse.org/bugs/show_bug.cgi?id=145099)
*
* this will be removed after fixing the bug#145737
* (https://bugs.eclipse.org/bugs/show_bug.cgi?id=145737)
*/
private class CommandSearchLauncher extends CommandLauncher{
private class CommandSearchLauncher extends CommandLauncher {
@Override
protected String[] constructCommandArray(String command, String[] commandArgs) {
String[] args = new String[1 + commandArgs.length];
if(!isWindows()){
//find a full path to an executable
String cmd = getExecutable(command, fCmd.getEnvironment());
if(cmd != null)
command = cmd;
if (Platform.getOS().equals(Platform.OS_WIN32)) {
// find a location of the executable
String envPathValue = fCmd.getEnvironment().get(PATH_ENV);
IPath location = PathUtil.findProgramLocation(command, envPathValue);
if(location != null) {
try {
// Handle cygwin link
command = Cygwin.cygwinToWindowsPath(location.toString(), envPathValue);
} catch (Exception e) {
command = location.toString();
}
}
//if not found, continue with the command passed as an argument
}
@ -99,7 +72,6 @@ public class CommandBuilder implements IBuildModelBuilder {
return args;
}
@Override
protected void printCommandLine(OutputStream os) {
if (os != null) {
@ -274,7 +246,7 @@ public class CommandBuilder implements IBuildModelBuilder {
protected void printMessage(String msg, OutputStream os){
if (os != null) {
msg = ManagedMakeMessages.getFormattedString(BUILDER_MSG_HEADER, msg);
msg = ManagedMakeMessages.getFormattedString("InternalBuilder.msg.header", msg); //$NON-NLS-1$
printMessage(null, msg, os);
}
@ -305,53 +277,4 @@ public class CommandBuilder implements IBuildModelBuilder {
}
return buf.toString();
}
private String getExecutable(String command, Map<String, String> environment){
if(new Path(command).isAbsolute())
return command;
return searchExecutable(command, getPaths(environment));
}
private String[] getPaths(Map<String, String> env){
String pathsStr = env.get(PATH_ENV);
if(pathsStr == null){
Set<Entry<String, String>> entrySet = env.entrySet();
for (Entry<String, String> entry : entrySet) {
if(PATH_ENV.equalsIgnoreCase(entry.getKey())){
pathsStr = entry.getValue();
break;
}
}
}
if(pathsStr != null){
String delimiter = getDelimiter();
return pathsStr.split(delimiter);
}
return null;
}
private String getDelimiter(){
String delimiter = System.getProperty(PROPERTY_DELIMITER);
if(delimiter == null)
delimiter = isWindows() ? DELIMITER_WINDOWS : DELIMITER_UNIX;
return delimiter;
}
private String searchExecutable(String command, String paths[]){
if(paths == null)
return null;
for(int i = 0; i < paths.length; i++){
File file = new File(paths[i], command.toString());
if(file.isFile())
return file.toString();
}
return null;
}
private boolean isWindows() {
String prop = System.getProperty(PROPERTY_OS_NAME);
return prop != null ? prop.toLowerCase().startsWith(PROPERTY_OS_VALUE) : false;
}
}

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.errorparsers.AbstractErrorParser;
import org.eclipse.cdt.core.errorparsers.ErrorPattern;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.core.internal.registry.ExtensionRegistry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@ -903,7 +904,7 @@ public class ErrorParserFileMatchingTest extends TestCase {
String windowsFileName = fProject.getLocation().append(fileName).toOSString();
String cygwinFileName;
try {
cygwinFileName = ResourceHelper.windowsToCygwinPath(windowsFileName);
cygwinFileName = Cygwin.windowsToCygwinPath(windowsFileName);
} catch (UnsupportedOperationException e) {
// Skip the test if Cygwin is not available.
return;
@ -931,7 +932,7 @@ public class ErrorParserFileMatchingTest extends TestCase {
String usrIncludeWindowsPath;
try {
usrIncludeWindowsPath = ResourceHelper.cygwinToWindowsPath(cygwinFolder);
usrIncludeWindowsPath = Cygwin.cygwinToWindowsPath(cygwinFolder);
} catch (UnsupportedOperationException e) {
// Skip the test if Cygwin is not available.
return;
@ -961,7 +962,7 @@ public class ErrorParserFileMatchingTest extends TestCase {
String windowsFileName = anotherProject.getLocation().append(fileName).toOSString();
String cygwinFileName;
try {
cygwinFileName = ResourceHelper.windowsToCygwinPath(windowsFileName);
cygwinFileName = Cygwin.windowsToCygwinPath(windowsFileName);
} catch (UnsupportedOperationException e) {
// Skip the test if Cygwin is not available.
return;
@ -1010,7 +1011,7 @@ public class ErrorParserFileMatchingTest extends TestCase {
String windowsFileName = fProject.getLocation().append(fileName).toOSString();
String cygwinFileName;
try {
cygwinFileName = ResourceHelper.windowsToCygwinPath(windowsFileName);
cygwinFileName = Cygwin.windowsToCygwinPath(windowsFileName);
} catch (UnsupportedOperationException e) {
// Skip the test if Cygwin is not available.
return;

View file

@ -35,6 +35,7 @@ import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
import org.eclipse.cdt.core.settings.model.TestCfgDataProvider;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@ -629,24 +630,7 @@ public class ResourceHelper {
* @throws IOException on IO problem.
*/
public static String windowsToCygwinPath(String windowsPath) throws IOException, UnsupportedOperationException {
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
// Don't run this on non-windows platforms
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable.");
}
String[] args = {"cygpath", "-u", windowsPath};
Process cygpath;
try {
cygpath = Runtime.getRuntime().exec(args);
} catch (IOException ioe) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path.");
}
BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpath.getInputStream()));
String cygwinPath = stdout.readLine();
if (cygwinPath == null) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not available.");
}
return cygwinPath.trim();
return Cygwin.windowsToCygwinPath(windowsPath);
}
/**
@ -658,24 +642,7 @@ public class ResourceHelper {
* @throws IOException on IO problem.
*/
public static String cygwinToWindowsPath(String cygwinPath) throws IOException, UnsupportedOperationException {
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
// Don't run this on non-windows platforms
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable.");
}
String[] args = {"cygpath", "-w", cygwinPath};
Process cygpath;
try {
cygpath = Runtime.getRuntime().exec(args);
} catch (IOException ioe) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path.");
}
BufferedReader stdout = new BufferedReader(new InputStreamReader(cygpath.getInputStream()));
String windowsPath = stdout.readLine();
if (windowsPath == null) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not available.");
}
return windowsPath.trim();
return Cygwin.cygwinToWindowsPath(cygwinPath);
}
/**

View file

@ -25,10 +25,10 @@ import java.util.Vector;
import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager;
import org.eclipse.cdt.utils.CygPath;
import org.eclipse.cdt.utils.EFSExtensionManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@ -524,20 +524,13 @@ outer:
private IFile findCygwinFile(String filePath) {
IFile file=null;
IPath path;
CygPath cygpath = null;
try {
cygpath = new CygPath();
path = new Path(cygpath.getFileName(filePath));
IPath path = new Path(Cygwin.cygwinToWindowsPath(filePath));
file = findFileInWorkspace(path);
} catch (UnsupportedOperationException e) {
isCygwin = false;
} catch (Exception e) {
}
finally {
if (cygpath != null)
cygpath.dispose();
}
return file;
}

View file

@ -18,7 +18,7 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.utils.CygPath;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
@ -209,10 +209,8 @@ public class ErrorPattern {
IPath path = new Path(filename);
File file = path.toFile() ;
if (!file.exists() && isCygwin && path.isAbsolute()) {
CygPath cygpath = null ;
try {
cygpath = new CygPath("cygpath"); //$NON-NLS-1$
String cygfilename = cygpath.getFileName(filename);
String cygfilename = Cygwin.cygwinToWindowsPath(filename);
IPath convertedPath = new Path(cygfilename);
file = convertedPath.toFile() ;
if (file.exists()) {
@ -222,11 +220,6 @@ public class ErrorPattern {
isCygwin = false;
} catch (IOException e) {
}
finally {
if (null!=cygpath) {
cygpath.dispose();
}
}
}
return path ;
}

View file

@ -18,7 +18,7 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.utils.CygPath;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
@ -330,10 +330,8 @@ public class RegexErrorPattern implements Cloneable {
IPath path = new Path(filename);
File file = path.toFile() ;
if (!file.exists() && isCygwin && path.isAbsolute()) {
CygPath cygpath = null ;
try {
cygpath = new CygPath("cygpath"); //$NON-NLS-1$
String cygfilename = cygpath.getFileName(filename);
String cygfilename = Cygwin.cygwinToWindowsPath(filename);
IPath convertedPath = new Path(cygfilename);
file = convertedPath.toFile() ;
if (file.exists()) {
@ -342,10 +340,6 @@ public class RegexErrorPattern implements Cloneable {
} catch (UnsupportedOperationException e) {
isCygwin = false;
} catch (IOException e) {
} finally {
if (null!=cygpath) {
cygpath.dispose();
}
}
}
return path ;

View file

@ -0,0 +1,136 @@
/*******************************************************************************
* 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.internal.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
/**
* A collection of cygwin-related utilities.
*/
public class Cygwin {
private static IPath findCygpathLocation(String envPath) {
return PathUtil.findProgramLocation("cygpath", envPath); //$NON-NLS-1$
}
/**
* Check if cygwin path conversion utilities are available in the path.
*
* @param envPath - list of directories to search for cygwin utilities separated
* by path separator (format of environment variable $PATH).
* @return {@code true} if cygwin is available, {@code false} otherwise.
*/
public static boolean isAvailable(String envPath) {
return Platform.getOS().equals(Platform.OS_WIN32) && findCygpathLocation(envPath) != null;
}
/**
* Conversion from Cygwin path to Windows path.
*
* @param cygwinPath - Cygwin path.
* @param envPath - list of directories to search for cygwin utilities separated
* by path separator (format of environment variable $PATH).
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
*
* @throws UnsupportedOperationException if Cygwin is unavailable.
* @throws IOException on IO problem.
*/
public static String cygwinToWindowsPath(String cygwinPath, String envPath) throws IOException, UnsupportedOperationException {
if (cygwinPath == null || cygwinPath.trim().length() == 0)
return cygwinPath;
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
// Don't run this on non-windows platforms
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
}
IPath cygpathLocation = findCygpathLocation(envPath);
if (cygpathLocation == null) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$
}
String[] args = {cygpathLocation.toOSString(), "-w", cygwinPath}; //$NON-NLS-1$
Process cygpathProcess = Runtime.getRuntime().exec(args);
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.
*
* @param cygwinPath - Cygwin path.
* @return Windows style converted path. Note that that also converts cygwin links to their targets.
*
* @throws UnsupportedOperationException if Cygwin is unavailable.
* @throws IOException on IO problem.
*/
public static String cygwinToWindowsPath(String cygwinPath) throws IOException, UnsupportedOperationException {
return cygwinToWindowsPath(cygwinPath, null);
}
/**
* Conversion from Windows path to Cygwin path.
*
* @param windowsPath - Windows path.
* @param envPath - list of directories to search for cygwin utilities (value of environment variable $PATH).
* @return Cygwin style converted path.
*
* @throws UnsupportedOperationException if Cygwin is unavailable.
* @throws IOException on IO problem.
*/
public static String windowsToCygwinPath(String windowsPath, String envPath) throws IOException, UnsupportedOperationException {
if (windowsPath == null || windowsPath.trim().length() == 0)
return windowsPath;
if (!Platform.getOS().equals(Platform.OS_WIN32)) {
// Don't run this on non-windows platforms
throw new UnsupportedOperationException("Not a Windows system, Cygwin is unavailable."); //$NON-NLS-1$
}
IPath cygpathLocation = findCygpathLocation(envPath);
if (cygpathLocation == null) {
throw new UnsupportedOperationException("Cygwin utility cygpath is not in the system search path."); //$NON-NLS-1$
}
String[] args = {cygpathLocation.toOSString(), "-u", windowsPath}; //$NON-NLS-1$
Process cygpath = Runtime.getRuntime().exec(args);
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.
*
* @param windowsPath - Windows path.
* @return Cygwin style converted path.
*
* @throws UnsupportedOperationException if Cygwin is unavailable.
* @throws IOException on IO problem.
*/
public static String windowsToCygwinPath(String windowsPath) throws IOException, UnsupportedOperationException {
return windowsToCygwinPath(windowsPath, null);
}
}

View file

@ -17,6 +17,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
@ -59,6 +60,10 @@ public class CygPath {
this("cygpath"); //$NON-NLS-1$
}
/**
* Use this method for series of translations of paths.
* If a single path needs to be translated consider {@link Cygwin#cygwinToWindowsPath(String)}.
*/
public String getFileName(String name) throws IOException {
// bug 214603, empty names don't create a response
if (name == null || name.length() == 0)

View file

@ -340,7 +340,8 @@ public class PathUtil {
* @param pathsStr - the list of paths to inspect separated by path separator
* defined in the platform (i.e. ":" in Unix and ";" in Windows).
* In case pathStr is {@code null} environment variable ${PATH} is inspected.
* @return - absolute location of the file on the file system.
* @return - absolute location of the file on the file system
* or {@code null} if not found.
* @since 5.3
*/
public static IPath findProgramLocation(String prog, String pathsStr) {
@ -402,7 +403,8 @@ public class PathUtil {
*
* @param prog - program to find. For Windows, extensions "com" and "exe"
* can be omitted.
* @return - absolute location of the file on the file system.
* @return - absolute location of the file on the file system
* or {@code null} if not found.
* @since 5.3
*/
public static IPath findProgramLocation(String prog) {