--- /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;\r
+import java.io.File;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;\r
+import net.sf.antcontrib.cpptasks.compiler.LinkType;\r
+import net.sf.antcontrib.cpptasks.compiler.Linker;\r
+import net.sf.antcontrib.cpptasks.compiler.Processor;\r
+import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration;\r
+import net.sf.antcontrib.cpptasks.gcc.GccLinker;\r
+import net.sf.antcontrib.cpptasks.types.FlexLong;\r
+import net.sf.antcontrib.cpptasks.types.LibrarySet;\r
+import net.sf.antcontrib.cpptasks.types.LinkerArgument;\r
+import net.sf.antcontrib.cpptasks.types.SystemLibrarySet;\r
+\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.tools.ant.Project;\r
+import org.apache.tools.ant.types.FlexInteger;\r
+/**\r
+ * A linker definition. linker elements may be placed either as children of a\r
+ * cc element or the project element. A linker element with an id attribute may\r
+ * be referenced by linker elements with refid or extends attributes.\r
+ * \r
+ * @author Adam Murdoch\r
+ * @author Curt Arnold\r
+ */\r
+public class LinkerDef extends ProcessorDef {\r
+ private long base;\r
+ private String entry;\r
+ private Boolean fixed;\r
+ private Boolean incremental;\r
+ private final Vector librarySets = new Vector();\r
+ private Boolean map;\r
+ private int stack;\r
+ private final Vector sysLibrarySets = new Vector();\r
+ private final Vector versionInfos = new Vector();\r
+ private Boolean defaultflag = new Boolean(true);\r
+ /**\r
+ * Default constructor\r
+ * \r
+ * @see java.lang.Object#Object()\r
+ */\r
+ public LinkerDef() {\r
+ base = -1;\r
+ stack = -1;\r
+ }\r
+ private void addActiveLibrarySet(Project project, Vector libsets,\r
+ Vector srcSets) {\r
+ Enumeration srcenum = srcSets.elements();\r
+ while (srcenum.hasMoreElements()) {\r
+ LibrarySet set = (LibrarySet) srcenum.nextElement();\r
+ if (set.isActive(project)) {\r
+ libsets.addElement(set);\r
+ }\r
+ }\r
+ }\r
+ private void addActiveSystemLibrarySets(Project project, Vector libsets) {\r
+ addActiveLibrarySet(project, libsets, sysLibrarySets);\r
+ }\r
+ private void addActiveUserLibrarySets(Project project, Vector libsets) {\r
+ addActiveLibrarySet(project, libsets, librarySets);\r
+ }\r
+ /**\r
+ * Adds a linker command-line arg.\r
+ */\r
+ public void addConfiguredLinkerArg(LinkerArgument arg) {\r
+ addConfiguredProcessorArg(arg);\r
+ }\r
+ /**\r
+ * Adds a compiler command-line arg.\r
+ */\r
+ public void addConfiguredLinkerParam(LinkerParam param) {\r
+ if (isReference()) {\r
+ throw noChildrenAllowed();\r
+ }\r
+ addConfiguredProcessorParam(param);\r
+ }\r
+ /**\r
+ * Adds a system library set.\r
+ */\r
+ public void addLibset(LibrarySet libset) {\r
+ if (isReference()) {\r
+ throw super.noChildrenAllowed();\r
+ }\r
+ if (libset == null) {\r
+ throw new NullPointerException("libset");\r
+ }\r
+ librarySets.addElement(libset);\r
+ }\r
+ /**\r
+ * Adds a system library set.\r
+ */\r
+ public void addSyslibset(SystemLibrarySet libset) {\r
+ if (isReference()) {\r
+ throw super.noChildrenAllowed();\r
+ }\r
+ if (libset == null) {\r
+ throw new NullPointerException("libset");\r
+ }\r
+ sysLibrarySets.addElement(libset);\r
+ }\r
+ \r
+ /**\r
+ * Adds desriptive version information to be included in the\r
+ * generated file. The first active version info block will\r
+ * be used.\r
+ */\r
+ public void addConfiguredVersioninfo(VersionInfo newVersionInfo) {\r
+ if (isReference()) {\r
+ throw noChildrenAllowed();\r
+ }\r
+ newVersionInfo.setProject(this.getProject());\r
+ versionInfos.addElement(newVersionInfo);\r
+ }\r
+ \r
+ public ProcessorConfiguration createConfiguration(CCTask task,\r
+ LinkType linkType, ProcessorDef baseDef, TargetDef targetPlatform) {\r
+ //\r
+ // must combine some local context (the linkType)\r
+ // with the referenced element\r
+ //\r
+ // get a pointer to the definition (either local or referenced)\r
+ ProcessorDef thisDef = this;\r
+ if (isReference()) {\r
+ thisDef = ((ProcessorDef) getCheckedRef(ProcessorDef.class,\r
+ "ProcessorDef"));\r
+ }\r
+ //\r
+ // find the appropriate processor (combines local linkType\r
+ // with possibly remote linker name)\r
+ Processor proc = getProcessor();\r
+ proc = proc.getLinker(linkType);\r
+ ProcessorDef[] defaultProviders = getDefaultProviders(baseDef);\r
+ return proc.createConfiguration(task, linkType, defaultProviders,\r
+ thisDef, targetPlatform);\r
+ }\r
+ public void execute() throws org.apache.tools.ant.BuildException {\r
+ throw new org.apache.tools.ant.BuildException(\r
+ "Not an actual task, but looks like one for documentation purposes");\r
+ }\r
+ /**\r
+ * Returns an array of active library sets for this linker definition.\r
+ */\r
+ public LibrarySet[] getActiveLibrarySets(LinkerDef[] defaultProviders,\r
+ int index) { \r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getActiveUserLibrarySets(defaultProviders, index);\r
+ }\r
+ Project p = getProject();\r
+ Vector libsets = new Vector();\r
+ for (int i = index; i < defaultProviders.length; i++) {\r
+ defaultProviders[i].addActiveUserLibrarySets(p, libsets);\r
+ defaultProviders[i].addActiveSystemLibrarySets(p, libsets);\r
+ }\r
+ addActiveUserLibrarySets(p, libsets);\r
+ addActiveSystemLibrarySets(p, libsets);\r
+ LibrarySet[] sets = new LibrarySet[libsets.size()];\r
+ libsets.copyInto(sets);\r
+ return sets;\r
+ }\r
+ /**\r
+ * Returns an array of active library sets for this linker definition.\r
+ */\r
+ public LibrarySet[] getActiveSystemLibrarySets(\r
+ LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getActiveUserLibrarySets(defaultProviders, index);\r
+ }\r
+ Project p = getProject();\r
+ Vector libsets = new Vector();\r
+ for (int i = index; i < defaultProviders.length; i++) {\r
+ defaultProviders[i].addActiveSystemLibrarySets(p, libsets);\r
+ }\r
+ addActiveSystemLibrarySets(p, libsets);\r
+ LibrarySet[] sets = new LibrarySet[libsets.size()];\r
+ libsets.copyInto(sets);\r
+ return sets;\r
+ }\r
+ /**\r
+ * Returns an array of active library sets for this linker definition.\r
+ */\r
+ public LibrarySet[] getActiveUserLibrarySets(LinkerDef[] defaultProviders,\r
+ int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getActiveUserLibrarySets(defaultProviders, index);\r
+ }\r
+ Project p = getProject();\r
+ Vector libsets = new Vector();\r
+ for (int i = index; i < defaultProviders.length; i++) {\r
+ defaultProviders[i].addActiveUserLibrarySets(p, libsets);\r
+ }\r
+ addActiveUserLibrarySets(p, libsets);\r
+ LibrarySet[] sets = new LibrarySet[libsets.size()];\r
+ libsets.copyInto(sets);\r
+ return sets;\r
+ }\r
+ public long getBase(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getBase(defaultProviders, index);\r
+ }\r
+ if (base <= 0) {\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getBase(defaultProviders,\r
+ index + 1);\r
+ }\r
+ }\r
+ return base;\r
+ }\r
+ public Boolean getFixed(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getFixed(defaultProviders, index);\r
+ }\r
+ if (fixed == null) {\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getFixed(defaultProviders,\r
+ index + 1);\r
+ }\r
+ }\r
+ return fixed;\r
+ }\r
+ public boolean getIncremental(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getIncremental(defaultProviders, index);\r
+ }\r
+ if (incremental != null) {\r
+ return incremental.booleanValue();\r
+ }\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getIncremental(defaultProviders, index + 1);\r
+ }\r
+ return false;\r
+ }\r
+ public boolean getMap(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getMap(defaultProviders, index);\r
+ }\r
+ if (map != null) {\r
+ return map.booleanValue();\r
+ }\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getMap(defaultProviders, index + 1);\r
+ }\r
+ return false;\r
+ }\r
+ public final Boolean getDefaultflag(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class,\r
+ "LinkerDef")).getDefaultflag(defaultProviders, index);\r
+ }\r
+ return defaultflag;\r
+ }\r
+ public String getEntry(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getEntry(defaultProviders, index);\r
+ }\r
+ if (entry != null) {\r
+ return entry;\r
+ }\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getEntry(defaultProviders, index + 1);\r
+ }\r
+ return null;\r
+ }\r
+\r
+ public Processor getProcessor() {\r
+ Linker linker = (Linker) super.getProcessor();\r
+ if (linker == null) {\r
+ linker = GccLinker.getInstance();\r
+ }\r
+ if (getLibtool() && linker instanceof CommandLineLinker) {\r
+ CommandLineLinker cmdLineLinker = (CommandLineLinker) linker;\r
+ linker = cmdLineLinker.getLibtoolLinker();\r
+ }\r
+ return linker;\r
+ }\r
+ public int getStack(LinkerDef[] defaultProviders, int index) {\r
+ if (isReference()) {\r
+ return ((LinkerDef) getCheckedRef(LinkerDef.class, "LinkerDef"))\r
+ .getStack(defaultProviders, index);\r
+ }\r
+ if (stack < 0) {\r
+ if (defaultProviders != null && index < defaultProviders.length) {\r
+ return defaultProviders[index].getStack(defaultProviders,\r
+ index + 1);\r
+ }\r
+ }\r
+ return stack;\r
+ }\r
+ /**\r
+ * Sets the base address. May be specified in either decimal or hex.\r
+ * \r
+ * @param base\r
+ * base address\r
+ * \r
+ */\r
+ public void setBase(FlexLong base) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.base = base.longValue();\r
+ }\r
+ /**\r
+ * Sets the starting address.\r
+ * \r
+ * @param name\r
+ * function name\r
+ */\r
+ public void setEntry(String entry) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.entry = entry;\r
+ }\r
+ /**\r
+ * If true, marks the file to be loaded only at its preferred address.\r
+ */\r
+ public void setFixed(boolean fixed) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.fixed = booleanValueOf(fixed);\r
+ }\r
+ /**\r
+ * If true, allows incremental linking.\r
+ * \r
+ */\r
+ public void setIncremental(boolean incremental) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.incremental = booleanValueOf(incremental);\r
+ }\r
+ /**\r
+ * If set to true, a map file will be produced.\r
+ */\r
+ public void setMap(boolean map) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.map = booleanValueOf(map);\r
+ }\r
+ /**\r
+ * Sets linker type.\r
+ * \r
+ * \r
+ * <table width="100%" border="1"> <thead>Supported linkers </thead>\r
+ * <tr>\r
+ * <td>gcc</td>\r
+ * <td>Gcc Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>g++</td>\r
+ * <td>G++ Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>ld</td>\r
+ * <td>Ld Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>ar</td>\r
+ * <td>Gcc Librarian</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>msvc</td>\r
+ * <td>Microsoft Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>bcc</td>\r
+ * <td>Borland Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>df</td>\r
+ * <td>Compaq Visual Fortran Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>icl</td>\r
+ * <td>Intel Linker for Windows (IA-32)</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>ecl</td>\r
+ * <td>Intel Linker for Windows (IA-64)</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>icc</td>\r
+ * <td>Intel Linker for Linux (IA-32)</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>ecc</td>\r
+ * <td>Intel Linker for Linux (IA-64)</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>CC</td>\r
+ * <td>Sun ONE Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>aCC</td>\r
+ * <td>HP aC++ Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>os390</td>\r
+ * <td>OS390 Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>os390batch</td>\r
+ * <td>OS390 Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>os400</td>\r
+ * <td>IccLinker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>sunc89</td>\r
+ * <td>C89 Linker</td>\r
+ * </tr>\r
+ * <tr>\r
+ * <td>xlC</td>\r
+ * <td>VisualAge Linker</td>\r
+ * </tr>\r
+ * </table>\r
+ * \r
+ */\r
+ public void setName(LinkerEnum name) throws BuildException {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ Linker linker = name.getLinker();\r
+ super.setProcessor(linker);\r
+ }\r
+ protected void setProcessor(Processor proc) throws BuildException {\r
+ Linker linker = null;\r
+ if (proc instanceof Linker) {\r
+ linker = (Linker) proc;\r
+ } else {\r
+ LinkType linkType = new LinkType();\r
+ linker = proc.getLinker(linkType);\r
+ }\r
+ super.setProcessor(linker);\r
+ }\r
+ /**\r
+ * Sets stack size in bytes.\r
+ */\r
+ public void setStack(FlexInteger stack) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.stack = stack.intValue();\r
+ }\r
+ public void visitSystemLibraries(Linker linker, FileVisitor libraryVisitor) {\r
+ Project p = getProject();\r
+ if (p == null) {\r
+ throw new java.lang.IllegalStateException("project must be set");\r
+ }\r
+ if (isReference()) {\r
+ LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,\r
+ "Linker"));\r
+ master.visitSystemLibraries(linker, libraryVisitor);\r
+ } else {\r
+ //\r
+ // if this linker extends another,\r
+ // visit its libraries first\r
+ //\r
+ LinkerDef extendsDef = (LinkerDef) getExtends();\r
+ if (extendsDef != null) {\r
+ extendsDef.visitSystemLibraries(linker, libraryVisitor);\r
+ }\r
+ if (sysLibrarySets.size() > 0) {\r
+ File[] libpath = linker.getLibraryPath();\r
+ for (int i = 0; i < sysLibrarySets.size(); i++) {\r
+ LibrarySet set = (LibrarySet) sysLibrarySets.elementAt(i);\r
+ if (set.isActive(p)) {\r
+ set.visitLibraries(p, linker, libpath,\r
+ libraryVisitor);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ public void visitUserLibraries(Linker linker, FileVisitor libraryVisitor) {\r
+ Project p = getProject();\r
+ if (p == null) {\r
+ throw new java.lang.IllegalStateException("project must be set");\r
+ }\r
+ if (isReference()) {\r
+ LinkerDef master = ((LinkerDef) getCheckedRef(LinkerDef.class,\r
+ "Linker"));\r
+ master.visitUserLibraries(linker, libraryVisitor);\r
+ } else {\r
+ //\r
+ // if this linker extends another,\r
+ // visit its libraries first\r
+ //\r
+ LinkerDef extendsDef = (LinkerDef) getExtends();\r
+ if (extendsDef != null) {\r
+ extendsDef.visitUserLibraries(linker, libraryVisitor);\r
+ }\r
+ //\r
+ // visit the user libraries\r
+ //\r
+ if (librarySets.size() > 0) {\r
+ File[] libpath = linker.getLibraryPath();\r
+ for (int i = 0; i < librarySets.size(); i++) {\r
+ LibrarySet set = (LibrarySet) librarySets.elementAt(i);\r
+ if (set.isActive(p)) {\r
+ set.visitLibraries(p, linker, libpath,\r
+ libraryVisitor);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ /**\r
+ * Enables or disables default flags.\r
+ * \r
+ * @param defaultflag\r
+ * if true, default flags will add to command line.\r
+ * \r
+ */\r
+ public void setDefaultflag(boolean defaultflag) {\r
+ if (isReference()) {\r
+ throw tooManyAttributes();\r
+ }\r
+ this.defaultflag = booleanValueOf(defaultflag);\r
+ }\r
+}\r