3 * Copyright 2002-2004 The Ant-Contrib project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package net
.sf
.antcontrib
.cpptasks
;
19 import java
.util
.Enumeration
;
20 import java
.util
.Vector
;
22 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinker
;
23 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
24 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
25 import net
.sf
.antcontrib
.cpptasks
.compiler
.Processor
;
26 import net
.sf
.antcontrib
.cpptasks
.compiler
.ProcessorConfiguration
;
27 import net
.sf
.antcontrib
.cpptasks
.gcc
.GccLinker
;
28 import net
.sf
.antcontrib
.cpptasks
.types
.FlexLong
;
29 import net
.sf
.antcontrib
.cpptasks
.types
.LibrarySet
;
30 import net
.sf
.antcontrib
.cpptasks
.types
.LinkerArgument
;
31 import net
.sf
.antcontrib
.cpptasks
.types
.SystemLibrarySet
;
33 import org
.apache
.tools
.ant
.BuildException
;
34 import org
.apache
.tools
.ant
.Project
;
35 import org
.apache
.tools
.ant
.types
.FlexInteger
;
37 * A linker definition. linker elements may be placed either as children of a
38 * cc element or the project element. A linker element with an id attribute may
39 * be referenced by linker elements with refid or extends attributes.
41 * @author Adam Murdoch
44 public class LinkerDef
extends ProcessorDef
{
47 private Boolean fixed
;
48 private Boolean incremental
;
49 private final Vector librarySets
= new Vector();
52 private final Vector sysLibrarySets
= new Vector();
53 private final Vector versionInfos
= new Vector();
54 private Boolean defaultflag
= new Boolean(true);
58 * @see java.lang.Object#Object()
64 private void addActiveLibrarySet(Project project
, Vector libsets
,
66 Enumeration srcenum
= srcSets
.elements();
67 while (srcenum
.hasMoreElements()) {
68 LibrarySet set
= (LibrarySet
) srcenum
.nextElement();
69 if (set
.isActive(project
)) {
70 libsets
.addElement(set
);
74 private void addActiveSystemLibrarySets(Project project
, Vector libsets
) {
75 addActiveLibrarySet(project
, libsets
, sysLibrarySets
);
77 private void addActiveUserLibrarySets(Project project
, Vector libsets
) {
78 addActiveLibrarySet(project
, libsets
, librarySets
);
81 * Adds a linker command-line arg.
83 public void addConfiguredLinkerArg(LinkerArgument arg
) {
84 addConfiguredProcessorArg(arg
);
87 * Adds a compiler command-line arg.
89 public void addConfiguredLinkerParam(LinkerParam param
) {
91 throw noChildrenAllowed();
93 addConfiguredProcessorParam(param
);
96 * Adds a system library set.
98 public void addLibset(LibrarySet libset
) {
100 throw super.noChildrenAllowed();
102 if (libset
== null) {
103 throw new NullPointerException("libset");
105 librarySets
.addElement(libset
);
108 * Adds a system library set.
110 public void addSyslibset(SystemLibrarySet libset
) {
112 throw super.noChildrenAllowed();
114 if (libset
== null) {
115 throw new NullPointerException("libset");
117 sysLibrarySets
.addElement(libset
);
121 * Adds desriptive version information to be included in the
122 * generated file. The first active version info block will
125 public void addConfiguredVersioninfo(VersionInfo newVersionInfo
) {
127 throw noChildrenAllowed();
129 newVersionInfo
.setProject(this.getProject());
130 versionInfos
.addElement(newVersionInfo
);
133 public ProcessorConfiguration
createConfiguration(CCTask task
,
134 LinkType linkType
, ProcessorDef baseDef
, TargetDef targetPlatform
) {
136 // must combine some local context (the linkType)
137 // with the referenced element
139 // get a pointer to the definition (either local or referenced)
140 ProcessorDef thisDef
= this;
142 thisDef
= ((ProcessorDef
) getCheckedRef(ProcessorDef
.class,
146 // find the appropriate processor (combines local linkType
147 // with possibly remote linker name)
148 Processor proc
= getProcessor();
149 proc
= proc
.getLinker(linkType
);
150 ProcessorDef
[] defaultProviders
= getDefaultProviders(baseDef
);
151 return proc
.createConfiguration(task
, linkType
, defaultProviders
,
152 thisDef
, targetPlatform
);
154 public void execute() throws org
.apache
.tools
.ant
.BuildException
{
155 throw new org
.apache
.tools
.ant
.BuildException(
156 "Not an actual task, but looks like one for documentation purposes");
159 * Returns an array of active library sets for this linker definition.
161 public LibrarySet
[] getActiveLibrarySets(LinkerDef
[] defaultProviders
,
164 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
165 .getActiveUserLibrarySets(defaultProviders
, index
);
167 Project p
= getProject();
168 Vector libsets
= new Vector();
169 for (int i
= index
; i
< defaultProviders
.length
; i
++) {
170 defaultProviders
[i
].addActiveUserLibrarySets(p
, libsets
);
171 defaultProviders
[i
].addActiveSystemLibrarySets(p
, libsets
);
173 addActiveUserLibrarySets(p
, libsets
);
174 addActiveSystemLibrarySets(p
, libsets
);
175 LibrarySet
[] sets
= new LibrarySet
[libsets
.size()];
176 libsets
.copyInto(sets
);
180 * Returns an array of active library sets for this linker definition.
182 public LibrarySet
[] getActiveSystemLibrarySets(
183 LinkerDef
[] defaultProviders
, int index
) {
185 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
186 .getActiveUserLibrarySets(defaultProviders
, index
);
188 Project p
= getProject();
189 Vector libsets
= new Vector();
190 for (int i
= index
; i
< defaultProviders
.length
; i
++) {
191 defaultProviders
[i
].addActiveSystemLibrarySets(p
, libsets
);
193 addActiveSystemLibrarySets(p
, libsets
);
194 LibrarySet
[] sets
= new LibrarySet
[libsets
.size()];
195 libsets
.copyInto(sets
);
199 * Returns an array of active library sets for this linker definition.
201 public LibrarySet
[] getActiveUserLibrarySets(LinkerDef
[] defaultProviders
,
204 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
205 .getActiveUserLibrarySets(defaultProviders
, index
);
207 Project p
= getProject();
208 Vector libsets
= new Vector();
209 for (int i
= index
; i
< defaultProviders
.length
; i
++) {
210 defaultProviders
[i
].addActiveUserLibrarySets(p
, libsets
);
212 addActiveUserLibrarySets(p
, libsets
);
213 LibrarySet
[] sets
= new LibrarySet
[libsets
.size()];
214 libsets
.copyInto(sets
);
217 public long getBase(LinkerDef
[] defaultProviders
, int index
) {
219 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
220 .getBase(defaultProviders
, index
);
223 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
224 return defaultProviders
[index
].getBase(defaultProviders
,
230 public Boolean
getFixed(LinkerDef
[] defaultProviders
, int index
) {
232 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
233 .getFixed(defaultProviders
, index
);
236 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
237 return defaultProviders
[index
].getFixed(defaultProviders
,
243 public boolean getIncremental(LinkerDef
[] defaultProviders
, int index
) {
245 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
246 .getIncremental(defaultProviders
, index
);
248 if (incremental
!= null) {
249 return incremental
.booleanValue();
251 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
252 return defaultProviders
[index
].getIncremental(defaultProviders
, index
+ 1);
256 public boolean getMap(LinkerDef
[] defaultProviders
, int index
) {
258 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
259 .getMap(defaultProviders
, index
);
262 return map
.booleanValue();
264 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
265 return defaultProviders
[index
].getMap(defaultProviders
, index
+ 1);
269 public final Boolean
getDefaultflag(LinkerDef
[] defaultProviders
, int index
) {
271 return ((LinkerDef
) getCheckedRef(LinkerDef
.class,
272 "LinkerDef")).getDefaultflag(defaultProviders
, index
);
276 public String
getEntry(LinkerDef
[] defaultProviders
, int index
) {
278 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
279 .getEntry(defaultProviders
, index
);
284 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
285 return defaultProviders
[index
].getEntry(defaultProviders
, index
+ 1);
290 public Processor
getProcessor() {
291 Linker linker
= (Linker
) super.getProcessor();
292 if (linker
== null) {
293 linker
= GccLinker
.getInstance();
295 if (getLibtool() && linker
instanceof CommandLineLinker
) {
296 CommandLineLinker cmdLineLinker
= (CommandLineLinker
) linker
;
297 linker
= cmdLineLinker
.getLibtoolLinker();
301 public int getStack(LinkerDef
[] defaultProviders
, int index
) {
303 return ((LinkerDef
) getCheckedRef(LinkerDef
.class, "LinkerDef"))
304 .getStack(defaultProviders
, index
);
307 if (defaultProviders
!= null && index
< defaultProviders
.length
) {
308 return defaultProviders
[index
].getStack(defaultProviders
,
315 * Sets the base address. May be specified in either decimal or hex.
321 public void setBase(FlexLong base
) {
323 throw tooManyAttributes();
325 this.base
= base
.longValue();
328 * Sets the starting address.
333 public void setEntry(String entry
) {
335 throw tooManyAttributes();
340 * If true, marks the file to be loaded only at its preferred address.
342 public void setFixed(boolean fixed
) {
344 throw tooManyAttributes();
346 this.fixed
= booleanValueOf(fixed
);
349 * If true, allows incremental linking.
352 public void setIncremental(boolean incremental
) {
354 throw tooManyAttributes();
356 this.incremental
= booleanValueOf(incremental
);
359 * If set to true, a map file will be produced.
361 public void setMap(boolean map
) {
363 throw tooManyAttributes();
365 this.map
= booleanValueOf(map
);
371 * <table width="100%" border="1"> <thead>Supported linkers </thead>
374 * <td>Gcc Linker</td>
378 * <td>G++ Linker</td>
386 * <td>Gcc Librarian</td>
390 * <td>Microsoft Linker</td>
394 * <td>Borland Linker</td>
398 * <td>Compaq Visual Fortran Linker</td>
402 * <td>Intel Linker for Windows (IA-32)</td>
406 * <td>Intel Linker for Windows (IA-64)</td>
410 * <td>Intel Linker for Linux (IA-32)</td>
414 * <td>Intel Linker for Linux (IA-64)</td>
418 * <td>Sun ONE Linker</td>
422 * <td>HP aC++ Linker</td>
426 * <td>OS390 Linker</td>
429 * <td>os390batch</td>
430 * <td>OS390 Linker</td>
438 * <td>C89 Linker</td>
442 * <td>VisualAge Linker</td>
447 public void setName(LinkerEnum name
) throws BuildException
{
449 throw tooManyAttributes();
451 Linker linker
= name
.getLinker();
452 super.setProcessor(linker
);
454 protected void setProcessor(Processor proc
) throws BuildException
{
455 Linker linker
= null;
456 if (proc
instanceof Linker
) {
457 linker
= (Linker
) proc
;
459 LinkType linkType
= new LinkType();
460 linker
= proc
.getLinker(linkType
);
462 super.setProcessor(linker
);
465 * Sets stack size in bytes.
467 public void setStack(FlexInteger stack
) {
469 throw tooManyAttributes();
471 this.stack
= stack
.intValue();
473 public void visitSystemLibraries(Linker linker
, FileVisitor libraryVisitor
) {
474 Project p
= getProject();
476 throw new java
.lang
.IllegalStateException("project must be set");
479 LinkerDef master
= ((LinkerDef
) getCheckedRef(LinkerDef
.class,
481 master
.visitSystemLibraries(linker
, libraryVisitor
);
484 // if this linker extends another,
485 // visit its libraries first
487 LinkerDef extendsDef
= (LinkerDef
) getExtends();
488 if (extendsDef
!= null) {
489 extendsDef
.visitSystemLibraries(linker
, libraryVisitor
);
491 if (sysLibrarySets
.size() > 0) {
492 File
[] libpath
= linker
.getLibraryPath();
493 for (int i
= 0; i
< sysLibrarySets
.size(); i
++) {
494 LibrarySet set
= (LibrarySet
) sysLibrarySets
.elementAt(i
);
495 if (set
.isActive(p
)) {
496 set
.visitLibraries(p
, linker
, libpath
,
503 public void visitUserLibraries(Linker linker
, FileVisitor libraryVisitor
) {
504 Project p
= getProject();
506 throw new java
.lang
.IllegalStateException("project must be set");
509 LinkerDef master
= ((LinkerDef
) getCheckedRef(LinkerDef
.class,
511 master
.visitUserLibraries(linker
, libraryVisitor
);
514 // if this linker extends another,
515 // visit its libraries first
517 LinkerDef extendsDef
= (LinkerDef
) getExtends();
518 if (extendsDef
!= null) {
519 extendsDef
.visitUserLibraries(linker
, libraryVisitor
);
522 // visit the user libraries
524 if (librarySets
.size() > 0) {
525 File
[] libpath
= linker
.getLibraryPath();
526 for (int i
= 0; i
< librarySets
.size(); i
++) {
527 LibrarySet set
= (LibrarySet
) librarySets
.elementAt(i
);
528 if (set
.isActive(p
)) {
529 set
.visitLibraries(p
, linker
, libpath
,
537 * Enables or disables default flags.
540 * if true, default flags will add to command line.
543 public void setDefaultflag(boolean defaultflag
) {
545 throw tooManyAttributes();
547 this.defaultflag
= booleanValueOf(defaultflag
);