blob: 8ad1f24c4a1785cd392d5d12bc1906d8b2cfc7a1 [file] [log] [blame]
/*
* 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);
}
}