1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.ndk.internal.build; 18 19 import com.android.ide.eclipse.adt.AdtPlugin; 20 import com.android.ide.eclipse.ndk.internal.NdkManager; 21 22 import org.eclipse.cdt.core.CommandLauncher; 23 import org.eclipse.cdt.utils.CygPath; 24 import org.eclipse.core.runtime.CoreException; 25 import org.eclipse.core.runtime.IPath; 26 import org.eclipse.core.runtime.IProgressMonitor; 27 import org.eclipse.core.runtime.Path; 28 import org.eclipse.core.runtime.Platform; 29 30 import java.io.File; 31 import java.io.IOException; 32 import java.util.Arrays; 33 import java.util.List; 34 35 @SuppressWarnings("restriction") // for AdtPlugin internal classes 36 public class NdkCommandLauncher extends CommandLauncher { 37 private static CygPath sCygPath = null; 38 39 private static final List<String> WINDOWS_NATIVE_EXECUTABLES = Arrays.asList( 40 "exe", //$NON-NLS-1$ 41 "cmd", //$NON-NLS-1$ 42 "bat" //$NON-NLS-1$ 43 ); 44 45 static { 46 if (Platform.OS_WIN32.equals(Platform.getOS())) { 47 try { 48 sCygPath = new CygPath(); 49 } catch (IOException e) { 50 AdtPlugin.printErrorToConsole("Unable to launch cygpath. Is Cygwin on the path?", 51 e); 52 } 53 } 54 } 55 56 @Override 57 public Process execute(IPath commandPath, String[] args, String[] env, IPath changeToDirectory, 58 IProgressMonitor monitor) 59 throws CoreException { 60 if (!commandPath.isAbsolute()) 61 commandPath = new Path(NdkManager.getNdkLocation()).append(commandPath); 62 63 if (Platform.getOS().equals(Platform.OS_WIN32)) { 64 // convert cygwin paths to standard paths 65 if (sCygPath != null && commandPath.toString().startsWith("/cygdrive")) { //$NON-NLS-1$ 66 try { 67 String path = sCygPath.getFileName(commandPath.toString()); 68 commandPath = new Path(path); 69 } catch (IOException e) { 70 AdtPlugin.printErrorToConsole( 71 "Unexpected error while transforming cygwin path.", e); 72 } 73 } 74 75 if (isWindowsExecutable(commandPath)) { 76 // append necessary extension 77 commandPath = appendExecutableExtension(commandPath); 78 } else { 79 // Invoke using Cygwin shell if this is not a native windows executable 80 String[] newargs = new String[args.length + 1]; 81 newargs[0] = commandPath.toOSString(); 82 System.arraycopy(args, 0, newargs, 1, args.length); 83 84 commandPath = new Path("sh"); //$NON-NLS-1$ 85 args = newargs; 86 } 87 } 88 89 return super.execute(commandPath, args, env, changeToDirectory, monitor); 90 } 91 92 private boolean isWindowsExecutable(IPath commandPath) { 93 String ext = commandPath.getFileExtension(); 94 if (isWindowsExecutableExtension(ext)) { 95 return true; 96 } 97 98 ext = findWindowsExecutableExtension(commandPath); 99 if (ext != null) { 100 return true; 101 } 102 103 return false; 104 } 105 106 private IPath appendExecutableExtension(IPath commandPath) { 107 if (isWindowsExecutableExtension(commandPath.getFileExtension())) { 108 return commandPath; 109 } 110 111 String ext = findWindowsExecutableExtension(commandPath); 112 if (ext != null) { 113 return commandPath.addFileExtension(ext); 114 } 115 116 return commandPath; 117 } 118 119 private String findWindowsExecutableExtension(IPath command) { 120 for (String e: WINDOWS_NATIVE_EXECUTABLES) { 121 File exeFile = command.addFileExtension(e).toFile(); 122 if (exeFile.exists()) { 123 return e; 124 } 125 } 126 127 return null; 128 } 129 130 private boolean isWindowsExecutableExtension(String extension) { 131 return extension != null && WINDOWS_NATIVE_EXECUTABLES.contains(extension); 132 } 133 } 134