mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12:10 +02:00
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
This commit is contained in:
parent
903eb7ed3a
commit
7043af66fb
28 changed files with 726 additions and 628 deletions
|
@ -11,9 +11,12 @@ import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.IBuildConfiguration;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
@ -47,6 +51,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
|
|
||||||
private final IToolChainType type;
|
private final IToolChainType type;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final String command;
|
||||||
private String version;
|
private String version;
|
||||||
private String target;
|
private String target;
|
||||||
private Path path;
|
private Path path;
|
||||||
|
@ -55,6 +60,7 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
|
|
||||||
public GCCToolChain(IToolChainType type, Path path, String command) {
|
public GCCToolChain(IToolChainType type, Path path, String command) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.command = command;
|
||||||
getVersion(path.resolve(command).toString());
|
getVersion(path.resolve(command).toString());
|
||||||
this.name = command + '-' + version;
|
this.name = command + '-' + version;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
@ -64,9 +70,10 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
envVars = new IEnvironmentVariable[] { pathVar };
|
envVars = new IEnvironmentVariable[] { pathVar };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected GCCToolChain(IToolChainType type, String name) {
|
protected GCCToolChain(IToolChainType type, String name, String command) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.command = command;
|
||||||
// TODO need to pull the other info out of preferences
|
// 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<String> command) {
|
protected void addDiscoveryOptions(List<String> command) {
|
||||||
command.add("-E"); //$NON-NLS-1$
|
command.add("-E"); //$NON-NLS-1$
|
||||||
command.add("-P"); //$NON-NLS-1$
|
command.add("-P"); //$NON-NLS-1$
|
||||||
|
@ -127,9 +138,11 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, List<String> args,
|
public IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, String[] args,
|
||||||
List<String> includePaths, IResource resource, Path buildDirectory) {
|
IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI) {
|
||||||
try {
|
try {
|
||||||
|
Path buildDirectory = Paths.get(buildDirectoryURI);
|
||||||
|
|
||||||
List<String> commandLine = new ArrayList<>();
|
List<String> commandLine = new ArrayList<>();
|
||||||
if (command.isAbsolute()) {
|
if (command.isAbsolute()) {
|
||||||
commandLine.add(command.toString());
|
commandLine.add(command.toString());
|
||||||
|
@ -137,12 +150,14 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
commandLine.add(path.resolve(command).toString());
|
commandLine.add(path.resolve(command).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String includePath : includePaths) {
|
if (baseScannerInfo != null && baseScannerInfo.getIncludePaths() != null) {
|
||||||
commandLine.add("-I" + includePath); //$NON-NLS-1$
|
for (String includePath : baseScannerInfo.getIncludePaths()) {
|
||||||
|
commandLine.add("-I" + includePath); //$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addDiscoveryOptions(commandLine);
|
addDiscoveryOptions(commandLine);
|
||||||
commandLine.addAll(args);
|
commandLine.addAll(Arrays.asList(args));
|
||||||
|
|
||||||
// Change output to stdout
|
// Change output to stdout
|
||||||
for (int i = 0; i < commandLine.size() - 1; ++i) {
|
for (int i = 0; i < commandLine.size() - 1; ++i) {
|
||||||
|
@ -260,4 +275,41 @@ public class GCCToolChain extends PlatformObject implements IToolChain {
|
||||||
return path.resolve(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<IResource> 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()]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,16 +68,6 @@
|
||||||
public="true">
|
public="true">
|
||||||
</launchConfigurationType>
|
</launchConfigurationType>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
|
||||||
point="org.eclipse.core.runtime.adapters">
|
|
||||||
<factory
|
|
||||||
adaptableType="org.eclipse.core.resources.IBuildConfiguration"
|
|
||||||
class="org.eclipse.cdt.cmake.core.internal.CMakeBuildConfigurationFactory">
|
|
||||||
<adapter
|
|
||||||
type="org.eclipse.cdt.cmake.core.internal.CMakeBuildConfiguration">
|
|
||||||
</adapter>
|
|
||||||
</factory>
|
|
||||||
</extension>
|
|
||||||
<extension
|
<extension
|
||||||
point="org.eclipse.cdt.core.ScannerInfoProvider2">
|
point="org.eclipse.cdt.core.ScannerInfoProvider2">
|
||||||
<provider
|
<provider
|
||||||
|
|
|
@ -8,9 +8,13 @@
|
||||||
package org.eclipse.cdt.cmake.core;
|
package org.eclipse.cdt.cmake.core;
|
||||||
|
|
||||||
import org.eclipse.cdt.cmake.core.internal.Activator;
|
import org.eclipse.cdt.cmake.core.internal.Activator;
|
||||||
|
import org.eclipse.cdt.core.build.CBuilder;
|
||||||
|
import org.eclipse.core.resources.ICommand;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
import org.eclipse.core.resources.IProjectNature;
|
import org.eclipse.core.resources.IProjectNature;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
|
||||||
public class CMakeNature implements IProjectNature {
|
public class CMakeNature implements IProjectNature {
|
||||||
|
|
||||||
|
@ -18,17 +22,17 @@ public class CMakeNature implements IProjectNature {
|
||||||
|
|
||||||
private IProject project;
|
private IProject project;
|
||||||
|
|
||||||
public static boolean hasNature(IProject project) {
|
public static void setupBuilder(IProjectDescription projDesc) throws CoreException {
|
||||||
try {
|
ICommand command = projDesc.newCommand();
|
||||||
return project.hasNature(ID);
|
CBuilder.setupBuilder(command);
|
||||||
} catch (CoreException e) {
|
projDesc.setBuildSpec(new ICommand[] { command });
|
||||||
Activator.log(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure() throws CoreException {
|
public void configure() throws CoreException {
|
||||||
|
IProjectDescription projDesc = project.getDescription();
|
||||||
|
setupBuilder(projDesc);
|
||||||
|
project.setDescription(projDesc, new NullProgressMonitor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,18 +10,15 @@ package org.eclipse.cdt.cmake.core;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.cmake.core.internal.CMakeBuilder;
|
|
||||||
import org.eclipse.cdt.cmake.core.internal.CMakeTemplateGenerator;
|
import org.eclipse.cdt.cmake.core.internal.CMakeTemplateGenerator;
|
||||||
import org.eclipse.cdt.core.CCProjectNature;
|
import org.eclipse.cdt.core.CCProjectNature;
|
||||||
import org.eclipse.cdt.core.CProjectNature;
|
import org.eclipse.cdt.core.CProjectNature;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.IPathEntry;
|
import org.eclipse.cdt.core.model.IPathEntry;
|
||||||
import org.eclipse.core.resources.ICommand;
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IFolder;
|
import org.eclipse.core.resources.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
|
@ -59,11 +56,6 @@ public class CMakeProjectGenerator {
|
||||||
newIds[newIds.length - 1] = CMakeNature.ID;
|
newIds[newIds.length - 1] = CMakeNature.ID;
|
||||||
projDesc.setNatureIds(newIds);
|
projDesc.setNatureIds(newIds);
|
||||||
|
|
||||||
ICommand command = projDesc.newCommand();
|
|
||||||
command.setBuilderName(CMakeBuilder.ID);
|
|
||||||
command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
|
|
||||||
projDesc.setBuildSpec(new ICommand[] { command });
|
|
||||||
|
|
||||||
project.setDescription(projDesc, monitor);
|
project.setDescription(projDesc, monitor);
|
||||||
|
|
||||||
IPathEntry[] entries = new IPathEntry[] { CoreModel.newOutputEntry(sourceFolder.getFullPath()) };
|
IPathEntry[] entries = new IPathEntry[] { CoreModel.newOutputEntry(sourceFolder.getFullPath()) };
|
||||||
|
|
|
@ -7,18 +7,86 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.cmake.core.internal;
|
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.ConsoleOutputStream;
|
||||||
|
import org.eclipse.cdt.core.IConsoleParser;
|
||||||
import org.eclipse.cdt.core.build.CBuildConfiguration;
|
import org.eclipse.cdt.core.build.CBuildConfiguration;
|
||||||
import org.eclipse.cdt.core.build.IToolChain;
|
import org.eclipse.cdt.core.build.IToolChain;
|
||||||
|
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||||
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
|
import org.eclipse.cdt.core.resources.IConsole;
|
||||||
import org.eclipse.core.resources.IBuildConfiguration;
|
import org.eclipse.core.resources.IBuildConfiguration;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
public class CMakeBuildConfiguration extends CBuildConfiguration {
|
public class CMakeBuildConfiguration extends CBuildConfiguration {
|
||||||
|
|
||||||
public CMakeBuildConfiguration(IBuildConfiguration config) {
|
public CMakeBuildConfiguration(IBuildConfiguration config, String name) {
|
||||||
super(config);
|
super(config, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CMakeBuildConfiguration(IBuildConfiguration config, IToolChain toolChain) {
|
public CMakeBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) {
|
||||||
super(config, toolChain);
|
super(config, name, toolChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProject[] build(int kind, Map<String, String> 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<String> 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<String> 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<IBuildConfiguration, CMakeBuildConfiguration> cache = new HashMap<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?>[] getAdapterList() {
|
|
||||||
return new Class<?>[] { CMakeBuildConfiguration.class };
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public <T> T getAdapter(Object adaptableObject, Class<T> 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<String, String> properties = new HashMap<>();
|
|
||||||
properties.put(IToolChain.ATTR_OS, Platform.getOS());
|
|
||||||
properties.put(IToolChain.ATTR_ARCH, Platform.getOSArch());
|
|
||||||
Collection<IToolChain> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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<String, String> 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<String> 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<String> 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ public class CMakeLaunchDescriptorType implements ILaunchDescriptorType {
|
||||||
public ILaunchDescriptor getDescriptor(Object launchObject) throws CoreException {
|
public ILaunchDescriptor getDescriptor(Object launchObject) throws CoreException {
|
||||||
if (launchObject instanceof IProject) {
|
if (launchObject instanceof IProject) {
|
||||||
IProject project = (IProject) launchObject;
|
IProject project = (IProject) launchObject;
|
||||||
if (CMakeNature.hasNature(project)) {
|
if (project.hasNature(CMakeNature.ID)) {
|
||||||
CMakeLaunchDescriptor desc = descriptors.get(project);
|
CMakeLaunchDescriptor desc = descriptors.get(project);
|
||||||
if (desc == null) {
|
if (desc == null) {
|
||||||
desc = new CMakeLaunchDescriptor(this, project);
|
desc = new CMakeLaunchDescriptor(this, project);
|
||||||
|
|
|
@ -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) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -869,5 +869,17 @@
|
||||||
</adapter>
|
</adapter>
|
||||||
</factory>
|
</factory>
|
||||||
</extension>
|
</extension>
|
||||||
|
<extension
|
||||||
|
id="cBuilder"
|
||||||
|
point="org.eclipse.core.resources.builders">
|
||||||
|
<builder
|
||||||
|
callOnEmptyDelta="true"
|
||||||
|
isConfigurable="true"
|
||||||
|
supportsConfigurations="true">
|
||||||
|
<run
|
||||||
|
class="org.eclipse.cdt.core.build.CBuilder">
|
||||||
|
</run>
|
||||||
|
</builder>
|
||||||
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,19 +7,48 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.build;
|
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.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.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.IBuildConfiguration;
|
||||||
|
import org.eclipse.core.resources.IContainer;
|
||||||
import org.eclipse.core.resources.IFolder;
|
import org.eclipse.core.resources.IFolder;
|
||||||
|
import org.eclipse.core.resources.IMarker;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.core.runtime.PlatformObject;
|
import org.eclipse.core.runtime.PlatformObject;
|
||||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
import org.osgi.service.prefs.BackingStoreException;
|
import org.osgi.service.prefs.BackingStoreException;
|
||||||
import org.osgi.service.prefs.Preferences;
|
import org.osgi.service.prefs.Preferences;
|
||||||
|
|
||||||
|
@ -28,8 +57,10 @@ import org.osgi.service.prefs.Preferences;
|
||||||
* settings for subclasses.
|
* settings for subclasses.
|
||||||
*
|
*
|
||||||
* @since 6.0
|
* @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_TYPE = "cdt.toolChain.type"; //$NON-NLS-1$
|
||||||
private static final String TOOLCHAIN_NAME = "cdt.toolChain.name"; //$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 IBuildConfiguration config;
|
||||||
private final IToolChain toolChain;
|
private final IToolChain toolChain;
|
||||||
|
|
||||||
protected CBuildConfiguration(IBuildConfiguration config) {
|
protected CBuildConfiguration(IBuildConfiguration config, String name) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
String[] split = config.getName().split("/");
|
this.name = name;
|
||||||
if (split.length == 2) {
|
|
||||||
name = split[1];
|
|
||||||
} else {
|
|
||||||
name = config.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load toolchain from prefs
|
// Load toolchain from prefs
|
||||||
Preferences settings = getSettings();
|
Preferences settings = getSettings();
|
||||||
|
@ -59,14 +85,9 @@ public abstract class CBuildConfiguration extends PlatformObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CBuildConfiguration(IBuildConfiguration config, IToolChain toolChain) {
|
protected CBuildConfiguration(IBuildConfiguration config, String name, IToolChain toolChain) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
String[] split = config.getName().split("/");
|
this.name = name;
|
||||||
if (split.length == 2) {
|
|
||||||
name = split[1];
|
|
||||||
} else {
|
|
||||||
name = config.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.toolChain = toolChain;
|
this.toolChain = toolChain;
|
||||||
Preferences settings = getSettings();
|
Preferences settings = getSettings();
|
||||||
|
@ -79,6 +100,7 @@ public abstract class CBuildConfiguration extends PlatformObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public IBuildConfiguration getBuildConfiguration() {
|
public IBuildConfiguration getBuildConfiguration() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
@ -91,28 +113,31 @@ public abstract class CBuildConfiguration extends PlatformObject {
|
||||||
return config.getProject();
|
return config.getProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IFolder getBuildFolder() {
|
public IContainer getBuildContainer() throws CoreException {
|
||||||
try {
|
// TODO should really be passing a monitor in here or create this in
|
||||||
// TODO should really be passing a monitor in here or create this in
|
// a better spot. should also throw the core exception
|
||||||
// a better spot. should also throw the core exception
|
// TODO make the name of this folder a project property
|
||||||
// TODO make the name of this folder a project property
|
IFolder buildRootFolder = getProject().getFolder("build"); //$NON-NLS-1$
|
||||||
IFolder buildRootFolder = getProject().getFolder("build"); //$NON-NLS-1$
|
if (!buildRootFolder.exists()) {
|
||||||
if (!buildRootFolder.exists()) {
|
buildRootFolder.create(IResource.FORCE | IResource.DERIVED, true, new NullProgressMonitor());
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
return null;
|
IFolder buildFolder = buildRootFolder.getFolder(name);
|
||||||
|
if (!buildFolder.exists()) {
|
||||||
|
buildFolder.create(true, true, new NullProgressMonitor());
|
||||||
|
}
|
||||||
|
return buildFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getBuildDirectory() {
|
public URI getBuildDirectoryURI() throws CoreException {
|
||||||
return getBuildFolder().getLocation().toFile().toPath();
|
return getBuildContainer().getLocationURI();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getBuildDirectory() throws CoreException {
|
||||||
|
return Paths.get(getBuildDirectoryURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setBuildEnvironment(Map<String, String> env) {
|
||||||
|
CCorePlugin.getDefault().getBuildEnvironmentManager().setEnvironment(env, config, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActive(IProgressMonitor monitor) throws CoreException {
|
public void setActive(IProgressMonitor monitor) throws CoreException {
|
||||||
|
@ -132,8 +157,247 @@ public abstract class CBuildConfiguration extends PlatformObject {
|
||||||
.node(getProject().getName()).node(config.getName());
|
.node(getProject().getName()).node(config.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public IToolChain getToolChain() {
|
public IToolChain getToolChain() {
|
||||||
return toolChain;
|
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<String, String> attributes = problemMarkerInfo.getAttributes();
|
||||||
|
if (attributes != null) {
|
||||||
|
for (Entry<String, String> 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<String, String> 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<IResource, IExtendedScannerInfo> 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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String, String> 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,10 +7,16 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.build;
|
package org.eclipse.cdt.core.build;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
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.IBuildConfiguration;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IAdaptable;
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the root interface for "new style" CDT build configurations. Adapting
|
* This is the root interface for "new style" CDT build configurations. Adapting
|
||||||
|
@ -41,4 +47,8 @@ public interface ICBuildConfiguration extends IAdaptable, IScannerInfoProvider {
|
||||||
|
|
||||||
IEnvironmentVariable[] getVariables();
|
IEnvironmentVariable[] getVariables();
|
||||||
|
|
||||||
|
IProject[] build(int kind, Map<String, String> args, IConsole console, IProgressMonitor monitor) throws CoreException;
|
||||||
|
|
||||||
|
void clean(IConsole console, IProgressMonitor monitor) throws CoreException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,6 @@ public interface ICBuildConfigurationManager {
|
||||||
*/
|
*/
|
||||||
ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig);
|
ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig);
|
||||||
|
|
||||||
ICBuildConfiguration getDefaultBuildConfiguration(IProject project);
|
ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.eclipse.cdt.core.build;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IBuildConfiguration;
|
import org.eclipse.core.resources.IBuildConfiguration;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CBuildConfigurationProvider provides C build configurations.
|
* A CBuildConfigurationProvider provides C build configurations.
|
||||||
|
@ -30,7 +31,7 @@ public interface ICBuildConfigurationProvider {
|
||||||
* @param config
|
* @param config
|
||||||
* @return CDT build configuration for the Platform build configuration
|
* @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.
|
* Returns a default C build configuration for a given project if any.
|
||||||
|
@ -38,6 +39,6 @@ public interface ICBuildConfigurationProvider {
|
||||||
* @param project
|
* @param project
|
||||||
* @return default C build configuration for the project
|
* @return default C build configuration for the project
|
||||||
*/
|
*/
|
||||||
ICBuildConfiguration getDefaultCBuildConfiguration(IProject project);
|
ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) throws CoreException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.build;
|
package org.eclipse.cdt.core.build;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||||
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
|
||||||
|
@ -47,11 +47,13 @@ public interface IToolChain extends IAdaptable {
|
||||||
|
|
||||||
IEnvironmentVariable[] getVariables();
|
IEnvironmentVariable[] getVariables();
|
||||||
|
|
||||||
IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, List<String> args,
|
IExtendedScannerInfo getScannerInfo(IBuildConfiguration buildConfig, Path command, String[] args,
|
||||||
List<String> includePaths, IResource resource, Path buildDirectory);
|
IExtendedScannerInfo baseScannerInfo, IResource resource, URI buildDirectoryURI);
|
||||||
|
|
||||||
String[] getErrorParserIds();
|
String[] getErrorParserIds();
|
||||||
|
|
||||||
Path getCommandPath(String command);
|
Path getCommandPath(String command);
|
||||||
|
|
||||||
|
IResource[] getResourcesFromCommand(String[] command, URI buildDirectoryURI);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,16 +140,18 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) {
|
public ICBuildConfiguration getBuildConfiguration(IBuildConfiguration buildConfig) {
|
||||||
|
initProviders();
|
||||||
synchronized (configs) {
|
synchronized (configs) {
|
||||||
ICBuildConfiguration config = configs.get(buildConfig);
|
ICBuildConfiguration config = configs.get(buildConfig);
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$
|
String[] segments = buildConfig.getName().split("/"); //$NON-NLS-1$
|
||||||
if (segments.length == 2) {
|
if (segments.length == 2) {
|
||||||
String providerId = segments[0];
|
String providerId = segments[0];
|
||||||
|
String configName = segments[1];
|
||||||
|
|
||||||
Provider provider = getProviderDelegate(providerId);
|
Provider provider = getProviderDelegate(providerId);
|
||||||
if (provider != null && provider.supports(buildConfig.getProject())) {
|
if (provider != null && provider.supports(buildConfig.getProject())) {
|
||||||
config = provider.getProvider().getCBuildConfiguration(buildConfig);
|
config = provider.getProvider().getCBuildConfiguration(buildConfig, configName);
|
||||||
configs.put(buildConfig, config);
|
configs.put(buildConfig, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +161,7 @@ public class CBuildConfigurationManager implements ICBuildConfigurationManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICBuildConfiguration getDefaultBuildConfiguration(IProject project) {
|
public ICBuildConfiguration getDefaultBuildConfiguration(IProject project) throws CoreException {
|
||||||
initProviders();
|
initProviders();
|
||||||
for (Provider provider : providers.values()) {
|
for (Provider provider : providers.values()) {
|
||||||
if (provider.supports(project)) {
|
if (provider.supports(project)) {
|
||||||
|
|
|
@ -59,7 +59,11 @@ public class BuildOutputStream extends ConsoleOutputStream implements IErrorMark
|
||||||
@Override
|
@Override
|
||||||
public void write(String s, ProblemMarkerInfo marker) throws IOException {
|
public void write(String s, ProblemMarkerInfo marker) throws IOException {
|
||||||
fPartitioner.appendToDocument(s, fStream, marker);
|
fPartitioner.appendToDocument(s, fStream, marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void write(String msg) throws IOException {
|
||||||
|
fPartitioner.appendToDocument(msg, fStream, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,12 +56,24 @@ class MultiBuildConsoleAdapter implements IConsole {
|
||||||
two.write(b, off, len);
|
two.write(b, off, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void write(String msg) throws IOException {
|
||||||
|
one.write(msg);
|
||||||
|
two.write(msg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(String s, ProblemMarkerInfo marker) throws IOException {
|
public void write(String s, ProblemMarkerInfo marker) throws IOException {
|
||||||
one.write(s, marker);
|
one.write(s, marker);
|
||||||
two.write(s, marker);
|
two.write(s, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() throws IOException {
|
||||||
|
one.flush();
|
||||||
|
two.flush();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
one.flush();
|
one.flush();
|
||||||
|
|
|
@ -13,18 +13,17 @@ package org.eclipse.cdt.internal.qt.core;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
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.dom.ILinkage;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.index.IIndexLinkage;
|
import org.eclipse.cdt.core.index.IIndexLinkage;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.internal.core.index.CIndex;
|
import org.eclipse.cdt.internal.core.index.CIndex;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
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.ICommand;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
import org.eclipse.core.resources.IProjectNature;
|
import org.eclipse.core.resources.IProjectNature;
|
||||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
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
|
@Override
|
||||||
public void configure() throws CoreException {
|
public void configure() throws CoreException {
|
||||||
IProjectDescription projDesc = project.getDescription();
|
IProjectDescription projDesc = project.getDescription();
|
||||||
ICommand command = projDesc.newCommand();
|
setupBuilder(projDesc);
|
||||||
command.setBuilderName(QtBuilder.ID);
|
|
||||||
command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
|
|
||||||
projDesc.setBuildSpec(new ICommand[] { command });
|
|
||||||
project.setDescription(projDesc, new NullProgressMonitor());
|
project.setDescription(projDesc, new NullProgressMonitor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,18 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.CBuildConfiguration;
|
||||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||||
import org.eclipse.cdt.core.build.IToolChain;
|
import org.eclipse.cdt.core.build.IToolChain;
|
||||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
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.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.internal.qt.core.Activator;
|
||||||
import org.eclipse.cdt.qt.core.IQtBuildConfiguration;
|
import org.eclipse.cdt.qt.core.IQtBuildConfiguration;
|
||||||
import org.eclipse.cdt.qt.core.IQtInstall;
|
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.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.osgi.service.prefs.BackingStoreException;
|
import org.osgi.service.prefs.BackingStoreException;
|
||||||
import org.osgi.service.prefs.Preferences;
|
import org.osgi.service.prefs.Preferences;
|
||||||
|
|
||||||
|
@ -47,8 +56,8 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild
|
||||||
private final String launchMode;
|
private final String launchMode;
|
||||||
private Map<String, String> properties;
|
private Map<String, String> properties;
|
||||||
|
|
||||||
public QtBuildConfiguration(IBuildConfiguration config) {
|
public QtBuildConfiguration(IBuildConfiguration config, String name) {
|
||||||
super(config);
|
super(config, name);
|
||||||
|
|
||||||
Preferences settings = getSettings();
|
Preferences settings = getSettings();
|
||||||
String installName = settings.get(QTINSTALL_NAME, ""); //$NON-NLS-1$
|
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$
|
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 {
|
throws CoreException {
|
||||||
super(config, toolChain);
|
super(config, name, toolChain);
|
||||||
this.qtInstall = qtInstall;
|
this.qtInstall = qtInstall;
|
||||||
this.launchMode = launchMode;
|
this.launchMode = launchMode;
|
||||||
|
|
||||||
|
@ -122,7 +132,7 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getProgramPath() {
|
public Path getProgramPath() throws CoreException {
|
||||||
String projectName = getProject().getName();
|
String projectName = getProject().getName();
|
||||||
switch (Platform.getOS()) {
|
switch (Platform.getOS()) {
|
||||||
case Platform.OS_MACOSX:
|
case Platform.OS_MACOSX:
|
||||||
|
@ -158,8 +168,10 @@ public class QtBuildConfiguration extends CBuildConfiguration implements ICBuild
|
||||||
cmd.add(getProjectFile().toString());
|
cmd.add(getProjectFile().toString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ProcessBuilder procBuilder = new ProcessBuilder(cmd).directory(getProjectFile().getParent().toFile());
|
ProcessBuilder processBuilder = new ProcessBuilder(cmd)
|
||||||
Process proc = procBuilder.start();
|
.directory(getProjectFile().getParent().toFile());
|
||||||
|
setBuildEnvironment(processBuilder.environment());
|
||||||
|
Process proc = processBuilder.start();
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
|
||||||
properties = new HashMap<>();
|
properties = new HashMap<>();
|
||||||
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
|
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) {
|
for (int i = 0; i < includePaths.length; ++i) {
|
||||||
Path path = Paths.get(includePaths[i]);
|
Path path = Paths.get(includePaths[i]);
|
||||||
if (!path.isAbsolute()) {
|
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());
|
IExtendedScannerInfo baseScannerInfo = new ExtendedScannerInfo(null, includePaths);
|
||||||
return getToolChain().getScannerInfo(getBuildConfiguration(), command, args, Arrays.asList(includePaths),
|
try {
|
||||||
resource, dir);
|
return getToolChain().getScannerInfo(getBuildConfiguration(), command,
|
||||||
|
args.toArray(new String[args.size()]), baseScannerInfo, resource,
|
||||||
|
getBuildContainer().getLocationURI());
|
||||||
|
} catch (CoreException e) {
|
||||||
|
Activator.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void subscribe(IResource resource, IScannerInfoChangeListener listener) {
|
public IProject[] build(int kind, Map<String, String> 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<String> 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
|
@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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
import org.eclipse.core.runtime.Platform;
|
import org.eclipse.core.runtime.Platform;
|
||||||
import org.eclipse.launchbar.core.target.ILaunchTarget;
|
|
||||||
|
|
||||||
public class QtBuildConfigurationProvider implements ICBuildConfigurationProvider {
|
public class QtBuildConfigurationProvider implements ICBuildConfigurationProvider {
|
||||||
|
|
||||||
|
@ -42,18 +41,14 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config) {
|
public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) {
|
||||||
try {
|
try {
|
||||||
// Double check to make sure this config is ours
|
// Double check to make sure this config is ours
|
||||||
if (!config.getName().startsWith(getId() + '/')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.getProject().hasNature(QtNature.ID)) {
|
if (!config.getProject().hasNature(QtNature.ID)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new QtBuildConfiguration(config);
|
return new QtBuildConfiguration(config, name);
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
Activator.log(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$
|
String configName = "qt." + qtInstall.getSpec() + "." + launchMode; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName,
|
IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName,
|
||||||
monitor);
|
monitor);
|
||||||
QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, toolChain, qtInstall,
|
QtBuildConfiguration qtConfig = new QtBuildConfiguration(config, configName, toolChain, qtInstall,
|
||||||
launchMode);
|
launchMode);
|
||||||
configManager.addBuildConfiguration(config, qtConfig);
|
configManager.addBuildConfiguration(config, qtConfig);
|
||||||
return qtConfig;
|
return qtConfig;
|
||||||
|
@ -130,35 +125,4 @@ public class QtBuildConfigurationProvider implements ICBuildConfigurationProvide
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QtBuildConfiguration createConfiguration(IProject project, ILaunchTarget target, String launchMode,
|
|
||||||
IProgressMonitor monitor) throws CoreException {
|
|
||||||
// Find the toolchains
|
|
||||||
Map<String, String> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String, String> 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<String> 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<String, String> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,35 +17,31 @@ import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.IPathEntry;
|
import org.eclipse.cdt.core.model.IPathEntry;
|
||||||
import org.eclipse.cdt.internal.qt.core.Activator;
|
import org.eclipse.cdt.internal.qt.core.Activator;
|
||||||
import org.eclipse.cdt.internal.qt.core.QtNature;
|
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.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.tools.templates.freemarker.FMProjectGenerator;
|
import org.eclipse.tools.templates.freemarker.FMProjectGenerator;
|
||||||
import org.eclipse.tools.templates.freemarker.SourceRoot;
|
import org.eclipse.tools.templates.freemarker.SourceRoot;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
|
||||||
public class QtProjectGenerator extends FMProjectGenerator {
|
public class QtProjectGenerator extends FMProjectGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initProjectDescription(IProjectDescription description) {
|
protected void initProjectDescription(IProjectDescription description) {
|
||||||
// Natures
|
|
||||||
description
|
description
|
||||||
.setNatureIds(new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, QtNature.ID });
|
.setNatureIds(new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, QtNature.ID });
|
||||||
|
QtNature.setupBuilder(description);
|
||||||
|
}
|
||||||
|
|
||||||
// Builders
|
@Override
|
||||||
ICommand command = description.newCommand();
|
public Bundle getSourceBundle() {
|
||||||
command.setBuilderName(QtBuilder.ID);
|
return Activator.getDefault().getBundle();
|
||||||
command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
|
|
||||||
description.setBuildSpec(new ICommand[] { command });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
|
public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException {
|
||||||
setBundle(Activator.getDefault().getBundle());
|
|
||||||
super.generate(model, monitor);
|
super.generate(model, monitor);
|
||||||
|
|
||||||
// Create the sourcefolders
|
// Create the sourcefolders
|
||||||
|
|
|
@ -10,16 +10,17 @@ package org.eclipse.cdt.qt.core;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
import org.eclipse.cdt.core.build.ICBuildConfiguration;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
public interface IQtBuildConfiguration extends ICBuildConfiguration {
|
public interface IQtBuildConfiguration extends ICBuildConfiguration {
|
||||||
|
|
||||||
Path getBuildDirectory();
|
Path getBuildDirectory() throws CoreException;
|
||||||
|
|
||||||
Path getQmakeCommand();
|
Path getQmakeCommand();
|
||||||
|
|
||||||
String getQmakeConfig();
|
String getQmakeConfig();
|
||||||
|
|
||||||
Path getProgramPath();
|
Path getProgramPath() throws CoreException;
|
||||||
|
|
||||||
String getLaunchMode();
|
String getLaunchMode();
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||||
import org.eclipse.jface.dialogs.Dialog;
|
import org.eclipse.jface.dialogs.Dialog;
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.ui.IWorkbench;
|
|
||||||
import org.eclipse.ui.actions.WorkspaceModifyOperation;
|
import org.eclipse.ui.actions.WorkspaceModifyOperation;
|
||||||
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
|
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
|
||||||
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
|
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
|
||||||
|
@ -80,9 +78,4 @@ public class HelloWorldWizard extends BasicNewResourceWizard {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(IWorkbench theWorkbench, IStructuredSelection currentSelection) {
|
|
||||||
super.init(theWorkbench, currentSelection);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue