--- /dev/null
+/*\r
+ * \r
+ * Copyright 2002-2004 The Ant-Contrib project\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package net.sf.antcontrib.cpptasks.gcc;\r
+import java.io.File;\r
+import java.util.Vector;\r
+\r
+import net.sf.antcontrib.cpptasks.CCTask;\r
+import net.sf.antcontrib.cpptasks.CUtil;\r
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;\r
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;\r
+import net.sf.antcontrib.cpptasks.compiler.LinkType;\r
+import net.sf.antcontrib.cpptasks.types.LibrarySet;\r
+import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;\r
+\r
+/**\r
+ * Abstract adapter for ld-like linkers\r
+ * \r
+ * @author Curt Arnold\r
+ */\r
+public abstract class AbstractLdLinker extends CommandLineLinker {\r
+ private String outputPrefix;\r
+ private static String[] defaultflags = new String[]{};\r
+ protected AbstractLdLinker(String command, String identifierArg,\r
+ String[] extensions, String[] ignoredExtensions,\r
+ String outputPrefix, String outputSuffix, boolean isLibtool,\r
+ AbstractLdLinker libtoolLinker) {\r
+ super(command, identifierArg, extensions, ignoredExtensions,\r
+ outputSuffix, isLibtool, libtoolLinker);\r
+ this.outputPrefix = outputPrefix;\r
+ }\r
+ public void addBase(long base, Vector args) {\r
+ if (base >= 0) {\r
+ args.addElement("--image-base");\r
+ args.addElement(Long.toHexString(base));\r
+ }\r
+ }\r
+ public void addFixed(Boolean fixed, Vector args) {\r
+ }\r
+ protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {\r
+ if(defaultflag != null && defaultflag.booleanValue()){\r
+ for (int i = 0; i < defaultflags.length; i++) {\r
+ args.addElement(defaultflags[i]);\r
+ }\r
+ }\r
+ if (debug) {\r
+ args.addElement("-g");\r
+ }\r
+ if (isDarwin()) {\r
+ if (linkType.isPluginModule()) {\r
+ args.addElement("-bundle");\r
+ } else {\r
+ if (linkType.isSharedLibrary()) {\r
+ args.addElement("-prebind");\r
+ args.addElement("-dynamiclib");\r
+ }\r
+ }\r
+ } else {\r
+ if (linkType.isStaticRuntime()) {\r
+ args.addElement("-static");\r
+ }\r
+ if (linkType.isPluginModule()) {\r
+ args.addElement("-shared");\r
+ } else {\r
+ if (linkType.isSharedLibrary()) {\r
+ args.addElement("-shared");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void addIncremental(boolean incremental, Vector args) {\r
+ if (incremental) {\r
+ args.addElement("-i");\r
+ }\r
+ }\r
+ protected int addLibraryPatterns(String[] libnames, StringBuffer buf,\r
+ String prefix, String extension, String[] patterns, int offset) {\r
+ for (int i = 0; i < libnames.length; i++) {\r
+ buf.setLength(0);\r
+ buf.append(prefix);\r
+ buf.append(libnames[i]);\r
+ buf.append(extension);\r
+ patterns[offset + i] = buf.toString();\r
+ }\r
+ return offset + libnames.length;\r
+ }\r
+ public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,\r
+ Vector preargs, Vector midargs, Vector endargs) {\r
+ Vector libnames = new Vector();\r
+ super.addLibrarySets(task, libsets, preargs, midargs, endargs);\r
+ LibraryTypeEnum previousLibraryType = null;\r
+ for (int i = 0; i < libsets.length; i++) {\r
+ LibrarySet set = libsets[i];\r
+ File libdir = set.getDir(null);\r
+ String[] libs = set.getLibs();\r
+ if (libdir != null) {\r
+ if (set.getType() != null && \r
+ "framework".equals(set.getType().getValue()) &&\r
+ isDarwin()) {\r
+ endargs.addElement("-F" + libdir.getAbsolutePath()); \r
+ } else {\r
+ endargs.addElement("-L" + libdir.getAbsolutePath());\r
+ }\r
+ }\r
+ //\r
+ // if there has been a change of library type\r
+ //\r
+ if (set.getType() != previousLibraryType) {\r
+ if (set.getType() != null && "static".equals(set.getType().getValue())) {\r
+ endargs.addElement("-Bstatic");\r
+ previousLibraryType = set.getType();\r
+ } else {\r
+ if (set.getType() == null || \r
+ !"framework".equals(set.getType().getValue()) ||\r
+ !isDarwin()) {\r
+ endargs.addElement("-Bdynamic");\r
+ previousLibraryType = set.getType();\r
+ }\r
+ }\r
+ }\r
+ StringBuffer buf = new StringBuffer("-l");\r
+ if (set.getType() != null && \r
+ "framework".equals(set.getType().getValue()) && \r
+ isDarwin()) {\r
+ buf.setLength(0);\r
+ buf.append("-framework ");\r
+ }\r
+ int initialLength = buf.length();\r
+ for (int j = 0; j < libs.length; j++) {\r
+ //\r
+ // reset the buffer to just "-l"\r
+ //\r
+ buf.setLength(initialLength);\r
+ //\r
+ // add the library name\r
+ buf.append(libs[j]);\r
+ libnames.addElement(libs[j]);\r
+ //\r
+ // add the argument to the list\r
+ endargs.addElement(buf.toString());\r
+ }\r
+ }\r
+ String rc[] = new String[libnames.size()];\r
+ for (int i = 0; i < libnames.size(); i++) {\r
+ rc[i] = (String) libnames.elementAt(i);\r
+ }\r
+ return rc;\r
+ }\r
+ public void addMap(boolean map, Vector args) {\r
+ if (map) {\r
+ args.addElement("-M");\r
+ }\r
+ }\r
+ public void addStack(int stack, Vector args) {\r
+ if (stack > 0) {\r
+ args.addElement("--stack");\r
+ args.addElement(Integer.toString(stack));\r
+ }\r
+ }\r
+ /* (non-Javadoc)\r
+ * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)\r
+ */\r
+ protected void addEntry(String entry, Vector args) {\r
+ if (entry != null) {\r
+ args.addElement("-e");\r
+ args.addElement(entry);\r
+ }\r
+ }\r
+ \r
+ public String getCommandFileSwitch(String commandFile) {\r
+ throw new IllegalStateException("ld does not support command files");\r
+ }\r
+ /**\r
+ * Returns library path.\r
+ * \r
+ */\r
+ protected File[] getEnvironmentIncludePath() {\r
+ return CUtil.getPathFromEnvironment("LIB", ":");\r
+ }\r
+ public String getLibraryKey(File libfile) {\r
+ String libname = libfile.getName();\r
+ int lastDot = libname.lastIndexOf('.');\r
+ if (lastDot >= 0) {\r
+ return libname.substring(0, lastDot);\r
+ }\r
+ return libname;\r
+ }\r
+ /**\r
+ * Returns library path.\r
+ * \r
+ */\r
+ public File[] getLibraryPath() {\r
+ return new File[0];\r
+ }\r
+ public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {\r
+ StringBuffer buf = new StringBuffer();\r
+ int patternCount = libnames.length;\r
+ if (libType == null) {\r
+ patternCount *= 2;\r
+ }\r
+ String[] patterns = new String[patternCount];\r
+ int offset = 0;\r
+ if (libType == null || "static".equals(libType.getValue())) {\r
+ offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);\r
+ }\r
+ if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) {\r
+ for(int i = 0; i < libnames.length; i++) {\r
+ buf.setLength(0);\r
+ buf.append(libnames[i]);\r
+ buf.append(".framework/");\r
+ buf.append(libnames[i]);\r
+ patterns[offset++] = buf.toString();\r
+ }\r
+ } else {\r
+ if (libType == null || !"static".equals(libType.getValue())) {\r
+ if (isHPUX()) {\r
+ offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,\r
+ offset);\r
+ } else {\r
+ offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,\r
+ offset);\r
+ }\r
+ }\r
+ }\r
+ return patterns;\r
+ }\r
+ public int getMaximumCommandLength() {\r
+ return Integer.MAX_VALUE;\r
+ }\r
+ public String getOutputFileName(String baseName) {\r
+ return outputPrefix + super.getOutputFileName(baseName);\r
+ }\r
+ public String[] getOutputFileSwitch(String outputFile) {\r
+ return GccProcessor.getOutputFileSwitch("-o", outputFile);\r
+ }\r
+ public boolean isCaseSensitive() {\r
+ return true;\r
+ }\r
+ protected boolean isHPUX() {\r
+ String osname = System.getProperty("os.name").toLowerCase();\r
+ if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {\r
+ return true;\r
+ }\r
+ return false;\r
+ }\r
+ /**\r
+ * Prepares argument list for exec command. Will return null if command\r
+ * line would exceed allowable command line buffer.\r
+ * \r
+ * @param outputFile\r
+ * linker output file\r
+ * @param sourceFiles\r
+ * linker input files (.obj, .o, .res)\r
+ * @param args\r
+ * linker arguments\r
+ * @return arguments for runTask\r
+ */\r
+ public String[] prepareArguments(CCTask task, String outputDir,\r
+ String outputFile, String[] sourceFiles,\r
+ CommandLineLinkerConfiguration config) {\r
+ //\r
+ // need to suppress sources that correspond to\r
+ // library set entries since they are already\r
+ // in the argument list\r
+ String[] libnames = config.getLibraryNames();\r
+ if (libnames == null || libnames.length == 0) {\r
+ return super.prepareArguments(task, outputDir, outputFile,\r
+ sourceFiles, config);\r
+ }\r
+ //\r
+ //\r
+ // null out any sources that correspond to library names\r
+ //\r
+ String[] localSources = (String[]) sourceFiles.clone();\r
+ int extra = 0;\r
+ for (int i = 0; i < libnames.length; i++) {\r
+ String libname = libnames[i];\r
+ for (int j = 0; j < localSources.length; j++) {\r
+ if (localSources[j] != null\r
+ && localSources[j].indexOf(libname) > 0\r
+ && localSources[j].indexOf("lib") > 0) {\r
+ String filename = new File(localSources[j]).getName();\r
+ if (filename.startsWith("lib")\r
+ && filename.substring(3).startsWith(libname)) {\r
+ String extension = filename\r
+ .substring(libname.length() + 3);\r
+ if (extension.equals(".a") || extension.equals(".so")\r
+ || extension.equals(".sl")) {\r
+ localSources[j] = null;\r
+ extra++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ if (extra == 0) {\r
+ return super.prepareArguments(task, outputDir, outputFile,\r
+ sourceFiles, config);\r
+ }\r
+ String[] finalSources = new String[localSources.length - extra];\r
+ int index = 0;\r
+ for (int i = 0; i < localSources.length; i++) {\r
+ if (localSources[i] != null) {\r
+ finalSources[index++] = localSources[i];\r
+ }\r
+ }\r
+ return super.prepareArguments(task, outputDir, outputFile,\r
+ finalSources, config);\r
+ }\r
+}\r