Restructuring for better separation of Tool packages.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1674 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -0,0 +1,75 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.AslcompilerDef;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
|
||||
/**
|
||||
* An abstract asl compiler implementation.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractAslcompiler extends AbstractProcessor
|
||||
implements Aslcompiler {
|
||||
private String outputSuffix;
|
||||
protected AbstractAslcompiler(String[] sourceExtensions,
|
||||
String[] headerExtensions, String outputSuffix) {
|
||||
super(sourceExtensions, headerExtensions);
|
||||
this.outputSuffix = outputSuffix;
|
||||
}
|
||||
abstract protected AslcompilerConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
AslcompilerDef specificConfig, TargetDef targetPlatform);
|
||||
|
||||
public ProcessorConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
ProcessorDef specificConfig, TargetDef targetPlatform) {
|
||||
if (specificConfig == null) {
|
||||
throw new NullPointerException("specificConfig");
|
||||
}
|
||||
return createConfiguration(task, linkType, baseConfigs,
|
||||
(AslcompilerDef) specificConfig, targetPlatform);
|
||||
}
|
||||
|
||||
public String getOutputFileName(String inputFile) {
|
||||
if (bid(inputFile) > 1) {
|
||||
String baseName = getBaseOutputName(inputFile);
|
||||
return baseName + outputSuffix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected String getBaseOutputName(String inputFile) {
|
||||
int lastSlash = inputFile.lastIndexOf('/');
|
||||
int lastReverse = inputFile.lastIndexOf('\\');
|
||||
int lastSep = inputFile.lastIndexOf(File.separatorChar);
|
||||
if (lastReverse > lastSlash) {
|
||||
lastSlash = lastReverse;
|
||||
}
|
||||
if (lastSep > lastSlash) {
|
||||
lastSlash = lastSep;
|
||||
}
|
||||
int lastPeriod = inputFile.lastIndexOf('.');
|
||||
if (lastPeriod < 0) {
|
||||
lastPeriod = inputFile.length();
|
||||
}
|
||||
return inputFile.substring(lastSlash + 1, lastPeriod);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.AssemblerDef;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
/**
|
||||
* An abstract assembler implementation.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractAssembler extends AbstractProcessor
|
||||
implements Assembler {
|
||||
private String outputSuffix;
|
||||
protected AbstractAssembler(String[] sourceExtensions,
|
||||
String[] headerExtensions, String outputSuffix) {
|
||||
super(sourceExtensions, headerExtensions);
|
||||
this.outputSuffix = outputSuffix;
|
||||
}
|
||||
abstract protected AssemblerConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
AssemblerDef specificConfig, TargetDef targetPlatform);
|
||||
public ProcessorConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
ProcessorDef specificConfig, TargetDef targetPlatform) {
|
||||
if (specificConfig == null) {
|
||||
throw new NullPointerException("specificConfig");
|
||||
}
|
||||
return createConfiguration(task, linkType, baseConfigs,
|
||||
(AssemblerDef) specificConfig, targetPlatform);
|
||||
}
|
||||
public String getOutputFileName(String inputFile) {
|
||||
if (bid(inputFile) > 1) {
|
||||
String baseName = getBaseOutputName(inputFile);
|
||||
return baseName + outputSuffix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected String getBaseOutputName(String inputFile) {
|
||||
int lastSlash = inputFile.lastIndexOf('/');
|
||||
int lastReverse = inputFile.lastIndexOf('\\');
|
||||
int lastSep = inputFile.lastIndexOf(File.separatorChar);
|
||||
if (lastReverse > lastSlash) {
|
||||
lastSlash = lastReverse;
|
||||
}
|
||||
if (lastSep > lastSlash) {
|
||||
lastSlash = lastSep;
|
||||
}
|
||||
int lastPeriod = inputFile.lastIndexOf('.');
|
||||
if (lastPeriod < 0) {
|
||||
lastPeriod = inputFile.length();
|
||||
}
|
||||
return inputFile.substring(lastSlash + 1, lastPeriod);
|
||||
}
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Vector;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CUtil;
|
||||
import net.sf.antcontrib.cpptasks.CompilerDef;
|
||||
import net.sf.antcontrib.cpptasks.DependencyInfo;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.parser.Parser;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
|
||||
/**
|
||||
* An abstract compiler implementation.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public abstract class AbstractCompiler extends AbstractProcessor
|
||||
implements
|
||||
Compiler {
|
||||
private static final String[] emptyIncludeArray = new String[0];
|
||||
private String outputSuffix;
|
||||
protected AbstractCompiler(String[] sourceExtensions,
|
||||
String[] headerExtensions, String outputSuffix) {
|
||||
super(sourceExtensions, headerExtensions);
|
||||
this.outputSuffix = outputSuffix;
|
||||
}
|
||||
/**
|
||||
* Checks file name to see if parse should be attempted
|
||||
*
|
||||
* Default implementation returns false for files with extensions '.dll',
|
||||
* 'tlb', '.res'
|
||||
*
|
||||
*/
|
||||
protected boolean canParse(File sourceFile) {
|
||||
String sourceName = sourceFile.toString();
|
||||
int lastPeriod = sourceName.lastIndexOf('.');
|
||||
if (lastPeriod >= 0 && lastPeriod == sourceName.length() - 4) {
|
||||
String ext = sourceName.substring(lastPeriod).toUpperCase();
|
||||
if (ext.equals(".DLL") || ext.equals(".TLB") || ext.equals(".RES")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
abstract protected CompilerConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
CompilerDef specificConfig, TargetDef targetPlatform);
|
||||
public ProcessorConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
ProcessorDef specificConfig, TargetDef targetPlatform) {
|
||||
if (specificConfig == null) {
|
||||
throw new NullPointerException("specificConfig");
|
||||
}
|
||||
return createConfiguration(task, linkType, baseConfigs,
|
||||
(CompilerDef) specificConfig, targetPlatform);
|
||||
}
|
||||
abstract protected Parser createParser(File sourceFile);
|
||||
protected String getBaseOutputName(String inputFile) {
|
||||
int lastSlash = inputFile.lastIndexOf('/');
|
||||
int lastReverse = inputFile.lastIndexOf('\\');
|
||||
int lastSep = inputFile.lastIndexOf(File.separatorChar);
|
||||
if (lastReverse > lastSlash) {
|
||||
lastSlash = lastReverse;
|
||||
}
|
||||
if (lastSep > lastSlash) {
|
||||
lastSlash = lastSep;
|
||||
}
|
||||
int lastPeriod = inputFile.lastIndexOf('.');
|
||||
if (lastPeriod < 0) {
|
||||
lastPeriod = inputFile.length();
|
||||
}
|
||||
return inputFile.substring(lastSlash + 1, lastPeriod);
|
||||
}
|
||||
public String getOutputFileName(String inputFile) {
|
||||
//
|
||||
// if a recognized input file
|
||||
//
|
||||
if (bid(inputFile) > 1) {
|
||||
String baseName = getBaseOutputName(inputFile);
|
||||
return baseName + outputSuffix;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Returns dependency info for the specified source file
|
||||
*
|
||||
* @param task
|
||||
* task for any diagnostic output
|
||||
* @param source
|
||||
* file to be parsed
|
||||
* @param includePath
|
||||
* include path to be used to resolve included files
|
||||
*
|
||||
* @param sysIncludePath
|
||||
* sysinclude path from build file, files resolved using
|
||||
* sysInclude path will not participate in dependency analysis
|
||||
*
|
||||
* @param envIncludePath
|
||||
* include path from environment variable, files resolved with
|
||||
* envIncludePath will not participate in dependency analysis
|
||||
*
|
||||
* @param baseDir
|
||||
* used to produce relative paths in DependencyInfo
|
||||
* @param includePathIdentifier
|
||||
* used to distinguish DependencyInfo's from different include
|
||||
* path settings
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public final DependencyInfo parseIncludes(CCTask task, File source,
|
||||
File[] includePath, File[] sysIncludePath, File[] envIncludePath,
|
||||
File baseDir, String includePathIdentifier) {
|
||||
//
|
||||
// if any of the include files can not be identified
|
||||
// change the sourceLastModified to Long.MAX_VALUE to
|
||||
// force recompilation of anything that depends on it
|
||||
long sourceLastModified = source.lastModified();
|
||||
File[] sourcePath = new File[1];
|
||||
sourcePath[0] = new File(source.getParent());
|
||||
Vector onIncludePath = new Vector();
|
||||
Vector onSysIncludePath = new Vector();
|
||||
String baseDirPath;
|
||||
try {
|
||||
baseDirPath = baseDir.getCanonicalPath();
|
||||
} catch (IOException ex) {
|
||||
baseDirPath = baseDir.toString();
|
||||
}
|
||||
String relativeSource = CUtil.getRelativePath(baseDirPath, source);
|
||||
String[] includes = emptyIncludeArray;
|
||||
if (canParse(source)) {
|
||||
Parser parser = createParser(source);
|
||||
try {
|
||||
Reader reader = new BufferedReader(new FileReader(source));
|
||||
parser.parse(reader);
|
||||
includes = parser.getIncludes();
|
||||
} catch (IOException ex) {
|
||||
task.log("Error parsing " + source.toString() + ":"
|
||||
+ ex.toString());
|
||||
includes = new String[0];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < includes.length; i++) {
|
||||
String includeName = includes[i];
|
||||
if (!resolveInclude(includeName, sourcePath, onIncludePath)) {
|
||||
if (!resolveInclude(includeName, includePath, onIncludePath)) {
|
||||
if (!resolveInclude(includeName, sysIncludePath,
|
||||
onSysIncludePath)) {
|
||||
if (!resolveInclude(includeName, envIncludePath,
|
||||
onSysIncludePath)) {
|
||||
//
|
||||
// this should be enough to require us to reparse
|
||||
// the file with the missing include for dependency
|
||||
// information without forcing a rebuild
|
||||
sourceLastModified++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < onIncludePath.size(); i++) {
|
||||
String relativeInclude = CUtil.getRelativePath(baseDirPath,
|
||||
(File) onIncludePath.elementAt(i));
|
||||
onIncludePath.setElementAt(relativeInclude, i);
|
||||
}
|
||||
for (int i = 0; i < onSysIncludePath.size(); i++) {
|
||||
String relativeInclude = CUtil.getRelativePath(baseDirPath,
|
||||
(File) onSysIncludePath.elementAt(i));
|
||||
onSysIncludePath.setElementAt(relativeInclude, i);
|
||||
}
|
||||
return new DependencyInfo(includePathIdentifier, relativeSource,
|
||||
sourceLastModified, onIncludePath, onSysIncludePath);
|
||||
}
|
||||
protected boolean resolveInclude(String includeName, File[] includePath,
|
||||
Vector onThisPath) {
|
||||
for (int i = 0; i < includePath.length; i++) {
|
||||
File includeFile = new File(includePath[i], includeName);
|
||||
if (includeFile.exists()) {
|
||||
onThisPath.addElement(includeFile);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.LinkerDef;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
|
||||
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* An abstract Linker implementation.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public abstract class AbstractLinker extends AbstractProcessor
|
||||
implements
|
||||
Linker {
|
||||
public AbstractLinker(String[] objExtensions, String[] ignoredExtensions) {
|
||||
super(objExtensions, ignoredExtensions);
|
||||
}
|
||||
/**
|
||||
* Returns the bid of the processor for the file.
|
||||
*
|
||||
* A linker will bid 1 on any unrecognized file type.
|
||||
*
|
||||
* @param inputFile
|
||||
* filename of input file
|
||||
* @return bid for the file, 0 indicates no interest, 1 indicates that the
|
||||
* processor recognizes the file but doesn't process it (header
|
||||
* files, for example), 100 indicates strong interest
|
||||
*/
|
||||
public int bid(String inputFile) {
|
||||
int bid = super.bid(inputFile);
|
||||
switch (bid) {
|
||||
//
|
||||
// unrecognized extension, take the file
|
||||
//
|
||||
case 0 :
|
||||
return 1;
|
||||
//
|
||||
// discard the ignored extensions
|
||||
//
|
||||
case 1 :
|
||||
return 0;
|
||||
}
|
||||
return bid;
|
||||
}
|
||||
public Processor changeEnvironment(boolean newEnvironment, Environment env) {
|
||||
return this;
|
||||
}
|
||||
abstract protected LinkerConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
LinkerDef specificConfig, TargetDef targetPlatform);
|
||||
public ProcessorConfiguration createConfiguration(CCTask task,
|
||||
LinkType linkType, ProcessorDef[] baseConfigs,
|
||||
ProcessorDef specificConfig,
|
||||
TargetDef targetPlatform) {
|
||||
if (specificConfig == null) {
|
||||
throw new NullPointerException("specificConfig");
|
||||
}
|
||||
return createConfiguration(task, linkType, baseConfigs,
|
||||
(LinkerDef) specificConfig, targetPlatform);
|
||||
}
|
||||
public String getLibraryKey(File libfile) {
|
||||
return libfile.getName();
|
||||
}
|
||||
public abstract String getOutputFileName(String fileName);
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* An abstract processor (compiler/linker) implementation.
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public abstract class AbstractProcessor implements Processor, Cloneable {
|
||||
/**
|
||||
* default bid for a file name that the processor recognizes but does not
|
||||
* process and does not want to fall through to the linker
|
||||
*/
|
||||
public final static int DEFAULT_DISCARD_BID = 1;
|
||||
/**
|
||||
* default bid for a file name that the processor desires to process
|
||||
*/
|
||||
public final static int DEFAULT_PROCESS_BID = 100;
|
||||
/**
|
||||
* Determines the identification of a command line processor by capture the
|
||||
* first line of its output for a specific command.
|
||||
*
|
||||
* @param command
|
||||
* array of command line arguments starting with executable
|
||||
* name. For example, { "cl" }
|
||||
* @param fallback
|
||||
* start of identifier if there is an error in executing the
|
||||
* command
|
||||
* @return identifier for the processor
|
||||
*/
|
||||
protected static String getIdentifier(String[] command, String fallback) {
|
||||
String identifier = fallback;
|
||||
try {
|
||||
String[] cmdout = CaptureStreamHandler.run(command);
|
||||
if (cmdout.length > 0) {
|
||||
identifier = cmdout[0];
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
identifier = fallback + ":" + ex.toString();
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
private final String[] headerExtensions;
|
||||
private final String[] sourceExtensions;
|
||||
protected AbstractProcessor(String[] sourceExtensions,
|
||||
String[] headerExtensions) {
|
||||
this.sourceExtensions = (String[]) sourceExtensions.clone();
|
||||
this.headerExtensions = (String[]) headerExtensions.clone();
|
||||
}
|
||||
/**
|
||||
* Returns the bid of the processor for the file.
|
||||
*
|
||||
* @param inputFile
|
||||
* filename of input file
|
||||
* @return bid for the file, 0 indicates no interest, 1 indicates that the
|
||||
* processor recognizes the file but doesn't process it (header
|
||||
* files, for example), 100 indicates strong interest
|
||||
*/
|
||||
public int bid(String inputFile) {
|
||||
String lower = inputFile.toLowerCase();
|
||||
for (int i = 0; i < sourceExtensions.length; i++) {
|
||||
if (lower.endsWith(sourceExtensions[i])) {
|
||||
return DEFAULT_PROCESS_BID;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < headerExtensions.length; i++) {
|
||||
if (lower.endsWith(headerExtensions[i])) {
|
||||
return DEFAULT_DISCARD_BID;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public Processor changeEnvironment(boolean newEnvironment, Environment env) {
|
||||
return this;
|
||||
}
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
public String[] getHeaderExtensions() {
|
||||
return (String[]) this.headerExtensions.clone();
|
||||
}
|
||||
abstract public String getIdentifier();
|
||||
/**
|
||||
* Gets the target operating system architecture
|
||||
*
|
||||
* @return String target operating system architecture
|
||||
*/
|
||||
protected String getOSArch() {
|
||||
return System.getProperty("os.arch");
|
||||
}
|
||||
/**
|
||||
* Gets the target operating system name
|
||||
*
|
||||
* @return String target operating system name
|
||||
*/
|
||||
protected String getOSName() {
|
||||
return System.getProperty("os.name");
|
||||
}
|
||||
public String[] getSourceExtensions() {
|
||||
return (String[]) this.sourceExtensions.clone();
|
||||
}
|
||||
/**
|
||||
* Returns true if the target operating system is Mac OS X or Darwin.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected boolean isDarwin() {
|
||||
String osName = getOSName();
|
||||
return "Mac OS X".equals(osName);
|
||||
}
|
||||
public final String toString() {
|
||||
return getIdentifier();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
/**
|
||||
* A asl compiler.
|
||||
*
|
||||
*/
|
||||
public interface Aslcompiler extends Processor {
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for an ASL compiler
|
||||
*
|
||||
*/
|
||||
public interface AslcompilerConfiguration extends ProcessorConfiguration {
|
||||
void aslcompiler(CCTask task, File outputDir, String[] sourceFiles) throws BuildException;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
/**
|
||||
* A assembler.
|
||||
*
|
||||
*/
|
||||
public interface Assembler extends Processor {
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for an assembler
|
||||
*
|
||||
*/
|
||||
public interface AssemblerConfiguration extends ProcessorConfiguration {
|
||||
void assembler(CCTask task, File outputDir, String[] sourceFiles) throws BuildException;
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.tools.ant.taskdefs.Execute;
|
||||
import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
|
||||
/**
|
||||
* Implements ExecuteStreamHandler to capture the output of a Execute to an
|
||||
* array of strings
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public class CaptureStreamHandler implements ExecuteStreamHandler {
|
||||
/**
|
||||
* Runs an executable and captures the output in a String array
|
||||
*
|
||||
* @param cmdline
|
||||
* command line arguments
|
||||
* @return output of process
|
||||
*/
|
||||
public static String[] run(String[] cmdline) {
|
||||
CaptureStreamHandler handler = new CaptureStreamHandler();
|
||||
Execute exec = new Execute(handler);
|
||||
exec.setCommandline(cmdline);
|
||||
try {
|
||||
int status = exec.execute();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
return handler.getOutput();
|
||||
}
|
||||
private InputStream errorStream;
|
||||
private InputStream fromProcess;
|
||||
public CaptureStreamHandler() {
|
||||
}
|
||||
public String[] getOutput() {
|
||||
String[] output;
|
||||
if (fromProcess != null) {
|
||||
Vector lines = new Vector(10);
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(errorStream));
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int j = 0; j < 100; j++) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) {
|
||||
reader = new BufferedReader(new InputStreamReader(
|
||||
fromProcess));
|
||||
break;
|
||||
}
|
||||
lines.addElement(line);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
output = new String[lines.size()];
|
||||
lines.copyInto(output);
|
||||
return output;
|
||||
}
|
||||
output = new String[0];
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* Install a handler for the error stream of the subprocess.
|
||||
*
|
||||
* @param is
|
||||
* input stream to read from the error stream from the
|
||||
* subprocess
|
||||
*/
|
||||
public void setProcessErrorStream(InputStream is) throws IOException {
|
||||
errorStream = is;
|
||||
}
|
||||
/**
|
||||
* Install a handler for the input stream of the subprocess.
|
||||
*
|
||||
* @param os
|
||||
* output stream to write to the standard input stream of the
|
||||
* subprocess
|
||||
*/
|
||||
public void setProcessInputStream(OutputStream os) throws IOException {
|
||||
os.close();
|
||||
}
|
||||
/**
|
||||
* Install a handler for the output stream of the subprocess.
|
||||
*
|
||||
* @param is
|
||||
* input stream to read from the error stream from the
|
||||
* subprocess
|
||||
*/
|
||||
public void setProcessOutputStream(InputStream is) throws IOException {
|
||||
fromProcess = is;
|
||||
}
|
||||
/**
|
||||
* Start handling of the streams.
|
||||
*/
|
||||
public void start() throws IOException {
|
||||
}
|
||||
/**
|
||||
* Stop handling of the streams - will not be restarted.
|
||||
*/
|
||||
public void stop() {
|
||||
}
|
||||
}
|
@ -0,0 +1,226 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.AslcompilerDef;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CUtil;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* An abstract ASL Compiler implementation which uses an external program to
|
||||
* perform the ASL compile.
|
||||
*
|
||||
*/
|
||||
public abstract class CommandLineAslcompiler extends AbstractAslcompiler{
|
||||
|
||||
private String command;
|
||||
private String identifier;
|
||||
private String identifierArg;
|
||||
|
||||
protected CommandLineAslcompiler(String command, String identifierArg,
|
||||
String[] sourceExtensions, String[] headerExtensions,
|
||||
String outputSuffix) {
|
||||
super(sourceExtensions, headerExtensions, outputSuffix);
|
||||
this.command = command;
|
||||
this.identifierArg = identifierArg;
|
||||
}
|
||||
|
||||
abstract protected void addImpliedArgs(Vector args, boolean debug,
|
||||
Boolean defaultflag);
|
||||
|
||||
/**
|
||||
* Compile a ACPI source file
|
||||
*
|
||||
*/
|
||||
public void aslcompiler(CCTask task, File outputDir, String[] sourceFiles,
|
||||
String[] args, String[] endArgs) throws BuildException{
|
||||
String command = getCommand();
|
||||
int baseLength = command.length() + args.length + endArgs.length;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
baseLength += args[i].length();
|
||||
}
|
||||
for (int i = 0; i < endArgs.length; i++) {
|
||||
baseLength += endArgs[i].length();
|
||||
}
|
||||
if (baseLength > getMaximumCommandLength()) {
|
||||
throw new BuildException(
|
||||
"Command line is over maximum length without sepcifying source file");
|
||||
}
|
||||
int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();
|
||||
int argumentCountPerInputFile = getArgumentCountPerInputFIle();
|
||||
for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {
|
||||
int cmdLength = baseLength;
|
||||
int firstFileNextExec;
|
||||
for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length
|
||||
&& (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {
|
||||
cmdLength += getTotalArgumentLengthForInputFile(outputDir,
|
||||
sourceFiles[firstFileNextExec]);
|
||||
if (cmdLength >= getMaximumCommandLength())
|
||||
break;
|
||||
}
|
||||
if (firstFileNextExec == sourceIndex) {
|
||||
throw new BuildException(
|
||||
"Extremely long file name, can't fit on command line");
|
||||
}
|
||||
int argCount = args.length + 1 + endArgs.length
|
||||
+ (firstFileNextExec - sourceIndex)
|
||||
* argumentCountPerInputFile;
|
||||
String[] commandline = new String[argCount];
|
||||
int index = 0;
|
||||
commandline[index++] = command;
|
||||
for (int j = 0; j < args.length; j++) {
|
||||
commandline[index++] = args[j];
|
||||
}
|
||||
for (int j = sourceIndex; j < firstFileNextExec; j++) {
|
||||
for (int k = 0; k < argumentCountPerInputFile; k++) {
|
||||
commandline[index++] = getInputFileArgument(outputDir,
|
||||
sourceFiles[j], k);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < endArgs.length; j++) {
|
||||
commandline[index++] = endArgs[j];
|
||||
}
|
||||
int retval = runCommand(task, outputDir, commandline);
|
||||
// if with monitor, add more code
|
||||
if (retval != 0) {
|
||||
throw new BuildException(this.getCommand()
|
||||
+ " failed with return code " + retval,
|
||||
task.getLocation());
|
||||
}
|
||||
sourceIndex = firstFileNextExec;
|
||||
}
|
||||
}
|
||||
|
||||
protected AslcompilerConfiguration createConfiguration(final CCTask task,
|
||||
final LinkType linkType,
|
||||
final ProcessorDef[] baseDefs,
|
||||
final AslcompilerDef specificDef,
|
||||
final TargetDef targetPlatform) {
|
||||
Vector args = new Vector();
|
||||
AslcompilerDef[] defaultProviders = new AslcompilerDef[baseDefs.length +1];
|
||||
for (int i = 0; i < baseDefs.length; i++) {
|
||||
defaultProviders[i + 1] = (AslcompilerDef) baseDefs[i];
|
||||
}
|
||||
defaultProviders[0] = specificDef;
|
||||
Vector cmdArgs = new Vector();
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally and specific AslcompilerDef
|
||||
//
|
||||
CommandLineArgument[] commandArgs;
|
||||
for (int i = defaultProviders.length - 1; i >=0; i--){
|
||||
commandArgs = defaultProviders[i].getActiveProcessorArgs();
|
||||
for (int j = 0; j < commandArgs.length; j++) {
|
||||
if (commandArgs[j].getLocation() == 0) {
|
||||
args.addElement(commandArgs[j].getValue());
|
||||
}
|
||||
else {
|
||||
cmdArgs.addElement(commandArgs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// omit param
|
||||
boolean debug = specificDef.getDebug(baseDefs, 0);
|
||||
Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);
|
||||
this.addImpliedArgs(args, debug, defaultflag);
|
||||
Enumeration argEnum = cmdArgs.elements();
|
||||
int endCount = 0;
|
||||
while( argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();
|
||||
switch (arg.getLocation()) {
|
||||
case 1 :
|
||||
args.addElement(arg.getValue());
|
||||
break;
|
||||
case 2 :
|
||||
endCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String[] endArgs = new String[endCount];
|
||||
argEnum = cmdArgs.elements();
|
||||
int index = 0;
|
||||
while (argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum.nextElement();
|
||||
if (arg.getLocation() == 2) {
|
||||
endArgs[index++] = arg.getValue();
|
||||
}
|
||||
}
|
||||
String[] argArray = new String[args.size()];
|
||||
args.copyInto(argArray);
|
||||
return new CommandLineAslcompilerConfiguration(this, argArray, true, endArgs);
|
||||
}
|
||||
|
||||
protected int getArgumentCountPerInputFile() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
if (identifier == null) {
|
||||
if (identifierArg == null) {
|
||||
identifier = getIdentifier(new String[]{command}, command);
|
||||
}
|
||||
else {
|
||||
identifier = getIdentifier(
|
||||
new String[]{command, identifierArg}, command);
|
||||
}
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public final String getCommand() {
|
||||
return command;
|
||||
}
|
||||
abstract public int getMaximumCommandLength();
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
protected int getTotalArgumentLengthForInputFile(File outputDir,
|
||||
String inputFile) {
|
||||
return inputFile.length() + 1;
|
||||
}
|
||||
protected int runCommand(CCTask task, File workingDir, String[] cmdline)
|
||||
throws BuildException {
|
||||
return CUtil.runCommand(task, workingDir, cmdline, false, null);
|
||||
|
||||
}
|
||||
protected int getMaximumInputFilesPerCommand(){
|
||||
return 1;
|
||||
}
|
||||
protected int getArgumentCountPerInputFIle(){
|
||||
return 1;
|
||||
}
|
||||
protected String getInputFileArgument(File outputDir, String filename, int index) {
|
||||
//
|
||||
// if there is an embedded space,
|
||||
// must enclose in quotes
|
||||
if (filename.indexOf(' ') >= 0) {
|
||||
StringBuffer buf = new StringBuffer("\"");
|
||||
buf.append(filename);
|
||||
buf.append("\"");
|
||||
return buf.toString();
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
|
||||
/**
|
||||
* A configuration for an ASL compiler
|
||||
*
|
||||
*/
|
||||
public final class CommandLineAslcompilerConfiguration implements
|
||||
AslcompilerConfiguration {
|
||||
|
||||
private String[] args;
|
||||
|
||||
private CommandLineAslcompiler acpi;
|
||||
|
||||
private String[] endArgs;
|
||||
|
||||
private boolean rebuild;
|
||||
|
||||
public CommandLineAslcompilerConfiguration (CommandLineAslcompiler acpi,
|
||||
String[] args, boolean rebuild, String[] endArgs) {
|
||||
if (acpi == null) {
|
||||
throw new NullPointerException("acpi");
|
||||
}
|
||||
if (args == null) {
|
||||
this.args = new String[0];
|
||||
} else {
|
||||
this.args = (String[]) args.clone();
|
||||
}
|
||||
this.acpi = acpi;
|
||||
this.rebuild = rebuild;
|
||||
this.endArgs = (String[]) endArgs.clone();
|
||||
}
|
||||
|
||||
public int bid (String inputFile) {
|
||||
int acpiBid = acpi.bid(inputFile);
|
||||
return acpiBid;
|
||||
}
|
||||
|
||||
public void aslcompiler (CCTask task, File outputDir, String[] sourceFiles)
|
||||
throws BuildException {
|
||||
try {
|
||||
acpi.aslcompiler(task, outputDir, sourceFiles, args, endArgs);
|
||||
} catch (BuildException ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public String getIdentifier () {
|
||||
return acpi.getCommand();
|
||||
}
|
||||
|
||||
public ProcessorParam[] getParams () {
|
||||
return new ProcessorParam[0];
|
||||
}
|
||||
|
||||
public boolean getRebuild () {
|
||||
return rebuild;
|
||||
}
|
||||
|
||||
public String[] getPreArguments () {
|
||||
return (String[]) args.clone();
|
||||
}
|
||||
|
||||
public String[] getEndArguments () {
|
||||
return (String[]) endArgs.clone();
|
||||
}
|
||||
|
||||
public String getOutputFileName (String inputFile) {
|
||||
return acpi.getOutputFileName(inputFile);
|
||||
}
|
||||
}
|
@ -0,0 +1,326 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.AssemblerDef;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CUtil;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
|
||||
/**
|
||||
* An abstract Assembler implementation which uses an external program to
|
||||
* perform the assemble.
|
||||
*
|
||||
*/
|
||||
public abstract class CommandLineAssembler extends AbstractAssembler {
|
||||
|
||||
private String command;
|
||||
|
||||
private String identifier;
|
||||
|
||||
private String identifierArg;
|
||||
|
||||
protected CommandLineAssembler (String command, String identifierArg,
|
||||
String[] sourceExtensions, String[] headerExtensions,
|
||||
String outputSuffix) {
|
||||
super(sourceExtensions, headerExtensions, outputSuffix);
|
||||
this.command = command;
|
||||
this.identifierArg = identifierArg;
|
||||
}
|
||||
|
||||
abstract protected void addImpliedArgs(Vector args, boolean debug,
|
||||
Boolean defaultflag);
|
||||
|
||||
/**
|
||||
* Adds command-line arguments for include directories.
|
||||
*
|
||||
* If relativeArgs is not null will add corresponding relative paths include
|
||||
* switches to that vector (for use in building a configuration identifier
|
||||
* that is consistent between machines).
|
||||
*
|
||||
* @param baseDirPaths
|
||||
* A vector containing the parts of the working directory,
|
||||
* produced by CUtil.DecomposeFile.
|
||||
* @param includeDirs
|
||||
* Array of include directory paths
|
||||
* @param args
|
||||
* Vector of command line arguments used to execute the task
|
||||
* @param relativeArgs
|
||||
* Vector of command line arguments used to build the
|
||||
* configuration identifier
|
||||
*/
|
||||
protected void addIncludes(String baseDirPath, File[] includeDirs,
|
||||
Vector args, Vector relativeArgs, StringBuffer includePathId) {
|
||||
for (int i = 0; i < includeDirs.length; i++) {
|
||||
args.addElement(getIncludeDirSwitch(includeDirs[i]
|
||||
.getAbsolutePath()));
|
||||
if (relativeArgs != null) {
|
||||
String relative = CUtil.getRelativePath(baseDirPath,
|
||||
includeDirs[i]);
|
||||
relativeArgs.addElement(getIncludeDirSwitch(relative));
|
||||
if (includePathId != null) {
|
||||
if (includePathId.length() == 0) {
|
||||
includePathId.append("/I");
|
||||
} else {
|
||||
includePathId.append(" /I");
|
||||
}
|
||||
includePathId.append(relative);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected String getIncludeDirSwitch(String source);
|
||||
|
||||
/**
|
||||
* Assembles a source file
|
||||
*
|
||||
*/
|
||||
public void assembler(CCTask task, File outputDir, String[] sourceFiles,
|
||||
String[] args, String[] endArgs) throws BuildException {
|
||||
String command = getCommand();
|
||||
int baseLength = command.length() + args.length + endArgs.length;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
baseLength += args[i].length();
|
||||
}
|
||||
for (int i = 0; i < endArgs.length; i++) {
|
||||
baseLength += endArgs[i].length();
|
||||
}
|
||||
if (baseLength > getMaximumCommandLength()) {
|
||||
throw new BuildException(
|
||||
"Command line is over maximum length without sepcifying source file");
|
||||
}
|
||||
int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();
|
||||
int argumentCountPerInputFile = getArgumentCountPerInputFIle();
|
||||
for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {
|
||||
int cmdLength = baseLength;
|
||||
int firstFileNextExec;
|
||||
for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length
|
||||
&& (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {
|
||||
cmdLength += getTotalArgumentLengthForInputFile(outputDir,
|
||||
sourceFiles[firstFileNextExec]);
|
||||
if (cmdLength >= getMaximumCommandLength())
|
||||
break;
|
||||
}
|
||||
if (firstFileNextExec == sourceIndex) {
|
||||
throw new BuildException(
|
||||
"Extremely long file name, can't fit on command line");
|
||||
}
|
||||
int argCount = args.length + 1 + endArgs.length
|
||||
+ (firstFileNextExec - sourceIndex)
|
||||
* argumentCountPerInputFile;
|
||||
String[] commandline = new String[argCount];
|
||||
int index = 0;
|
||||
commandline[index++] = command;
|
||||
for (int j = 0; j < args.length; j++) {
|
||||
commandline[index++] = args[j];
|
||||
}
|
||||
for (int j = sourceIndex; j < firstFileNextExec; j++) {
|
||||
for (int k = 0; k < argumentCountPerInputFile; k++) {
|
||||
commandline[index++] = getInputFileArgument(outputDir,
|
||||
sourceFiles[j], k);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < endArgs.length; j++) {
|
||||
commandline[index++] = endArgs[j];
|
||||
}
|
||||
int retval = runCommand(task, outputDir, commandline);
|
||||
// if with monitor, add more code
|
||||
if (retval != 0) {
|
||||
throw new BuildException(this.getCommand()
|
||||
+ " failed with return code " + retval, task
|
||||
.getLocation());
|
||||
}
|
||||
sourceIndex = firstFileNextExec;
|
||||
}
|
||||
}
|
||||
|
||||
protected AssemblerConfiguration createConfiguration(final CCTask task,
|
||||
final LinkType linkType, final ProcessorDef[] baseDefs,
|
||||
final AssemblerDef specificDef,
|
||||
final TargetDef targetPlatform) {
|
||||
Vector args = new Vector();
|
||||
AssemblerDef[] defaultProviders = new AssemblerDef[baseDefs.length + 1];
|
||||
for (int i = 0; i < baseDefs.length; i++) {
|
||||
defaultProviders[i + 1] = (AssemblerDef) baseDefs[i];
|
||||
}
|
||||
defaultProviders[0] = specificDef;
|
||||
Vector cmdArgs = new Vector();
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally and specific AssemblerDef
|
||||
//
|
||||
CommandLineArgument[] commandArgs;
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
commandArgs = defaultProviders[i].getActiveProcessorArgs();
|
||||
for (int j = 0; j < commandArgs.length; j++) {
|
||||
if (commandArgs[j].getLocation() == 0) {
|
||||
args.addElement(commandArgs[j].getValue());
|
||||
} else {
|
||||
cmdArgs.addElement(commandArgs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// omit param
|
||||
boolean debug = specificDef.getDebug(baseDefs, 0);
|
||||
Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);
|
||||
this.addImpliedArgs(args, debug, defaultflag);
|
||||
//
|
||||
// Want to have distinct set of arguments with relative
|
||||
// path names for includes that are used to build
|
||||
// the configuration identifier
|
||||
//
|
||||
Vector relativeArgs = (Vector) args.clone();
|
||||
//
|
||||
// add all active include an
|
||||
//
|
||||
StringBuffer includePathIdentifier = new StringBuffer();
|
||||
File baseDir = specificDef.getProject().getBaseDir();
|
||||
String baseDirPath;
|
||||
try {
|
||||
baseDirPath = baseDir.getCanonicalPath();
|
||||
} catch (IOException ex) {
|
||||
baseDirPath = baseDir.toString();
|
||||
}
|
||||
Vector includePath = new Vector();
|
||||
Vector sysIncludePath = new Vector();
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
String[] incPath = defaultProviders[i].getActiveIncludePaths();
|
||||
for (int j = 0; j < incPath.length; j++) {
|
||||
includePath.addElement(incPath[j]);
|
||||
}
|
||||
incPath = defaultProviders[i].getActiveSysIncludePaths();
|
||||
for (int j = 0; j < incPath.length; j++) {
|
||||
sysIncludePath.addElement(incPath[j]);
|
||||
}
|
||||
}
|
||||
File[] incPath = new File[includePath.size()];
|
||||
for (int i = 0; i < includePath.size(); i++) {
|
||||
incPath[i] = new File((String) includePath.elementAt(i));
|
||||
}
|
||||
File[] sysIncPath = new File[sysIncludePath.size()];
|
||||
for (int i = 0; i < sysIncludePath.size(); i++) {
|
||||
sysIncPath[i] = new File((String) sysIncludePath.elementAt(i));
|
||||
}
|
||||
addIncludes(baseDirPath, incPath, args, relativeArgs,
|
||||
includePathIdentifier);
|
||||
addIncludes(baseDirPath, sysIncPath, args, null, null);
|
||||
StringBuffer buf = new StringBuffer(getIdentifier());
|
||||
for (int i = 0; i < relativeArgs.size(); i++) {
|
||||
buf.append(relativeArgs.elementAt(i));
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.setLength(buf.length() - 1);
|
||||
Enumeration argEnum = cmdArgs.elements();
|
||||
int endCount = 0;
|
||||
while (argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum
|
||||
.nextElement();
|
||||
switch (arg.getLocation()) {
|
||||
case 1:
|
||||
args.addElement(arg.getValue());
|
||||
break;
|
||||
case 2:
|
||||
endCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String[] endArgs = new String[endCount];
|
||||
argEnum = cmdArgs.elements();
|
||||
int index = 0;
|
||||
while (argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum
|
||||
.nextElement();
|
||||
if (arg.getLocation() == 2) {
|
||||
endArgs[index++] = arg.getValue();
|
||||
}
|
||||
}
|
||||
String[] argArray = new String[args.size()];
|
||||
args.copyInto(argArray);
|
||||
return new CommandLineAssemblerConfiguration(this, incPath, sysIncPath,
|
||||
new File[0], argArray, true, endArgs, new String[0]);
|
||||
}
|
||||
|
||||
protected int getArgumentCountPerInputFile() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected abstract File[] getEnvironmentIncludePath();
|
||||
|
||||
public String getIdentifier() {
|
||||
if (identifier == null) {
|
||||
if (identifierArg == null) {
|
||||
identifier = getIdentifier(new String[] { command }, command);
|
||||
} else {
|
||||
identifier = getIdentifier(new String[] { command,
|
||||
identifierArg }, command);
|
||||
}
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public final String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
abstract public int getMaximumCommandLength();
|
||||
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
protected int getTotalArgumentLengthForInputFile(File outputDir,
|
||||
String inputFile) {
|
||||
return inputFile.length() + 1;
|
||||
}
|
||||
|
||||
protected int runCommand(CCTask task, File workingDir, String[] cmdline)
|
||||
throws BuildException {
|
||||
return CUtil.runCommand(task, workingDir, cmdline, false, null);
|
||||
}
|
||||
|
||||
protected int getMaximumInputFilesPerCommand() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
protected int getArgumentCountPerInputFIle() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected String getInputFileArgument(File outputDir, String filename,
|
||||
int index) {
|
||||
//
|
||||
// if there is an embedded space,
|
||||
// must enclose in quotes
|
||||
if (filename.indexOf(' ') >= 0) {
|
||||
StringBuffer buf = new StringBuffer("\"");
|
||||
buf.append(filename);
|
||||
buf.append("\"");
|
||||
return buf.toString();
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2005 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
|
||||
/**
|
||||
* A configuration for an assember
|
||||
*
|
||||
*/
|
||||
public final class CommandLineAssemblerConfiguration implements
|
||||
AssemblerConfiguration {
|
||||
|
||||
private String[] args;
|
||||
|
||||
private CommandLineAssembler assembler;
|
||||
|
||||
private String[] endArgs;
|
||||
|
||||
//
|
||||
// include path from environment variable
|
||||
// not explicitly stated in Ant script
|
||||
//
|
||||
private File[] envIncludePath;
|
||||
|
||||
private String[] exceptFiles;
|
||||
|
||||
private File[] includePath;
|
||||
|
||||
private boolean rebuild;
|
||||
|
||||
private File[] sysIncludePath;
|
||||
|
||||
public CommandLineAssemblerConfiguration (CommandLineAssembler assembler,
|
||||
File[] includePath, File[] sysIncludePath,
|
||||
File[] envIncludePath, String[] args, boolean rebuild,
|
||||
String[] endArgs, String[] exceptFiles) {
|
||||
if (assembler == null) {
|
||||
throw new NullPointerException("assembler");
|
||||
}
|
||||
if (args == null) {
|
||||
this.args = new String[0];
|
||||
} else {
|
||||
this.args = (String[]) args.clone();
|
||||
}
|
||||
if (includePath == null) {
|
||||
this.includePath = new File[0];
|
||||
} else {
|
||||
this.includePath = (File[]) includePath.clone();
|
||||
}
|
||||
if (sysIncludePath == null) {
|
||||
this.sysIncludePath = new File[0];
|
||||
} else {
|
||||
this.sysIncludePath = (File[]) sysIncludePath.clone();
|
||||
}
|
||||
if (envIncludePath == null) {
|
||||
this.envIncludePath = new File[0];
|
||||
} else {
|
||||
this.envIncludePath = (File[]) envIncludePath.clone();
|
||||
}
|
||||
this.assembler = assembler;
|
||||
this.rebuild = rebuild;
|
||||
this.endArgs = (String[]) endArgs.clone();
|
||||
this.exceptFiles = (String[]) exceptFiles.clone();
|
||||
}
|
||||
|
||||
public int bid(String inputFile) {
|
||||
int assembleBid = assembler.bid(inputFile);
|
||||
return assembleBid;
|
||||
}
|
||||
|
||||
public void assembler(CCTask task, File outputDir, String[] sourceFiles)
|
||||
throws BuildException {
|
||||
try {
|
||||
assembler.assembler(task, outputDir, sourceFiles, args, endArgs);
|
||||
} catch (BuildException ex) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public String getOutputFileName(String inputFile) {
|
||||
return assembler.getOutputFileName(inputFile);
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return assembler.getCommand();
|
||||
}
|
||||
|
||||
public ProcessorParam[] getParams() {
|
||||
return new ProcessorParam[0];
|
||||
}
|
||||
|
||||
public boolean getRebuild() {
|
||||
return rebuild;
|
||||
}
|
||||
|
||||
public String[] getPreArguments() {
|
||||
return (String[]) args.clone();
|
||||
}
|
||||
|
||||
public String[] getEndArguments() {
|
||||
return (String[]) endArgs.clone();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.parser.CParser;
|
||||
import net.sf.antcontrib.cpptasks.parser.Parser;
|
||||
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* An abstract Compiler implementation which uses an external program to
|
||||
* perform the compile.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public abstract class CommandLineCCompiler extends CommandLineCompiler {
|
||||
protected CommandLineCCompiler(String command, String identifierArg,
|
||||
String[] sourceExtensions, String[] headerExtensions,
|
||||
String outputSuffix, boolean libtool,
|
||||
CommandLineCCompiler libtoolCompiler, boolean newEnvironment,
|
||||
Environment env) {
|
||||
super(command, identifierArg, sourceExtensions, headerExtensions,
|
||||
outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
|
||||
}
|
||||
protected Parser createParser(File source) {
|
||||
return new CParser();
|
||||
}
|
||||
}
|
@ -0,0 +1,435 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CUtil;
|
||||
import net.sf.antcontrib.cpptasks.CompilerDef;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
|
||||
import net.sf.antcontrib.cpptasks.types.UndefineArgument;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
import net.sf.antcontrib.cpptasks.OptimizationEnum;;
|
||||
/**
|
||||
* An abstract Compiler implementation which uses an external program to
|
||||
* perform the compile.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public abstract class CommandLineCompiler extends AbstractCompiler {
|
||||
private String command;
|
||||
private final Environment env;
|
||||
private String identifier;
|
||||
private String identifierArg;
|
||||
private boolean libtool;
|
||||
private CommandLineCompiler libtoolCompiler;
|
||||
private final boolean newEnvironment;
|
||||
protected CommandLineCompiler(String command, String identifierArg,
|
||||
String[] sourceExtensions, String[] headerExtensions,
|
||||
String outputSuffix, boolean libtool,
|
||||
CommandLineCompiler libtoolCompiler, boolean newEnvironment,
|
||||
Environment env) {
|
||||
super(sourceExtensions, headerExtensions, outputSuffix);
|
||||
this.command = command;
|
||||
if (libtool && libtoolCompiler != null) {
|
||||
throw new java.lang.IllegalArgumentException(
|
||||
"libtoolCompiler should be null when libtool is true");
|
||||
}
|
||||
this.libtool = libtool;
|
||||
this.libtoolCompiler = libtoolCompiler;
|
||||
this.identifierArg = identifierArg;
|
||||
this.newEnvironment = newEnvironment;
|
||||
this.env = env;
|
||||
}
|
||||
abstract protected void addImpliedArgs(Vector args, boolean debug,
|
||||
boolean multithreaded, boolean exceptions, LinkType linkType,
|
||||
Boolean rtti, OptimizationEnum optimization, Boolean defaultflag);
|
||||
/**
|
||||
* Adds command-line arguments for include directories.
|
||||
*
|
||||
* If relativeArgs is not null will add corresponding relative paths
|
||||
* include switches to that vector (for use in building a configuration
|
||||
* identifier that is consistent between machines).
|
||||
*
|
||||
* @param baseDirPaths
|
||||
* A vector containing the parts of the working directory,
|
||||
* produced by CUtil.DecomposeFile.
|
||||
* @param includeDirs
|
||||
* Array of include directory paths
|
||||
* @param args
|
||||
* Vector of command line arguments used to execute the task
|
||||
* @param relativeArgs
|
||||
* Vector of command line arguments used to build the
|
||||
* configuration identifier
|
||||
*/
|
||||
protected void addIncludes(String baseDirPath, File[] includeDirs,
|
||||
Vector args, Vector relativeArgs, StringBuffer includePathId) {
|
||||
for (int i = 0; i < includeDirs.length; i++) {
|
||||
args.addElement(getIncludeDirSwitch(includeDirs[i]
|
||||
.getAbsolutePath()));
|
||||
if (relativeArgs != null) {
|
||||
String relative = CUtil.getRelativePath(baseDirPath,
|
||||
includeDirs[i]);
|
||||
relativeArgs.addElement(getIncludeDirSwitch(relative));
|
||||
if (includePathId != null) {
|
||||
if (includePathId.length() == 0) {
|
||||
includePathId.append("/I");
|
||||
} else {
|
||||
includePathId.append(" /I");
|
||||
}
|
||||
includePathId.append(relative);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
abstract protected void addWarningSwitch(Vector args, int warnings);
|
||||
protected void buildDefineArguments(CompilerDef[] defs, Vector args) {
|
||||
//
|
||||
// assume that we aren't inheriting defines from containing <cc>
|
||||
//
|
||||
UndefineArgument[] merged = defs[0].getActiveDefines();
|
||||
for (int i = 1; i < defs.length; i++) {
|
||||
//
|
||||
// if we are inheriting, merge the specific defines with the
|
||||
// containing defines
|
||||
merged = UndefineArgument.merge(defs[i].getActiveDefines(), merged);
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(30);
|
||||
for (int i = 0; i < merged.length; i++) {
|
||||
buf.setLength(0);
|
||||
UndefineArgument current = merged[i];
|
||||
if (current.isDefine()) {
|
||||
getDefineSwitch(buf, current.getName(), current.getValue());
|
||||
} else {
|
||||
getUndefineSwitch(buf, current.getName());
|
||||
}
|
||||
args.addElement(buf.toString());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compiles a source file.
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public void compile(CCTask task, File outputDir, String[] sourceFiles,
|
||||
String[] args, String[] endArgs, boolean relentless,
|
||||
CommandLineCompilerConfiguration config, ProgressMonitor monitor)
|
||||
throws BuildException {
|
||||
BuildException exc = null;
|
||||
//
|
||||
// determine length of executable name and args
|
||||
//
|
||||
String command = getCommand();
|
||||
int baseLength = command.length() + args.length + endArgs.length;
|
||||
if (libtool) {
|
||||
baseLength += 8;
|
||||
}
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
baseLength += args[i].length();
|
||||
}
|
||||
for (int i = 0; i < endArgs.length; i++) {
|
||||
baseLength += endArgs[i].length();
|
||||
}
|
||||
if (baseLength > getMaximumCommandLength()) {
|
||||
throw new BuildException(
|
||||
"Command line is over maximum length without specifying source file");
|
||||
}
|
||||
//
|
||||
// typically either 1 or Integer.MAX_VALUE
|
||||
//
|
||||
int maxInputFilesPerCommand = getMaximumInputFilesPerCommand();
|
||||
int argumentCountPerInputFile = getArgumentCountPerInputFile();
|
||||
for (int sourceIndex = 0; sourceIndex < sourceFiles.length;) {
|
||||
int cmdLength = baseLength;
|
||||
int firstFileNextExec;
|
||||
for (firstFileNextExec = sourceIndex; firstFileNextExec < sourceFiles.length
|
||||
&& (firstFileNextExec - sourceIndex) < maxInputFilesPerCommand; firstFileNextExec++) {
|
||||
cmdLength += getTotalArgumentLengthForInputFile(outputDir,
|
||||
sourceFiles[firstFileNextExec]);
|
||||
if (cmdLength >= getMaximumCommandLength())
|
||||
break;
|
||||
}
|
||||
if (firstFileNextExec == sourceIndex) {
|
||||
throw new BuildException(
|
||||
"Extremely long file name, can't fit on command line");
|
||||
}
|
||||
int argCount = args.length + 1 + endArgs.length
|
||||
+ (firstFileNextExec - sourceIndex)
|
||||
* argumentCountPerInputFile;
|
||||
if (libtool) {
|
||||
argCount++;
|
||||
}
|
||||
String[] commandline = new String[argCount];
|
||||
int index = 0;
|
||||
if (libtool) {
|
||||
commandline[index++] = "libtool";
|
||||
}
|
||||
commandline[index++] = command;
|
||||
for (int j = 0; j < args.length; j++) {
|
||||
commandline[index++] = args[j];
|
||||
}
|
||||
for (int j = sourceIndex; j < firstFileNextExec; j++) {
|
||||
for (int k = 0; k < argumentCountPerInputFile; k++) {
|
||||
commandline[index++] = getInputFileArgument(outputDir,
|
||||
sourceFiles[j], k);
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < endArgs.length; j++) {
|
||||
commandline[index++] = endArgs[j];
|
||||
}
|
||||
int retval = runCommand(task, outputDir, commandline);
|
||||
if (monitor != null) {
|
||||
String[] fileNames = new String[firstFileNextExec - sourceIndex];
|
||||
for (int j = 0; j < fileNames.length; j++) {
|
||||
fileNames[j] = sourceFiles[sourceIndex + j];
|
||||
}
|
||||
monitor.progress(fileNames);
|
||||
}
|
||||
//
|
||||
// if the process returned a failure code and
|
||||
// we aren't holding an exception from an earlier
|
||||
// interation
|
||||
if (retval != 0 && exc == null) {
|
||||
//
|
||||
// construct the exception
|
||||
//
|
||||
exc = new BuildException(this.getCommand()
|
||||
+ " failed with return code " + retval, task
|
||||
.getLocation());
|
||||
//
|
||||
// and throw it now unless we are relentless
|
||||
//
|
||||
if (!relentless) {
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
sourceIndex = firstFileNextExec;
|
||||
}
|
||||
//
|
||||
// if the compiler returned a failure value earlier
|
||||
// then throw an exception
|
||||
if (exc != null) {
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
protected CompilerConfiguration createConfiguration(final CCTask task,
|
||||
final LinkType linkType,
|
||||
final ProcessorDef[] baseDefs,
|
||||
final CompilerDef specificDef,
|
||||
final TargetDef targetPlatform) {
|
||||
Vector args = new Vector();
|
||||
CompilerDef[] defaultProviders = new CompilerDef[baseDefs.length + 1];
|
||||
for (int i = 0; i < baseDefs.length; i++) {
|
||||
defaultProviders[i + 1] = (CompilerDef) baseDefs[i];
|
||||
}
|
||||
defaultProviders[0] = specificDef;
|
||||
Vector cmdArgs = new Vector();
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally the specific CompilerDef
|
||||
CommandLineArgument[] commandArgs;
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
commandArgs = defaultProviders[i].getActiveProcessorArgs();
|
||||
for (int j = 0; j < commandArgs.length; j++) {
|
||||
if (commandArgs[j].getLocation() == 0) {
|
||||
args.addElement(commandArgs[j].getValue());
|
||||
} else {
|
||||
cmdArgs.addElement(commandArgs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector params = new Vector();
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally the specific CompilerDef
|
||||
ProcessorParam[] paramArray;
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
paramArray = defaultProviders[i].getActiveProcessorParams();
|
||||
for (int j = 0; j < paramArray.length; j++) {
|
||||
params.add(paramArray[j]);
|
||||
}
|
||||
}
|
||||
paramArray = (ProcessorParam[]) (params
|
||||
.toArray(new ProcessorParam[params.size()]));
|
||||
boolean multithreaded = specificDef.getMultithreaded(defaultProviders,
|
||||
1);
|
||||
boolean debug = specificDef.getDebug(baseDefs, 0);
|
||||
boolean exceptions = specificDef.getExceptions(defaultProviders, 1);
|
||||
Boolean rtti = specificDef.getRtti(defaultProviders, 1);
|
||||
Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);
|
||||
OptimizationEnum optimization = specificDef.getOptimization(defaultProviders, 1);
|
||||
this.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization, defaultflag);
|
||||
//
|
||||
// add all appropriate defines and undefines
|
||||
//
|
||||
buildDefineArguments(defaultProviders, args);
|
||||
//
|
||||
// Want to have distinct set of arguments with relative
|
||||
// path names for includes that are used to build
|
||||
// the configuration identifier
|
||||
//
|
||||
Vector relativeArgs = (Vector) args.clone();
|
||||
//
|
||||
// add all active include and sysincludes
|
||||
//
|
||||
StringBuffer includePathIdentifier = new StringBuffer();
|
||||
File baseDir = specificDef.getProject().getBaseDir();
|
||||
String baseDirPath;
|
||||
try {
|
||||
baseDirPath = baseDir.getCanonicalPath();
|
||||
} catch (IOException ex) {
|
||||
baseDirPath = baseDir.toString();
|
||||
}
|
||||
Vector includePath = new Vector();
|
||||
Vector sysIncludePath = new Vector();
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
String[] incPath = defaultProviders[i].getActiveIncludePaths();
|
||||
for (int j = 0; j < incPath.length; j++) {
|
||||
includePath.addElement(incPath[j]);
|
||||
}
|
||||
incPath = defaultProviders[i].getActiveSysIncludePaths();
|
||||
for (int j = 0; j < incPath.length; j++) {
|
||||
sysIncludePath.addElement(incPath[j]);
|
||||
}
|
||||
}
|
||||
File[] incPath = new File[includePath.size()];
|
||||
for (int i = 0; i < includePath.size(); i++) {
|
||||
incPath[i] = new File((String) includePath.elementAt(i));
|
||||
}
|
||||
File[] sysIncPath = new File[sysIncludePath.size()];
|
||||
for (int i = 0; i < sysIncludePath.size(); i++) {
|
||||
sysIncPath[i] = new File((String) sysIncludePath.elementAt(i));
|
||||
}
|
||||
addIncludes(baseDirPath, incPath, args, relativeArgs,
|
||||
includePathIdentifier);
|
||||
addIncludes(baseDirPath, sysIncPath, args, null, null);
|
||||
StringBuffer buf = new StringBuffer(getIdentifier());
|
||||
for (int i = 0; i < relativeArgs.size(); i++) {
|
||||
buf.append(relativeArgs.elementAt(i));
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.setLength(buf.length() - 1);
|
||||
String configId = buf.toString();
|
||||
int warnings = specificDef.getWarnings(defaultProviders, 0);
|
||||
addWarningSwitch(args, warnings);
|
||||
Enumeration argEnum = cmdArgs.elements();
|
||||
int endCount = 0;
|
||||
while (argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum
|
||||
.nextElement();
|
||||
switch (arg.getLocation()) {
|
||||
case 1 :
|
||||
args.addElement(arg.getValue());
|
||||
break;
|
||||
case 2 :
|
||||
endCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String[] endArgs = new String[endCount];
|
||||
argEnum = cmdArgs.elements();
|
||||
int index = 0;
|
||||
while (argEnum.hasMoreElements()) {
|
||||
CommandLineArgument arg = (CommandLineArgument) argEnum
|
||||
.nextElement();
|
||||
if (arg.getLocation() == 2) {
|
||||
endArgs[index++] = arg.getValue();
|
||||
}
|
||||
}
|
||||
String[] argArray = new String[args.size()];
|
||||
args.copyInto(argArray);
|
||||
boolean rebuild = specificDef.getRebuild(baseDefs, 0);
|
||||
File[] envIncludePath = getEnvironmentIncludePath();
|
||||
return new CommandLineCompilerConfiguration(this, configId, incPath,
|
||||
sysIncPath, envIncludePath, includePathIdentifier.toString(),
|
||||
argArray, paramArray, rebuild, endArgs);
|
||||
}
|
||||
protected int getArgumentCountPerInputFile() {
|
||||
return 1;
|
||||
}
|
||||
protected final String getCommand() {
|
||||
return command;
|
||||
}
|
||||
abstract protected void getDefineSwitch(StringBuffer buffer, String define,
|
||||
String value);
|
||||
protected abstract File[] getEnvironmentIncludePath();
|
||||
public String getIdentifier() {
|
||||
if (identifier == null) {
|
||||
if (identifierArg == null) {
|
||||
identifier = getIdentifier(new String[]{command}, command);
|
||||
} else {
|
||||
identifier = getIdentifier(
|
||||
new String[]{command, identifierArg}, command);
|
||||
}
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
abstract protected String getIncludeDirSwitch(String source);
|
||||
protected String getInputFileArgument(File outputDir, String filename,
|
||||
int index) {
|
||||
//
|
||||
// if there is an embedded space,
|
||||
// must enclose in quotes
|
||||
if (filename.indexOf(' ') >= 0) {
|
||||
StringBuffer buf = new StringBuffer("\"");
|
||||
buf.append(filename);
|
||||
buf.append("\"");
|
||||
return buf.toString();
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
protected final boolean getLibtool() {
|
||||
return libtool;
|
||||
}
|
||||
/**
|
||||
* Obtains the same compiler, but with libtool set
|
||||
*
|
||||
* Default behavior is to ignore libtool
|
||||
*/
|
||||
public final CommandLineCompiler getLibtoolCompiler() {
|
||||
if (libtoolCompiler != null) {
|
||||
return libtoolCompiler;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
abstract public int getMaximumCommandLength();
|
||||
protected int getMaximumInputFilesPerCommand() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
protected int getTotalArgumentLengthForInputFile(File outputDir,
|
||||
String inputFile) {
|
||||
return inputFile.length() + 1;
|
||||
}
|
||||
abstract protected void getUndefineSwitch(StringBuffer buffer, String define);
|
||||
/**
|
||||
* This method is exposed so test classes can overload and test the
|
||||
* arguments without actually spawning the compiler
|
||||
*/
|
||||
protected int runCommand(CCTask task, File workingDir, String[] cmdline)
|
||||
throws BuildException {
|
||||
return CUtil.runCommand(task, workingDir, cmdline, newEnvironment, env);
|
||||
}
|
||||
protected final void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CompilerParam;
|
||||
import net.sf.antcontrib.cpptasks.DependencyInfo;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for a C++ compiler
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public final class CommandLineCompilerConfiguration
|
||||
implements
|
||||
CompilerConfiguration {
|
||||
private/* final */String[] args;
|
||||
private/* final */CommandLineCompiler compiler;
|
||||
private String[] endArgs;
|
||||
//
|
||||
// include path from environment variable not
|
||||
// explicitly stated in Ant script
|
||||
private/* final */File[] envIncludePath;
|
||||
private String[] exceptFiles;
|
||||
private/* final */String identifier;
|
||||
private/* final */File[] includePath;
|
||||
private/* final */String includePathIdentifier;
|
||||
private boolean isPrecompiledHeaderGeneration;
|
||||
private/* final */ProcessorParam[] params;
|
||||
private/* final */boolean rebuild;
|
||||
private/* final */File[] sysIncludePath;
|
||||
public CommandLineCompilerConfiguration(CommandLineCompiler compiler,
|
||||
String identifier, File[] includePath, File[] sysIncludePath,
|
||||
File[] envIncludePath, String includePathIdentifier, String[] args,
|
||||
ProcessorParam[] params, boolean rebuild, String[] endArgs) {
|
||||
if (compiler == null) {
|
||||
throw new NullPointerException("compiler");
|
||||
}
|
||||
if (identifier == null) {
|
||||
throw new NullPointerException("identifier");
|
||||
}
|
||||
if (includePathIdentifier == null) {
|
||||
throw new NullPointerException("includePathIdentifier");
|
||||
}
|
||||
if (args == null) {
|
||||
this.args = new String[0];
|
||||
} else {
|
||||
this.args = (String[]) args.clone();
|
||||
}
|
||||
if (includePath == null) {
|
||||
this.includePath = new File[0];
|
||||
} else {
|
||||
this.includePath = (File[]) includePath.clone();
|
||||
}
|
||||
if (sysIncludePath == null) {
|
||||
this.sysIncludePath = new File[0];
|
||||
} else {
|
||||
this.sysIncludePath = (File[]) sysIncludePath.clone();
|
||||
}
|
||||
if (envIncludePath == null) {
|
||||
this.envIncludePath = new File[0];
|
||||
} else {
|
||||
this.envIncludePath = (File[]) envIncludePath.clone();
|
||||
}
|
||||
this.compiler = compiler;
|
||||
this.params = (ProcessorParam[]) params.clone();
|
||||
this.rebuild = rebuild;
|
||||
this.identifier = identifier;
|
||||
this.includePathIdentifier = includePathIdentifier;
|
||||
this.endArgs = (String[]) endArgs.clone();
|
||||
exceptFiles = null;
|
||||
isPrecompiledHeaderGeneration = false;
|
||||
}
|
||||
public CommandLineCompilerConfiguration(
|
||||
CommandLineCompilerConfiguration base, String[] additionalArgs,
|
||||
String[] exceptFiles, boolean isPrecompileHeaderGeneration) {
|
||||
compiler = base.compiler;
|
||||
identifier = base.identifier;
|
||||
rebuild = base.rebuild;
|
||||
includePath = (File[]) base.includePath.clone();
|
||||
sysIncludePath = (File[]) base.sysIncludePath.clone();
|
||||
endArgs = (String[]) base.endArgs.clone();
|
||||
envIncludePath = (File[]) base.envIncludePath.clone();
|
||||
includePathIdentifier = base.includePathIdentifier;
|
||||
if (exceptFiles != null) {
|
||||
this.exceptFiles = (String[]) exceptFiles.clone();
|
||||
}
|
||||
this.isPrecompiledHeaderGeneration = isPrecompileHeaderGeneration;
|
||||
args = new String[base.args.length + additionalArgs.length];
|
||||
for (int i = 0; i < base.args.length; i++) {
|
||||
args[i] = base.args[i];
|
||||
}
|
||||
int index = base.args.length;
|
||||
for (int i = 0; i < additionalArgs.length; i++) {
|
||||
args[index++] = additionalArgs[i];
|
||||
}
|
||||
}
|
||||
public int bid(String inputFile) {
|
||||
int compilerBid = compiler.bid(inputFile);
|
||||
if (compilerBid > 0 && exceptFiles != null) {
|
||||
for (int i = 0; i < exceptFiles.length; i++) {
|
||||
if (inputFile.equals(exceptFiles[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return compilerBid;
|
||||
}
|
||||
public void compile(CCTask task, File outputDir, String[] sourceFiles,
|
||||
boolean relentless, ProgressMonitor monitor) throws BuildException {
|
||||
if (monitor != null) {
|
||||
monitor.start(this);
|
||||
}
|
||||
try {
|
||||
compiler.compile(task, outputDir, sourceFiles, args, endArgs,
|
||||
relentless, this, monitor);
|
||||
if (monitor != null) {
|
||||
monitor.finish(this, true);
|
||||
}
|
||||
} catch (BuildException ex) {
|
||||
if (monitor != null) {
|
||||
monitor.finish(this, false);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* This method may be used to get two distinct compiler configurations, one
|
||||
* for compiling the specified file and producing a precompiled header
|
||||
* file, and a second for compiling other files using the precompiled
|
||||
* header file.
|
||||
*
|
||||
* The last (preferrably only) include directive in the prototype file will
|
||||
* be used to mark the boundary between pre-compiled and normally compiled
|
||||
* headers.
|
||||
*
|
||||
* @param prototype
|
||||
* A source file (for example, stdafx.cpp) that is used to build
|
||||
* the precompiled header file. @returns null if precompiled
|
||||
* headers are not supported or a two element array containing
|
||||
* the precompiled header generation configuration and the
|
||||
* consuming configuration
|
||||
*
|
||||
*/
|
||||
public CompilerConfiguration[] createPrecompileConfigurations(
|
||||
File prototype, String[] nonPrecompiledFiles) {
|
||||
if (compiler instanceof PrecompilingCompiler) {
|
||||
return ((PrecompilingCompiler) compiler)
|
||||
.createPrecompileConfigurations(this, prototype,
|
||||
nonPrecompiledFiles);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Returns a string representation of this configuration. Should be
|
||||
* canonical so that equivalent configurations will have equivalent string
|
||||
* representations
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
public String getIncludePathIdentifier() {
|
||||
return includePathIdentifier;
|
||||
}
|
||||
public String getOutputFileName(String inputFile) {
|
||||
return compiler.getOutputFileName(inputFile);
|
||||
}
|
||||
public CompilerParam getParam(String name) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (name.equals(params[i].getName()))
|
||||
return (CompilerParam) params[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public ProcessorParam[] getParams() {
|
||||
return params;
|
||||
}
|
||||
public boolean getRebuild() {
|
||||
return rebuild;
|
||||
}
|
||||
public boolean isPrecompileGeneration() {
|
||||
return isPrecompiledHeaderGeneration;
|
||||
}
|
||||
public DependencyInfo parseIncludes(CCTask task, File baseDir, File source) {
|
||||
return compiler.parseIncludes(task, source, includePath,
|
||||
sysIncludePath, envIncludePath, baseDir,
|
||||
getIncludePathIdentifier());
|
||||
}
|
||||
public String toString() {
|
||||
return identifier;
|
||||
}
|
||||
public String[] getPreArguments() {
|
||||
return (String[]) args.clone();
|
||||
}
|
||||
public String[] getEndArguments() {
|
||||
return (String[]) endArgs.clone();
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.parser.FortranParser;
|
||||
import net.sf.antcontrib.cpptasks.parser.Parser;
|
||||
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* An abstract Compiler implementation which uses an external program to
|
||||
* perform the compile.
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public abstract class CommandLineFortranCompiler extends CommandLineCompiler {
|
||||
protected CommandLineFortranCompiler(String command, String identifierArg,
|
||||
String[] sourceExtensions, String[] headerExtensions,
|
||||
String outputSuffix, boolean libtool,
|
||||
CommandLineFortranCompiler libtoolCompiler, boolean newEnvironment,
|
||||
Environment env) {
|
||||
super(command, identifierArg, sourceExtensions, headerExtensions,
|
||||
outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
|
||||
}
|
||||
protected Parser createParser(File source) {
|
||||
return new FortranParser();
|
||||
}
|
||||
}
|
@ -0,0 +1,404 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CUtil;
|
||||
import net.sf.antcontrib.cpptasks.LinkerDef;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
import net.sf.antcontrib.cpptasks.types.CommandLineArgument;
|
||||
import net.sf.antcontrib.cpptasks.types.LibrarySet;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract Linker implementation that performs the link via an external
|
||||
* command.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public abstract class CommandLineLinker extends AbstractLinker
|
||||
{
|
||||
private String command;
|
||||
private Environment env = null;
|
||||
private String identifier;
|
||||
private String identifierArg;
|
||||
private boolean isLibtool;
|
||||
private String[] librarySets;
|
||||
private CommandLineLinker libtoolLinker;
|
||||
private boolean newEnvironment = false;
|
||||
private String outputSuffix;
|
||||
|
||||
|
||||
/** Creates a comand line linker invocation */
|
||||
public CommandLineLinker(String command,
|
||||
String identifierArg,
|
||||
String[] extensions,
|
||||
String[] ignoredExtensions, String outputSuffix,
|
||||
boolean isLibtool, CommandLineLinker libtoolLinker)
|
||||
{
|
||||
super(extensions, ignoredExtensions);
|
||||
this.command = command;
|
||||
this.identifierArg = identifierArg;
|
||||
this.outputSuffix = outputSuffix;
|
||||
this.isLibtool = isLibtool;
|
||||
this.libtoolLinker = libtoolLinker;
|
||||
}
|
||||
protected abstract void addBase(long base, Vector args);
|
||||
|
||||
protected abstract void addFixed(Boolean fixed, Vector args);
|
||||
|
||||
abstract protected void addImpliedArgs(boolean debug,
|
||||
LinkType linkType, Vector args, Boolean defaultflag);
|
||||
protected abstract void addIncremental(boolean incremental, Vector args);
|
||||
|
||||
//
|
||||
// Windows processors handle these through file list
|
||||
//
|
||||
protected String[] addLibrarySets(CCTask task, LibrarySet[] libsets, Vector preargs,
|
||||
Vector midargs, Vector endargs) {
|
||||
return null;
|
||||
}
|
||||
protected abstract void addMap(boolean map, Vector args);
|
||||
protected abstract void addStack(int stack, Vector args);
|
||||
protected abstract void addEntry(String entry, Vector args);
|
||||
|
||||
protected LinkerConfiguration createConfiguration(
|
||||
CCTask task,
|
||||
LinkType linkType,
|
||||
ProcessorDef[] baseDefs, LinkerDef specificDef, TargetDef targetPlatform) {
|
||||
|
||||
Vector preargs = new Vector();
|
||||
Vector midargs = new Vector();
|
||||
Vector endargs = new Vector();
|
||||
Vector[] args = new Vector[] { preargs, midargs, endargs };
|
||||
|
||||
LinkerDef[] defaultProviders = new LinkerDef[baseDefs.length+1];
|
||||
defaultProviders[0] = specificDef;
|
||||
for(int i = 0; i < baseDefs.length; i++) {
|
||||
defaultProviders[i+1] = (LinkerDef) baseDefs[i];
|
||||
}
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally the specific CompilerDef
|
||||
CommandLineArgument[] commandArgs;
|
||||
for(int i = defaultProviders.length-1; i >= 0; i--) {
|
||||
commandArgs = defaultProviders[i].getActiveProcessorArgs();
|
||||
for(int j = 0; j < commandArgs.length; j++) {
|
||||
args[commandArgs[j].getLocation()].
|
||||
addElement(commandArgs[j].getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Vector params = new Vector();
|
||||
//
|
||||
// add command line arguments inherited from <cc> element
|
||||
// any "extends" and finally the specific CompilerDef
|
||||
ProcessorParam[] paramArray;
|
||||
for (int i = defaultProviders.length - 1; i >= 0; i--) {
|
||||
paramArray = defaultProviders[i].getActiveProcessorParams();
|
||||
for (int j = 0; j < paramArray.length; j++) {
|
||||
params.add(paramArray[j]);
|
||||
}
|
||||
}
|
||||
|
||||
paramArray = (ProcessorParam[])(params.toArray(new ProcessorParam[params.size()]));
|
||||
|
||||
boolean debug = specificDef.getDebug(baseDefs,0);
|
||||
|
||||
|
||||
String startupObject = getStartupObject(linkType);
|
||||
Boolean defaultflag = specificDef.getDefaultflag(defaultProviders, 1);
|
||||
addImpliedArgs(debug, linkType, preargs, defaultflag);
|
||||
addIncremental(specificDef.getIncremental(defaultProviders,1), preargs);
|
||||
addFixed(specificDef.getFixed(defaultProviders,1), preargs);
|
||||
addMap(specificDef.getMap(defaultProviders,1), preargs);
|
||||
addBase(specificDef.getBase(defaultProviders,1), preargs);
|
||||
addStack(specificDef.getStack(defaultProviders,1), preargs);
|
||||
addEntry(specificDef.getEntry(defaultProviders, 1), preargs);
|
||||
|
||||
String[] libnames = null;
|
||||
LibrarySet[] libsets = specificDef.getActiveLibrarySets(defaultProviders,1);
|
||||
if (libsets.length > 0) {
|
||||
libnames = addLibrarySets(task, libsets, preargs, midargs, endargs);
|
||||
}
|
||||
|
||||
StringBuffer buf = new StringBuffer(getIdentifier());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Enumeration argenum = args[i].elements();
|
||||
while (argenum.hasMoreElements()) {
|
||||
buf.append(' ');
|
||||
buf.append(argenum.nextElement().toString());
|
||||
}
|
||||
}
|
||||
String configId = buf.toString();
|
||||
|
||||
String[][] options = new String[][] {
|
||||
new String[args[0].size() + args[1].size()],
|
||||
new String[args[2].size()] };
|
||||
args[0].copyInto(options[0]);
|
||||
int offset = args[0].size();
|
||||
for (int i = 0; i < args[1].size(); i++) {
|
||||
options[0][i+offset] = (String) args[1].elementAt(i);
|
||||
}
|
||||
args[2].copyInto(options[1]);
|
||||
|
||||
|
||||
boolean rebuild = specificDef.getRebuild(baseDefs,0);
|
||||
boolean map = specificDef.getMap(defaultProviders,1);
|
||||
|
||||
//task.log("libnames:"+libnames.length, Project.MSG_VERBOSE);
|
||||
return new CommandLineLinkerConfiguration(this,configId,options,
|
||||
paramArray,
|
||||
rebuild,map,libnames, startupObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows drived linker to decorate linker option.
|
||||
* Override by GccLinker to prepend a "-Wl," to
|
||||
* pass option to through gcc to linker.
|
||||
*
|
||||
* @param buf buffer that may be used and abused in the decoration process,
|
||||
* must not be null.
|
||||
* @param arg linker argument
|
||||
*/
|
||||
protected String decorateLinkerOption(StringBuffer buf, String arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
protected final String getCommand() {
|
||||
return command;
|
||||
}
|
||||
protected abstract String getCommandFileSwitch(String commandFile);
|
||||
|
||||
|
||||
public String getIdentifier() {
|
||||
if(identifier == null) {
|
||||
if (identifierArg == null) {
|
||||
identifier = getIdentifier(new String[] { command }, command);
|
||||
} else {
|
||||
identifier = getIdentifier(new String[] { command, identifierArg },
|
||||
command);
|
||||
}
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
public final CommandLineLinker getLibtoolLinker() {
|
||||
if (libtoolLinker != null) {
|
||||
return libtoolLinker;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
protected abstract int getMaximumCommandLength();
|
||||
|
||||
public String getOutputFileName(String baseName) {
|
||||
return baseName + outputSuffix;
|
||||
}
|
||||
|
||||
protected String[] getOutputFileSwitch(CCTask task, String outputFile) {
|
||||
return getOutputFileSwitch(outputFile);
|
||||
}
|
||||
protected abstract String[] getOutputFileSwitch(String outputFile);
|
||||
protected String getStartupObject(LinkType linkType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a link using a command line linker
|
||||
*
|
||||
*/
|
||||
public void link(CCTask task,
|
||||
File outputFile,
|
||||
String[] sourceFiles,
|
||||
CommandLineLinkerConfiguration config)
|
||||
throws BuildException
|
||||
{
|
||||
File parentDir = new File(outputFile.getParent());
|
||||
String parentPath;
|
||||
try {
|
||||
parentPath = parentDir.getCanonicalPath();
|
||||
} catch(IOException ex) {
|
||||
parentPath = parentDir.getAbsolutePath();
|
||||
}
|
||||
String[] execArgs = prepareArguments(task, parentPath,outputFile.getName(),
|
||||
sourceFiles, config);
|
||||
int commandLength = 0;
|
||||
for(int i = 0; i < execArgs.length; i++) {
|
||||
commandLength += execArgs[i].length() + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// if command length exceeds maximum
|
||||
// (1024 for Windows) then create a temporary
|
||||
// file containing everything but the command name
|
||||
if(commandLength >= this.getMaximumCommandLength()) {
|
||||
try {
|
||||
execArgs = prepareResponseFile(outputFile,execArgs);
|
||||
}
|
||||
catch(IOException ex) {
|
||||
throw new BuildException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
int retval = runCommand(task,parentDir,execArgs);
|
||||
//
|
||||
// if the process returned a failure code then
|
||||
// throw an BuildException
|
||||
//
|
||||
if(retval != 0) {
|
||||
//
|
||||
// construct the exception
|
||||
//
|
||||
throw new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepares argument list for exec command. Will return null
|
||||
* if command line would exceed allowable command line buffer.
|
||||
*
|
||||
* @param outputFile linker output file
|
||||
* @param sourceFiles linker input files (.obj, .o, .res)
|
||||
* @param args linker arguments
|
||||
* @return arguments for runTask
|
||||
*/
|
||||
protected String[] prepareArguments(
|
||||
CCTask task,
|
||||
String outputDir,
|
||||
String outputFile,
|
||||
String[] sourceFiles,
|
||||
CommandLineLinkerConfiguration config) {
|
||||
|
||||
String[] preargs = config.getPreArguments();
|
||||
String[] endargs = config.getEndArguments();
|
||||
String outputSwitch[] = getOutputFileSwitch(task, outputFile);
|
||||
int allArgsCount = preargs.length + 1 + outputSwitch.length +
|
||||
sourceFiles.length + endargs.length;
|
||||
if (isLibtool) {
|
||||
allArgsCount++;
|
||||
}
|
||||
String[] allArgs = new String[allArgsCount];
|
||||
int index = 0;
|
||||
if (isLibtool) {
|
||||
allArgs[index++] = "libtool";
|
||||
}
|
||||
allArgs[index++] = this.getCommand();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < preargs.length; i++) {
|
||||
allArgs[index++] = decorateLinkerOption(buf, preargs[i]);
|
||||
}
|
||||
for (int i = 0; i < outputSwitch.length; i++) {
|
||||
allArgs[index++] = outputSwitch[i];
|
||||
}
|
||||
for (int i = 0; i < sourceFiles.length; i++) {
|
||||
allArgs[index++] = prepareFilename(buf,outputDir,sourceFiles[i]);
|
||||
}
|
||||
for (int i = 0; i < endargs.length; i++) {
|
||||
allArgs[index++] = decorateLinkerOption(buf, endargs[i]);
|
||||
}
|
||||
return allArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes filename into argument form
|
||||
*
|
||||
*/
|
||||
protected String prepareFilename(StringBuffer buf,
|
||||
String outputDir, String sourceFile) {
|
||||
String relativePath = CUtil.getRelativePath(outputDir,
|
||||
new File(sourceFile));
|
||||
return quoteFilename(buf,relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares argument list to execute the linker using a
|
||||
* response file.
|
||||
*
|
||||
* @param outputFile linker output file
|
||||
* @param args output of prepareArguments
|
||||
* @return arguments for runTask
|
||||
*/
|
||||
protected String[] prepareResponseFile(File outputFile,String[] args) throws IOException
|
||||
{
|
||||
String baseName = outputFile.getName();
|
||||
File commandFile = new File(outputFile.getParent(),baseName + ".rsp");
|
||||
FileWriter writer = new FileWriter(commandFile);
|
||||
int execArgCount = 1;
|
||||
if (isLibtool) {
|
||||
execArgCount++;
|
||||
}
|
||||
String[] execArgs = new String[execArgCount+1];
|
||||
for (int i = 0; i < execArgCount; i++) {
|
||||
execArgs[i] = args[i];
|
||||
}
|
||||
execArgs[execArgCount] = getCommandFileSwitch(commandFile.toString());
|
||||
for(int i = execArgCount; i < args.length; i++) {
|
||||
//
|
||||
// if embedded space and not quoted then
|
||||
// quote argument
|
||||
if (args[i].indexOf(" ") >= 0 && args[i].charAt(0) != '\"') {
|
||||
writer.write('\"');
|
||||
writer.write(args[i]);
|
||||
writer.write("\"\n");
|
||||
} else {
|
||||
writer.write(args[i]);
|
||||
writer.write('\n');
|
||||
}
|
||||
}
|
||||
writer.close();
|
||||
return execArgs;
|
||||
}
|
||||
|
||||
|
||||
protected String quoteFilename(StringBuffer buf,String filename) {
|
||||
if(filename.indexOf(' ') >= 0) {
|
||||
buf.setLength(0);
|
||||
buf.append('\"');
|
||||
buf.append(filename);
|
||||
buf.append('\"');
|
||||
return buf.toString();
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is exposed so test classes can overload
|
||||
* and test the arguments without actually spawning the
|
||||
* compiler
|
||||
*/
|
||||
protected int runCommand(CCTask task, File workingDir,String[] cmdline)
|
||||
throws BuildException {
|
||||
return CUtil.runCommand(task,workingDir,cmdline, newEnvironment, env);
|
||||
}
|
||||
|
||||
protected final void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.LinkerParam;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
import net.sf.antcontrib.cpptasks.TargetInfo;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for a command line linker
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public final class CommandLineLinkerConfiguration
|
||||
implements
|
||||
LinkerConfiguration {
|
||||
private/* final */String[][] args;
|
||||
private/* final */String identifier;
|
||||
private String[] libraryNames;
|
||||
private/* final */CommandLineLinker linker;
|
||||
private/* final */boolean map;
|
||||
private/* final */ProcessorParam[] params;
|
||||
private/* final */boolean rebuild;
|
||||
private String startupObject;
|
||||
public CommandLineLinkerConfiguration(CommandLineLinker linker,
|
||||
String identifier, String[][] args, ProcessorParam[] params,
|
||||
boolean rebuild, boolean map, String[] libraryNames,
|
||||
String startupObject) {
|
||||
if (linker == null) {
|
||||
throw new NullPointerException("linker");
|
||||
}
|
||||
if (args == null) {
|
||||
throw new NullPointerException("args");
|
||||
} else {
|
||||
this.args = (String[][]) args.clone();
|
||||
}
|
||||
this.linker = linker;
|
||||
this.params = (ProcessorParam[]) params.clone();
|
||||
this.rebuild = rebuild;
|
||||
this.identifier = identifier;
|
||||
this.map = map;
|
||||
if (libraryNames == null) {
|
||||
this.libraryNames = new String[0];
|
||||
} else {
|
||||
this.libraryNames = (String[]) libraryNames.clone();
|
||||
}
|
||||
this.startupObject = startupObject;
|
||||
}
|
||||
public int bid(String filename) {
|
||||
return linker.bid(filename);
|
||||
}
|
||||
public String[] getEndArguments() {
|
||||
String[] clone = (String[]) args[1].clone();
|
||||
return clone;
|
||||
}
|
||||
/**
|
||||
* Returns a string representation of this configuration. Should be
|
||||
* canonical so that equivalent configurations will have equivalent string
|
||||
* representations
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
public String[] getLibraryNames() {
|
||||
String[] clone = (String[]) libraryNames.clone();
|
||||
return clone;
|
||||
}
|
||||
public boolean getMap() {
|
||||
return map;
|
||||
}
|
||||
public String getOutputFileName(String inputFile) {
|
||||
return linker.getOutputFileName(inputFile);
|
||||
}
|
||||
public LinkerParam getParam(String name) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (name.equals(params[i].getName()))
|
||||
return (LinkerParam) params[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public ProcessorParam[] getParams() {
|
||||
return params;
|
||||
}
|
||||
public String[] getPreArguments() {
|
||||
String[] clone = (String[]) args[0].clone();
|
||||
return clone;
|
||||
}
|
||||
public boolean getRebuild() {
|
||||
return rebuild;
|
||||
}
|
||||
public String getStartupObject() {
|
||||
return startupObject;
|
||||
}
|
||||
public void link(CCTask task, TargetInfo linkTarget) throws BuildException {
|
||||
//
|
||||
// AllSourcePath's include any syslibsets
|
||||
//
|
||||
String[] sourcePaths = linkTarget.getAllSourcePaths();
|
||||
linker.link(task, linkTarget.getOutput(), sourcePaths, this);
|
||||
}
|
||||
public String toString() {
|
||||
return identifier;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
/**
|
||||
* A compiler.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public interface Compiler extends Processor {
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.CompilerParam;
|
||||
import net.sf.antcontrib.cpptasks.DependencyInfo;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for a compiler
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface CompilerConfiguration extends ProcessorConfiguration {
|
||||
void compile(CCTask task, File outputDir, String[] sourceFiles,
|
||||
boolean relentless, ProgressMonitor monitor) throws BuildException;
|
||||
/**
|
||||
*
|
||||
* This method may be used to get two distinct compiler configurations, one
|
||||
* for compiling the specified file and producing a precompiled header
|
||||
* file, and a second for compiling other files using the precompiled
|
||||
* header file.
|
||||
*
|
||||
* The last (preferrably only) include directive in the prototype file will
|
||||
* be used to mark the boundary between pre-compiled and normally compiled
|
||||
* headers.
|
||||
*
|
||||
* @param prototype
|
||||
* A source file (for example, stdafx.cpp) that is used to build
|
||||
* the precompiled header file. @returns null if precompiled
|
||||
* headers are not supported or a two element array containing
|
||||
* the precompiled header generation configuration and the
|
||||
* consuming configuration
|
||||
*
|
||||
*/
|
||||
CompilerConfiguration[] createPrecompileConfigurations(File prototype,
|
||||
String[] nonPrecompiledFiles);
|
||||
/**
|
||||
* Returns an digest for the include path for the configuration.
|
||||
*
|
||||
* This is used to determine if cached dependency information is invalid
|
||||
* because the include paths have changed
|
||||
*/
|
||||
String getIncludePathIdentifier();
|
||||
public CompilerParam getParam(String name);
|
||||
boolean isPrecompileGeneration();
|
||||
DependencyInfo parseIncludes(CCTask task, File baseDir, File source);
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import net.sf.antcontrib.cpptasks.OutputTypeEnum;
|
||||
import net.sf.antcontrib.cpptasks.SubsystemEnum;
|
||||
/**
|
||||
* This class represents the target platform for the compile and link step. The
|
||||
* name is an anachronism and should be changed.
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public class LinkType {
|
||||
private OutputTypeEnum outputType = new OutputTypeEnum();
|
||||
private boolean staticRuntime = false;
|
||||
private SubsystemEnum subsystem = new SubsystemEnum();
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* By default, an gui executable with a dynamically linked runtime
|
||||
*
|
||||
*/
|
||||
public LinkType() {
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce an executable
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isExecutable() {
|
||||
String value = outputType.getValue();
|
||||
return value.equals("executable");
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce a plugin module.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isPluginModule() {
|
||||
String value = outputType.getValue();
|
||||
return value.equals("plugin");
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce a shared library.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSharedLibrary() {
|
||||
String value = outputType.getValue();
|
||||
return value.equals("shared") || value.equals("plugin");
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce a static library.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isStaticLibrary() {
|
||||
String value = outputType.getValue();
|
||||
return value.equals("static");
|
||||
}
|
||||
/**
|
||||
* Gets whether the module should use a statically linked runtime library.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isStaticRuntime() {
|
||||
return staticRuntime;
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce a module for a console subsystem.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSubsystemConsole() {
|
||||
String value = subsystem.getValue();
|
||||
return value.equals("console");
|
||||
}
|
||||
/**
|
||||
* Gets whether the link should produce a module for a graphical user
|
||||
* interface subsystem.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isSubsystemGUI() {
|
||||
String value = subsystem.getValue();
|
||||
return value.equals("gui");
|
||||
}
|
||||
/**
|
||||
* Sets the output type (execuable, shared, etc).
|
||||
*
|
||||
* @param outputType,
|
||||
* may not be null
|
||||
*/
|
||||
public void setOutputType(OutputTypeEnum outputType) {
|
||||
if (outputType == null) {
|
||||
throw new IllegalArgumentException("outputType");
|
||||
}
|
||||
this.outputType = outputType;
|
||||
}
|
||||
/**
|
||||
* Requests use of a static runtime library.
|
||||
*
|
||||
* @param staticRuntime
|
||||
* if true, use static runtime library if possible.
|
||||
*/
|
||||
public void setStaticRuntime(boolean staticRuntime) {
|
||||
this.staticRuntime = staticRuntime;
|
||||
}
|
||||
/**
|
||||
* Sets the subsystem (gui, console, etc).
|
||||
*
|
||||
* @param subsystem
|
||||
* subsystem, may not be null
|
||||
*/
|
||||
public void setSubsystem(SubsystemEnum subsystem) {
|
||||
if (subsystem == null) {
|
||||
throw new IllegalArgumentException("subsystem");
|
||||
}
|
||||
this.subsystem = subsystem;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
|
||||
/**
|
||||
* A linker for executables, and static and dynamic libraries.
|
||||
*
|
||||
* @author Adam Murdoch
|
||||
*/
|
||||
public interface Linker extends Processor {
|
||||
/**
|
||||
* Extracts the significant part of a library name to ensure there aren't
|
||||
* collisions
|
||||
*/
|
||||
String getLibraryKey(File libname);
|
||||
/**
|
||||
* returns the library path for the linker
|
||||
*/
|
||||
File[] getLibraryPath();
|
||||
/**
|
||||
* Returns a set of filename patterns corresponding to library names.
|
||||
*
|
||||
* For example, "advapi32" would be expanded to "advapi32.dll" by
|
||||
* DevStudioLinker and to "libadvapi32.a" and "libadvapi32.so" by
|
||||
* GccLinker.
|
||||
*
|
||||
* @param libnames
|
||||
* array of library names
|
||||
*/
|
||||
String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libraryType);
|
||||
/**
|
||||
* Gets the linker for the specified link type.
|
||||
*
|
||||
* @return appropriate linker or null, will return this if this linker can
|
||||
* handle the specified link type
|
||||
*/
|
||||
Linker getLinker(LinkType linkType);
|
||||
/**
|
||||
* Returns true if the linker is case-sensitive
|
||||
*/
|
||||
boolean isCaseSensitive();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.LinkerParam;
|
||||
import net.sf.antcontrib.cpptasks.TargetInfo;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
/**
|
||||
* A configuration for a linker
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface LinkerConfiguration extends ProcessorConfiguration {
|
||||
public LinkerParam getParam(String name);
|
||||
void link(CCTask task, TargetInfo linkTarget) throws BuildException;
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.parser.CParser;
|
||||
import net.sf.antcontrib.cpptasks.parser.Parser;
|
||||
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* A command line C compiler that can utilize precompilation of header files
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public abstract class PrecompilingCommandLineCCompiler
|
||||
extends
|
||||
PrecompilingCommandLineCompiler {
|
||||
protected PrecompilingCommandLineCCompiler(String command,
|
||||
String identifierArg, String[] sourceExtensions,
|
||||
String[] headerExtensions, String outputSuffix, boolean libtool,
|
||||
PrecompilingCommandLineCCompiler libtoolCompiler,
|
||||
boolean newEnvironment, Environment env) {
|
||||
super(command, identifierArg, sourceExtensions, headerExtensions,
|
||||
outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
|
||||
}
|
||||
protected Parser createParser(File source) {
|
||||
return new CParser();
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import net.sf.antcontrib.cpptasks.parser.Parser;
|
||||
|
||||
import org.apache.tools.ant.BuildException;
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* A command line C compiler that can utilize precompilation of header files
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public abstract class PrecompilingCommandLineCompiler
|
||||
extends
|
||||
CommandLineCompiler implements PrecompilingCompiler {
|
||||
protected PrecompilingCommandLineCompiler(String command,
|
||||
String identifierArg, String[] sourceExtensions,
|
||||
String[] headerExtensions, String outputSuffix, boolean libtool,
|
||||
PrecompilingCommandLineCompiler libtoolCompiler,
|
||||
boolean newEnvironment, Environment env) {
|
||||
super(command, identifierArg, sourceExtensions, headerExtensions,
|
||||
outputSuffix, libtool, libtoolCompiler, newEnvironment, env);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* This method may be used to get two distinct compiler configurations, one
|
||||
* for compiling the specified file and producing a precompiled header
|
||||
* file, and a second for compiling other files using the precompiled
|
||||
* header file.
|
||||
*
|
||||
* The last (preferrably only) include directive in the prototype file will
|
||||
* be used to mark the boundary between pre-compiled and normally compiled
|
||||
* headers.
|
||||
*
|
||||
* @param config
|
||||
* base configuration
|
||||
* @param prototype
|
||||
* A source file (for example, stdafx.cpp) that is used to build
|
||||
* the precompiled header file. @returns null if precompiled
|
||||
* headers are not supported or a two element array containing
|
||||
* the precompiled header generation configuration and the
|
||||
* consuming configuration
|
||||
*
|
||||
*/
|
||||
public CompilerConfiguration[] createPrecompileConfigurations(
|
||||
CompilerConfiguration config, File prototype, String[] exceptFiles) {
|
||||
//
|
||||
// cast should success or someone is passing us a configuration
|
||||
// that was prepared by another processor
|
||||
//
|
||||
CommandLineCompilerConfiguration cmdLineConfig = (CommandLineCompilerConfiguration) config;
|
||||
//
|
||||
// parse prototype file to determine last header
|
||||
//
|
||||
Parser parser = createParser(prototype);
|
||||
String[] includes;
|
||||
try {
|
||||
Reader reader = new BufferedReader(new FileReader(prototype));
|
||||
parser.parse(reader);
|
||||
includes = parser.getIncludes();
|
||||
} catch (IOException ex) {
|
||||
throw new BuildException(
|
||||
"Error parsing precompiled header protoype: "
|
||||
+ prototype.toString() + ":" + ex.toString());
|
||||
}
|
||||
if (includes.length == 0) {
|
||||
throw new BuildException("Precompiled header prototype: "
|
||||
+ prototype.toString()
|
||||
+ " does not contain any include directives.");
|
||||
}
|
||||
CompilerConfiguration[] configs = new CompilerConfiguration[2];
|
||||
configs[0] = createPrecompileGeneratingConfig(cmdLineConfig, prototype,
|
||||
includes[0]);
|
||||
configs[1] = createPrecompileUsingConfig(cmdLineConfig, prototype,
|
||||
includes[0], exceptFiles);
|
||||
return configs;
|
||||
}
|
||||
abstract protected CompilerConfiguration createPrecompileGeneratingConfig(
|
||||
CommandLineCompilerConfiguration baseConfig, File prototype,
|
||||
String lastInclude);
|
||||
abstract protected CompilerConfiguration createPrecompileUsingConfig(
|
||||
CommandLineCompilerConfiguration baseConfig, File prototype,
|
||||
String lastInclude, String[] exceptFiles);
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import java.io.File;
|
||||
/**
|
||||
* A compiler that can utilize precompilation of header files
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface PrecompilingCompiler {
|
||||
/**
|
||||
*
|
||||
* This method may be used to get two distinct compiler configurations, one
|
||||
* for compiling the specified file and producing a precompiled header
|
||||
* file, and a second for compiling other files using the precompiled
|
||||
* header file.
|
||||
*
|
||||
* The last (preferrably only) include directive in the prototype file will
|
||||
* be used to mark the boundary between pre-compiled and normally compiled
|
||||
* headers.
|
||||
*
|
||||
* @param config
|
||||
* base configuration
|
||||
* @param prototype
|
||||
* A source file (for example, stdafx.cpp) that is used to build
|
||||
* the precompiled header file. @returns null if precompiled
|
||||
* headers are not supported or a two element array containing
|
||||
* the precompiled header generation configuration and the
|
||||
* consuming configuration
|
||||
*
|
||||
*/
|
||||
CompilerConfiguration[] createPrecompileConfigurations(
|
||||
CompilerConfiguration config, File prototype,
|
||||
String[] nonPrecompiledFiles);
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import net.sf.antcontrib.cpptasks.CCTask;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorDef;
|
||||
import net.sf.antcontrib.cpptasks.TargetDef;
|
||||
import org.apache.tools.ant.types.Environment;
|
||||
/**
|
||||
* A processor. Base interface for Compiler and Linker
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface Processor {
|
||||
/**
|
||||
* Returns a bid indicating the desire of this compiler to process the
|
||||
* file.
|
||||
*
|
||||
* @param inputFile
|
||||
* input file
|
||||
* @return 0 = no interest, 100 = high interest
|
||||
*/
|
||||
int bid(String inputFile);
|
||||
Processor changeEnvironment(boolean newEnvironment, Environment env);
|
||||
/**
|
||||
* Returns the compiler configuration for <cc>or <compiler>element.
|
||||
*
|
||||
* @param defaultProviders
|
||||
* When specificConfig corresponds to a <compiler>or linker
|
||||
* element, defaultProvider will be a zero to two element array.
|
||||
* If there is an extends attribute, the first element will be
|
||||
* the referenced ProcessorDef, unless inherit = false, the last
|
||||
* element will be the containing <cc>element
|
||||
* @param specificConfig
|
||||
* A <cc>or <compiler>element.
|
||||
* @return resulting configuration
|
||||
*/
|
||||
ProcessorConfiguration createConfiguration(CCTask task, LinkType linkType,
|
||||
ProcessorDef[] defaultProviders, ProcessorDef specificConfig,
|
||||
TargetDef targetPlatform);
|
||||
/**
|
||||
* Retrieve an identifier that identifies the specific version of the
|
||||
* compiler. Compilers with the same identifier should produce the same
|
||||
* output files for the same input files and command line switches.
|
||||
*/
|
||||
String getIdentifier();
|
||||
/**
|
||||
* Gets the linker that is associated with this processors
|
||||
*/
|
||||
Linker getLinker(LinkType type);
|
||||
/**
|
||||
* Output file name (no path components) corresponding to source file
|
||||
*
|
||||
* @param inputFile
|
||||
* input file
|
||||
* @return output file name or null if no output file or name not
|
||||
* determined by input file
|
||||
*/
|
||||
String getOutputFileName(String inputFile);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2002-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
import net.sf.antcontrib.cpptasks.ProcessorParam;
|
||||
/**
|
||||
* A configuration for a C++ compiler, linker or other processor
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface ProcessorConfiguration {
|
||||
/**
|
||||
* An indication of how much this compiler would like to process this file
|
||||
*
|
||||
* @return 0 is no interest to process, 100 is strong interest to process
|
||||
*/
|
||||
int bid(String filename);
|
||||
/**
|
||||
* Returns a string representation of this configuration. Should be
|
||||
* canonical so that equivalent configurations will have equivalent string
|
||||
* representations
|
||||
*/
|
||||
String getIdentifier();
|
||||
/**
|
||||
* Output file name (no path components) corresponding to source file
|
||||
*
|
||||
* @param inputFile
|
||||
* input file
|
||||
* @return output file name or null if no output file or name not
|
||||
* determined by input file
|
||||
*/
|
||||
String getOutputFileName(String inputFile);
|
||||
ProcessorParam[] getParams();
|
||||
/**
|
||||
* If true, all files using this configuration should be rebuilt and any
|
||||
* existing output files should be ignored
|
||||
*/
|
||||
boolean getRebuild();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* Copyright 2001-2004 The Ant-Contrib project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.antcontrib.cpptasks.compiler;
|
||||
/**
|
||||
* Interface to receive notification of compile progress
|
||||
*
|
||||
* @author Curt Arnold
|
||||
*/
|
||||
public interface ProgressMonitor {
|
||||
public void finish(ProcessorConfiguration config, boolean normal);
|
||||
/**
|
||||
* Called to notify monitor of progress
|
||||
*
|
||||
*/
|
||||
void progress(String[] sources);
|
||||
public void start(ProcessorConfiguration config);
|
||||
}
|
Reference in New Issue
Block a user