| /* |
| * Copyright (C) 2012 The Android Open Source Project |
| * |
| * Licensed under the Eclipse Public License, Version 1.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.eclipse.org/org/documents/epl-v10.php |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.ide.eclipse.ndk.internal; |
| |
| import com.android.ide.eclipse.adt.AdtPlugin; |
| import com.android.ide.eclipse.ndk.internal.launch.NdkLaunchConstants; |
| |
| import org.eclipse.cdt.core.CommandLauncher; |
| import org.eclipse.cdt.core.ICommandLauncher; |
| import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; |
| import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; |
| import org.eclipse.core.resources.IProject; |
| 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.debug.core.ILaunchConfigurationWorkingCopy; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.EnumSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| @SuppressWarnings("restriction") |
| public class NdkHelper { |
| private static final String MAKE = "make"; //$NON-NLS-1$ |
| private static final String CORE_MAKEFILE_PATH = "/build/core/build-local.mk"; //$NON-NLS-1$ |
| |
| /** |
| * Obtain the ABI's the application is compatible with. |
| * The ABI's are obtained by reading the result of the following command: |
| * make --no-print-dir -f ${NdkRoot}/build/core/build-local.mk -C <project-root> DUMP_APP_ABI |
| */ |
| public static Collection<NativeAbi> getApplicationAbis(IProject project, |
| IProgressMonitor monitor) { |
| ICommandLauncher launcher = new CommandLauncher(); |
| launcher.setProject(project); |
| String[] args = new String[] { |
| "--no-print-dir", //$NON-NLS-1$ |
| "-f", //$NON-NLS-1$ |
| NdkManager.getNdkLocation() + CORE_MAKEFILE_PATH, |
| "-C", //$NON-NLS-1$ |
| project.getLocation().toOSString(), |
| "DUMP_APP_ABI", //$NON-NLS-1$ |
| }; |
| try { |
| launcher.execute(getPathToMake(), args, null, project.getLocation(), monitor); |
| } catch (CoreException e) { |
| AdtPlugin.printErrorToConsole(e.getLocalizedMessage()); |
| return Collections.emptyList(); |
| } |
| |
| ByteArrayOutputStream stdout = new ByteArrayOutputStream(); |
| ByteArrayOutputStream stderr = new ByteArrayOutputStream(); |
| launcher.waitAndRead(stdout, stderr, monitor); |
| |
| String abis = stdout.toString().trim(); |
| Set<NativeAbi> nativeAbis = EnumSet.noneOf(NativeAbi.class); |
| for (String abi: abis.split(" ")) { //$NON-NLS-1$ |
| if (abi.equals("all")) { //$NON-NLS-1$ |
| return EnumSet.allOf(NativeAbi.class); |
| } |
| |
| try { |
| nativeAbis.add(NativeAbi.getByString(abi)); |
| } catch (IllegalArgumentException e) { |
| AdtPlugin.printErrorToConsole(project, "Unknown Application ABI: ", abi); |
| } |
| } |
| |
| return nativeAbis; |
| } |
| |
| /** |
| * Obtain the toolchain prefix to use for given project and abi. |
| * The prefix is obtained by reading the result of: |
| * make --no-print-dir -f ${NdkRoot}/build/core/build-local.mk \ |
| * -C <project-root> \ |
| * DUMP_TOOLCHAIN_PREFIX APP_ABI=abi |
| */ |
| public static String getToolchainPrefix(IProject project, NativeAbi abi, |
| IProgressMonitor monitor) { |
| ICommandLauncher launcher = new CommandLauncher(); |
| launcher.setProject(project); |
| String[] args = new String[] { |
| "--no-print-dir", //$NON-NLS-1$ |
| "-f", //$NON-NLS-1$ |
| NdkManager.getNdkLocation() + CORE_MAKEFILE_PATH, |
| "-C", //$NON-NLS-1$ |
| project.getLocation().toOSString(), |
| "DUMP_TOOLCHAIN_PREFIX", //$NON-NLS-1$ |
| "APP_ABI=" + abi.getAbi(), //$NON-NLS-1$ |
| }; |
| try { |
| launcher.execute(getPathToMake(), args, null, project.getLocation(), monitor); |
| } catch (CoreException e) { |
| AdtPlugin.printErrorToConsole(e.getLocalizedMessage()); |
| return null; |
| } |
| |
| ByteArrayOutputStream stdout = new ByteArrayOutputStream(); |
| ByteArrayOutputStream stderr = new ByteArrayOutputStream(); |
| launcher.waitAndRead(stdout, stderr, monitor); |
| return stdout.toString().trim(); |
| } |
| |
| private static IPath getPathToMake() { |
| return getFullPathTo(MAKE); |
| } |
| |
| /** |
| * Obtain a path to the utilities prebuilt folder in NDK. This is typically |
| * "${NdkRoot}/prebuilt/<platform>/bin/". If the executable is not found, it simply returns |
| * the name of the executable (which is equal to assuming that it is available on the path). |
| */ |
| private static synchronized IPath getFullPathTo(String executable) { |
| if (Platform.getOS().equals(Platform.OS_WIN32)) { |
| executable += ".exe"; |
| } |
| |
| IPath ndkRoot = new Path(NdkManager.getNdkLocation()); |
| IPath prebuilt = ndkRoot.append("prebuilt"); //$NON-NLS-1$ |
| if (!prebuilt.toFile().exists() || !prebuilt.toFile().canRead()) { |
| return new Path(executable); |
| } |
| |
| File[] platforms = prebuilt.toFile().listFiles(); |
| if (platforms != null) { |
| for (File p: platforms) { |
| IPath exePath = prebuilt.append(p.getName()) |
| .append("bin") //$NON-NLS-1$ |
| .append(executable); |
| if (exePath.toFile().exists()) { |
| return exePath; |
| } |
| } |
| } |
| |
| return new Path(executable); |
| } |
| |
| public static void setLaunchConfigDefaults(ILaunchConfigurationWorkingCopy config) { |
| config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP, true); |
| config.setAttribute(NdkLaunchConstants.ATTR_NDK_GDB, NdkLaunchConstants.DEFAULT_GDB); |
| config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_GDB_INIT, |
| NdkLaunchConstants.DEFAULT_GDBINIT); |
| config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_PORT, |
| NdkLaunchConstants.DEFAULT_GDB_PORT); |
| config.setAttribute(IGDBLaunchConfigurationConstants.ATTR_HOST, "localhost"); //$NON-NLS-1$ |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false); |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE_ATTACH); |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, |
| NdkLaunchConstants.DEFAULT_PROGRAM); |
| |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, |
| IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE); |
| config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ID, |
| "gdbserver"); //$NON-NLS-1$ |
| |
| List<String> solibPaths = new ArrayList<String>(2); |
| solibPaths.add(NdkLaunchConstants.DEFAULT_SOLIB_PATH); |
| config.setAttribute(NdkLaunchConstants.ATTR_NDK_SOLIB, solibPaths); |
| } |
| } |