Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java')
-rw-r--r--build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java968
1 files changed, 0 insertions, 968 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java
deleted file mode 100644
index aadd19e8233..00000000000
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/MakefileGenerator.java
+++ /dev/null
@@ -1,968 +0,0 @@
-package org.eclipse.cdt.managedbuilder.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 v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Rational Software - Initial API and implementation
- * **********************************************************************/
-
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.search.ICSearchConstants;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.cdt.internal.core.model.Util;
-import org.eclipse.cdt.internal.core.search.PathCollector;
-import org.eclipse.cdt.internal.core.search.PatternSearchJob;
-import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
-import org.eclipse.cdt.internal.core.search.matching.CSearchPattern;
-import org.eclipse.cdt.internal.core.sourcedependency.DependencyQueryJob;
-import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
-import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-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.IResourceProxy;
-import org.eclipse.core.resources.IResourceProxyVisitor;
-import org.eclipse.core.resources.IResourceStatus;
-import org.eclipse.core.resources.IWorkspaceRoot;
-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.Path;
-
-public class MakefileGenerator {
- // String constants for messages
- private static final String MESSAGE = "ManagedMakeBuilder.message"; //$NON-NLS-1$
- private static final String BUILD_ERROR = MESSAGE + ".error"; //$NON-NLS-1$
- private static final String COMMENT = "ManagedMakeBuilder.comment"; //$NON-NLS-1$
- private static final String MOD_LIST = COMMENT + ".module.list"; //$NON-NLS-1$
- private static final String SRC_LISTS = COMMENT + ".source.list"; //$NON-NLS-1$
- private static final String MOD_RULES = COMMENT + ".build.rule"; //$NON-NLS-1$
- private static final String MOD_INCL = COMMENT + ".module.make.includes"; //$NON-NLS-1$
- private static final String DEP_INCL = COMMENT + ".module.dep.includes"; //$NON-NLS-1$
- private static final String AUTO_DEP = COMMENT + ".autodeps"; //$NON-NLS-1$
-
- // String constants for makefile contents
- protected static final String COLON = ":";
- protected static final String DEPFILE_NAME = "subdir.dep"; //$NON-NLS-1$
- protected static final String DOT = ".";
- protected static final String MAKEFILE_NAME = "makefile"; //$NON-NLS-1$
- protected static final String MODFILE_NAME = "subdir.mk"; //$NON-NLS-1$
- protected static final String LINEBREAK = "\\";
- protected static final String NEWLINE = System.getProperty("line.separator");
- protected static final String LOGICAL_AND = "&&";
- protected static final String SEPARATOR = "/";
- protected static final String TAB = "\t";
- protected static final String WHITESPACE = " ";
- protected static final String WILDCARD = "%";
-
- // Local variables needed by generator
- protected IManagedBuildInfo info;
- protected List modifiedList;
- protected IProgressMonitor monitor;
- protected List subdirList;
- protected IProject project;
- protected List ruleList;
- protected IPath topBuildDir;
- private String target;
- private String extension;
-
- /**
- * This class is used to recursively walk the project and determine which
- * modules contribute buildable source files.
- */
- protected class ResourceProxyVisitor implements IResourceProxyVisitor {
- private MakefileGenerator generator;
- private IManagedBuildInfo info;
-
- /**
- * Constructs a new resource proxy visitor to quickly visit project
- * resources.
- */
- public ResourceProxyVisitor(MakefileGenerator generator, IManagedBuildInfo info) {
- this.generator = generator;
- this.info = info;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.resources.IResourceProxy)
- */
- public boolean visit(IResourceProxy proxy) throws CoreException {
- // No point in proceeding, is there
- if (generator == null) {
- return false;
- }
-
- // Is this a resource we should even consider
- if (proxy.getType() == IResource.FILE) {
- // Check extension to see if build model should build this file
- IResource resource = proxy.requestResource();
- String ext = resource.getFileExtension();
- if (info.buildsFileType(ext)) {
- if (!generator.isGeneratedResource(resource)) {
- generator.appendBuildSubdirectory(resource);
- }
- }
- return false;
- }
-
- // Recurse into subdirectories
- return true;
- }
-
- }
-
- public class ResourceDeltaVisitor implements IResourceDeltaVisitor {
- private MakefileGenerator generator;
- private IManagedBuildInfo info;
-
- /**
- *
- */
- public ResourceDeltaVisitor(MakefileGenerator generator, IManagedBuildInfo info) {
- this.generator = generator;
- this.info = info;
- }
-
- /* (non-javadoc)
- * Answers a list of resource names in the workspace that depend on the resource
- * specified in the argument.
- *
- * @param resource the root of the dependency tree
- * @return IResource[]
- */
- private IResource[] findDependencies(IResource resource) {
- PathCollector pathCollector = new PathCollector();
- ICSearchScope scope = SearchEngine.createWorkspaceScope();
- CSearchPattern pattern = CSearchPattern.createPattern(resource.getLocation().toOSString(), ICSearchConstants.INCLUDE, ICSearchConstants.REFERENCES, ICSearchConstants.EXACT_MATCH, true);
- IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
- indexManager.performConcurrentJob(
- new PatternSearchJob(
- (CSearchPattern) pattern,
- scope,
- pathCollector,
- indexManager),
- ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
- null, null);
-
- // We will get back an array of resource names relative to the workspace
- String[] deps = pathCollector.getPaths();
-
- // Convert them to something useful
- List depList = new ArrayList();
- IResource res = null;
- IWorkspaceRoot root = null;
- if (generator.project != null) {
- root = generator.project.getWorkspace().getRoot();
- }
- for (int index = 0; index < deps.length; ++index) {
- res = root.findMember(deps[index]);
- if (res != null) {
- depList.add(res);
- }
- }
-
- return (IResource[]) depList.toArray(new IResource[depList.size()]);
- }
-
- private void handleHeaderDependency(IResource resource, boolean moved) {
- // If this is a move and the resource is external to the project, touch that resource
- if (resource.getProject().equals(generator.project)) {
- generator.appendModifiedSubdirectory(resource);
- } else {
- if (moved) {
- try {
- resource.touch(new NullProgressMonitor());
- } catch (CoreException e) {
- }
- }
- }
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.core.resources.IResourceDeltaVisitor#visit(org.eclipse.core.resources.IResourceDelta)
- */
- public boolean visit(IResourceDelta delta) throws CoreException {
- // Should the visitor keep iterating in current directory
- boolean keepLooking = false;
- IResource resource = delta.getResource();
-
- // What kind of resource change has occurred
- if (resource.getType() == IResource.FILE) {
- String ext = resource.getFileExtension();
- boolean moved = false;
- switch (delta.getKind()) {
- case IResourceDelta.ADDED:
- moved = delta.getFlags() == IResourceDelta.MOVED_TO;
- if (!generator.isGeneratedResource(resource)) {
- // This is a source file so just add its container
- if (info.buildsFileType(ext)) {
- generator.appendModifiedSubdirectory(resource);
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps = findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- }
- }
- break;
- case IResourceDelta.REMOVED:
- moved = delta.getFlags() == IResourceDelta.MOVED_FROM;
- if (!generator.isGeneratedResource(resource)) {
- // This is a source file so just add its container
- if (info.buildsFileType(ext)) {
- generator.appendModifiedSubdirectory(resource);
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps = findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- }
- }
- break;
- case IResourceDelta.CHANGED:
- if (!generator.isGeneratedResource(resource)) {
- if (info.buildsFileType(ext)) {
- keepLooking = true;
- } else if (info.isHeaderFile(ext)) {
- // Add the container of the resource and any resources that depend on it
- generator.appendModifiedSubdirectory(resource);
- IResource[] deps= findDependencies(resource);
- for (int i = 0; i < deps.length; ++i){
- handleHeaderDependency(deps[i], moved);
- }
- // That does it for this directory, so don't bother to keep looking
- }
- }
- break;
- default:
- keepLooking = true;
- break;
- }
- } if (resource.getType() == IResource.PROJECT) {
- // If there is a zero-length delta, something the project depends on has changed so just call make
- IResourceDelta[] children = delta.getAffectedChildren();
- if (children != null && children.length > 0) {
- keepLooking = true;
- }
- } else {
- // If the resource is part of the generated directory structure don't recurse
- if (!generator.isGeneratedResource(resource)) {
- keepLooking = true;
- }
- }
-
- return keepLooking;
- }
- }
-
- /**
- * @param project
- * @param info
- * @param monitor
- */
- public MakefileGenerator(IProject project, IManagedBuildInfo info, IProgressMonitor monitor) {
- super();
- // Save the project so we can get path and member information
- this.project = project;
- // Save the monitor reference for reporting back to the user
- this.monitor = monitor;
- // Get the build info for the project
- this.info = info;
- // Get the name of the build target
- target = info.getBuildArtifactName();
- // Get its extension
- extension = (new Path(target)).getFileExtension();
- if (extension == null) {
- extension = new String();
- }
- }
-
- /* (non-javadoc)
- * Calculates dependencies for all the source files in the argument. A source
- * file can depend on any number of header files, so the dependencies have to
- * be added to its dependency list.
- *
- * @param module
- * @return
- */
- protected StringBuffer addSourceDependencies(IContainer module) throws CoreException {
- // Calculate the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- String relativePath = moduleRelativePath.toString();
- relativePath += relativePath.length() == 0 ? "" : SEPARATOR;
-
- // Create the buffer to hold the output for the module and a dep calculator
- StringBuffer buffer = new StringBuffer();
- buffer.append(ManagedBuilderCorePlugin.getResourceString(AUTO_DEP) + NEWLINE);
- IndexManager indexManager = CCorePlugin.getDefault().getCoreModel().getIndexManager();
-
- /*
- * Visit each resource in the folder that we have a rule to build.
- * The dependency output for each resource will be in the format
- * <relativePath>/<resourceName>.<outputExtension> : <dep1> ... <depn>
- * with long lines broken.
- */
- IResource[] resources = module.members();
- for (int i = 0; i < resources.length; i++) {
- IResource resource = resources[i];
- if (resource.getType() == IResource.FILE) {
- String inputExt = resource.getFileExtension();
- if (info.buildsFileType(inputExt)) {
- // Get the filename without an extension
- String fileName = resource.getFullPath().removeFileExtension().lastSegment();
- if (fileName == null) continue;
- String outputExt = info.getOutputExtension(inputExt);
- if (outputExt != null) {
- fileName += DOT + outputExt;
- }
- // ASk the dep generator to find all the deps for this resource
- ArrayList dependencies = new ArrayList();
- try {
- indexManager.performConcurrentJob(new DependencyQueryJob(project, (IFile)resource, indexManager, dependencies), ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null, null);
- } catch (Exception e) {
- continue;
- }
- if (dependencies.size() == 0) continue;
- buffer.append(relativePath + fileName + COLON + WHITESPACE);
- Iterator iter = dependencies.listIterator();
- while (iter.hasNext()) {
- buffer.append(LINEBREAK + NEWLINE);
- String path = (String)iter.next();
- buffer.append(path + WHITESPACE);
- }
- buffer.append(NEWLINE);
- }
- }
- }
- return buffer;
- }
-
- /* (non-javadoc)
- * @param buffer
- * @param info
- */
- protected StringBuffer addMacros() {
- StringBuffer buffer = new StringBuffer();
-
- // Add the ROOT macro
- buffer.append("ROOT := .." + NEWLINE);
-
- // Get the clean command from the build model
- buffer.append("RM := ");
- buffer.append(info.getCleanCommand() + NEWLINE + NEWLINE);
-
- buffer.append(ManagedBuilderCorePlugin.getResourceString(SRC_LISTS) + NEWLINE);
- buffer.append("C_SRCS := " + NEWLINE);
- buffer.append("CC_SRCS := " + NEWLINE);
- buffer.append("CXX_SRCS := " + NEWLINE);
- buffer.append("CAPC_SRCS := " + NEWLINE);
- buffer.append("CPP_SRCS := " + NEWLINE + NEWLINE);
-
- // Add the libraries this project depends on
- buffer.append("LIBS := ");
- String[] libs = info.getLibsForTarget(extension);
- for (int i = 0; i < libs.length; i++) {
- String string = libs[i];
- buffer.append(LINEBREAK + NEWLINE + string);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- // Add the extra user-specified objects
- buffer.append("USER_OBJS := ");
- String[] userObjs = info.getUserObjectsForTarget(extension);
- for (int j = 0; j < userObjs.length; j++) {
- String string = userObjs[j];
- buffer.append(LINEBREAK + NEWLINE + string);
- }
- buffer.append(NEWLINE + NEWLINE);
-
- buffer.append("OBJS = $(C_SRCS:$(ROOT)/%.c=%.o) $(CC_SRCS:$(ROOT)/%.cc=%.o) $(CXX_SRCS:$(ROOT)/%.cxx=%.o) $(CAPC_SRCS:$(ROOT)/%.C=%.o) $(CPP_SRCS:$(ROOT)/%.cpp=%.o)" + NEWLINE);
- return (buffer.append(NEWLINE));
- }
-
- /* (non-javadoc)
- * @return
- */
- protected StringBuffer addSubdirectories() {
- StringBuffer buffer = new StringBuffer();
- // Add the comment
- buffer.append(ManagedBuilderCorePlugin.getResourceString(MOD_LIST) + NEWLINE);
- buffer.append("SUBDIRS := " + LINEBREAK + NEWLINE);
-
- // Get all the module names
- ListIterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- IContainer container = (IContainer) iter.next();
- // Check the special case where the module is the project root
- if (container.getFullPath() == project.getFullPath()) {
- buffer.append("." + WHITESPACE + LINEBREAK + NEWLINE);
- } else {
- IPath path = container.getProjectRelativePath();
- buffer.append(path.toString() + WHITESPACE + LINEBREAK + NEWLINE);
- }
- }
-
- // Now add the makefile instruction to include all the subdirectory makefile fragments
- buffer.append(NEWLINE);
- buffer.append(ManagedBuilderCorePlugin.getResourceString(MOD_INCL) + NEWLINE);
- buffer.append("-include ${patsubst %, %/subdir.mk, $(SUBDIRS)}" + NEWLINE);
-
- buffer.append(NEWLINE + NEWLINE);
- return buffer;
- }
-
-
- /* (non-javadoc)
- * Answers a <code>StringBuffer</code> containing all of the sources contributed by
- * a container to the build.
- *
- * @param module
- * @return StringBuffer
- */
- protected StringBuffer addSources(IContainer module) throws CoreException {
- // Calculate the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- String relativePath = moduleRelativePath.toString();
- relativePath += relativePath.length() == 0 ? "" : SEPARATOR;
-
- // String buffers
- StringBuffer buffer = new StringBuffer();
- StringBuffer cBuffer = new StringBuffer("C_SRCS += " + LINEBREAK + NEWLINE);
- cBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE);
- StringBuffer ccBuffer = new StringBuffer("CC_SRCS += \\" + NEWLINE);
- ccBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE);
- StringBuffer cxxBuffer = new StringBuffer("CXX_SRCS += \\" + NEWLINE);
- cxxBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE);
- StringBuffer capcBuffer = new StringBuffer("CAPC_SRCS += \\" + NEWLINE);
- capcBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE);
- StringBuffer cppBuffer = new StringBuffer("CPP_SRCS += \\" + NEWLINE);
- cppBuffer.append("${addprefix $(ROOT)/" + relativePath + "," + LINEBREAK + NEWLINE);
- StringBuffer ruleBuffer = new StringBuffer(ManagedBuilderCorePlugin.getResourceString(MOD_RULES) + NEWLINE);
-
- // Put the comment in
- buffer.append(ManagedBuilderCorePlugin.getResourceString(SRC_LISTS) + NEWLINE);
-
- // Visit the resources in this folder
- IResource[] resources = module.members();
- for (int i = 0; i < resources.length; i++) {
- IResource resource = resources[i];
- if (resource.getType() == IResource.FILE) {
- String ext = resource.getFileExtension();
- if (info.buildsFileType(ext)) {
- if (new String("c").equals(ext)) {
- cBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("cc").equalsIgnoreCase(ext)) {
- ccBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("cxx").equalsIgnoreCase(ext)) {
- cxxBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else if (new String("C").equals(ext)) {
- capcBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- } else {
- cppBuffer.append(resource.getName() + WHITESPACE + LINEBREAK + NEWLINE);
- }
-
- // Try to add the rule for the file
- addRule(relativePath, ruleBuffer, resource);
- }
- }
- }
-
- // Finish the commands in the buffers
- buffer.append(cBuffer.append("}" + NEWLINE + NEWLINE));
- buffer.append(ccBuffer.append("}" + NEWLINE + NEWLINE));
- buffer.append(cxxBuffer.append("}" + NEWLINE + NEWLINE));
- buffer.append(capcBuffer.append("}" + NEWLINE + NEWLINE));
- buffer.append(cppBuffer.append("}" + NEWLINE + NEWLINE));
-
- return buffer.append(ruleBuffer + NEWLINE);
- }
-
- /* (non-javadoc)
- * Answers a <code>StrinBuffer</code> containing all of the required targets to
- * properly build the project.
- *
- * @return StringBuffer
- */
- protected StringBuffer addTargets(boolean rebuild) {
- StringBuffer buffer = new StringBuffer();
-
- // Assemble the information needed to generate the targets
- String cmd = info.getToolForTarget(extension);
- String flags = info.getFlagsForTarget(extension);
- String outflag = info.getOutputFlag(extension);
- String outputPrefix = info.getOutputPrefix(extension);
- String targets = rebuild ? "clean all" : "all";
-
- // Get all the projects the build target depends on
- IProject[] deps = null;
- try {
- deps = project.getReferencedProjects();
- } catch (CoreException e) {
- // There are 2 exceptions; the project does not exist or it is not open
- // and neither conditions apply if we are building for it ....
- }
-
- // Write out the all target first in case someone just runs make
- // all: targ_<target_name> [deps]
- String defaultTarget = "all:";
- if (deps.length > 0) {
- defaultTarget += WHITESPACE + "deps";
- }
- buffer.append(defaultTarget + WHITESPACE + outputPrefix + target + NEWLINE);
- buffer.append(NEWLINE);
-
- /*
- * The build target may depend on other projects in the workspace. These are
- * captured in the deps target:
- * deps:
- * <cd <Proj_Dep_1/build_dir>; $(MAKE) [clean all | all]>
- */
- List managedProjectOutputs = new ArrayList();
- if (deps.length > 0) {
- buffer.append("deps:" + NEWLINE);
- if (deps != null) {
- for (int i = 0; i < deps.length; i++) {
- IProject dep = deps[i];
- String buildDir = dep.getLocation().toString();
- String depTargets = targets;
- if (ManagedBuildManager.manages(dep)) {
- // Add the current configuration to the makefile path
- IManagedBuildInfo depInfo = ManagedBuildManager.getBuildInfo(dep);
- buildDir += SEPARATOR + depInfo.getConfigurationName();
-
- // Extract the build artifact to add to the dependency list
- String depTarget = depInfo.getBuildArtifactName();
- String depExt = (new Path(depTarget)).getFileExtension();
- String depPrefix = depInfo.getOutputPrefix(depExt);
- if (depInfo.isDirty()) {
- depTargets = "clean all";
- }
- managedProjectOutputs.add(buildDir + SEPARATOR + depPrefix + depTarget);
- }
- buffer.append(TAB + "-cd" + WHITESPACE + buildDir + WHITESPACE + LOGICAL_AND + WHITESPACE + "$(MAKE) " + depTargets + NEWLINE);
- }
- }
- buffer.append(NEWLINE);
- }
-
- /*
- * Write out the target rule as:
- * targ_<prefix><target>.<extension>: $(OBJS) [<dep_proj_1_output> ... <dep_proj_n_output>]
- * $(BUILD_TOOL) $(FLAGS) $(OUTPUT_FLAG) $@ $(OBJS) $(USER_OBJS) $(LIB_DEPS)
- */
- buffer.append(outputPrefix + target + COLON + WHITESPACE + "$(OBJS)");
- Iterator iter = managedProjectOutputs.listIterator();
- while (iter.hasNext()) {
- buffer.append(WHITESPACE + (String)iter.next());
- }
- buffer.append(NEWLINE);
- buffer.append(TAB + cmd + WHITESPACE + flags + WHITESPACE + outflag + WHITESPACE + "$@" + WHITESPACE + "$(OBJS) $(USER_OBJS) $(LIBS)");
- buffer.append(NEWLINE + NEWLINE);
-
- // Always add a clean target
- buffer.append("clean:" + NEWLINE);
- buffer.append(TAB + "-$(RM)" + WHITESPACE + "$(OBJS)" + WHITESPACE + outputPrefix + target + NEWLINE + NEWLINE);
-
- buffer.append(".PHONY: all clean deps" + NEWLINE + NEWLINE);
-
- buffer.append(ManagedBuilderCorePlugin.getResourceString(DEP_INCL) + NEWLINE);
- buffer.append("-include ${patsubst %, %/subdir.dep, $(SUBDIRS)}" + NEWLINE);
- return buffer;
- }
-
- /* (non-javadoc)
- *
- * @param relativePath
- * @param buffer
- * @param resource
- */
- protected void addRule(String relativePath, StringBuffer buffer, IResource resource) {
- String rule = null;
- String cmd = null;
- String buildFlags = null;
- String inputExtension = null;
- String outputExtension = null;
- String outflag = null;
- String outputPrefix = null;
-
- // Is there a special rule for this file
- if (false) {
- }
- else {
- // Get the extension of the resource
- inputExtension = resource.getFileExtension();
- // ASk the build model what it will produce from this
- outputExtension = info.getOutputExtension(inputExtension);
- /*
- * Create the pattern rule in the format
- * <relative_path>/%.o: $(ROOT)/<relative_path>/%.cpp
- * $(CC) $(CFLAGS) $(OUTPUT_FLAG) $@ $<
- *
- * Note that CC CFLAGS and OUTPUT_FLAG all come from the build model
- * and are resolved to a real command before writing to the module
- * makefile, so a real command might look something like
- * source1/%.o: $(ROOT)/source1/%.cpp
- * g++ -g -O2 -c -I/cygdrive/c/eclipse/workspace/Project/headers -o $@ $<
- */
- rule = relativePath + WILDCARD + DOT + outputExtension + COLON + WHITESPACE + "$(ROOT)" + SEPARATOR + relativePath + WILDCARD + DOT + inputExtension;
- }
-
- // Check if the rule is listed as something we already generated in the makefile
- if (!getRuleList().contains(rule)) {
- // Add it to the list
- getRuleList().add(rule);
-
- // Add the rule and command to the makefile
- buffer.append(rule + NEWLINE);
- cmd = info.getToolForSource(inputExtension);
- buildFlags = info.getFlagsForSource(inputExtension);
- outflag = info.getOutputFlag(outputExtension);
- outputPrefix = info.getOutputPrefix(outputExtension);
- buffer.append(TAB + cmd + WHITESPACE + buildFlags + WHITESPACE + outflag + WHITESPACE + outputPrefix + "$@" + WHITESPACE + "$<" + NEWLINE + NEWLINE);
- }
- }
-
- /**
- * Adds the container of the argument to the list of folders in the project that
- * contribute source files to the build. The resource visitor has already established
- * that the build model knows how to build the files. It has also checked that
- * the resource is not generated as part of the build.
- *
- * @param resource
- */
- public void appendBuildSubdirectory(IResource resource) {
- IContainer container = resource.getParent();
- if (!getSubdirList().contains(container)) {
- getSubdirList().add(container);
- }
-
- }
-
- /**
- * Adds the container of the argument to a list of subdirectories that are part
- * of an incremental rebuild of the project. The makefile fragments for these
- * directories will be regenerated as a result of the build.
- *
- * @param resource
- */
- public void appendModifiedSubdirectory(IResource resource) {
- IContainer container = resource.getParent();
- if (!getModifiedList().contains(container)) {
- getModifiedList().add(container);
- }
- }
-
- /**
- * Check whether the build has been cancelled. Cancellation requests
- * propagated to the caller by throwing <code>OperationCanceledException</code>.
- *
- * @see org.eclipse.core.runtime.OperationCanceledException#OperationCanceledException()
- */
- public void checkCancel() {
- if (monitor != null && monitor.isCanceled()) {
- throw new OperationCanceledException();
- }
- }
-
-
- /**
- * Clients call this method when an incremental rebuild is required. The argument
- * contains a set of resource deltas that will be used to determine which
- * subdirectories need a new makefile and dependency list (if any).
- *
- * @param delta
- * @throws CoreException
- */
- public void generateMakefiles(IResourceDelta delta) throws CoreException {
- /*
- * Let's do a sanity check right now.
- *
- * 1. This is an incremental build, so if the top-level directory is not
- * there, then a rebuild is needed.
- */
- IFolder folder = project.getFolder(info.getConfigurationName());
- if (!folder.exists()) {
- regenerateMakefiles();
- return;
- }
-
- // Visit the resources in the delta and compile a list of subdirectories to regenerate
- ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(this, info);
- delta.accept(visitor);
-
- // See if the user has cancelled the build
- checkCancel();
-
- // The top-level makefile needs this information
- ResourceProxyVisitor resourceVisitor = new ResourceProxyVisitor(this, info);
- project.accept(resourceVisitor, IResource.NONE);
- checkCancel();
-
- // Regenerate any fragments that are missing for the exisiting directories NOT modified
- Iterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- IContainer subdirectory = (IContainer)iter.next();
- if (!getModifiedList().contains(subdirectory)) {
- // Make sure a fragment makefile and dependency file exist
- IFile makeFragment = project.getFile(subdirectory.getFullPath().addTrailingSeparator().append(MODFILE_NAME));
- IFile depFragment = project.getFile(subdirectory.getFullPath().addTrailingSeparator().append(DEPFILE_NAME));
- if (!makeFragment.exists() || !depFragment.exists()) {
- // If one or both are missing, then add it to the list to be generated
- getModifiedList().add(subdirectory);
- }
- }
- }
-
- // Re-create the top-level makefile
- topBuildDir = createDirectory(info.getConfigurationName());
- IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
- IFile makefileHandle = createFile(makefilePath);
- populateTopMakefile(makefileHandle, false);
- checkCancel();
-
- // Regenerate any fragments for modified directories
- iter = getModifiedList().listIterator();
- while (iter.hasNext()) {
- populateFragmentMakefile((IContainer) iter.next());
- checkCancel();
- }
- }
-
- /* (non-javadoc)
- *
- * @return List
- */
- private List getModifiedList() {
- if (modifiedList == null) {
- modifiedList = new ArrayList();
- }
- return modifiedList;
- }
-
- /* (non-javadoc)
- * Answers the list of known build rules. This keeps me from generating duplicate
- * rules for known file extensions.
- *
- * @return List
- */
- private List getRuleList() {
- if (ruleList == null) {
- ruleList = new ArrayList();
- }
- return ruleList;
- }
-
- /* (non-javadoc)
- * Answers the list of subdirectories contributing source code to the build
- *
- * @return List
- */
- private List getSubdirList() {
- if (subdirList == null) {
- subdirList = new ArrayList();
- }
- return subdirList;
- }
-
- /* (non-javadoc)
- * @param string
- * @return IPath
- */
- private IPath createDirectory(String dirName) throws CoreException {
- // Create or get the handle for the build directory
- IFolder folder = project.getFolder(dirName);
- if (!folder.exists()) {
-
- // Make sure that parent folders exist
- IPath parentPath = (new Path(dirName)).removeLastSegments(1);
- // Assume that the parent exists if the path is empty
- if (!parentPath.isEmpty()) {
- IFolder parent = project.getFolder(parentPath);
- if (!parent.exists()) {
- createDirectory(parentPath.toString());
- }
- }
-
- // Now make the requested folder
- try {
- folder.create(true, true, null);
- }
- catch (CoreException e) {
- if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
- folder.refreshLocal(IResource.DEPTH_ZERO, null);
- else
- throw e;
- }
- }
- return folder.getFullPath();
- }
-
- /* (non-javadoc)
- * @param makefilePath
- * @param monitor
- * @return IFile
- */
- private IFile createFile(IPath makefilePath) throws CoreException {
- // Create or get the handle for the makefile
- IWorkspaceRoot root = CCorePlugin.getWorkspace().getRoot();
- IFile newFile = root.getFileForLocation(makefilePath);
- if (newFile == null) {
- newFile = root.getFile(makefilePath);
- }
- // Create the file if it does not exist
- ByteArrayInputStream contents = new ByteArrayInputStream(new byte[0]);
- try {
- newFile.create(contents, false, monitor);
- }
- catch (CoreException e) {
- // If the file already existed locally, just refresh to get contents
- if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED)
- newFile.refreshLocal(IResource.DEPTH_ZERO, null);
- else
- throw e;
- }
-
- return newFile;
- }
-
- /**
- * Answers the <code>IPath</code> of the top directory generated for the build
- * output, or <code>null</code> if none has been generated.
- *
- * @return IPath
- */
- public IPath getTopBuildDir() {
- return topBuildDir;
- }
-
- /**
- * Answers <code>true</code> if the argument is found in a generated container
- * @param resource
- * @return boolean
- */
- public boolean isGeneratedResource(IResource resource) {
- // Is this a generated directory ...
- IPath path = resource.getProjectRelativePath();
- String[] configNames = info.getConfigurationNames();
- for (int i = 0; i < configNames.length; i++) {
- String name = configNames[i];
- IPath root = new Path(name);
- // It is if it is a root of the resource pathname
- if (root.isPrefixOf(path)) return true;
- }
-
- return false;
- }
-
- /* (non-javadoc)
- * Create the entire contents of the makefile.
- *
- * @param fileHandle The file to place the contents in.
- * @param rebuild FLag signalling that the user is doing a full rebuild
- * @throws CoreException
- */
- protected void populateTopMakefile(IFile fileHandle, boolean rebuild) throws CoreException {
- StringBuffer buffer = new StringBuffer();
-
- // Add the macro definitions
- buffer.append(addMacros());
-
- // Append the module list
- buffer.append(addSubdirectories());
-
- // Add targets
- buffer.append(addTargets(rebuild));
-
- // Save the file
- Util.save(buffer, fileHandle);
- }
-
- /* (non-javadoc)
- * @param module
- * @throws CoreException
- */
- protected void populateFragmentMakefile(IContainer module) throws CoreException {
- // Calcualte the new directory relative to the build output
- IPath moduleRelativePath = module.getProjectRelativePath();
- IPath buildRoot = getTopBuildDir().removeFirstSegments(1);
- if (buildRoot == null) {
- return;
- }
- IPath moduleOutputPath = buildRoot.append(moduleRelativePath);
-
- // Now create the directory
- IPath moduleOutputDir = createDirectory(moduleOutputPath.toString());
-
- // Create a module makefile
- IFile modMakefile = createFile(moduleOutputDir.addTrailingSeparator().append(MODFILE_NAME));
- StringBuffer makeBuf = new StringBuffer();
- makeBuf.append(addSources(module));
-
- // Create a module dep file
- IFile modDepfile = createFile(moduleOutputDir.addTrailingSeparator().append(DEPFILE_NAME));
- StringBuffer depBuf = new StringBuffer();
- depBuf.append(addSourceDependencies(module));
-
- // Save the files
- Util.save(makeBuf, modMakefile);
- Util.save(depBuf, modDepfile);
- }
-
-
- /**
- * @throws CoreException
- */
- public void regenerateMakefiles() throws CoreException {
- // Visit the resources in the project
- ResourceProxyVisitor visitor = new ResourceProxyVisitor(this, info);
- project.accept(visitor, IResource.NONE);
-
- // See if the user has cancelled the build
- checkCancel();
-
- // Populate the makefile if any source files have been found in the project
- if (getSubdirList().isEmpty()) {
- return;
- }
-
- // Create the top-level directory for the build output
- topBuildDir = createDirectory(info.getConfigurationName());
-
- // Create the top-level makefile
- IPath makefilePath = topBuildDir.addTrailingSeparator().append(MAKEFILE_NAME);
- IFile makefileHandle = createFile(makefilePath);
-
- populateTopMakefile(makefileHandle, true);
- checkCancel();
-
- // Now populate the module makefiles
- ListIterator iter = getSubdirList().listIterator();
- while (iter.hasNext()) {
- populateFragmentMakefile((IContainer)iter.next());
- checkCancel();
- }
- }
-}

Back to the top