Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.tcf.cdt.ui')
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/plugin.xml6
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchContext.java16
-rw-r--r--plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchProjectBuilder.java260
4 files changed, 282 insertions, 3 deletions
diff --git a/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
index fcd7d5927..35243d9a6 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.tcf.cdt.ui/META-INF/MANIFEST.MF
@@ -23,7 +23,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.8.0",
org.eclipse.cdt.launch;bundle-version="7.1.0",
org.eclipse.cdt.dsf.ui;bundle-version="2.3.0",
org.eclipse.ui.editors,
- org.eclipse.ui.workbench
+ org.eclipse.ui.workbench,
+ org.eclipse.core.variables
Bundle-ActivationPolicy: lazy
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/plugins/org.eclipse.tcf.cdt.ui/plugin.xml b/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
index 835a9cd58..b9033a763 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
+++ b/plugins/org.eclipse.tcf.cdt.ui/plugin.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?><!--
- Copyright (c) 2010, 2015 Wind River Systems, Inc. and others.
+ Copyright (c) 2010, 2016 Wind River Systems, Inc. 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
@@ -16,6 +16,10 @@
<class name="org.eclipse.tcf.internal.cdt.ui.TCFLaunchContext" />
</extension>
+ <extension point="org.eclipse.tcf.debug.launch_project_builder">
+ <class name="org.eclipse.tcf.internal.cdt.ui.TCFLaunchProjectBuilder" />
+ </extension>
+
<extension
point="org.eclipse.core.runtime.adapters">
<factory
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchContext.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchContext.java
index f07bf0cdd..4a66ec42e 100644
--- a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchContext.java
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchContext.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2016 Wind River Systems, Inc. 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
@@ -10,12 +10,16 @@
*******************************************************************************/
package org.eclipse.tcf.internal.cdt.ui;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IBinary;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.launch.LaunchUtils;
import org.eclipse.cdt.ui.CElementLabelProvider;
@@ -226,6 +230,16 @@ public class TCFLaunchContext implements ITCFLaunchContext {
return projDes.getActiveConfiguration().getId();
}
+ public Map<String,String> getBuildConfigIDs(IProject project) {
+ ICProjectDescription projDes = CCorePlugin.getDefault().getProjectDescription(project);
+ if (projDes == null) return null;
+ ICConfigurationDescription[] configurations = projDes.getConfigurations();
+ if (configurations == null) return null;
+ Map<String,String> map = new LinkedHashMap<String,String>();
+ for (ICConfigurationDescription c : configurations) map.put(c.getId(), c.getName());
+ return map;
+ }
+
/**
* Iterate through and suck up all of the executable files that we can find.
*/
diff --git a/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchProjectBuilder.java b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchProjectBuilder.java
new file mode 100644
index 000000000..e937fbc62
--- /dev/null
+++ b/plugins/org.eclipse.tcf.cdt.ui/src/org/eclipse/tcf/internal/cdt/ui/TCFLaunchProjectBuilder.java
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Xilinx, Inc. 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:
+ * Xilinx - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.internal.cdt.ui;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.launch.LaunchUtils;
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.tcf.debug.ITCFLaunchProjectBuilder;
+import org.eclipse.tcf.internal.debug.launch.TCFLaunchDelegate;
+
+/**
+ * Build CDT project.
+ * This is an specialization of the default project build logic.
+ * Unfortunately, CDT does not profile an API for building a project. See bug 313927.
+ * See org.eclipse.cdt.launch.AbstractCLaunchDelegate2 for more details.
+ */
+public class TCFLaunchProjectBuilder implements ITCFLaunchProjectBuilder {
+
+ @Override
+ public boolean isSupportedProject(String name) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ return CCorePlugin.getDefault().getCoreModel().create(project) != null;
+ }
+
+ @Override
+ public IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException {
+ String name = configuration.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
+ if (name.length() == 0) return null;
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ if (project == null) return null;
+ ICProject c_project = CCorePlugin.getDefault().getCoreModel().create(project);
+ if (c_project == null) return null;
+
+ IProject[] ordered_projects = null;
+ HashSet<IProject> project_set = new HashSet<IProject>();
+ getReferencedProjectSet(c_project.getProject(), project_set);
+
+ String[] ordered_names = ResourcesPlugin.getWorkspace().getDescription().getBuildOrder();
+ if (ordered_names != null) {
+ // Projects may not be in the build order but should still be built if selected
+ ArrayList<IProject> unordered_list = new ArrayList<IProject>(project_set.size());
+ ArrayList<IProject> ordered_list = new ArrayList<IProject>(project_set.size());
+ unordered_list.addAll(project_set);
+
+ for (String nm : ordered_names) {
+ for (IProject proj : unordered_list) {
+ if (proj.getName().equals(nm)) {
+ ordered_list.add(proj);
+ unordered_list.remove(proj);
+ break;
+ }
+ }
+ }
+
+ // Add any remaining projects to the end of the list
+ ordered_list.addAll(unordered_list);
+ ordered_projects = ordered_list.toArray(new IProject[ordered_list.size()]);
+ }
+ else {
+ // Try the project prerequisite order then
+ IProject[] projects = project_set.toArray(new IProject[project_set.size()]);
+ ordered_projects = ResourcesPlugin.getWorkspace().computeProjectOrder(projects).projects;
+ }
+ return ordered_projects;
+ }
+
+ /* Recursively creates a set of projects referenced by a project */
+ private void getReferencedProjectSet(IProject proj, Set<IProject> set) throws CoreException {
+ set.add(proj);
+ for (IProject ref : proj.getReferencedProjects()) {
+ if (ref.exists() && !set.contains(ref)) {
+ getReferencedProjectSet(ref, set);
+ }
+ }
+ }
+
+ /**
+ * Builds the project referenced in the launch configuration
+ */
+ public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
+ try {
+ SubMonitor submon = SubMonitor.convert(monitor, "", 1); //$NON-NLS-1$
+
+ String name = configuration.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
+ if (name.length() == 0) return true;
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ if (project == null) return true;
+
+ String buildConfigID = null;
+
+ if (configuration.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_BUILD_CONFIG_AUTO, false)) {
+ String program_path = configuration.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, ""); //$NON-NLS-1$
+ program_path = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(program_path);
+ ICConfigurationDescription buildConfig = LaunchUtils.getBuildConfigByProgramPath(project, program_path);
+ if (buildConfig != null) buildConfigID = buildConfig.getId();
+ }
+
+ if (buildConfigID == null) buildConfigID = configuration.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_BUILD_CONFIG_ID, (String)null);
+
+ // There's no guarantee the ID stored in the launch config is valid.
+ // The user may have deleted the build configuration.
+ if (buildConfigID != null) {
+ boolean idIsGood = false;
+ ICProjectDescription desc = CCorePlugin.getDefault().getProjectDescription(project, false);
+ if (desc != null) idIsGood = desc.getConfigurationById(buildConfigID) != null;
+ if (!idIsGood) buildConfigID = null; // use active configuration
+ }
+
+ buildProject(project, buildConfigID, submon.newChild(1));
+ return false;
+ }
+ finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+
+ /**
+ * This is an specialization of the platform method
+ * LaunchConfigurationDelegate#buildProjects(IProject[], IProgressMonitor).
+ * It builds only one project and it builds a particular CDT build
+ * configuration of it. It was added to address bug 309126 and 312709
+ */
+ public void buildProject(final IProject project, final String buildConfigID, IProgressMonitor monitor) throws CoreException {
+ final int TOTAL_TICKS = 1000;
+
+ // Some day, this will hopefully be a simple pass-thru to a cdt.core
+ // utility. See bug 313927
+
+ IWorkspaceRunnable build = new IWorkspaceRunnable(){
+ @Override
+ public void run(IProgressMonitor pm) throws CoreException {
+ SubMonitor localmonitor = SubMonitor.convert(pm, "", TOTAL_TICKS); //$NON-NLS-1$
+ try {
+ // Number of times we'll end up calling IProject.build()
+ final int buildCount = (buildConfigID == null) ? 1 : project.getDescription().getBuildSpec().length;
+ if (buildCount == 0) return; // the case for an imported-executable project; see bugzilla 315396
+ final int subtaskTicks = TOTAL_TICKS / buildCount;
+
+ if (buildConfigID != null) {
+ // Build a specific configuration
+
+ // To pass args, we have to specify the builder name.
+ // There can be multiple so this can require multiple
+ // builds. Note that this happens under the covers in
+ // the 'else' (args-less) case below
+ Map<String,String> cfgIdArgs = cfgIdsToMap(new String[] {buildConfigID}, new HashMap<String,String>());
+ cfgIdArgs.put(CONTENTS, CONTENTS_CONFIGURATION_IDS);
+ ICommand[] commands = project.getDescription().getBuildSpec();
+ assert buildCount == commands.length;
+ for (ICommand command : commands) {
+ Map<String, String> args = command.getArguments();
+ if (args == null) {
+ args = new HashMap<String, String>(cfgIdArgs);
+ }
+ else {
+ args.putAll(cfgIdArgs);
+ }
+
+ if (localmonitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, command.getBuilderName(), args, localmonitor.newChild(subtaskTicks));
+ }
+ }
+ else {
+ // Build the active configuration
+ project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, localmonitor.newChild(subtaskTicks));
+ }
+ }
+ finally {
+ if (pm != null) pm.done();
+ }
+ }
+ };
+ ResourcesPlugin.getWorkspace().run(build, new SubProgressMonitor(monitor, TOTAL_TICKS, 0) {
+ private boolean cancelled;
+ @Override
+ public void setCanceled(boolean b) {
+ // Only cancel this operation, not the top-level launch.
+ cancelled = b;
+ }
+ @Override
+ public boolean isCanceled() {
+ // Canceled if this monitor has been explicitly canceled
+ // || parent has been canceled.
+ return cancelled || super.isCanceled();
+ }
+ });
+ }
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static final String CONFIGURATION_IDS = "org.eclipse.cdt.make.core.configurationIds"; //$NON-NLS-1$
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static final String CONTENTS = "org.eclipse.cdt.make.core.contents"; //$NON-NLS-1$
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static final String CONTENTS_CONFIGURATION_IDS = "org.eclipse.cdt.make.core.configurationIds"; //$NON-NLS-1$
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static Map<String, String> cfgIdsToMap(String ids[], Map<String, String> map){
+ map.put(CONFIGURATION_IDS, encodeList(Arrays.asList(ids)));
+ return map;
+ }
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static String encodeList(List<String> values) {
+ StringBuffer str = new StringBuffer();
+ Iterator<String> entries = values.iterator();
+ while (entries.hasNext()) {
+ String entry = entries.next();
+ str.append(escapeChars(entry, "|\\", '\\')); //$NON-NLS-1$
+ str.append("|"); //$NON-NLS-1$
+ }
+ return str.toString();
+ }
+
+ /** TODO: Temporarily duplicated from BuilderFactory. Remove when 313927 is addressed */
+ private static String escapeChars(String string, String escapeChars, char escapeChar) {
+ StringBuffer str = new StringBuffer(string);
+ for (int i = 0; i < str.length(); i++) {
+ if (escapeChars.indexOf(str.charAt(i)) != -1) {
+ str.insert(i, escapeChar);
+ i++;
+ }
+ }
+ return str.toString();
+ }
+}

Back to the top