1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-05 16:56:04 +02:00

new make builder core plugin

This commit is contained in:
David Inglis 2003-08-13 19:15:45 +00:00
parent b32258ab17
commit c8b2ea56f7
16 changed files with 1494 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1 @@
bin

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.cdt.make.core</name>
<comment></comment>
<projects>
<project>org.eclipse.cdt.core</project>
<project>org.eclipse.cdt.core.linux</project>
<project>org.eclipse.cdt.core.qnx</project>
<project>org.eclipse.cdt.core.solaris</project>
<project>org.eclipse.cdt.core.win32</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,30 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>10th July, 2002</p>
<h3>License</h3>
<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
Common Public License Version 1.0 (&quot;CPL&quot;). A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
<h3>Contributions</h3>
<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
to others under the terms of the Other License. In addition, with regard to Modifications for which you are the copyright holder, you are also
providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
the CPL.</p>
</body>
</html>

View file

@ -0,0 +1,4 @@
source.cdtmakecore.jar = src/
bin.includes = plugin.xml,\
*.jar,\
cdtmakecore.jar

View file

@ -0,0 +1,5 @@
pluginName=C/C++ Standard make Build Core
providerName=Eclipse.org
natureMake.name=CDT Make Nature
builderMake.name=CDT Makefile Builder

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin
id="org.eclipse.cdt.make.core"
name="%pluginName"
version="1.0.0"
provider-name="%providerName"
class="org.eclipse.cdt.make.core.MakeCorePlugin">
<runtime>
<library name="cdtmakecore.jar"/>
</runtime>
<requires>
<import plugin="org.eclipse.core.resources"/>
<import plugin="org.eclipse.cdt.core"/>
<import plugin="org.apache.xerces"/>
</requires>
<extension
id="MakeBuildManager"
point="org.eclipse.cdt.core.ScannerInfoProvider">
<cextension>
<run
class="org.eclipse.cdt.make.core.MakeBuildManager">
</run>
</cextension>
</extension>
<extension
id="makeNature"
name="%natureMake.name"
point="org.eclipse.core.resources.natures">
<requires-nature
id="org.eclipse.cdt.core.cnature">
</requires-nature>
<runtime>
<run
class="org.eclipse.cdt.make.core.MakeProjectNature">
</run>
</runtime>
<builder
id="org.eclipse.cdt.make.core.makeBuilder">
</builder>
</extension>
<extension
id="makeBuilder"
name="%builderMake.name"
point="org.eclipse.core.resources.builders">
<builder hasNature="true">
<run class="org.eclipse.cdt.make.core.MakeBuilder">
<parameter
name="defaultCommand"
value="make">
</parameter>
</run>
</builder>
</extension>
<extension
id="make"
name="%makeproject.name"
point="org.eclipse.cdt.core.CProject">
<cproject
class="org.eclipse.cdt.make.internal.core.MakeProject">
</cproject>
</extension>
<!-- Not really used but could be in the future -->
<extension
id="makeBuilder"
name="%makebuildmodel.name"
point="org.eclipse.cdt.core.CBuildModel">
<run
class="org.eclipse.cdt.make.internal.core.MakeBuilder">
</run>
</extension>
</plugin>

View file

@ -0,0 +1,353 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
public class BuildInfoFactory {
public static final String PREFIX = MakeCorePlugin.getUniqueIdentifier();
public static final String BUILD_COMMAND = PREFIX + ".buildCommand";
public static final String BUILD_LOCATION = PREFIX + ".buildLocation";
public static final String STOP_ON_ERROR = PREFIX + ".stopOnError";
public static final String USE_DEFAULT_BUILD_CMD = PREFIX + ".useDefaultBuildCmd";
public static final String BUILD_TARGET_AUTO = PREFIX + ".autoBuildTarget";
public static final String BUILD_TARGET_INCREMENTAL = PREFIX + ".incrementalBuildTarget";
public static final String BUILD_TARGET_FULL = PREFIX + ".fullBuildTarget";
public static final String BUILD_FULL_ENABLED = PREFIX + ".enableFullBuild";
public static final String BUILD_INCREMENTAL_ENABLED = PREFIX + ".enabledIncrementalBuild";
public static final String BUILD_AUTO_ENABLED = PREFIX + ".enableAutoBuild";
public static final String BUILD_ARGUMENTS = PREFIX + ".buildArguments";
public abstract static class Store implements IMakeBuilderInfo, IScannerInfo {
// List of include paths
protected List pathList;
protected List symbolList;
public void setUseDefaultBuildCmd(boolean on) {
putValue(USE_DEFAULT_BUILD_CMD, new Boolean(on).toString());
}
public boolean isDefaultBuildCmd() {
if (getString(USE_DEFAULT_BUILD_CMD) == null) { // if no property then default to true
return true;
}
return getBoolean(USE_DEFAULT_BUILD_CMD);
}
public void setBuildCommand(IPath location) {
putValue(BUILD_COMMAND, location.toString());
}
public IPath getBuildCommand() {
if (isDefaultBuildCmd()) {
String command = getBuildParameter("defaultCommand");
if (command == null) {
return new Path("make");
}
return new Path(command);
}
return new Path(getString(BUILD_COMMAND));
}
protected String getBuildParameter(String name) {
IExtension extension =
Platform.getPluginRegistry().getExtension(
ResourcesPlugin.PI_RESOURCES,
ResourcesPlugin.PT_BUILDERS,
getBuilderID());
if (extension == null)
return null;
IConfigurationElement[] configs = extension.getConfigurationElements();
if (configs.length == 0)
return null;
//The nature exists, or this builder doesn't specify a nature
IConfigurationElement[] runElement = configs[0].getChildren("run");
IConfigurationElement[] paramElement = runElement[0].getChildren("parameter");
for (int i = 0; i < paramElement.length; i++) {
if (paramElement[i].getAttribute("name").equals(name)) {
return paramElement[i].getAttribute("value");
}
}
return null;
}
protected abstract String getBuilderID();
public void setBuildLocation(IPath location) {
putValue(BUILD_LOCATION, location.toString());
}
public IPath getBuildLocation() {
String location = getString(BUILD_LOCATION);
return new Path(location == null ? "" : location);
}
public void setStopOnError(boolean enabled) {
putValue(STOP_ON_ERROR, new Boolean(enabled).toString());
}
public boolean isStopOnError() {
return getBoolean(STOP_ON_ERROR);
}
public void setAutoBuildTarget(String target) {
putValue(BUILD_TARGET_AUTO, target);
}
public String getAutoBuildTarget() {
return getString(BUILD_TARGET_AUTO);
}
public void setIncrementalBuildTarget(String target) {
putValue(BUILD_TARGET_INCREMENTAL, target);
}
public String getIncrementalBuildTarget() {
return getString(BUILD_TARGET_INCREMENTAL);
}
public void setFullBuildTarget(String target) {
putValue(BUILD_TARGET_FULL, target);
}
public String getFullBuildTarget() {
return getString(BUILD_TARGET_FULL);
}
public void setPreprocessorSymbols(String[] symbols) {
// Clear out any existing symbols and add the new stuff
getSymbolList().clear();
getSymbolList().addAll(Arrays.asList(symbols));
}
public void setIncludePaths(String[] paths) {
// Clear the existing list and add the paths
getPathList().clear();
getPathList().addAll(Arrays.asList(paths));
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths()
*/
public String[] getIncludePaths() {
return (String[]) getPathList().toArray(new String[getPathList().size()]);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths()
*/
public Map getDefinedSymbols() {
// Return the defined symbols for the default configuration
HashMap symbols = new HashMap();
String[] symbolList = getPreprocessorSymbols();
for (int i = 0; i < symbolList.length; ++i) {
String symbol = symbolList[i];
if (symbol.length() == 0) {
continue;
}
String key = new String();
String value = new String();
int index = symbol.indexOf("=");
if (index != -1) {
key = symbol.substring(0, index).trim();
value = symbol.substring(index + 1).trim();
} else {
key = symbol.trim();
}
symbols.put(key, value);
}
return symbols;
}
protected List getPathList() {
if (pathList == null) {
pathList = new ArrayList();
}
return pathList;
}
public String[] getPreprocessorSymbols() {
return (String[]) getSymbolList().toArray(new String[getSymbolList().size()]);
}
protected List getSymbolList() {
if (symbolList == null) {
symbolList = new ArrayList();
}
return symbolList;
}
public boolean getBoolean(String property) {
return Boolean.valueOf(getString(property)).booleanValue();
}
public abstract void putValue(String name, String value);
public abstract String getString(String property);
public void setAutoBuildEnable(boolean enabled) {
putValue(BUILD_AUTO_ENABLED, new Boolean(enabled).toString());
}
public boolean isAutoBuildEnable() {
return getBoolean(BUILD_AUTO_ENABLED);
}
public void setIncrementalBuildEnable(boolean enabled) {
putValue(BUILD_INCREMENTAL_ENABLED, new Boolean(enabled).toString());
}
public boolean isIncrementalBuildEnabled() {
return getBoolean(BUILD_INCREMENTAL_ENABLED);
}
public void setFullBuildEnable(boolean enabled) {
putValue(BUILD_FULL_ENABLED, new Boolean(enabled).toString());
}
public boolean isFullBuildEnabled() {
return getBoolean(BUILD_FULL_ENABLED);
}
public String getBuildArguments() {
return getString(BUILD_ARGUMENTS);
}
public void setBuildArguments(String args) {
putValue(BUILD_ARGUMENTS, args);
}
}
public static class Preference extends Store {
private Preferences prefs;
private String builderID;
public Preference(Preferences prefs, String builderID) {
this.prefs = prefs;
this.builderID = builderID;
}
public void putValue(String name, String value) {
prefs.setValue(name, value);
}
public String getString(String property) {
return prefs.getString(property);
}
public void setDefault(String name, String value) {
prefs.setDefault(name, value);
}
protected String getBuilderID() {
return builderID;
}
}
public static class BuildProperty extends Store {
private IProject project;
private String builderID;
public BuildProperty(IProject project, String builderID) {
this.project = project;
this.builderID = builderID;
}
public void putValue(String name, String value) {
try {
ICommand builder = MakeProjectNature.getBuildSpec(project);
Map args = builder.getArguments();
args.put(name, value);
builder.setArguments(args);
} catch (CoreException e) {
}
}
public String getString(String name) {
ICommand builder;
try {
builder = MakeProjectNature.getBuildSpec(project);
Map args = builder.getArguments();
return (String) args.get(name);
} catch (CoreException e) {
}
return null;
}
public String getBuilderID() {
return builderID;
}
}
public static class BuildArguments extends Store {
private Map args;
private String builderID;
public BuildArguments(Map args, String builderID) {
this.args = args;
this.builderID = builderID;
}
public void putValue(String name, String value) {
}
public String getString(String name) {
return (String) args.get(name);
}
public String getBuilderID() {
return builderID;
}
}
public static IMakeBuilderInfo create(Preferences prefs, String builderID) {
return new BuildInfoFactory.Preference(prefs, builderID);
}
public static IMakeBuilderInfo create(IProject project, String builderID) {
return new BuildInfoFactory.BuildProperty(project, builderID);
}
public static IMakeBuilderInfo create(Map args, String builderID) {
return new BuildInfoFactory.BuildArguments(args, builderID);
}
public static void initializeDefaultPreferences(Preferences prefs) {
prefs.setDefault(BUILD_COMMAND, "make");
prefs.setDefault(BUILD_LOCATION, "");
prefs.setDefault(STOP_ON_ERROR, new Boolean(false).toString());
prefs.setDefault(USE_DEFAULT_BUILD_CMD, new Boolean(true).toString());
prefs.setDefault(BUILD_AUTO_ENABLED, new Boolean(false).toString());
prefs.setDefault(BUILD_FULL_ENABLED, new Boolean(true).toString());
prefs.setDefault(BUILD_INCREMENTAL_ENABLED, new Boolean(true).toString());
prefs.setDefault(BUILD_TARGET_AUTO, "all");
prefs.setDefault(BUILD_TARGET_INCREMENTAL, "all");
prefs.setDefault(BUILD_TARGET_FULL, "clean all");
}
}

View file

@ -0,0 +1,50 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import org.eclipse.core.runtime.IPath;
public interface IMakeBuilderInfo {
IPath getBuildLocation();
boolean isStopOnError();
boolean isDefaultBuildCmd();
IPath getBuildCommand();
String getBuildArguments();
boolean isAutoBuildEnable();
String getAutoBuildTarget();
boolean isIncrementalBuildEnabled();
String getIncrementalBuildTarget();
boolean isFullBuildEnabled();
String getFullBuildTarget();
public String[] getPreprocessorSymbols();
public String[] getIncludePaths();
void setBuildLocation(IPath location);
void setStopOnError(boolean on);
void setUseDefaultBuildCmd(boolean on);
void setBuildCommand(IPath command);
void setBuildArguments(String args);
void setAutoBuildEnable(boolean enabled);
void setAutoBuildTarget(String target);
void setIncrementalBuildEnable(boolean enabled);
void setIncrementalBuildTarget(String target);
void setFullBuildEnable(boolean enabled);
void setFullBuildTarget(String target);
public void setPreprocessorSymbols(String[] symbols);
public void setIncludePaths(String[] paths);
}

View file

@ -0,0 +1,299 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICDescriptor;
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.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class MakeBuildManager extends AbstractCExtension implements IScannerInfoProvider {
// This is the id of the IScannerInfoProvider extension point entry
public static final String INTERFACE_IDENTITY = MakeCorePlugin.getUniqueIdentifier() + ".MakeBuildManager";
// Name we will use to store build property with the project
private static final QualifiedName buildInfoProperty
= new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "makeBuildInfo");
private static final String ID = MakeCorePlugin.getUniqueIdentifier() + ".makeBuildInfo";
public static final String INCLUDE_PATH = "includePath";
public static final String PATH = "path";
public static final String DEFINED_SYMBOL = "definedSymbol";
public static final String SYMBOL = "symbol";
// Listeners interested in build model changes
private static Map buildModelListeners;
/**
* @param project
* @return
*/
private static IMakeBuilderInfo findBuildInfo(IResource resource, boolean create) throws CoreException {
IMakeBuilderInfo buildInfo = null;
// See if there's already one associated with the resource for this session
try {
buildInfo = (IMakeBuilderInfo)resource.getSessionProperty(buildInfoProperty);
} catch (CoreException e) {
}
// Try to load one for the project
if (buildInfo == null && resource instanceof IProject) {
try {
buildInfo = loadBuildInfo((IProject)resource);
} catch (CoreException e) {
}
}
// There is nothing persisted for the session, or saved in a file so
// create a build info object
if (buildInfo == null && create) {
buildInfo = BuildInfoFactory.create((IProject)resource, MakeBuilder.BUILDER_ID);
try {
((IProject)resource).setSessionProperty(buildInfoProperty, buildInfo);
} catch (CoreException e) {
buildInfo = null;
}
}
return buildInfo;
}
public static IMakeBuilderInfo getBuildInfo(IProject project) throws CoreException {
return findBuildInfo(project, false);
}
public static IMakeBuilderInfo getBuildInfo(IProject project, boolean create) throws CoreException {
return findBuildInfo(project, create);
}
/*
* @return
*/
private static synchronized Map getBuildModelListeners() {
if (buildModelListeners == null) {
buildModelListeners = new HashMap();
}
return buildModelListeners;
}
public static void setPreprocessorSymbols(IProject project, String[] symbols)
throws CoreException
{
// Get the information for the project
IMakeBuilderInfo info = getBuildInfo(project);
// Set the new information
if (info != null) {
String[] oldSymbols = info.getPreprocessorSymbols();
if (!Arrays.equals(oldSymbols, symbols)) {
info.setPreprocessorSymbols(symbols);
// Alert the listeners
setScannerInfoDirty(project, info);
}
}
}
public static void setIncludePaths(IProject project, String[] paths)
throws CoreException
{
// Get the build info for the project
IMakeBuilderInfo info = getBuildInfo(project);
if (info != null) {
String[] oldPaths = info.getIncludePaths();
if (!Arrays.equals(oldPaths, paths)) {
info.setIncludePaths(paths);
setScannerInfoDirty(project, info);
}
}
}
/**
* @param project
* @param info
*/
private static void setScannerInfoDirty(IProject project, IMakeBuilderInfo info) {
// Call in the cavalry
List listeners = (List) getBuildModelListeners().get(project);
if (listeners == null) {
return;
}
ListIterator iter = listeners.listIterator();
while (iter.hasNext()) {
((IScannerInfoChangeListener)iter.next()).changeNotification(project, (IScannerInfo) info);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource)
*/
public IScannerInfo getScannerInformation(IResource resource) {
IMakeBuilderInfo info;
try {
info = getBuildInfo((IProject)resource);
} catch (CoreException e) {
return null;
}
return (IScannerInfo)info;
}
/*
* Loads the build file and parses the nodes for build information. The
* information is then associated with the resource for the duration of
* the session.
*/
private static IMakeBuilderInfo loadBuildInfo(IProject project) throws CoreException {
ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
IMakeBuilderInfo buildInfo = BuildInfoFactory.create(project, MakeBuilder.BUILDER_ID);
Node child = descriptor.getProjectData(ID).getFirstChild();
ArrayList includes = new ArrayList();
ArrayList symbols = new ArrayList();
while (child != null) {
if (child.getNodeName().equals(INCLUDE_PATH)) {
// Add the path to the property list
includes.add(((Element)child).getAttribute(PATH));
} else if (child.getNodeName().equals(DEFINED_SYMBOL)) {
// Add the symbol to the symbol list
symbols.add(((Element)child).getAttribute(SYMBOL));
}
child = child.getNextSibling();
}
buildInfo.setIncludePaths((String[]) includes.toArray(new String[includes.size()]));
buildInfo.setPreprocessorSymbols((String[]) symbols.toArray(new String[symbols.size()]));
project.setSessionProperty(buildInfoProperty, buildInfo);
return buildInfo;
}
/**
* The build model manager for standard builds only caches the build
* information for a resource on a per-session basis. This method
* allows clients of the build model manager to programmatically
* remove the association between the resource and the information
* while the reource is still open or in the workspace. The Eclipse core
* will take care of removing it if a resource is closed or deleted.
*
* @param resource
*/
public static void removeBuildInfo(IResource resource) {
try {
resource.setSessionProperty(buildInfoProperty, null);
} catch (CoreException e) {
}
}
/**
* Persists build-specific information in the build file. Build
* information for standard make projects consists of preprocessor
* symbols and includes paths. Other project-related information is
* stored in the persistent properties of the project.
*
* @param project
*/
public static void saveBuildInfo(IProject project) throws CoreException {
ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
Element rootElement = descriptor.getProjectData(ID);
// Clear out all current children
// Note: Probably would be a better idea to merge in the data
Node child = rootElement.getFirstChild();
while (child != null) {
rootElement.removeChild(child);
child = rootElement.getFirstChild();
}
// Save the build info
IMakeBuilderInfo buildInfo = getBuildInfo(project);
if (buildInfo != null) {
// Serialize the include paths
Document doc = rootElement.getOwnerDocument();
ListIterator iter = Arrays.asList(buildInfo.getIncludePaths()).listIterator();
while (iter.hasNext()){
Element pathElement = doc.createElement(INCLUDE_PATH);
pathElement.setAttribute(PATH, (String)iter.next());
rootElement.appendChild(pathElement);
}
// Now do the same for the symbols
iter = Arrays.asList(buildInfo.getPreprocessorSymbols()).listIterator();
while (iter.hasNext()) {
Element symbolElement = doc.createElement(DEFINED_SYMBOL);
symbolElement.setAttribute(SYMBOL, (String)iter.next());
rootElement.appendChild(symbolElement);
}
descriptor.saveProjectData();
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource, org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
*/
public synchronized void subscribe(IResource resource, IScannerInfoChangeListener listener) {
IResource project = null;
if (resource instanceof IProject) {
project = resource;
} else if (resource instanceof IFile) {
project = ((IFile)resource).getProject();
} else {
return;
}
// Get listeners for this resource
Map map = getBuildModelListeners();
List list = (List) map.get(project);
if (list == null) {
// Create a new list
list = new ArrayList();
}
if (!list.contains(listener)) {
// Add the new listener for the resource
list.add(listener);
map.put(project, list);
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource, org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
*/
public synchronized void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
IResource project = null;
if (resource instanceof IProject) {
project = resource;
} else if (resource instanceof IFile) {
project = ((IFile)resource).getProject();
} else {
return;
}
// Remove the listener
Map map = getBuildModelListeners();
List list = (List) map.get(project);
if (list != null && !list.isEmpty()) {
// The list is not empty so try to remove listener
list.remove(listener);
map.put(project, list);
}
}
}

View file

@ -0,0 +1,294 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.ConsoleOutputStream;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.core.resources.IConsole;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;
public class MakeBuilder extends ACBuilder {
private static final String BUILD_ERROR = "MakeBuilder.buildError";
public final static String BUILDER_ID = MakeCorePlugin.getUniqueIdentifier() + ".makeBuilder";
public MakeBuilder() {
}
public class MyResourceDeltaVisitor implements IResourceDeltaVisitor {
boolean bContinue;
public boolean visit(IResourceDelta delta) throws CoreException {
IResource resource = delta.getResource();
if (resource != null && resource.getProject() == getProject()) {
bContinue = true;
return false;
}
return true;
}
public boolean shouldBuild() {
return bContinue;
}
}
/**
* @see IncrementalProjectBuilder#build
*/
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
boolean bPerformBuild = true;
IMakeBuilderInfo info = BuildInfoFactory.create(args, MakeBuilder.BUILDER_ID);
if (!shouldBuild(kind, info)) {
return new IProject[0];
}
if (kind == IncrementalProjectBuilder.AUTO_BUILD) {
MyResourceDeltaVisitor vis = new MyResourceDeltaVisitor();
IResourceDelta delta = getDelta(getProject());
if (delta != null) {
delta.accept(vis);
bPerformBuild = vis.shouldBuild();
} else
bPerformBuild = false;
}
if (bPerformBuild) {
boolean isClean = invokeMake(kind, info, monitor);
if (isClean) {
forgetLastBuiltState();
}
}
checkCancel(monitor);
return getProject().getReferencedProjects();
}
private boolean invokeMake(int kind, IMakeBuilderInfo info, IProgressMonitor monitor) {
boolean isClean = false;
boolean isCanceled = false;
IProject currProject = getProject();
SubProgressMonitor subMonitor = null;
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor.beginTask("Invoking the C Builder: " + currProject.getName(), IProgressMonitor.UNKNOWN);
try {
IPath buildCommand = info.getBuildCommand();
if (buildCommand != null) {
IConsole console = CCorePlugin.getDefault().getConsole();
console.start(currProject);
ConsoleOutputStream cos = console.getOutputStream();
// remove all markers for this project
removeAllMarkers(currProject);
IPath workingDirectory = info.getBuildLocation();
String[] targets = getTargets(kind, info);
if (targets.length != 0 && targets[targets.length - 1].equals("clean"))
isClean = true;
// Before launching give visual cues via the monitor
subMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN);
subMonitor.subTask("Invoking Command: " + buildCommand.toString());
String errMsg = null;
CommandLauncher launcher = new CommandLauncher();
// Print the command for visual interaction.
launcher.showCommand(true);
// Set the environmennt, some scripts may need the CWD var to be set.
Properties props = launcher.getEnvironment();
props.put("CWD", workingDirectory.toOSString());
props.put("PWD", workingDirectory.toOSString());
String[] env = null;
ArrayList envList = new ArrayList();
Enumeration names = props.propertyNames();
if (names != null) {
while (names.hasMoreElements()) {
String key = (String) names.nextElement();
envList.add(key + "=" + props.getProperty(key));
}
env = (String[]) envList.toArray(new String[envList.size()]);
}
ErrorParserManager epm = new ErrorParserManager(this);
epm.setOutputStream(cos);
OutputStream stdout = epm.getOutputStream();
OutputStream stderr = epm.getOutputStream();
String[] buildArguments = targets;
if (info.isDefaultBuildCmd()) {
if ( !info.isStopOnError()) {
buildArguments = new String[targets.length + 1];
buildArguments[0] = "-k";
System.arraycopy(targets, 0, buildArguments, 1, targets.length);
}
} else {
String args = info.getBuildArguments();
if ( args != null && !args.equals("")) {
String[] newArgs = makeArray(args);
buildArguments = new String[targets.length + newArgs.length];
System.arraycopy(newArgs, 0, buildArguments, 0, newArgs.length);
System.arraycopy(targets, 0, buildArguments, newArgs.length + 1, targets.length);
}
}
Process p = launcher.execute(buildCommand, buildArguments, env, workingDirectory);
if (p != null) {
try {
// Close the input of the Process explicitely.
// We will never write to it.
p.getOutputStream().close();
} catch (IOException e) {
}
if (launcher.waitAndRead(stdout, stderr, subMonitor) != CommandLauncher.OK)
errMsg = launcher.getErrorMessage();
isCanceled = monitor.isCanceled();
monitor.setCanceled(false);
subMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN);
subMonitor.subTask("Refresh From Local");
try {
currProject.refreshLocal(IResource.DEPTH_INFINITE, subMonitor);
} catch (CoreException e) {
}
subMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN);
subMonitor.subTask("Parsing");
} else {
errMsg = launcher.getErrorMessage();
}
if (errMsg != null) {
StringBuffer buf = new StringBuffer(buildCommand.toString() + " ");
for (int i = 0; i < buildArguments.length; i++) {
buf.append(buildArguments[i]);
buf.append(' ');
}
String errorDesc = MakeCorePlugin.getFormattedString(BUILD_ERROR, buf.toString());
buf = new StringBuffer(errorDesc);
buf.append(System.getProperty("line.separator", "\n"));
buf.append("(").append(errMsg).append(")");
cos.write(buf.toString().getBytes());
cos.flush();
}
stdout.close();
stderr.close();
epm.reportProblems();
subMonitor.done();
monitor.setCanceled(isCanceled);
}
} catch (Exception e) {
CCorePlugin.log(e);
}
monitor.done();
return (isClean);
}
/**
* Check whether the build has been canceled.
*/
public void checkCancel(IProgressMonitor monitor) {
if (monitor != null && monitor.isCanceled())
throw new OperationCanceledException();
}
protected boolean shouldBuild(int kind, IMakeBuilderInfo info) {
switch (kind) {
case IncrementalProjectBuilder.AUTO_BUILD :
return info.isAutoBuildEnable();
case IncrementalProjectBuilder.INCREMENTAL_BUILD :
return info.isIncrementalBuildEnabled();
case IncrementalProjectBuilder.FULL_BUILD :
return info.isFullBuildEnabled();
}
return true;
}
protected String[] getTargets(int kind, IMakeBuilderInfo info) {
String targets = "";
switch (kind) {
case IncrementalProjectBuilder.AUTO_BUILD :
targets = info.getAutoBuildTarget();
break;
case IncrementalProjectBuilder.INCREMENTAL_BUILD :
targets = info.getIncrementalBuildTarget();
break;
case IncrementalProjectBuilder.FULL_BUILD :
targets = info.getFullBuildTarget();
break;
}
return makeArray(targets);
}
// Turn the string into an array.
String[] makeArray(String string) {
string.trim();
char[] array = string.toCharArray();
ArrayList aList = new ArrayList();
StringBuffer buffer = new StringBuffer();
boolean inComment = false;
for (int i = 0; i < array.length; i++) {
char c = array[i];
if (array[i] == '"' || array[i] == '\'') {
if (i > 0 && array[i - 1] == '\\') {
inComment = false;
} else {
inComment = !inComment;
}
}
if (c == ' ' && !inComment) {
aList.add(buffer.toString());
buffer = new StringBuffer();
} else {
buffer.append(c);
}
}
if (buffer.length() > 0)
aList.add(buffer.toString());
return (String[]) aList.toArray(new String[aList.size()]);
}
private void removeAllMarkers(IProject currProject) throws CoreException {
IWorkspace workspace = currProject.getWorkspace();
// remove all markers
IMarker[] markers = currProject.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
if (markers != null) {
workspace.deleteMarkers(markers);
}
}
}

View file

@ -0,0 +1,88 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.runtime.IPluginDescriptor;
import org.eclipse.core.runtime.Plugin;
/**
* The main plugin class to be used in the desktop.
*/
public class MakeCorePlugin extends Plugin {
//The shared instance.
private static MakeCorePlugin plugin;
//Resource bundle.
private ResourceBundle resourceBundle;
/**
* The constructor.
*/
public MakeCorePlugin(IPluginDescriptor descriptor) {
super(descriptor);
plugin = this;
try {
resourceBundle = ResourceBundle.getBundle("org.eclipse.cdt.make.core.PluginResources");
} catch (MissingResourceException x) {
resourceBundle = null;
}
}
/**
* Returns the shared instance.
*/
public static MakeCorePlugin getDefault() {
return plugin;
}
/**
* Returns the string from the plugin's resource bundle,
* or 'key' if not found.
*/
public static String getResourceString(String key) {
ResourceBundle bundle = MakeCorePlugin.getDefault().getResourceBundle();
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
return key;
}
}
public static String getFormattedString(String key, String arg) {
return MessageFormat.format(getResourceString(key), new String[] { arg });
}
/**
* Returns the plugin's resource bundle,
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
public static String getUniqueIdentifier() {
if (getDefault() == null) {
// If the default instance is not yet initialized,
// return a static identifier. This identifier must
// match the plugin id defined in plugin.xml
return "org.eclipse.cdt.make.core"; //$NON-NLS-1$
}
return getDefault().getDescriptor().getUniqueIdentifier();
}
protected void initializeDefaultPluginPreferences() {
BuildInfoFactory.initializeDefaultPreferences(getPluginPreferences());
getPluginPreferences().setDefault(CCorePlugin.PREF_BINARY_PARSER, CCorePlugin.PLUGIN_ID + ".ELF");
}
}

View file

@ -0,0 +1,152 @@
package org.eclipse.cdt.make.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* IBM Rational Software - Initial API and implementation
***********************************************************************/
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
public class MakeProjectNature implements IProjectNature {
private IMakeBuilderInfo fBuildInfo;
public final static String NATURE_ID = MakeCorePlugin.getUniqueIdentifier() + ".makeNature";
private IProject fProject;
public static void addNature(IProject project, SubProgressMonitor monitor) throws CoreException {
IProjectDescription description = project.getDescription();
String[] prevNatures= description.getNatureIds();
for (int i= 0; i < prevNatures.length; i++) {
if (NATURE_ID.equals(prevNatures[i]))
return;
}
String[] newNatures= new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length]= NATURE_ID;
description.setNatureIds(newNatures);
project.setDescription(description, monitor);
}
public static ICommand getBuildSpec(IProject project) throws CoreException {
IProjectDescription description = project.getDescription();
ICommand[] commands = description.getBuildSpec();
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(MakeBuilder.BUILDER_ID)) {
return commands[i];
}
}
return null;
}
public void addToBuildSpec(String builderID, IProgressMonitor mon) throws CoreException {
addToBuildSpec(getProject(), builderID, mon);
}
/**
* Adds a builder to the build spec for the given project.
*/
public static void addToBuildSpec(IProject project, String builderID, IProgressMonitor mon) throws CoreException {
IProjectDescription description = project.getDescription();
ICommand[] commands = description.getBuildSpec();
boolean found = false;
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(builderID)) {
found = true;
break;
}
}
if (!found) {
ICommand command = description.newCommand();
command.setBuilderName(builderID);
ICommand[] newCommands = new ICommand[commands.length + 1];
// Add it before other builders. See 1FWJK7I: ITPJCORE:WIN2000
System.arraycopy(commands, 0, newCommands, 1, commands.length);
newCommands[0] = command;
description.setBuildSpec(newCommands);
project.setDescription(description, mon);
}
}
public void removeBuildSpec(IProgressMonitor mon) throws CoreException {
removeFromBuildSpec(MakeBuilder.BUILDER_ID, mon);
}
/**
* Removes the given builder from the build spec for the given project.
*/
public void removeFromBuildSpec(String builderID, IProgressMonitor mon) throws CoreException {
IProjectDescription description = getProject().getDescription();
ICommand[] commands = description.getBuildSpec();
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(builderID)) {
ICommand[] newCommands = new ICommand[commands.length - 1];
System.arraycopy(commands, 0, newCommands, 0, i);
System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
description.setBuildSpec(newCommands);
break;
}
}
getProject().setDescription(description, mon);
}
/**
* @see IProjectNature#configure
*/
public void configure() throws CoreException {
addToBuildSpec(MakeBuilder.BUILDER_ID, null);
IMakeBuilderInfo info = BuildInfoFactory.create(MakeCorePlugin.getDefault().getPluginPreferences(), MakeBuilder.BUILDER_ID);
fBuildInfo.setBuildLocation(info.getBuildLocation());
fBuildInfo.setUseDefaultBuildCmd(info.isDefaultBuildCmd());
fBuildInfo.setStopOnError(info.isStopOnError());
fBuildInfo.setBuildCommand(info.getBuildCommand());
fBuildInfo.setAutoBuildEnable(info.isAutoBuildEnable());
fBuildInfo.setAutoBuildTarget(info.getAutoBuildTarget());
fBuildInfo.setIncrementalBuildEnable(info.isIncrementalBuildEnabled());
fBuildInfo.setIncrementalBuildTarget(info.getIncrementalBuildTarget());
fBuildInfo.setFullBuildEnable(info.isFullBuildEnabled());
fBuildInfo.setFullBuildTarget(info.getFullBuildTarget());
}
/**
* @see IProjectNature#deconfigure
*/
public void deconfigure() throws CoreException {
removeFromBuildSpec(MakeBuilder.BUILDER_ID, null);
}
/**
* @see IProjectNature#getProject
*/
public IProject getProject() {
return fProject;
}
/**
* @see IProjectNature#setProject
*/
public void setProject(IProject project) {
try {
fProject = project;
fBuildInfo = MakeBuildManager.getBuildInfo(fProject, true);
} catch (CoreException e) {
}
}
}

View file

@ -0,0 +1,2 @@
MakeBuilder.buildError= Error launching builder ({0})

View file

@ -0,0 +1,58 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.make.internal.core;
import org.eclipse.cdt.core.AbstractCExtension;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.core.runtime.IPath;
public class MakeBuilder extends AbstractCExtension /*implements ICBuilder */ {
public IPath[] getIncludePaths() {
return new IPath[0];
}
public void setIncludePaths(IPath[] incPaths) {
}
public IPath[] getLibraryPaths() {
return new IPath[0];
}
public void setLibraryPaths(IPath[] libPaths) {
}
public String[] getLibraries() {
return new String[0];
}
public void setLibraries(String[] libs) {
}
// public IOptimization getOptimization() {
// return null;
// }
//
// public IProject[] build(CIncrementalBuilder cbuilder) {
// ICExtensionReference ref = getExtensionReference();
// System.out.println("MakeBuilder!!!!\n Command is:" + ref.getExtensionData("command"));
// return null;
// }
//
// public void setOptimization(IOptimization o) {
// }
public String getID() {
return MakeCorePlugin.getUniqueIdentifier() + ".makeBuilder";
}
}

View file

@ -0,0 +1,44 @@
package org.eclipse.cdt.make.internal.core;
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
***********************************************************************/
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ICDescriptor;
import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.core.ICOwner;
import org.eclipse.cdt.make.core.MakeBuildManager;
import org.eclipse.cdt.make.core.MakeCorePlugin;
import org.eclipse.core.runtime.CoreException;
public class MakeProject implements ICOwner {
public void configure(ICDescriptor cproject) throws CoreException {
cproject.remove(CCorePlugin.BUILDER_MODEL_ID);
ICExtensionReference ext = cproject.create(CCorePlugin.BUILDER_MODEL_ID, MakeCorePlugin.getUniqueIdentifier() + ".makeBuilder");
ext.setExtensionData("command", "make");
cproject.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID);
cproject.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, MakeBuildManager.INTERFACE_IDENTITY);
}
public void update(ICDescriptor cproject, String extensionID) throws CoreException {
if ( extensionID.equals(CCorePlugin.BUILDER_MODEL_ID ) ) {
ICExtensionReference ext = cproject.create(CCorePlugin.BUILDER_MODEL_ID, MakeCorePlugin.getUniqueIdentifier() + ".makeBuilder");
ext.setExtensionData("command", "make");
}
if ( extensionID.equals(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID)) {
cproject.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, MakeBuildManager.INTERFACE_IDENTITY);
}
if ( extensionID.equals(CCorePlugin.BINARY_PARSER_UNIQ_ID)) {
cproject.create(CCorePlugin.BINARY_PARSER_UNIQ_ID, CCorePlugin.PLUGIN_ID + ".Elf");
}
}
}