diff --git a/build/org.eclipse.cdt.make.core/plugin.xml b/build/org.eclipse.cdt.make.core/plugin.xml
index 63816b70211..5de1999d0e0 100644
--- a/build/org.eclipse.cdt.make.core/plugin.xml
+++ b/build/org.eclipse.cdt.make.core/plugin.xml
@@ -197,7 +197,7 @@
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakefileBuildConfigurationProvider.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java
similarity index 94%
rename from build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakefileBuildConfigurationProvider.java
rename to build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java
index f820c4eb7e9..1406011df48 100644
--- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakefileBuildConfigurationProvider.java
+++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakefileBuildConfigurationProvider.java
@@ -5,19 +5,21 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
-package org.eclipse.cdt.make.internal.core;
+package org.eclipse.cdt.make.core;
import org.eclipse.cdt.core.build.ICBuildConfiguration;
import org.eclipse.cdt.core.build.ICBuildConfigurationManager;
import org.eclipse.cdt.core.build.ICBuildConfigurationProvider;
import org.eclipse.cdt.core.build.IToolChain;
import org.eclipse.cdt.core.build.StandardBuildConfiguration;
-import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+/**
+ * @since 7.4
+ */
public class MakefileBuildConfigurationProvider implements ICBuildConfigurationProvider {
public static final String ID = "org.eclipse.cdt.make.core.provider"; //$NON-NLS-1$
diff --git a/build/org.eclipse.cdt.make.core/templates/simple/Makefile b/build/org.eclipse.cdt.make.core/templates/simple/Makefile
index 02622849e17..404907713d5 100644
--- a/build/org.eclipse.cdt.make.core/templates/simple/Makefile
+++ b/build/org.eclipse.cdt.make.core/templates/simple/Makefile
@@ -1,11 +1,16 @@
+PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+
OBJS = ${projectName}.o
all: ${projectName}
${projectName}: $(OBJS)
- $(CC) -o $@ $^
+ $(CXX) -o $@ $^
-%.o: ../../%.cpp
+%.o: $(PROJECT_ROOT)%.cpp
+ $(CXX) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
+
+%.o: $(PROJECT_ROOT)%.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
clean:
diff --git a/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
index aa7adc5bd1d..02ee6cafbcf 100644
--- a/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
@@ -37,7 +37,8 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
org.eclipse.compare;bundle-version="[3.3.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="1.2.0",
org.eclipse.tools.templates.ui;bundle-version="1.1.1",
- org.eclipse.tools.templates.freemarker;bundle-version="1.0.0"
+ org.eclipse.tools.templates.freemarker;bundle-version="1.0.0",
+ org.eclipse.cdt.launch;bundle-version="9.2.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.ibm.icu.text
diff --git a/build/org.eclipse.cdt.make.ui/plugin.xml b/build/org.eclipse.cdt.make.ui/plugin.xml
index 430a7a35fd2..e4c1f7bbd09 100644
--- a/build/org.eclipse.cdt.make.ui/plugin.xml
+++ b/build/org.eclipse.cdt.make.ui/plugin.xml
@@ -651,4 +651,11 @@
label="Make">
+
+
+
+
diff --git a/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeBuildSettingsTab.java b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeBuildSettingsTab.java
new file mode 100644
index 00000000000..8910088d725
--- /dev/null
+++ b/build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeBuildSettingsTab.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2017 QNX Software Systems 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
+ *******************************************************************************/
+package org.eclipse.cdt.make.internal.ui;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.build.ICBuildConfiguration;
+import org.eclipse.cdt.core.build.StandardBuildConfiguration;
+import org.eclipse.cdt.launch.ui.corebuild.CommonBuildTab;
+import org.eclipse.cdt.make.core.MakefileBuildConfigurationProvider;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+
+public class MakeBuildSettingsTab extends CommonBuildTab {
+
+ private Button projectButton;
+ private Button configButton;
+
+ private boolean defaultProject;
+
+ @Override
+ protected String getBuildConfigProviderId() {
+ return MakefileBuildConfigurationProvider.ID;
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ comp.setLayout(new GridLayout());
+ setControl(comp);
+
+ // Toolchain selector
+ Control tcControl = createToolchainSelector(comp);
+ tcControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // Build Output Group
+ Group group = new Group(comp, SWT.NONE);
+ group.setText("Build Output Location");
+ group.setLayout(new GridLayout());
+ group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ projectButton = new Button(group, SWT.RADIO);
+ projectButton.setText("Build in project directory");
+ projectButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+
+ configButton = new Button(group, SWT.RADIO);
+ configButton.setText("Build in configuration specific folder");
+ configButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ }
+
+ @Override
+ public String getName() {
+ return "Makefile";
+ }
+
+ @Override
+ protected void restoreProperties(Map properties) {
+ // TODO Auto-generated method stub
+ super.restoreProperties(properties);
+
+ String container = properties.get(StandardBuildConfiguration.BUILD_CONTAINER);
+ if (container != null && !container.trim().isEmpty()) {
+ IPath containerLoc = new Path(container);
+ if (containerLoc.segmentCount() == 1) {
+ // TODO what if it's not the project?
+ projectButton.setSelection(true);
+ defaultProject = true;
+ } else {
+ configButton.setSelection(true);
+ defaultProject = false;
+ }
+ }
+ }
+
+ @Override
+ protected void saveProperties(Map properties) {
+ super.saveProperties(properties);
+
+ try {
+ ICBuildConfiguration buildConfig = getBuildConfiguration();
+ if (buildConfig instanceof StandardBuildConfiguration) {
+ StandardBuildConfiguration stdConfig = (StandardBuildConfiguration) buildConfig;
+ if (defaultProject && !projectButton.getSelection()) {
+ properties.put(StandardBuildConfiguration.BUILD_CONTAINER,
+ stdConfig.getDefaultBuildContainer().getFullPath().toString());
+ } else if (!defaultProject && projectButton.getSelection()) {
+ properties.put(StandardBuildConfiguration.BUILD_CONTAINER,
+ stdConfig.getProject().getFullPath().toString());
+ }
+ }
+ } catch (CoreException e) {
+ MakeUIPlugin.log(e.getStatus());
+ }
+ }
+
+ @Override
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ super.initializeFrom(configuration);
+
+ ICBuildConfiguration buildConfig = getBuildConfiguration();
+ String container = buildConfig.getProperty(StandardBuildConfiguration.BUILD_CONTAINER);
+ if (container != null && !container.trim().isEmpty()) {
+ IPath containerLoc = new Path(container);
+ if (containerLoc.segmentCount() == 1) {
+ // TODO what if it's not the project?
+ projectButton.setSelection(true);
+ defaultProject = true;
+ } else {
+ configButton.setSelection(true);
+ defaultProject = false;
+ }
+ }
+ }
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ super.performApply(configuration);
+
+ try {
+ ICBuildConfiguration buildConfig = getBuildConfiguration();
+ if (buildConfig instanceof StandardBuildConfiguration) {
+ StandardBuildConfiguration stdConfig = (StandardBuildConfiguration) buildConfig;
+ if (defaultProject && !projectButton.getSelection()) {
+ stdConfig.setBuildContainer(stdConfig.getDefaultBuildContainer());
+ } else if (!defaultProject && projectButton.getSelection()) {
+ stdConfig.setBuildContainer(stdConfig.getProject());
+ }
+ }
+ } catch (CoreException e) {
+ MakeUIPlugin.log(e.getStatus());
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/.settings/.api_filters b/core/org.eclipse.cdt.core/.settings/.api_filters
index cc9a57dda17..b75949e3ada 100644
--- a/core/org.eclipse.cdt.core/.settings/.api_filters
+++ b/core/org.eclipse.cdt.core/.settings/.api_filters
@@ -74,4 +74,12 @@
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
index b3d47a4fc5e..ce7edae66b0 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuildConfiguration.java
@@ -147,7 +147,7 @@ public abstract class CBuildConfiguration extends PlatformObject
this.launchMode = launchMode;
Preferences settings = getSettings();
- settings.put(TOOLCHAIN_TYPE, toolChain.getProvider().getId());
+ settings.put(TOOLCHAIN_TYPE, toolChain.getTypeId());
settings.put(TOOLCHAIN_ID, toolChain.getId());
try {
settings.flush();
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java
index 5bed805c33f..01d6e4651c5 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java
@@ -9,6 +9,10 @@ package org.eclipse.cdt.core.build;
import java.io.IOException;
import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
@@ -20,11 +24,15 @@ import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.cdt.internal.core.build.Messages;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
/**
@@ -35,12 +43,26 @@ import org.eclipse.core.runtime.Status;
*/
public class StandardBuildConfiguration extends CBuildConfiguration {
- private String[] buildCommand = { "make", "-j", "-f", "../../Makefile", "all" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
- private String[] cleanCommand = { "make", "clean" }; //$NON-NLS-1$ //$NON-NLS-2$
+ /**
+ * @since 6.4
+ */
+ public static final String BUILD_CONTAINER = "stdbuild.build.container"; //$NON-NLS-1$
+
+ private String[] buildCommand;
+ private String[] cleanCommand;
private IContainer buildContainer;
public StandardBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
super(config, name);
+ String container = getProperty(BUILD_CONTAINER);
+ if (container != null && !container.trim().isEmpty()) {
+ IPath containerLoc = new org.eclipse.core.runtime.Path(container);
+ if (containerLoc.segmentCount() == 1) {
+ buildContainer = ResourcesPlugin.getWorkspace().getRoot().getProject(containerLoc.segment(0));
+ } else {
+ buildContainer = ResourcesPlugin.getWorkspace().getRoot().getFolder(containerLoc);
+ }
+ }
}
public StandardBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain,
@@ -50,6 +72,7 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
public void setBuildContainer(IContainer buildContainer) {
this.buildContainer = buildContainer;
+ setProperty(BUILD_CONTAINER, buildContainer.getFullPath().toString());
}
public void setBuildCommand(String[] buildCommand) {
@@ -60,11 +83,55 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
this.cleanCommand = cleanCommand;
}
+ private void createBuildContainer(IContainer container, IProgressMonitor monitor) throws CoreException {
+ IContainer parent = container.getParent();
+ if (!(parent instanceof IProject) && !parent.exists()) {
+ createBuildContainer(parent, monitor);
+ }
+
+ if (container instanceof IFolder) {
+ ((IFolder) container).create(IResource.FORCE | IResource.DERIVED, true, monitor);
+ }
+ }
+
@Override
public IContainer getBuildContainer() throws CoreException {
+ if (buildContainer == null) {
+ return super.getBuildContainer();
+ } else {
+ if (!(buildContainer instanceof IProject) && !buildContainer.exists()) {
+ createBuildContainer(buildContainer, new NullProgressMonitor());
+ }
+ }
return buildContainer != null ? buildContainer : super.getBuildContainer();
}
+ /**
+ * @since 6.4
+ */
+ public IContainer getDefaultBuildContainer() throws CoreException {
+ return super.getBuildContainer();
+ }
+
+ @Override
+ public String getProperty(String name) {
+ String prop = super.getProperty(name);
+ if (prop != null) {
+ return prop;
+ }
+
+ switch (name) {
+ case BUILD_CONTAINER:
+ try {
+ return getBuildContainer().getFullPath().toString();
+ } catch (CoreException e) {
+ CCorePlugin.log(e.getStatus());
+ }
+ }
+
+ return null;
+ }
+
@Override
public IProject[] build(int kind, Map args, IConsole console, IProgressMonitor monitor)
throws CoreException {
@@ -78,12 +145,25 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
outStream.write(String.format(Messages.StandardBuildConfiguration_0, buildDir.toString()));
- String[] command = new String[buildCommand.length];
- Path make = findCommand(buildCommand[0]);
- command[0] = make.toString();
- System.arraycopy(buildCommand, 1, command, 1, buildCommand.length - 1);
+ List command;
+ if (buildCommand != null) {
+ command = Arrays.asList(buildCommand);
+ Path make = findCommand(buildCommand[0]);
+ command.set(0, make.toString());
+ } else {
+ command = new ArrayList<>();
+ command.add(findCommand("make").toString()); //$NON-NLS-1$
+ command.add("-j"); //$NON-NLS-1$
+ if (!getBuildContainer().equals(getProject())) {
+ Path makefile = Paths.get(getProject().getFile("Makefile").getLocationURI()); //$NON-NLS-1$
+ Path relative = getBuildDirectory().relativize(makefile);
+ command.add("-f"); //$NON-NLS-1$
+ command.add(relative.toString());
+ }
+ command.add("all"); //$NON-NLS-1$
+ }
- try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this,
+ try (ErrorParserManager epm = new ErrorParserManager(project, getProject().getLocationURI(), this,
getToolChain().getErrorParserIds())) {
epm.setOutputStream(console.getOutputStream());
// run make
@@ -115,10 +195,20 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
ConsoleOutputStream outStream = console.getOutputStream();
- String[] command = new String[cleanCommand.length];
- Path make = findCommand(cleanCommand[0]);
- command[0] = make.toString();
- System.arraycopy(cleanCommand, 1, command, 1, cleanCommand.length - 1);
+ List command;
+ if (cleanCommand != null) {
+ command = Arrays.asList(cleanCommand);
+ } else {
+ command = new ArrayList<>();
+ command.add(findCommand("make").toString()); //$NON-NLS-1$
+ if (!getBuildContainer().equals(getProject())) {
+ Path makefile = Paths.get(getProject().getFile("Makefile").getLocationURI()); //$NON-NLS-1$
+ Path relative = getBuildDirectory().relativize(makefile);
+ command.add("-f"); //$NON-NLS-1$
+ command.add(relative.toString());
+ }
+ command.add("clean"); //$NON-NLS-1$
+ }
// run make
outStream.write(String.format("%s\n", String.join(" ", command))); //$NON-NLS-1$ //$NON-NLS-2$