diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/NdkHelper.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/NdkHelper.java | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/NdkHelper.java b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/NdkHelper.java new file mode 100644 index 000000000..8ad1f24c4 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.ndk/src/com/android/ide/eclipse/ndk/internal/NdkHelper.java @@ -0,0 +1,184 @@ +/* + * 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); + } +} |