summaryrefslogtreecommitdiff
path: root/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java')
-rw-r--r--src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
new file mode 100644
index 0000000..6a28805
--- /dev/null
+++ b/src/main/java/net/sf/antcontrib/cpptasks/borland/BorlandLinker.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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.borland;
+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.TargetMatcher;
+import net.sf.antcontrib.cpptasks.VersionInfo;
+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.compiler.Linker;
+import net.sf.antcontrib.cpptasks.platforms.WindowsPlatform;
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;
+
+/**
+ * Adapter for the Borland(r) ilink32 linker
+ *
+ * @author Curt Arnold
+ */
+public final class BorlandLinker extends CommandLineLinker {
+ private static final BorlandLinker dllLinker = new BorlandLinker(".dll");
+ private static final BorlandLinker instance = new BorlandLinker(".exe");
+ public static BorlandLinker getInstance() {
+ return instance;
+ }
+ private BorlandLinker(String outputSuffix) {
+ super("ilink32", "-r", new String[]{".obj", ".lib", ".res"},
+ new String[]{".map", ".pdb", ".lnk"}, outputSuffix, false, null);
+ }
+ protected void addBase(long base, Vector args) {
+ if (base >= 0) {
+ String baseAddr = Long.toHexString(base);
+ args.addElement("-b:" + baseAddr);
+ }
+ }
+ protected void addFixed(Boolean fixed, Vector args) {
+ }
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args) {
+ if (linkType.isExecutable()) {
+ if (linkType.isSubsystemConsole()) {
+ args.addElement("/ap");
+ } else {
+ if (linkType.isSubsystemGUI()) {
+ args.addElement("/Tpe");
+ }
+ }
+ }
+ if (linkType.isSharedLibrary()) {
+ args.addElement("/Tpd");
+ args.addElement("/Gi");
+ }
+ if (debug) {
+ args.addElement("-v");
+ }
+ }
+ protected void addIncremental(boolean incremental, Vector args) {
+ }
+ protected void addMap(boolean map, Vector args) {
+ if (!map) {
+ args.addElement("-x");
+ }
+ }
+ protected void addStack(int stack, Vector args) {
+ if (stack >= 0) {
+ String stackStr = Integer.toHexString(stack);
+ args.addElement("-S:" + stackStr);
+ }
+ }
+ /* (non-Javadoc)
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
+ */
+ protected void addEntry(String entry, Vector args) {
+ }
+
+ public String getCommandFileSwitch(String commandFile) {
+ return "@" + commandFile;
+ }
+ public String getIdentifier() {
+ return "Borland Linker";
+ }
+ public File[] getLibraryPath() {
+ return BorlandProcessor.getEnvironmentPath("ilink32", 'L',
+ new String[]{"..\\lib"});
+ }
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {
+ return BorlandProcessor.getLibraryPatterns(libnames, libType);
+ }
+ public Linker getLinker(LinkType type) {
+ if (type.isStaticLibrary()) {
+ return BorlandLibrarian.getInstance();
+ }
+ if (type.isSharedLibrary()) {
+ return dllLinker;
+ }
+ return instance;
+ }
+ public int getMaximumCommandLength() {
+ return 1024;
+ }
+ public String[] getOutputFileSwitch(String outFile) {
+ return BorlandProcessor.getOutputFileSwitch(outFile);
+ }
+ protected String getStartupObject(LinkType linkType) {
+ if (linkType.isSharedLibrary()) {
+ return "c0d32.obj";
+ }
+ if (linkType.isSubsystemGUI()) {
+ return "c0w32.obj";
+ }
+ if (linkType.isSubsystemConsole()) {
+ return "c0x32.obj";
+ }
+ return null;
+ }
+ public boolean isCaseSensitive() {
+ return BorlandProcessor.isCaseSensitive();
+ }
+ /**
+ * Prepares argument list for exec command.
+ *
+ * @param outputDir linker output directory
+ * @param outputName linker output name
+ * @param sourceFiles
+ * linker input files (.obj, .o, .res)
+ * @param config
+ * linker configuration
+ * @return arguments for runTask
+ */
+ protected String[] prepareArguments(
+ CCTask task,
+ String outputDir,
+ String outputName,
+ String[] sourceFiles,
+ CommandLineLinkerConfiguration config) {
+ String[] preargs = config.getPreArguments();
+ String[] endargs = config.getEndArguments();
+ Vector execArgs = new Vector(preargs.length + endargs.length + 10
+ + sourceFiles.length);
+ execArgs.addElement(this.getCommand());
+ for (int i = 0; i < preargs.length; i++) {
+ execArgs.addElement(preargs[i]);
+ }
+ for (int i = 0; i < endargs.length; i++) {
+ execArgs.addElement(endargs[i]);
+ }
+ //
+ // see if the input files have any known startup obj files
+ //
+ String startup = null;
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String filename = new File(sourceFiles[i]).getName().toLowerCase();
+ if (startup != null && filename.substring(0, 2).equals("c0")
+ && filename.substring(3, 5).equals("32")
+ && filename.substring(filename.length() - 4).equals(".obj")) {
+ startup = sourceFiles[i];
+ }
+ }
+ //
+ // c0w32.obj, c0x32.obj or c0d32.obj depending on
+ // link type
+ if (startup == null) {
+ startup = config.getStartupObject();
+ }
+ execArgs.addElement(startup);
+ Vector resFiles = new Vector();
+ Vector libFiles = new Vector();
+ String defFile = null;
+ StringBuffer buf = new StringBuffer();
+ for (int i = 0; i < sourceFiles.length; i++) {
+ String last4 = sourceFiles[i]
+ .substring(sourceFiles[i].length() - 4).toLowerCase();
+ if (last4.equals(".def")) {
+ defFile = quoteFilename(buf, sourceFiles[i]);
+ } else {
+ if (last4.equals(".res")) {
+ resFiles.addElement(quoteFilename(buf, sourceFiles[i]));
+ } else {
+ if (last4.equals(".lib")) {
+ libFiles.addElement(quoteFilename(buf, sourceFiles[i]));
+ } else {
+ execArgs.addElement(quoteFilename(buf, sourceFiles[i]));
+ }
+ }
+ }
+ }
+ //
+ // output file name
+ //
+ String outputFileName = new File(outputDir, outputName).toString();
+ execArgs.addElement("," + quoteFilename(buf, outputFileName));
+ if (config.getMap()) {
+ int lastPeriod = outputFileName.lastIndexOf('.');
+ String mapName;
+ if (lastPeriod < outputFileName.length() - 4) {
+ mapName = outputFileName + ".map";
+ } else {
+ mapName = outputFileName.substring(0, lastPeriod) + ".map";
+ }
+ execArgs.addElement("," + quoteFilename(buf, mapName) + ",");
+ } else {
+ execArgs.addElement(",,");
+ }
+ //
+ // add all the libraries
+ //
+ Enumeration libEnum = libFiles.elements();
+ boolean hasImport32 = false;
+ boolean hasCw32 = false;
+ while (libEnum.hasMoreElements()) {
+ String libName = (String) libEnum.nextElement();
+ if (libName.equalsIgnoreCase("import32.lib")) {
+ hasImport32 = true;
+ }
+ if (libName.equalsIgnoreCase("cw32.lib")) {
+ hasImport32 = true;
+ }
+ execArgs.addElement(quoteFilename(buf, libName));
+ }
+ if (!hasCw32) {
+ execArgs.addElement(quoteFilename(buf, "cw32.lib"));
+ }
+ if (!hasImport32) {
+ execArgs.addElement(quoteFilename(buf, "import32.lib"));
+ }
+ if (defFile == null) {
+ execArgs.addElement(",,");
+ } else {
+ execArgs.addElement("," + quoteFilename(buf, defFile) + ",");
+ }
+ Enumeration resEnum = resFiles.elements();
+ while (resEnum.hasMoreElements()) {
+ String resName = (String) resEnum.nextElement();
+ execArgs.addElement(quoteFilename(buf, resName));
+ }
+ String[] execArguments = new String[execArgs.size()];
+ execArgs.copyInto(execArguments);
+ return execArguments;
+ }
+ /**
+ * 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 cmdargs[] = BorlandProcessor.prepareResponseFile(outputFile, args, " + \n");
+ cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length -1]);
+ return cmdargs;
+ }
+
+ /**
+ * Adds source or object files to the bidded fileset to
+ * support version information.
+ *
+ * @param versionInfo version information
+ * @param linkType link type
+ * @param isDebug true if debug build
+ * @param outputFile name of generated executable
+ * @param objDir directory for generated files
+ * @param matcher bidded fileset
+ */
+ public void addVersionFiles(final VersionInfo versionInfo,
+ final LinkType linkType,
+ final File outputFile,
+ final boolean isDebug,
+ final File objDir,
+ final TargetMatcher matcher) throws IOException {
+ WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher);
+ }
+
+}