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$