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
.gcc
;
19 import java
.util
.Vector
;
21 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
22 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
23 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinker
;
24 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinkerConfiguration
;
25 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
26 import net
.sf
.antcontrib
.cpptasks
.types
.LibrarySet
;
27 import net
.sf
.antcontrib
.cpptasks
.types
.LibraryTypeEnum
;
30 * Abstract adapter for ld-like linkers
34 public abstract class AbstractLdLinker
extends CommandLineLinker
{
35 private String outputPrefix
;
36 private static String
[] defaultflags
= new String
[]{};
37 protected AbstractLdLinker(String command
, String identifierArg
,
38 String
[] extensions
, String
[] ignoredExtensions
,
39 String outputPrefix
, String outputSuffix
, boolean isLibtool
,
40 AbstractLdLinker libtoolLinker
) {
41 super(command
, identifierArg
, extensions
, ignoredExtensions
,
42 outputSuffix
, isLibtool
, libtoolLinker
);
43 this.outputPrefix
= outputPrefix
;
45 public void addBase(long base
, Vector args
) {
47 args
.addElement("--image-base");
48 args
.addElement(Long
.toHexString(base
));
51 public void addFixed(Boolean fixed
, Vector args
) {
53 protected void addImpliedArgs(boolean debug
, LinkType linkType
, Vector args
, Boolean defaultflag
) {
54 if(defaultflag
!= null && defaultflag
.booleanValue()){
55 for (int i
= 0; i
< defaultflags
.length
; i
++) {
56 args
.addElement(defaultflags
[i
]);
60 args
.addElement("-g");
63 if (linkType
.isPluginModule()) {
64 args
.addElement("-bundle");
66 if (linkType
.isSharedLibrary()) {
67 args
.addElement("-prebind");
68 args
.addElement("-dynamiclib");
72 if (linkType
.isStaticRuntime()) {
73 args
.addElement("-static");
75 if (linkType
.isPluginModule()) {
76 args
.addElement("-shared");
78 if (linkType
.isSharedLibrary()) {
79 args
.addElement("-shared");
84 public void addIncremental(boolean incremental
, Vector args
) {
86 args
.addElement("-i");
89 protected int addLibraryPatterns(String
[] libnames
, StringBuffer buf
,
90 String prefix
, String extension
, String
[] patterns
, int offset
) {
91 for (int i
= 0; i
< libnames
.length
; i
++) {
94 buf
.append(libnames
[i
]);
95 buf
.append(extension
);
96 patterns
[offset
+ i
] = buf
.toString();
98 return offset
+ libnames
.length
;
100 public String
[] addLibrarySets(CCTask task
, LibrarySet
[] libsets
,
101 Vector preargs
, Vector midargs
, Vector endargs
) {
102 Vector libnames
= new Vector();
103 super.addLibrarySets(task
, libsets
, preargs
, midargs
, endargs
);
104 LibraryTypeEnum previousLibraryType
= null;
105 for (int i
= 0; i
< libsets
.length
; i
++) {
106 LibrarySet set
= libsets
[i
];
107 File libdir
= set
.getDir(null);
108 String
[] libs
= set
.getLibs();
109 if (libdir
!= null) {
110 if (set
.getType() != null &&
111 "framework".equals(set
.getType().getValue()) &&
113 endargs
.addElement("-F" + libdir
.getAbsolutePath());
115 endargs
.addElement("-L" + libdir
.getAbsolutePath());
119 // if there has been a change of library type
121 if (set
.getType() != previousLibraryType
) {
122 if (set
.getType() != null && "static".equals(set
.getType().getValue())) {
123 endargs
.addElement("-Bstatic");
124 previousLibraryType
= set
.getType();
126 if (set
.getType() == null ||
127 !"framework".equals(set
.getType().getValue()) ||
129 endargs
.addElement("-Bdynamic");
130 previousLibraryType
= set
.getType();
134 StringBuffer buf
= new StringBuffer("-l");
135 if (set
.getType() != null &&
136 "framework".equals(set
.getType().getValue()) &&
139 buf
.append("-framework ");
141 int initialLength
= buf
.length();
142 for (int j
= 0; j
< libs
.length
; j
++) {
144 // reset the buffer to just "-l"
146 buf
.setLength(initialLength
);
148 // add the library name
150 libnames
.addElement(libs
[j
]);
152 // add the argument to the list
153 endargs
.addElement(buf
.toString());
156 String rc
[] = new String
[libnames
.size()];
157 for (int i
= 0; i
< libnames
.size(); i
++) {
158 rc
[i
] = (String
) libnames
.elementAt(i
);
162 public void addMap(boolean map
, Vector args
) {
164 args
.addElement("-M");
167 public void addStack(int stack
, Vector args
) {
169 args
.addElement("--stack");
170 args
.addElement(Integer
.toString(stack
));
174 * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
176 protected void addEntry(String entry
, Vector args
) {
178 args
.addElement("-e");
179 args
.addElement(entry
);
183 public String
getCommandFileSwitch(String commandFile
) {
184 throw new IllegalStateException("ld does not support command files");
187 * Returns library path.
190 protected File
[] getEnvironmentIncludePath() {
191 return CUtil
.getPathFromEnvironment("LIB", ":");
193 public String
getLibraryKey(File libfile
) {
194 String libname
= libfile
.getName();
195 int lastDot
= libname
.lastIndexOf('.');
197 return libname
.substring(0, lastDot
);
202 * Returns library path.
205 public File
[] getLibraryPath() {
208 public String
[] getLibraryPatterns(String
[] libnames
, LibraryTypeEnum libType
) {
209 StringBuffer buf
= new StringBuffer();
210 int patternCount
= libnames
.length
;
211 if (libType
== null) {
214 String
[] patterns
= new String
[patternCount
];
216 if (libType
== null || "static".equals(libType
.getValue())) {
217 offset
= addLibraryPatterns(libnames
, buf
, "lib", ".a", patterns
, 0);
219 if (libType
!= null && "framework".equals(libType
.getValue()) && isDarwin()) {
220 for(int i
= 0; i
< libnames
.length
; i
++) {
222 buf
.append(libnames
[i
]);
223 buf
.append(".framework/");
224 buf
.append(libnames
[i
]);
225 patterns
[offset
++] = buf
.toString();
228 if (libType
== null || !"static".equals(libType
.getValue())) {
230 offset
= addLibraryPatterns(libnames
, buf
, "lib", ".sl", patterns
,
233 offset
= addLibraryPatterns(libnames
, buf
, "lib", ".so", patterns
,
240 public int getMaximumCommandLength() {
241 return Integer
.MAX_VALUE
;
243 public String
getOutputFileName(String baseName
) {
244 return outputPrefix
+ super.getOutputFileName(baseName
);
246 public String
[] getOutputFileSwitch(String outputFile
) {
247 return GccProcessor
.getOutputFileSwitch("-o", outputFile
);
249 public boolean isCaseSensitive() {
252 protected boolean isHPUX() {
253 String osname
= System
.getProperty("os.name").toLowerCase();
254 if (osname
.indexOf("hp") >= 0 && osname
.indexOf("ux") >= 0) {
260 * Prepares argument list for exec command. Will return null if command
261 * line would exceed allowable command line buffer.
266 * linker input files (.obj, .o, .res)
269 * @return arguments for runTask
271 public String
[] prepareArguments(CCTask task
, String outputDir
,
272 String outputFile
, String
[] sourceFiles
,
273 CommandLineLinkerConfiguration config
) {
275 // need to suppress sources that correspond to
276 // library set entries since they are already
277 // in the argument list
278 String
[] libnames
= config
.getLibraryNames();
279 if (libnames
== null || libnames
.length
== 0) {
280 return super.prepareArguments(task
, outputDir
, outputFile
,
281 sourceFiles
, config
);
285 // null out any sources that correspond to library names
287 String
[] localSources
= (String
[]) sourceFiles
.clone();
289 for (int i
= 0; i
< libnames
.length
; i
++) {
290 String libname
= libnames
[i
];
291 for (int j
= 0; j
< localSources
.length
; j
++) {
292 if (localSources
[j
] != null
293 && localSources
[j
].indexOf(libname
) > 0
294 && localSources
[j
].indexOf("lib") > 0) {
295 String filename
= new File(localSources
[j
]).getName();
296 if (filename
.startsWith("lib")
297 && filename
.substring(3).startsWith(libname
)) {
298 String extension
= filename
299 .substring(libname
.length() + 3);
300 if (extension
.equals(".a") || extension
.equals(".so")
301 || extension
.equals(".sl")) {
302 localSources
[j
] = null;
310 return super.prepareArguments(task
, outputDir
, outputFile
,
311 sourceFiles
, config
);
313 String
[] finalSources
= new String
[localSources
.length
- extra
];
315 for (int i
= 0; i
< localSources
.length
; i
++) {
316 if (localSources
[i
] != null) {
317 finalSources
[index
++] = localSources
[i
];
320 return super.prepareArguments(task
, outputDir
, outputFile
,
321 finalSources
, config
);