From 7043af66fb1eb4ee06fb025905e37f961818e1e6 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Sat, 23 Apr 2016 21:32:25 -0400 Subject: [PATCH] Major change to new build arch to give configs more power. Creates a single central CBuilder builder which find the C Build Config and delegates the builds to it. That give configs full control over the builds. Qt and CMake build configs are adapted to this new structure. More features are added to the default super class for configs. Change-Id: I5ecfc7a4e9b909da6749189a059cdcd4a208fddd --- .../cdt/build/gcc/core/GCCToolChain.java | 66 +++- build/org.eclipse.cdt.cmake.core/plugin.xml | 10 - .../eclipse/cdt/cmake/core/CMakeNature.java | 20 +- .../cdt/cmake/core/CMakeProjectGenerator.java | 8 - .../internal/CMakeBuildConfiguration.java | 76 +++- .../CMakeBuildConfigurationFactory.java | 73 ---- .../cdt/cmake/core/internal/CMakeBuilder.java | 68 ---- .../internal/CMakeLaunchDescriptorType.java | 2 +- .../internal/CMakeScannerInfoProvider.java | 43 --- core/org.eclipse.cdt.core/plugin.xml | 12 + .../eclipse/cdt/core/ConsoleOutputStream.java | 2 +- .../cdt/core/build/BuildCommandRunner.java | 74 ---- .../cdt/core/build/CBuildConfiguration.java | 334 ++++++++++++++++-- .../org/eclipse/cdt/core/build/CBuilder.java | 75 ++++ .../cdt/core/build/ICBuildConfiguration.java | 10 + .../build/ICBuildConfigurationManager.java | 2 +- .../build/ICBuildConfigurationProvider.java | 5 +- .../eclipse/cdt/core/build/IToolChain.java | 8 +- .../build/CBuildConfigurationManager.java | 6 +- .../ui/buildconsole/BuildOutputStream.java | 6 +- .../MultiBuildConsoleAdapter.java | 12 + .../cdt/internal/qt/core/QtNature.java | 14 +- .../qt/core/build/QtBuildConfiguration.java | 147 +++++++- .../build/QtBuildConfigurationProvider.java | 42 +-- .../cdt/internal/qt/core/build/QtBuilder.java | 207 ----------- .../qt/core/project/QtProjectGenerator.java | 18 +- .../cdt/qt/core/IQtBuildConfiguration.java | 7 +- .../qt/ui/wizards/HelloWorldWizard.java | 7 - 28 files changed, 726 insertions(+), 628 deletions(-) delete mode 100644 build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationFactory.java delete mode 100644 build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuilder.java delete mode 100644 build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeScannerInfoProvider.java delete mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/BuildCommandRunner.java create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuilder.java delete mode 100644 qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java diff --git a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java index 8d16e94a719..5d7c5211fc3 100644 --- a/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java +++ b/build/org.eclipse.cdt.build.gcc.core/src/org/eclipse/cdt/build/gcc/core/GCCToolChain.java @@ -11,9 +11,12 @@ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,6 +34,7 @@ import org.eclipse.cdt.core.parser.IExtendedScannerInfo; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Platform; @@ -47,6 +51,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain { private final IToolChainType type; private final String name; + private final String command; private String version; private String target; private Path path; @@ -55,6 +60,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain { public GCCToolChain(IToolChainType type, Path path, String command) { this.type = type; + this.command = command; getVersion(path.resolve(command).toString()); this.name = command + '-' + version; this.path = path; @@ -64,9 +70,10 @@ public class GCCToolChain extends PlatformObject implements IToolChain { envVars = new IEnvironmentVariable[] { pathVar }; } - protected GCCToolChain(IToolChainType type, String name) { + protected GCCToolChain(IToolChainType type, String name, String command) { this.type = type; this.name = name; + this.command = command; // TODO need to pull the other info out of preferences } @@ -119,6 +126,10 @@ public class GCCToolChain extends PlatformObject implements IToolChain { } } + public String getTarget() { + return target; + } + protected void addDiscoveryOptions(List command) { command.add("-E"); //$NON-NLS-1$ command.add("-P"); //$NON-NLS-1$ @@ -127,9 +138,11 @@ public class GCCToolChain extends PlatformObject implements IToolChain { } @Override - public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, List args, - List includePaths, IResource resource, Path buildDirectory) { + public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, String[] args, + IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) { try { + Path buildDirectory = Paths.get(buildDirectoryURI); + List commandLine = new ArrayList<>(); if (command.isAbsolute()) { commandLine.add(command.toString()); @@ -137,12 +150,14 @@ public class GCCToolChain extends PlatformObject implements IToolChain { commandLine.add(path.resolve(command).toString()); } - for (String includePath : includePaths) { - commandLine.add("-I" + includePath); //$NON-NLS-1$ + if (baseScannerInfo != null && baseScannerInfo.getIncludePaths() != null) { + for (String includePath : baseScannerInfo.getIncludePaths()) { + commandLine.add("-I" + includePath); //$NON-NLS-1$ + } } addDiscoveryOptions(commandLine); - commandLine.addAll(args); + commandLine.addAll(Arrays.asList(args)); // Change output to stdout for (int i = 0; i < commandLine.size() - 1; ++i) { @@ -259,5 +274,42 @@ public class GCCToolChain extends PlatformObject implements IToolChain { public Path getCommandPath(String command) { return path.resolve(command); } - + + @Override + public IResource[] getResourcesFromCommand(String[] cmd, URI buildDirectoryURI) { + // Make sure this is our command + boolean found = false; + for (String arg : cmd) { + if (arg.startsWith("-")) { //$NON-NLS-1$ + break; + } + Path cmdPath = Paths.get(arg); + if (cmdPath.getFileName().toString().equals(command)) { + found = true; + break; + } + } + + if (!found) { + // not our command + return null; + } + + // Start at the back looking for arguments + List resources = new ArrayList<>(); + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + for (int i = cmd.length - 1; i >= 0; --i) { + String arg = cmd[i]; + if (arg.startsWith("-")) { //$NON-NLS-1$ + // ran into an option, we're done. + break; + } + for (IFile resource : root.findFilesForLocationURI(buildDirectoryURI.resolve(arg))) { + resources.add(resource); + } + } + + return resources.toArray(new IResource[resources.size()]); + } + } diff --git a/build/org.eclipse.cdt.cmake.core/plugin.xml b/build/org.eclipse.cdt.cmake.core/plugin.xml index 335c10f58e6..7b159d8230e 100644 --- a/build/org.eclipse.cdt.cmake.core/plugin.xml +++ b/build/org.eclipse.cdt.cmake.core/plugin.xml @@ -68,16 +68,6 @@ public="true"> - - - - - - args, IConsole console, IProgressMonitor monitor) + throws CoreException { + IProject project = getProject(); + try { + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + + ConsoleOutputStream outStream = console.getOutputStream(); + + Path buildDir = getBuildDirectory(); + + if (!Files.exists(buildDir.resolve("Makefile"))) { //$NON-NLS-1$ + // TODO assuming cmake is in the path here, probably need a + // preference in case it isn't. + List command = Arrays.asList("cmake", //$NON-NLS-1$ + "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath()); + ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); + Process process = processBuilder.start(); + outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ + watchProcess(process, new IConsoleParser[0], console); + } + + // TODO need to figure out which builder to call. Hardcoding to make + // for now. + List command = Arrays.asList("make"); + ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); // $NON-NLS-1$ + Process process = processBuilder.start(); + outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ + + // TODO error parsers + watchProcess(process, new IConsoleParser[0], console); + + project.refreshLocal(IResource.DEPTH_INFINITE, monitor); + return new IProject[] { project }; + } catch (IOException e) { + throw new CoreException(Activator.errorStatus("Building " + project.getName(), e)); + } + } + + @Override + public void clean(IConsole console, IProgressMonitor monitor) throws CoreException { + // TODO Auto-generated method stub + + } + + @Override + public IScannerInfo getScannerInformation(IResource resource) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationFactory.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationFactory.java deleted file mode 100644 index 8a1e35eeda9..00000000000 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuildConfigurationFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cmake.core.internal; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.cdt.core.build.IToolChain; -import org.eclipse.cdt.core.build.IToolChainManager; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.runtime.IAdapterFactory; -import org.eclipse.core.runtime.Platform; - -public class CMakeBuildConfigurationFactory implements IAdapterFactory { - - private static IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); - private static Map cache = new HashMap<>(); - - @Override - public Class[] getAdapterList() { - return new Class[] { CMakeBuildConfiguration.class }; - } - - @SuppressWarnings("unchecked") - @Override - public T getAdapter(Object adaptableObject, Class adapterType) { - if (adapterType.equals(CMakeBuildConfiguration.class) && adaptableObject instanceof IBuildConfiguration) { - IBuildConfiguration config = (IBuildConfiguration) adaptableObject; - synchronized (cache) { - CMakeBuildConfiguration cmakeConfig = cache.get(config); - if (cmakeConfig == null) { - if (!config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - cmakeConfig = new CMakeBuildConfiguration(config); - cache.put(config, cmakeConfig); - return (T) cmakeConfig; - } else { - // Default to local toolchain - Map properties = new HashMap<>(); - properties.put(IToolChain.ATTR_OS, Platform.getOS()); - properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch()); - Collection toolChains = toolChainManager.getToolChainsMatching(properties); - if (!toolChains.isEmpty()) { - // TODO propery handle when we have more than one - cmakeConfig = new CMakeBuildConfiguration(config, toolChains.iterator().next()); - cache.put(config, cmakeConfig); - return (T) cmakeConfig; - } - - // Use the first toolchain we can find - toolChains = toolChainManager.getToolChainsMatching(new HashMap<>()); - if (!toolChains.isEmpty()) { - // TODO propery handle when we have more - // than one - cmakeConfig = new CMakeBuildConfiguration(config, toolChains.iterator().next()); - cache.put(config, cmakeConfig); - return (T) cmakeConfig; - } - } - } else { - return (T) cmakeConfig; - } - } - } - return null; - } - -} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuilder.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuilder.java deleted file mode 100644 index 3be278e5dfa..00000000000 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeBuilder.java +++ /dev/null @@ -1,68 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cmake.core.internal; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.ConsoleOutputStream; -import org.eclipse.cdt.core.resources.IConsole; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; - -public class CMakeBuilder extends IncrementalProjectBuilder { - - public static final String ID = Activator.getId() + ".cmakeBuilder"; //$NON-NLS-1$ - - @Override - protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { - IProject project = getProject(); - try { - IConsole console = CCorePlugin.getDefault().getConsole(); - ConsoleOutputStream outStream = console.getOutputStream(); - - CMakeBuildConfiguration cmakeConfig = project.getActiveBuildConfig() - .getAdapter(CMakeBuildConfiguration.class); - Path buildDir = cmakeConfig.getBuildDirectory(); - - if (!Files.exists(buildDir.resolve("Makefile"))) { //$NON-NLS-1$ - // TODO assuming cmake is in the path here, probably need a - // preference in case it isn't. - List command = Arrays.asList("cmake", //$NON-NLS-1$ - "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON", new File(project.getLocationURI()).getAbsolutePath()); - ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); - Process process = processBuilder.start(); - outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ - //console.monitor(process, null, buildDir); - } - - // TODO need to figure out which builder to call. Hardcoding to make - // for now. - List command = Arrays.asList("make"); - ProcessBuilder processBuilder = new ProcessBuilder(command).directory(buildDir.toFile()); // $NON-NLS-1$ - Process process = processBuilder.start(); - outStream.write(String.join(" ", command) + '\n'); //$NON-NLS-1$ - //console.monitor(process, null, buildDir); - - project.refreshLocal(IResource.DEPTH_INFINITE, monitor); - return new IProject[] { project }; - } catch (IOException e) { - throw new CoreException(Activator.errorStatus("Building " + project.getName(), e)); - } - } - -} diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchDescriptorType.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchDescriptorType.java index 4a66f37d933..944084338af 100644 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchDescriptorType.java +++ b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeLaunchDescriptorType.java @@ -24,7 +24,7 @@ public class CMakeLaunchDescriptorType implements ILaunchDescriptorType { public ILaunchDescriptor getDescriptor(Object launchObject) throws CoreException { if (launchObject instanceof IProject) { IProject project = (IProject) launchObject; - if (CMakeNature.hasNature(project)) { + if (project.hasNature(CMakeNature.ID)) { CMakeLaunchDescriptor desc = descriptors.get(project); if (desc == null) { desc = new CMakeLaunchDescriptor(this, project); diff --git a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeScannerInfoProvider.java b/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeScannerInfoProvider.java deleted file mode 100644 index c5fd8d26d78..00000000000 --- a/build/org.eclipse.cdt.cmake.core/src/org/eclipse/cdt/cmake/core/internal/CMakeScannerInfoProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 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.cmake.core.internal; - -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; -import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; - -public class CMakeScannerInfoProvider implements IScannerInfoProvider { - - @Override - public IScannerInfo getScannerInformation(IResource resource) { - try { - IProject project = resource.getProject(); - IBuildConfiguration config = project.getActiveBuildConfig(); - CMakeBuildConfiguration cmakeConfig = config.getAdapter(CMakeBuildConfiguration.class); - if (cmakeConfig != null) { - return null; // TODO obviously - } - } catch (CoreException e) { - Activator.log(e); - } - return null; - } - - @Override - public void subscribe(IResource resource, IScannerInfoChangeListener listener) { - } - - @Override - public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { - } - -} diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index b8fe65b7b5e..7591899e132 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -869,5 +869,17 @@ + + + + + + diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ConsoleOutputStream.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ConsoleOutputStream.java index 134ba158fb4..bdff4c0d36d 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ConsoleOutputStream.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ConsoleOutputStream.java @@ -40,7 +40,7 @@ public class ConsoleOutputStream extends OutputStream { ascii[0] = (byte) c; fBuffer.append(new String(ascii)); } - + @Override public synchronized void write(byte[] b, int off, int len) throws IOException { fBuffer.append(new String(b, off, len)); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/BuildCommandRunner.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/BuildCommandRunner.java deleted file mode 100644 index 3a020303078..00000000000 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/BuildCommandRunner.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 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.core.build; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.ErrorParserManager; -import org.eclipse.cdt.core.resources.IConsole; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.CoreException; - -/** - * Utility to process the output of a build command, feeding it to an error - * parser monitor and then off to the build console. - * - * @since 6.0 - */ -public class BuildCommandRunner { - - private final IProject project; - private final IConsole console; - private final ErrorParserManager epm; - - public BuildCommandRunner(IProject project, IConsole console, ErrorParserManager epm) { - this.project = project; - this.console = console; - this.epm = epm; - } - - public int monitor(Process process) throws CoreException { - console.start(project); - epm.setOutputStream(console.getOutputStream()); - new ReaderThread(process.getInputStream()).start(); - new ReaderThread(process.getErrorStream()).start(); - - try { - return process.waitFor(); - } catch (InterruptedException e) { - return -1; - } - } - - private class ReaderThread extends Thread { - private final BufferedReader in; - - public ReaderThread(InputStream in) { - this.in = new BufferedReader(new InputStreamReader(in)); - } - - @Override - public void run() { - try { - for (String line = in.readLine(); line != null; line = in.readLine()) { - // Synchronize to avoid interleaving of lines - synchronized (BuildCommandRunner.this) { - epm.processLine(line); - } - } - } catch (IOException e) { - CCorePlugin.log(e); - } - } - } - -} 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 ce5f1c3b9b5..376d3d7e0b1 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 @@ -7,19 +7,48 @@ *******************************************************************************/ package org.eclipse.cdt.core.build; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.net.URI; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.IConsoleParser; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.core.ProblemMarkerInfo; +import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.osgi.util.NLS; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; @@ -28,8 +57,10 @@ import org.osgi.service.prefs.Preferences; * settings for subclasses. * * @since 6.0 + * @noextend This class is provisional and should be subclassed with caution. */ -public abstract class CBuildConfiguration extends PlatformObject { +public abstract class CBuildConfiguration extends PlatformObject + implements ICBuildConfiguration, IMarkerGenerator, IConsoleParser { private static final String TOOLCHAIN_TYPE = "cdt.toolChain.type"; //$NON-NLS-1$ private static final String TOOLCHAIN_NAME = "cdt.toolChain.name"; //$NON-NLS-1$ @@ -38,14 +69,9 @@ public abstract class CBuildConfiguration extends PlatformObject { private final IBuildConfiguration config; private final IToolChain toolChain; - protected CBuildConfiguration(IBuildConfiguration config) { + protected CBuildConfiguration(IBuildConfiguration config, String name) { this.config = config; - String[] split = config.getName().split("/"); - if (split.length == 2) { - name = split[1]; - } else { - name = config.getName(); - } + this.name = name; // Load toolchain from prefs Preferences settings = getSettings(); @@ -53,20 +79,15 @@ public abstract class CBuildConfiguration extends PlatformObject { String id = settings.get(TOOLCHAIN_NAME, ""); //$NON-NLS-1$ IToolChainManager toolChainManager = CCorePlugin.getService(IToolChainManager.class); toolChain = !id.isEmpty() ? toolChainManager.getToolChain(typeId, id) : null; - + if (toolChain == null) { CCorePlugin.log(String.format("Toolchain missing for config: %s", config.getName())); } } - protected CBuildConfiguration(IBuildConfiguration config, IToolChain toolChain) { + protected CBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) { this.config = config; - String[] split = config.getName().split("/"); - if (split.length == 2) { - name = split[1]; - } else { - name = config.getName(); - } + this.name = name; this.toolChain = toolChain; Preferences settings = getSettings(); @@ -79,6 +100,7 @@ public abstract class CBuildConfiguration extends PlatformObject { } } + @Override public IBuildConfiguration getBuildConfiguration() { return config; } @@ -91,28 +113,31 @@ public abstract class CBuildConfiguration extends PlatformObject { return config.getProject(); } - public IFolder getBuildFolder() { - try { - // TODO should really be passing a monitor in here or create this in - // a better spot. should also throw the core exception - // TODO make the name of this folder a project property - IFolder buildRootFolder = getProject().getFolder("build"); //$NON-NLS-1$ - if (!buildRootFolder.exists()) { - buildRootFolder.create(IResource.FORCE | IResource.DERIVED, true, new NullProgressMonitor()); - } - IFolder buildFolder = buildRootFolder.getFolder(name); - if (!buildFolder.exists()) { - buildFolder.create(true, true, new NullProgressMonitor()); - } - return buildFolder; - } catch (CoreException e) { - CCorePlugin.log(e); + public IContainer getBuildContainer() throws CoreException { + // TODO should really be passing a monitor in here or create this in + // a better spot. should also throw the core exception + // TODO make the name of this folder a project property + IFolder buildRootFolder = getProject().getFolder("build"); //$NON-NLS-1$ + if (!buildRootFolder.exists()) { + buildRootFolder.create(IResource.FORCE | IResource.DERIVED, true, new NullProgressMonitor()); } - return null; + IFolder buildFolder = buildRootFolder.getFolder(name); + if (!buildFolder.exists()) { + buildFolder.create(true, true, new NullProgressMonitor()); + } + return buildFolder; } - public Path getBuildDirectory() { - return getBuildFolder().getLocation().toFile().toPath(); + public URI getBuildDirectoryURI() throws CoreException { + return getBuildContainer().getLocationURI(); + } + + public Path getBuildDirectory() throws CoreException { + return Paths.get(getBuildDirectoryURI()); + } + + protected void setBuildEnvironment(Map env) { + CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(env, config, true); } public void setActive(IProgressMonitor monitor) throws CoreException { @@ -132,8 +157,247 @@ public abstract class CBuildConfiguration extends PlatformObject { .node(getProject().getName()).node(config.getName()); } + @Override public IToolChain getToolChain() { return toolChain; } + @Override + public IEnvironmentVariable getVariable(String name) { + // By default, none + return null; + } + + @Override + public IEnvironmentVariable[] getVariables() { + // by default, none + return null; + } + + @Override + public void addMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) { + addMarker(new ProblemMarkerInfo(file, lineNumber, errorDesc, severity, errorVar, null)); + } + + @Override + public void addMarker(ProblemMarkerInfo problemMarkerInfo) { + try { + IProject project = config.getProject(); + IResource markerResource = problemMarkerInfo.file; + if (markerResource == null) { + markerResource = project; + } + String externalLocation = null; + if (problemMarkerInfo.externalPath != null && !problemMarkerInfo.externalPath.isEmpty()) { + externalLocation = problemMarkerInfo.externalPath.toOSString(); + } + + // Try to find matching markers and don't put in duplicates + IMarker[] markers = markerResource.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, + IResource.DEPTH_ONE); + for (IMarker m : markers) { + int line = m.getAttribute(IMarker.LINE_NUMBER, -1); + int sev = m.getAttribute(IMarker.SEVERITY, -1); + String msg = (String) m.getAttribute(IMarker.MESSAGE); + if (line == problemMarkerInfo.lineNumber + && sev == mapMarkerSeverity(problemMarkerInfo.severity) + && msg.equals(problemMarkerInfo.description)) { + String extloc = (String) m.getAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION); + if (extloc == externalLocation || (extloc != null && extloc.equals(externalLocation))) { + if (project == null || project.equals(markerResource.getProject())) { + return; + } + String source = (String) m.getAttribute(IMarker.SOURCE_ID); + if (project.getName().equals(source)) { + return; + } + } + } + } + + String type = problemMarkerInfo.getType(); + if (type == null) { + type = ICModelMarker.C_MODEL_PROBLEM_MARKER; + } + + IMarker marker = markerResource.createMarker(type); + marker.setAttribute(IMarker.MESSAGE, problemMarkerInfo.description); + marker.setAttribute(IMarker.SEVERITY, mapMarkerSeverity(problemMarkerInfo.severity)); + marker.setAttribute(IMarker.LINE_NUMBER, problemMarkerInfo.lineNumber); + marker.setAttribute(IMarker.CHAR_START, problemMarkerInfo.startChar); + marker.setAttribute(IMarker.CHAR_END, problemMarkerInfo.endChar); + if (problemMarkerInfo.variableName != null) { + marker.setAttribute(ICModelMarker.C_MODEL_MARKER_VARIABLE, problemMarkerInfo.variableName); + } + if (externalLocation != null) { + URI uri = URIUtil.toURI(externalLocation); + if (uri.getScheme() != null) { + marker.setAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION, externalLocation); + String locationText = NLS.bind( + CCorePlugin.getResourceString("ACBuilder.ProblemsView.Location"), //$NON-NLS-1$ + problemMarkerInfo.lineNumber, externalLocation); + marker.setAttribute(IMarker.LOCATION, locationText); + } + } else if (problemMarkerInfo.lineNumber == 0) { + marker.setAttribute(IMarker.LOCATION, " "); //$NON-NLS-1$ + } + // Set source attribute only if the marker is being set to a file + // from different project + if (project != null && !project.equals(markerResource.getProject())) { + marker.setAttribute(IMarker.SOURCE_ID, project.getName()); + } + + // Add all other client defined attributes. + Map attributes = problemMarkerInfo.getAttributes(); + if (attributes != null) { + for (Entry entry : attributes.entrySet()) { + marker.setAttribute(entry.getKey(), entry.getValue()); + } + } + } catch (CoreException e) { + CCorePlugin.log(e.getStatus()); + } + } + + private int mapMarkerSeverity(int severity) { + switch (severity) { + case SEVERITY_ERROR_BUILD: + case SEVERITY_ERROR_RESOURCE: + return IMarker.SEVERITY_ERROR; + case SEVERITY_INFO: + return IMarker.SEVERITY_INFO; + case SEVERITY_WARNING: + return IMarker.SEVERITY_WARNING; + } + return IMarker.SEVERITY_ERROR; + } + + protected Path findCommand(String command) { + if (Platform.getOS().equals(Platform.OS_WIN32) && !command.endsWith(".exe")) { //$NON-NLS-1$ + command += ".exe"; //$NON-NLS-1$ + } + + Path cmdPath = Paths.get(command); + if (cmdPath.isAbsolute()) { + return cmdPath; + } + + Map env = new HashMap<>(System.getenv()); + setBuildEnvironment(env); + + String[] path = env.get("PATH").split(File.pathSeparator); //$NON-NLS-1$ + for (String dir : path) { + Path commandPath = Paths.get(dir, command); + if (Files.exists(commandPath)) { + return commandPath; + } + } + return null; + } + + protected int watchProcess(Process process, IConsoleParser[] consoleParsers, IConsole console) + throws CoreException { + new ReaderThread(process.getInputStream(), consoleParsers, console.getOutputStream()).start(); + new ReaderThread(process.getErrorStream(), consoleParsers, console.getErrorStream()).start(); + try { + return process.waitFor(); + } catch (InterruptedException e) { + CCorePlugin.log(e); + return -1; + } + } + + private static class ReaderThread extends Thread { + + private final BufferedReader in; + private final PrintStream out; + private final IConsoleParser[] consoleParsers; + + public ReaderThread(InputStream in, IConsoleParser[] consoleParsers, OutputStream out) { + this.in = new BufferedReader(new InputStreamReader(in)); + this.consoleParsers = consoleParsers; + this.out = new PrintStream(out); + } + + @Override + public void run() { + try { + for (String line = in.readLine(); line != null; line = in.readLine()) { + for (IConsoleParser consoleParser : consoleParsers) { + // Synchronize to avoid interleaving of lines + synchronized (consoleParser) { + consoleParser.processLine(line); + } + } + out.println(line); + } + } catch (IOException e) { + CCorePlugin.log(e); + } + } + + } + + private Map cheaterInfo; + private boolean infoChanged = false; + + private void initScannerInfo() { + if (cheaterInfo == null) { + cheaterInfo = new HashMap<>(); + } + } + + @Override + public IScannerInfo getScannerInformation(IResource resource) { + initScannerInfo(); + return cheaterInfo.get(resource); + } + + @Override + public boolean processLine(String line) { + // TODO smarter line parsing to deal with quoted arguments + String[] command = line.split("\\s+"); //$NON-NLS-1$ + + try { + IResource[] resources = getToolChain().getResourcesFromCommand(command, getBuildDirectoryURI()); + if (resources != null) { + for (IResource resource : resources) { + initScannerInfo(); + cheaterInfo.put(resource, + getToolChain().getScannerInfo(getBuildConfiguration(), findCommand(command[0]), + Arrays.copyOfRange(command, 1, command.length), null, resource, + getBuildDirectoryURI())); + infoChanged = true; + } + return true; + } else { + return false; + } + } catch (CoreException e) { + CCorePlugin.log(e); + return false; + } + } + + @Override + public void shutdown() { + // TODO persist changes + + // Trigger a reindex if anything changed + if (infoChanged) { + CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(getProject())); + infoChanged = false; + } + } + + @Override + public void subscribe(IResource resource, IScannerInfoChangeListener listener) { + // TODO for IScannerInfoProvider + } + + @Override + public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { + // TODO for IScannerInfoProvider + } + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuilder.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuilder.java new file mode 100644 index 00000000000..47f2eef8f5a --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/CBuilder.java @@ -0,0 +1,75 @@ +package org.eclipse.cdt.core.build; + +import java.io.IOException; +import java.util.Map; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.resources.IConsole; +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +/** + * @since 6.0 + */ +public class CBuilder extends IncrementalProjectBuilder { + + private static final String ID = CCorePlugin.PLUGIN_ID + ".cBuilder"; //$NON-NLS-1$ + + public static void setupBuilder(ICommand command) { + command.setBuilderName(CBuilder.ID); + command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false); + } + + @Override + protected IProject[] build(int kind, Map args, IProgressMonitor monitor) + throws CoreException { + try { + IProject project = getProject(); + + // Set up console + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(project); + + // Get the build configuration + ICBuildConfiguration config = getBuildConfig().getAdapter(ICBuildConfiguration.class); + if (config == null) { + console.getErrorStream().write("Build not configured correctly\n"); + return null; + } + + return config.build(kind, args, console, monitor); + } catch (IOException e) { + throw new CoreException( + new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Exception while building", e)); + } + } + + @Override + protected void clean(IProgressMonitor monitor) throws CoreException { + try { + IProject project = getProject(); + + // Set up console + IConsole console = CCorePlugin.getDefault().getConsole(); + console.start(project); + + // Get the build configuration + ICBuildConfiguration config = getBuildConfig().getAdapter(ICBuildConfiguration.class); + if (config == null) { + console.getErrorStream().write("Build not configured correctly\n"); + return; + } + + config.clean(console, monitor); + } catch (IOException e) { + throw new CoreException( + new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, "Exception while building", e)); + } + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java index 807bd997a94..0bbeaff2490 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfiguration.java @@ -7,10 +7,16 @@ *******************************************************************************/ package org.eclipse.cdt.core.build; +import java.util.Map; + import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; /** * This is the root interface for "new style" CDT build configurations. Adapting @@ -41,4 +47,8 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider { IEnvironmentVariable[] getVariables(); + IProject[] build(int kind, Map args, IConsole console, IProgressMonitor monitor) throws CoreException; + + void clean(IConsole console, IProgressMonitor monitor) throws CoreException; + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager.java index 181702e300f..6a70b434b05 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationManager.java @@ -54,6 +54,6 @@ public interface ICBuildConfigurationManager { */ ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig); - ICBuildConfiguration getDefaultBuildConfiguration(IProject project); + ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java index 961eb6d8aab..40aa5dde766 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/ICBuildConfigurationProvider.java @@ -9,6 +9,7 @@ package org.eclipse.cdt.core.build; import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; /** * A CBuildConfigurationProvider provides C build configurations. @@ -30,7 +31,7 @@ public interface ICBuildConfigurationProvider { * @param config * @return CDT build configuration for the Platform build configuration */ - ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config); + ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name); /** * Returns a default C build configuration for a given project if any. @@ -38,6 +39,6 @@ public interface ICBuildConfigurationProvider { * @param project * @return default C build configuration for the project */ - ICBuildConfiguration getDefaultCBuildConfiguration(IProject project); + ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java index 93801eae899..6510be961e4 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/IToolChain.java @@ -7,8 +7,8 @@ *******************************************************************************/ package org.eclipse.cdt.core.build; +import java.net.URI; import java.nio.file.Path; -import java.util.List; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.parser.IExtendedScannerInfo; @@ -47,11 +47,13 @@ public interface IToolChain extends IAdaptable { IEnvironmentVariable[] getVariables(); - IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, List args, - List includePaths, IResource resource, Path buildDirectory); + IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, String[] args, + IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI); String[] getErrorParserIds(); Path getCommandPath(String command); + IResource[] getResourcesFromCommand(String[] command, URI buildDirectoryURI); + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java index 5883b49ae4b..94a3dbe9fc8 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/build/CBuildConfigurationManager.java @@ -140,16 +140,18 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager, @Override public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) { + initProviders(); synchronized (configs) { ICBuildConfiguration config = configs.get(buildConfig); if (config == null) { String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$ if (segments.length == 2) { String providerId = segments[0]; + String configName = segments[1]; Provider provider = getProviderDelegate(providerId); if (provider != null && provider.supports(buildConfig.getProject())) { - config = provider.getProvider().getCBuildConfiguration(buildConfig); + config = provider.getProvider().getCBuildConfiguration(buildConfig, configName); configs.put(buildConfig, config); } } @@ -159,7 +161,7 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager, } @Override - public ICBuildConfiguration getDefaultBuildConfiguration(IProject project) { + public ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException { initProviders(); for (Provider provider : providers.values()) { if (provider.supports(project)) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java index 703712d4f06..25bd5cbf64a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/BuildOutputStream.java @@ -59,7 +59,11 @@ public class BuildOutputStream extends ConsoleOutputStream implements IErrorMark @Override public void write(String s, ProblemMarkerInfo marker) throws IOException { fPartitioner.appendToDocument(s, fStream, marker); - } + @Override + public synchronized void write(String msg) throws IOException { + fPartitioner.appendToDocument(msg, fStream, null); + } + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/MultiBuildConsoleAdapter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/MultiBuildConsoleAdapter.java index bfaa62d2058..e2907682f6d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/MultiBuildConsoleAdapter.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/buildconsole/MultiBuildConsoleAdapter.java @@ -56,12 +56,24 @@ class MultiBuildConsoleAdapter implements IConsole { two.write(b, off, len); } + @Override + public synchronized void write(String msg) throws IOException { + one.write(msg); + two.write(msg); + } + @Override public void write(String s, ProblemMarkerInfo marker) throws IOException { one.write(s, marker); two.write(s, marker); } + @Override + public void flush() throws IOException { + one.flush(); + two.flush(); + } + @Override public void close() throws IOException { one.flush(); diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtNature.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtNature.java index e98c3ce8188..03ae8ee323a 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtNature.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/QtNature.java @@ -13,18 +13,17 @@ package org.eclipse.cdt.internal.qt.core; import java.util.Arrays; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.build.CBuilder; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexLinkage; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.internal.core.index.CIndex; import org.eclipse.cdt.internal.core.index.IIndexFragment; -import org.eclipse.cdt.internal.qt.core.build.QtBuilder; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectNature; -import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -59,13 +58,16 @@ public class QtNature implements IProjectNature { } } + public static void setupBuilder(IProjectDescription projDesc) { + ICommand command = projDesc.newCommand(); + CBuilder.setupBuilder(command); + projDesc.setBuildSpec(new ICommand[] { command }); + } + @Override public void configure() throws CoreException { IProjectDescription projDesc = project.getDescription(); - ICommand command = projDesc.newCommand(); - command.setBuilderName(QtBuilder.ID); - command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false); - projDesc.setBuildSpec(new ICommand[] { command }); + setupBuilder(projDesc); project.setDescription(projDesc, new NullProgressMonitor()); } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java index 93722eb532e..2c53c5a1134 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfiguration.java @@ -19,12 +19,18 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.ConsoleOutputStream; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.IConsoleParser; import org.eclipse.cdt.core.build.CBuildConfiguration; import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.cdt.core.build.IToolChain; import org.eclipse.cdt.core.envvar.IEnvironmentVariable; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.parser.ExtendedScannerInfo; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; +import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.qt.core.IQtBuildConfiguration; import org.eclipse.cdt.qt.core.IQtInstall; @@ -34,7 +40,10 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; @@ -47,8 +56,8 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild private final String launchMode; private Map properties; - public QtBuildConfiguration(IBuildConfiguration config) { - super(config); + public QtBuildConfiguration(IBuildConfiguration config, String name) { + super(config, name); Preferences settings = getSettings(); String installName = settings.get(QTINSTALL_NAME, ""); //$NON-NLS-1$ @@ -62,9 +71,10 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild launchMode = settings.get(LAUNCH_MODE, ""); //$NON-NLS-1$ } - QtBuildConfiguration(IBuildConfiguration config, IToolChain toolChain, IQtInstall qtInstall, String launchMode) + QtBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain, IQtInstall qtInstall, + String launchMode) throws CoreException { - super(config, toolChain); + super(config, name, toolChain); this.qtInstall = qtInstall; this.launchMode = launchMode; @@ -122,7 +132,7 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild } @Override - public Path getProgramPath() { + public Path getProgramPath() throws CoreException { String projectName = getProject().getName(); switch (Platform.getOS()) { case Platform.OS_MACOSX: @@ -158,8 +168,10 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild cmd.add(getProjectFile().toString()); try { - ProcessBuilder procBuilder = new ProcessBuilder(cmd).directory(getProjectFile().getParent().toFile()); - Process proc = procBuilder.start(); + ProcessBuilder processBuilder = new ProcessBuilder(cmd) + .directory(getProjectFile().getParent().toFile()); + setBuildEnvironment(processBuilder.environment()); + Process proc = processBuilder.start(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) { properties = new HashMap<>(); for (String line = reader.readLine(); line != null; line = reader.readLine()) { @@ -226,21 +238,128 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild for (int i = 0; i < includePaths.length; ++i) { Path path = Paths.get(includePaths[i]); if (!path.isAbsolute()) { - includePaths[i] = getBuildDirectory().resolve(path).toString(); + try { + includePaths[i] = getBuildDirectory().resolve(path).toString(); + } catch (CoreException e) { + Activator.log(e); + } } } - Path dir = Paths.get(project.getLocationURI()); - return getToolChain().getScannerInfo(getBuildConfiguration(), command, args, Arrays.asList(includePaths), - resource, dir); + IExtendedScannerInfo baseScannerInfo = new ExtendedScannerInfo(null, includePaths); + try { + return getToolChain().getScannerInfo(getBuildConfiguration(), command, + args.toArray(new String[args.size()]), baseScannerInfo, resource, + getBuildContainer().getLocationURI()); + } catch (CoreException e) { + Activator.log(e); + return null; + } } @Override - public void subscribe(IResource resource, IScannerInfoChangeListener listener) { + public IProject[] build(int kind, Map args, IConsole console, IProgressMonitor monitor) + throws CoreException { + IProject project = getProject(); + try { + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + + ConsoleOutputStream errStream = console.getErrorStream(); + ConsoleOutputStream outStream = console.getOutputStream(); + + Path makeCommand = getMakeCommand(); + if (makeCommand == null) { + errStream.write("'make' not found.\n"); + return null; + } + + try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this, + getToolChain().getErrorParserIds())) { + Path buildDir = getBuildDirectory(); + if (!buildDir.resolve("Makefile").toFile().exists()) { //$NON-NLS-1$ + // Need to run qmake + List command = new ArrayList<>(); + command.add(getQmakeCommand().toString()); + + String config = getQmakeConfig(); + if (config != null) { + command.add(config); + } + + IFile projectFile = project.getFile(project.getName() + ".pro"); //$NON-NLS-1$ + command.add(projectFile.getLocation().toOSString()); + + ProcessBuilder processBuilder = new ProcessBuilder(command) + .directory(getBuildDirectory().toFile()); + setBuildEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + + StringBuffer msg = new StringBuffer(); + for (String arg : command) { + msg.append(arg).append(' '); + } + msg.append('\n'); + outStream.write(msg.toString()); + + // TODO qmake error parser + watchProcess(process, new IConsoleParser[0], console); + } + + // run make + ProcessBuilder processBuilder = new ProcessBuilder(makeCommand.toString()).directory(buildDir.toFile()); + setBuildEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + outStream.write(makeCommand.toString() + '\n'); + watchProcess(process, new IConsoleParser[] { epm }, console); + } + + getProject().refreshLocal(IResource.DEPTH_INFINITE, monitor); + return new IProject[] { project }; + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Building " + project.getName(), e)); //$NON-NLS-1$ + } } @Override - public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { + public void clean(IConsole console, IProgressMonitor monitor) throws CoreException { + IProject project = getProject(); + try { + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); + + ConsoleOutputStream errStream = console.getErrorStream(); + ConsoleOutputStream outStream = console.getOutputStream(); + + Path makeCommand = getMakeCommand(); + if (makeCommand == null) { + errStream.write("'make' not found.\n"); + return; + } + + Path buildDir = getBuildDirectory(); + + try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this, + getToolChain().getErrorParserIds())) { + // run make + ProcessBuilder processBuilder = new ProcessBuilder(makeCommand.toString(), "clean") //$NON-NLS-1$ + .directory(buildDir.toFile()); + setBuildEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + outStream.write(makeCommand.toString() + "clean\n"); //$NON-NLS-1$ + watchProcess(process, new IConsoleParser[] { epm }, console); + } + + project.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Cleaning " + project.getName(), e)); //$NON-NLS-1$ + } + } + + public Path getMakeCommand() { + Path makeCommand = findCommand("make"); //$NON-NLS-1$ + if (makeCommand == null) { + makeCommand = findCommand("mingw32-make"); //$NON-NLS-1$ + } + return makeCommand; } } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java index f0bbed84e37..f97e3efcb6e 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuildConfigurationProvider.java @@ -26,7 +26,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; -import org.eclipse.launchbar.core.target.ILaunchTarget; public class QtBuildConfigurationProvider implements ICBuildConfigurationProvider { @@ -42,18 +41,14 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide } @Override - public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config) { + public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) { try { // Double check to make sure this config is ours - if (!config.getName().startsWith(getId() + '/')) { - return null; - } - if (!config.getProject().hasNature(QtNature.ID)) { return null; } - return new QtBuildConfiguration(config); + return new QtBuildConfiguration(config, name); } catch (CoreException e) { Activator.log(e); } @@ -120,7 +115,7 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide String configName = "qt." + qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ //$NON-NLS-2$ IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, monitor); - QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, toolChain, qtInstall, + QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, configName, toolChain, qtInstall, launchMode); configManager.addBuildConfiguration(config, qtConfig); return qtConfig; @@ -130,35 +125,4 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide return null; } - public QtBuildConfiguration createConfiguration(IProject project, ILaunchTarget target, String launchMode, - IProgressMonitor monitor) throws CoreException { - // Find the toolchains - Map properties = new HashMap<>(); - String os = target.getAttribute(ILaunchTarget.ATTR_OS, null); - if (os != null) { - properties.put(IToolChain.ATTR_OS, os); - } - String arch = target.getAttribute(ILaunchTarget.ATTR_ARCH, null); - if (arch != null) { - properties.put(IToolChain.ATTR_ARCH, arch); - } - - for (IToolChain toolChain : toolChainManager.getToolChainsMatching(properties)) { - for (IQtInstall qtInstall : qtInstallManager.getInstalls()) { - if (qtInstallManager.supports(qtInstall, toolChain)) { - // TODO what if multiple matches - String configName = "qt." + qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ //$NON-NLS-2$ - IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, - monitor); - QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, toolChain, qtInstall, - launchMode); - configManager.addBuildConfiguration(config, qtConfig); - return qtConfig; - } - } - } - - return null; - } - } diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java deleted file mode 100644 index b5a21c515f1..00000000000 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/build/QtBuilder.java +++ /dev/null @@ -1,207 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015, 2016 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.internal.qt.core.build; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.ConsoleOutputStream; -import org.eclipse.cdt.core.ErrorParserManager; -import org.eclipse.cdt.core.build.BuildCommandRunner; -import org.eclipse.cdt.core.build.ICBuildConfiguration; -import org.eclipse.cdt.core.model.ICModelMarker; -import org.eclipse.cdt.core.resources.ACBuilder; -import org.eclipse.cdt.core.resources.IConsole; -import org.eclipse.cdt.internal.qt.core.Activator; -import org.eclipse.cdt.internal.qt.core.Messages; -import org.eclipse.cdt.qt.core.IQtBuildConfiguration; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; - -public class QtBuilder extends ACBuilder { - - public static final String ID = Activator.ID + ".qtBuilder"; //$NON-NLS-1$ - - @Override - protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException { - IProject project = getProject(); - try { - project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); - - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(project); - ConsoleOutputStream errStream = console.getErrorStream(); - ConsoleOutputStream outStream = console.getOutputStream(); - - ICBuildConfiguration cconfig = getBuildConfig().getAdapter(ICBuildConfiguration.class); - IQtBuildConfiguration qtConfig = cconfig.getAdapter(QtBuildConfiguration.class); - if (qtConfig == null) { - // Qt hasn't been configured yet print a message and bale - errStream.write(Messages.QtBuilder_0); - return null; - } - - Path makeCommand = getMakeCommand(getBuildConfig()); - if (makeCommand == null) { - errStream.write("'make' not found.\n"); - return null; - } - - try (ErrorParserManager epm = new ErrorParserManager(project, qtConfig.getBuildDirectory().toUri(), this, - qtConfig.getToolChain().getErrorParserIds())) { - BuildCommandRunner runner = new BuildCommandRunner(project, console, epm); - - Path buildDir = qtConfig.getBuildDirectory(); - if (!buildDir.resolve("Makefile").toFile().exists()) { //$NON-NLS-1$ - // Need to run qmake - List command = new ArrayList<>(); - command.add(qtConfig.getQmakeCommand().toString()); - - String config = qtConfig.getQmakeConfig(); - if (config != null) { - command.add(config); - } - - IFile projectFile = qtConfig.getBuildConfiguration().getProject() - .getFile(project.getName() + ".pro"); //$NON-NLS-1$ - command.add(projectFile.getLocation().toOSString()); - - ProcessBuilder processBuilder = new ProcessBuilder(command) - .directory(qtConfig.getBuildDirectory().toFile()); - CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(processBuilder.environment(), - getBuildConfig(), true); - Process process = processBuilder.start(); - - StringBuilder msg = new StringBuilder(); - for (String arg : command) { - msg.append(arg).append(' '); - } - msg.append('\n'); - outStream.write(msg.toString()); - - runner.monitor(process); - } - - // run make - ProcessBuilder procBuilder = new ProcessBuilder(makeCommand.toString()).directory(buildDir.toFile()); - CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(procBuilder.environment(), - getBuildConfig(), true); - Process process = procBuilder.start(); - outStream.write(makeCommand.toString() + '\n'); - runner.monitor(process); - } - - project.refreshLocal(IResource.DEPTH_INFINITE, monitor); - - // clear the scanner info cache - // TODO be more surgical about what to clear based on what was - // built. - // qtConfig.clearScannerInfoCache(); - - outStream.write("Complete.\n"); - return new IProject[] { project }; - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Building " + project.getName(), e)); //$NON-NLS-1$ - } - } - - @Override - protected void clean(IProgressMonitor monitor) throws CoreException { - IProject project = getProject(); - try { - project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE); - - IConsole console = CCorePlugin.getDefault().getConsole(); - console.start(getProject()); - ConsoleOutputStream errStream = console.getErrorStream(); - ConsoleOutputStream outStream = console.getOutputStream(); - - ICBuildConfiguration cconfig = getBuildConfig().getAdapter(ICBuildConfiguration.class); - IQtBuildConfiguration qtConfig = cconfig.getAdapter(QtBuildConfiguration.class); - if (qtConfig == null) { - // Qt hasn't been configured yet print a message and bale - errStream.write(Messages.QtBuilder_0); - return; - } - - Path makeCommand = getMakeCommand(getBuildConfig()); - if (makeCommand == null) { - errStream.write("'make' not found.\n"); - return; - } - - Path buildDir = qtConfig.getBuildDirectory(); - - try (ErrorParserManager epm = new ErrorParserManager(project, qtConfig.getBuildDirectory().toUri(), this, - qtConfig.getToolChain().getErrorParserIds())) { - BuildCommandRunner runner = new BuildCommandRunner(project, console, epm); - // run make - ProcessBuilder procBuilder = new ProcessBuilder(makeCommand.toString(), "clean") //$NON-NLS-1$ - .directory(buildDir.toFile()); - CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(procBuilder.environment(), - getBuildConfig(), true); - Process process = procBuilder.start(); - outStream.write(makeCommand.toString() + "clean\n"); //$NON-NLS-1$ - runner.monitor(process); - } - - project.refreshLocal(IResource.DEPTH_INFINITE, monitor); - - // clear the scanner info cache - // TODO be more surgical about what to clear based on what was - // built. - // qtConfig.clearScannerInfoCache(); - - outStream.write("Complete.\n"); - // TODO Auto-generated method stub - super.clean(monitor); - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.ID, "Cleaning " + project.getName(), e)); //$NON-NLS-1$ - } - } - - public Path getMakeCommand(IBuildConfiguration config) { - Path makeCommand = findCommand(getBuildConfig(), "make"); //$NON-NLS-1$ - if (makeCommand == null) { - makeCommand = findCommand(getBuildConfig(), "mingw32-make"); //$NON-NLS-1$ - } - return makeCommand; - } - - public Path findCommand(IBuildConfiguration config, String command) { - if (Platform.getOS().equals(Platform.OS_WIN32)) { - command += ".exe"; //$NON-NLS-1$ - } - Map env = new HashMap<>(System.getenv()); - CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(env, config, true); - String[] path = env.get("PATH").split(File.pathSeparator); //$NON-NLS-1$ - for (String dir : path) { - Path commandPath = Paths.get(dir, command); - if (Files.exists(commandPath)) { - return commandPath; - } - } - return null; - } - -} diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/project/QtProjectGenerator.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/project/QtProjectGenerator.java index 2cbd95f69bb..ac870cc917a 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/project/QtProjectGenerator.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/internal/qt/core/project/QtProjectGenerator.java @@ -17,35 +17,31 @@ import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.internal.qt.core.Activator; import org.eclipse.cdt.internal.qt.core.QtNature; -import org.eclipse.cdt.internal.qt.core.build.QtBuilder; -import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.tools.templates.freemarker.FMProjectGenerator; import org.eclipse.tools.templates.freemarker.SourceRoot; +import org.osgi.framework.Bundle; public class QtProjectGenerator extends FMProjectGenerator { @Override protected void initProjectDescription(IProjectDescription description) { - // Natures description .setNatureIds(new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, QtNature.ID }); - - // Builders - ICommand command = description.newCommand(); - command.setBuilderName(QtBuilder.ID); - command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false); - description.setBuildSpec(new ICommand[] { command }); + QtNature.setupBuilder(description); } + @Override + public Bundle getSourceBundle() { + return Activator.getDefault().getBundle(); + } + @Override public void generate(Map model, IProgressMonitor monitor) throws CoreException { - setBundle(Activator.getDefault().getBundle()); super.generate(model, monitor); // Create the sourcefolders diff --git a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java index 08abf17b83f..1e8dcf10e73 100644 --- a/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java +++ b/qt/org.eclipse.cdt.qt.core/src/org/eclipse/cdt/qt/core/IQtBuildConfiguration.java @@ -10,16 +10,17 @@ package org.eclipse.cdt.qt.core; import java.nio.file.Path; import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.core.runtime.CoreException; public interface IQtBuildConfiguration extends ICBuildConfiguration { - Path getBuildDirectory(); - + Path getBuildDirectory() throws CoreException; + Path getQmakeCommand(); String getQmakeConfig(); - Path getProgramPath(); + Path getProgramPath() throws CoreException; String getLaunchMode(); diff --git a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/wizards/HelloWorldWizard.java b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/wizards/HelloWorldWizard.java index 2a0297d9351..8b3f2a23dec 100644 --- a/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/wizards/HelloWorldWizard.java +++ b/qt/org.eclipse.cdt.qt.ui/src/org/eclipse/cdt/internal/qt/ui/wizards/HelloWorldWizard.java @@ -17,9 +17,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.IWorkbench; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; @@ -80,9 +78,4 @@ public class HelloWorldWizard extends BasicNewResourceWizard { return true; } - @Override - public void init(IWorkbench theWorkbench, IStructuredSelection currentSelection) { - super.init(theWorkbench, currentSelection); - } - }