diff options
Diffstat (limited to 'src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java')
-rw-r--r-- | src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java b/src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java new file mode 100644 index 0000000..a210e7e --- /dev/null +++ b/src/net/sf/antcontrib/cpptasks/gcc/AbstractLdLinker.java @@ -0,0 +1,325 @@ +/* + * + * 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.gcc; +import java.io.File; +import java.util.Vector; + +import net.sf.antcontrib.cpptasks.CCTask; +import net.sf.antcontrib.cpptasks.CUtil; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker; +import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration; +import net.sf.antcontrib.cpptasks.compiler.LinkType; +import net.sf.antcontrib.cpptasks.VersionInfo; +import net.sf.antcontrib.cpptasks.types.LibrarySet; +import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum; + +/** + * Abstract adapter for ld-like linkers + * + * @author Curt Arnold + */ +public abstract class AbstractLdLinker extends CommandLineLinker { + private String outputPrefix; + protected AbstractLdLinker(String command, String identifierArg, + String[] extensions, String[] ignoredExtensions, + String outputPrefix, String outputSuffix, boolean isLibtool, + AbstractLdLinker libtoolLinker) { + super(command, identifierArg, extensions, ignoredExtensions, + outputSuffix, isLibtool, libtoolLinker); + this.outputPrefix = outputPrefix; + } + public void addBase(long base, Vector args) { + if (base >= 0) { + args.addElement("--image-base"); + args.addElement(Long.toHexString(base)); + } + } + public void addFixed(Boolean fixed, Vector args) { + } + protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) { + if (debug) { + args.addElement("-g"); + } + if (isDarwin()) { + if (linkType.isPluginModule()) { + args.addElement("-bundle"); + } else { + if (linkType.isSharedLibrary()) { + args.addElement("-prebind"); + args.addElement("-dynamiclib"); + } + } + } else { + if (linkType.isStaticRuntime()) { + args.addElement("-static"); + } + if (linkType.isPluginModule()) { + args.addElement("-shared"); + } else { + if (linkType.isSharedLibrary()) { + args.addElement("-shared"); + } + } + } + } + public void addIncremental(boolean incremental, Vector args) { + if (incremental) { + args.addElement("-i"); + } + } + protected int addLibraryPatterns(String[] libnames, StringBuffer buf, + String prefix, String extension, String[] patterns, int offset) { + for (int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(prefix); + buf.append(libnames[i]); + buf.append(extension); + patterns[offset + i] = buf.toString(); + } + return offset + libnames.length; + } + public String[] addLibrarySets(CCTask task, LibrarySet[] libsets, + Vector preargs, Vector midargs, Vector endargs) { + Vector libnames = new Vector(); + super.addLibrarySets(task, libsets, preargs, midargs, endargs); + LibraryTypeEnum previousLibraryType = null; + for (int i = 0; i < libsets.length; i++) { + LibrarySet set = libsets[i]; + File libdir = set.getDir(null); + String[] libs = set.getLibs(); + if (libdir != null) { + if (set.getType() != null && + "framework".equals(set.getType().getValue()) && + isDarwin()) { + endargs.addElement("-F" + libdir.getAbsolutePath()); + } else { + endargs.addElement("-L" + libdir.getAbsolutePath()); + } + } + // + // if there has been a change of library type + // + if (set.getType() != previousLibraryType) { + if (set.getType() != null && "static".equals(set.getType().getValue())) { + endargs.addElement("-Bstatic"); + previousLibraryType = set.getType(); + } else { + if (set.getType() == null || + !"framework".equals(set.getType().getValue()) || + !isDarwin()) { + endargs.addElement("-Bdynamic"); + previousLibraryType = set.getType(); + } + } + } + StringBuffer buf = new StringBuffer("-l"); + if (set.getType() != null && + "framework".equals(set.getType().getValue()) && + isDarwin()) { + buf.setLength(0); + buf.append("-framework "); + } + int initialLength = buf.length(); + for (int j = 0; j < libs.length; j++) { + // + // reset the buffer to just "-l" + // + buf.setLength(initialLength); + // + // add the library name + buf.append(libs[j]); + libnames.addElement(libs[j]); + // + // add the argument to the list + endargs.addElement(buf.toString()); + } + } + String rc[] = new String[libnames.size()]; + for (int i = 0; i < libnames.size(); i++) { + rc[i] = (String) libnames.elementAt(i); + } + return rc; + } + public void addMap(boolean map, Vector args) { + if (map) { + args.addElement("-M"); + } + } + public void addStack(int stack, Vector args) { + if (stack > 0) { + args.addElement("--stack"); + args.addElement(Integer.toString(stack)); + } + } + /* (non-Javadoc) + * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector) + */ + protected void addEntry(String entry, Vector args) { + if (entry != null) { + args.addElement("-e"); + args.addElement(entry); + } + } + + public String getCommandFileSwitch(String commandFile) { + throw new IllegalStateException("ld does not support command files"); + } + /** + * Returns library path. + * + */ + protected File[] getEnvironmentIncludePath() { + return CUtil.getPathFromEnvironment("LIB", ":"); + } + public String getLibraryKey(File libfile) { + String libname = libfile.getName(); + int lastDot = libname.lastIndexOf('.'); + if (lastDot >= 0) { + return libname.substring(0, lastDot); + } + return libname; + } + /** + * Returns library path. + * + */ + public File[] getLibraryPath() { + return new File[0]; + } + public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) { + StringBuffer buf = new StringBuffer(); + int patternCount = libnames.length; + if (libType == null) { + patternCount *= 2; + } + String[] patterns = new String[patternCount]; + int offset = 0; + if (libType == null || "static".equals(libType.getValue())) { + offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0); + } + if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) { + for(int i = 0; i < libnames.length; i++) { + buf.setLength(0); + buf.append(libnames[i]); + buf.append(".framework/"); + buf.append(libnames[i]); + patterns[offset++] = buf.toString(); + } + } else { + if (libType == null || !"static".equals(libType.getValue())) { + if (isHPUX()) { + offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns, + offset); + } else { + offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns, + offset); + } + } + } + return patterns; + } + public int getMaximumCommandLength() { + return Integer.MAX_VALUE; + } + public String[] getOutputFileNames(String baseName, VersionInfo versionInfo) { + String[] baseNames = super.getOutputFileNames(baseName, versionInfo); + if (outputPrefix.length() > 0) { + for(int i = 0; i < baseNames.length; i++) { + baseNames[i] = outputPrefix + baseNames[i]; + } + } + return baseNames; + } + public String[] getOutputFileSwitch(String outputFile) { + return GccProcessor.getOutputFileSwitch("-o", outputFile); + } + + public boolean isCaseSensitive() { + return true; + } + protected boolean isHPUX() { + String osname = System.getProperty("os.name").toLowerCase(); + if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) { + return true; + } + return false; + } + /** + * 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 + */ + public String[] prepareArguments(CCTask task, String outputDir, + String outputFile, String[] sourceFiles, + CommandLineLinkerConfiguration config) { + // + // need to suppress sources that correspond to + // library set entries since they are already + // in the argument list + String[] libnames = config.getLibraryNames(); + if (libnames == null || libnames.length == 0) { + return super.prepareArguments(task, outputDir, outputFile, + sourceFiles, config); + } + // + // + // null out any sources that correspond to library names + // + String[] localSources = (String[]) sourceFiles.clone(); + int extra = 0; + for (int i = 0; i < libnames.length; i++) { + String libname = libnames[i]; + for (int j = 0; j < localSources.length; j++) { + if (localSources[j] != null + && localSources[j].indexOf(libname) > 0 + && localSources[j].indexOf("lib") > 0) { + String filename = new File(localSources[j]).getName(); + if (filename.startsWith("lib") + && filename.substring(3).startsWith(libname)) { + String extension = filename + .substring(libname.length() + 3); + if (extension.equals(".a") || extension.equals(".so") + || extension.equals(".sl")) { + localSources[j] = null; + extra++; + } + } + } + } + } + if (extra == 0) { + return super.prepareArguments(task, outputDir, outputFile, + sourceFiles, config); + } + String[] finalSources = new String[localSources.length - extra]; + int index = 0; + for (int i = 0; i < localSources.length; i++) { + if (localSources[i] != null) { + finalSources[index++] = localSources[i]; + } + } + return super.prepareArguments(task, outputDir, outputFile, + finalSources, config); + } +} |