]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | /*\r |
2 | * \r | |
3 | * Copyright 2002-2004 The Ant-Contrib project\r | |
4 | *\r | |
5 | * Licensed under the Apache License, Version 2.0 (the "License");\r | |
6 | * you may not use this file except in compliance with the License.\r | |
7 | * You may obtain a copy of the License at\r | |
8 | *\r | |
9 | * http://www.apache.org/licenses/LICENSE-2.0\r | |
10 | *\r | |
11 | * Unless required by applicable law or agreed to in writing, software\r | |
12 | * distributed under the License is distributed on an "AS IS" BASIS,\r | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r | |
14 | * See the License for the specific language governing permissions and\r | |
15 | * limitations under the License.\r | |
16 | */\r | |
17 | package net.sf.antcontrib.cpptasks.gcc;\r | |
18 | import java.io.File;\r | |
19 | import java.util.Vector;\r | |
20 | \r | |
21 | import net.sf.antcontrib.cpptasks.CCTask;\r | |
22 | import net.sf.antcontrib.cpptasks.CUtil;\r | |
23 | import net.sf.antcontrib.cpptasks.compiler.CommandLineLinker;\r | |
24 | import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;\r | |
25 | import net.sf.antcontrib.cpptasks.compiler.LinkType;\r | |
26 | import net.sf.antcontrib.cpptasks.types.LibrarySet;\r | |
27 | import net.sf.antcontrib.cpptasks.types.LibraryTypeEnum;\r | |
28 | \r | |
29 | /**\r | |
30 | * Abstract adapter for ld-like linkers\r | |
31 | * \r | |
32 | * @author Curt Arnold\r | |
33 | */\r | |
34 | public abstract class AbstractLdLinker extends CommandLineLinker {\r | |
35 | private String outputPrefix;\r | |
36 | private static String[] defaultflags = new String[]{};\r | |
37 | protected AbstractLdLinker(String command, String identifierArg,\r | |
38 | String[] extensions, String[] ignoredExtensions,\r | |
39 | String outputPrefix, String outputSuffix, boolean isLibtool,\r | |
40 | AbstractLdLinker libtoolLinker) {\r | |
41 | super(command, identifierArg, extensions, ignoredExtensions,\r | |
42 | outputSuffix, isLibtool, libtoolLinker);\r | |
43 | this.outputPrefix = outputPrefix;\r | |
44 | }\r | |
45 | public void addBase(long base, Vector args) {\r | |
46 | if (base >= 0) {\r | |
47 | args.addElement("--image-base");\r | |
48 | args.addElement(Long.toHexString(base));\r | |
49 | }\r | |
50 | }\r | |
51 | public void addFixed(Boolean fixed, Vector args) {\r | |
52 | }\r | |
53 | protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {\r | |
54 | if(defaultflag != null && defaultflag.booleanValue()){\r | |
55 | for (int i = 0; i < defaultflags.length; i++) {\r | |
56 | args.addElement(defaultflags[i]);\r | |
57 | }\r | |
58 | }\r | |
59 | if (debug) {\r | |
60 | args.addElement("-g");\r | |
61 | }\r | |
62 | if (isDarwin()) {\r | |
63 | if (linkType.isPluginModule()) {\r | |
64 | args.addElement("-bundle");\r | |
65 | } else {\r | |
66 | if (linkType.isSharedLibrary()) {\r | |
67 | args.addElement("-prebind");\r | |
68 | args.addElement("-dynamiclib");\r | |
69 | }\r | |
70 | }\r | |
71 | } else {\r | |
72 | if (linkType.isStaticRuntime()) {\r | |
73 | args.addElement("-static");\r | |
74 | }\r | |
75 | if (linkType.isPluginModule()) {\r | |
76 | args.addElement("-shared");\r | |
77 | } else {\r | |
78 | if (linkType.isSharedLibrary()) {\r | |
79 | args.addElement("-shared");\r | |
80 | }\r | |
81 | }\r | |
82 | }\r | |
83 | }\r | |
84 | public void addIncremental(boolean incremental, Vector args) {\r | |
85 | if (incremental) {\r | |
86 | args.addElement("-i");\r | |
87 | }\r | |
88 | }\r | |
89 | protected int addLibraryPatterns(String[] libnames, StringBuffer buf,\r | |
90 | String prefix, String extension, String[] patterns, int offset) {\r | |
91 | for (int i = 0; i < libnames.length; i++) {\r | |
92 | buf.setLength(0);\r | |
93 | buf.append(prefix);\r | |
94 | buf.append(libnames[i]);\r | |
95 | buf.append(extension);\r | |
96 | patterns[offset + i] = buf.toString();\r | |
97 | }\r | |
98 | return offset + libnames.length;\r | |
99 | }\r | |
100 | public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,\r | |
101 | Vector preargs, Vector midargs, Vector endargs) {\r | |
102 | Vector libnames = new Vector();\r | |
103 | super.addLibrarySets(task, libsets, preargs, midargs, endargs);\r | |
104 | LibraryTypeEnum previousLibraryType = null;\r | |
105 | for (int i = 0; i < libsets.length; i++) {\r | |
106 | LibrarySet set = libsets[i];\r | |
107 | File libdir = set.getDir(null);\r | |
108 | String[] libs = set.getLibs();\r | |
109 | if (libdir != null) {\r | |
110 | if (set.getType() != null && \r | |
111 | "framework".equals(set.getType().getValue()) &&\r | |
112 | isDarwin()) {\r | |
113 | endargs.addElement("-F" + libdir.getAbsolutePath()); \r | |
114 | } else {\r | |
115 | endargs.addElement("-L" + libdir.getAbsolutePath());\r | |
116 | }\r | |
117 | }\r | |
118 | //\r | |
119 | // if there has been a change of library type\r | |
120 | //\r | |
121 | if (set.getType() != previousLibraryType) {\r | |
122 | if (set.getType() != null && "static".equals(set.getType().getValue())) {\r | |
123 | endargs.addElement("-Bstatic");\r | |
124 | previousLibraryType = set.getType();\r | |
125 | } else {\r | |
126 | if (set.getType() == null || \r | |
127 | !"framework".equals(set.getType().getValue()) ||\r | |
128 | !isDarwin()) {\r | |
129 | endargs.addElement("-Bdynamic");\r | |
130 | previousLibraryType = set.getType();\r | |
131 | }\r | |
132 | }\r | |
133 | }\r | |
134 | StringBuffer buf = new StringBuffer("-l");\r | |
135 | if (set.getType() != null && \r | |
136 | "framework".equals(set.getType().getValue()) && \r | |
137 | isDarwin()) {\r | |
138 | buf.setLength(0);\r | |
139 | buf.append("-framework ");\r | |
140 | }\r | |
141 | int initialLength = buf.length();\r | |
142 | for (int j = 0; j < libs.length; j++) {\r | |
143 | //\r | |
144 | // reset the buffer to just "-l"\r | |
145 | //\r | |
146 | buf.setLength(initialLength);\r | |
147 | //\r | |
148 | // add the library name\r | |
149 | buf.append(libs[j]);\r | |
150 | libnames.addElement(libs[j]);\r | |
151 | //\r | |
152 | // add the argument to the list\r | |
153 | endargs.addElement(buf.toString());\r | |
154 | }\r | |
155 | }\r | |
156 | String rc[] = new String[libnames.size()];\r | |
157 | for (int i = 0; i < libnames.size(); i++) {\r | |
158 | rc[i] = (String) libnames.elementAt(i);\r | |
159 | }\r | |
160 | return rc;\r | |
161 | }\r | |
162 | public void addMap(boolean map, Vector args) {\r | |
163 | if (map) {\r | |
164 | args.addElement("-M");\r | |
165 | }\r | |
166 | }\r | |
167 | public void addStack(int stack, Vector args) {\r | |
168 | if (stack > 0) {\r | |
169 | args.addElement("--stack");\r | |
170 | args.addElement(Integer.toString(stack));\r | |
171 | }\r | |
172 | }\r | |
173 | /* (non-Javadoc)\r | |
174 | * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)\r | |
175 | */\r | |
176 | protected void addEntry(String entry, Vector args) {\r | |
177 | if (entry != null) {\r | |
178 | args.addElement("-e");\r | |
179 | args.addElement(entry);\r | |
180 | }\r | |
181 | }\r | |
182 | \r | |
183 | public String getCommandFileSwitch(String commandFile) {\r | |
184 | throw new IllegalStateException("ld does not support command files");\r | |
185 | }\r | |
186 | /**\r | |
187 | * Returns library path.\r | |
188 | * \r | |
189 | */\r | |
190 | protected File[] getEnvironmentIncludePath() {\r | |
191 | return CUtil.getPathFromEnvironment("LIB", ":");\r | |
192 | }\r | |
193 | public String getLibraryKey(File libfile) {\r | |
194 | String libname = libfile.getName();\r | |
195 | int lastDot = libname.lastIndexOf('.');\r | |
196 | if (lastDot >= 0) {\r | |
197 | return libname.substring(0, lastDot);\r | |
198 | }\r | |
199 | return libname;\r | |
200 | }\r | |
201 | /**\r | |
202 | * Returns library path.\r | |
203 | * \r | |
204 | */\r | |
205 | public File[] getLibraryPath() {\r | |
206 | return new File[0];\r | |
207 | }\r | |
208 | public String[] getLibraryPatterns(String[] libnames, LibraryTypeEnum libType) {\r | |
209 | StringBuffer buf = new StringBuffer();\r | |
210 | int patternCount = libnames.length;\r | |
211 | if (libType == null) {\r | |
212 | patternCount *= 2;\r | |
213 | }\r | |
214 | String[] patterns = new String[patternCount];\r | |
215 | int offset = 0;\r | |
216 | if (libType == null || "static".equals(libType.getValue())) {\r | |
217 | offset = addLibraryPatterns(libnames, buf, "lib", ".a", patterns, 0);\r | |
218 | }\r | |
219 | if (libType != null && "framework".equals(libType.getValue()) && isDarwin()) {\r | |
220 | for(int i = 0; i < libnames.length; i++) {\r | |
221 | buf.setLength(0);\r | |
222 | buf.append(libnames[i]);\r | |
223 | buf.append(".framework/");\r | |
224 | buf.append(libnames[i]);\r | |
225 | patterns[offset++] = buf.toString();\r | |
226 | }\r | |
227 | } else {\r | |
228 | if (libType == null || !"static".equals(libType.getValue())) {\r | |
229 | if (isHPUX()) {\r | |
230 | offset = addLibraryPatterns(libnames, buf, "lib", ".sl", patterns,\r | |
231 | offset);\r | |
232 | } else {\r | |
233 | offset = addLibraryPatterns(libnames, buf, "lib", ".so", patterns,\r | |
234 | offset);\r | |
235 | }\r | |
236 | }\r | |
237 | }\r | |
238 | return patterns;\r | |
239 | }\r | |
240 | public int getMaximumCommandLength() {\r | |
241 | return Integer.MAX_VALUE;\r | |
242 | }\r | |
243 | public String getOutputFileName(String baseName) {\r | |
244 | return outputPrefix + super.getOutputFileName(baseName);\r | |
245 | }\r | |
246 | public String[] getOutputFileSwitch(String outputFile) {\r | |
247 | return GccProcessor.getOutputFileSwitch("-o", outputFile);\r | |
248 | }\r | |
249 | public boolean isCaseSensitive() {\r | |
250 | return true;\r | |
251 | }\r | |
252 | protected boolean isHPUX() {\r | |
253 | String osname = System.getProperty("os.name").toLowerCase();\r | |
254 | if (osname.indexOf("hp") >= 0 && osname.indexOf("ux") >= 0) {\r | |
255 | return true;\r | |
256 | }\r | |
257 | return false;\r | |
258 | }\r | |
259 | /**\r | |
260 | * Prepares argument list for exec command. Will return null if command\r | |
261 | * line would exceed allowable command line buffer.\r | |
262 | * \r | |
263 | * @param outputFile\r | |
264 | * linker output file\r | |
265 | * @param sourceFiles\r | |
266 | * linker input files (.obj, .o, .res)\r | |
267 | * @param args\r | |
268 | * linker arguments\r | |
269 | * @return arguments for runTask\r | |
270 | */\r | |
271 | public String[] prepareArguments(CCTask task, String outputDir,\r | |
272 | String outputFile, String[] sourceFiles,\r | |
273 | CommandLineLinkerConfiguration config) {\r | |
274 | //\r | |
275 | // need to suppress sources that correspond to\r | |
276 | // library set entries since they are already\r | |
277 | // in the argument list\r | |
278 | String[] libnames = config.getLibraryNames();\r | |
279 | if (libnames == null || libnames.length == 0) {\r | |
280 | return super.prepareArguments(task, outputDir, outputFile,\r | |
281 | sourceFiles, config);\r | |
282 | }\r | |
283 | //\r | |
284 | //\r | |
285 | // null out any sources that correspond to library names\r | |
286 | //\r | |
287 | String[] localSources = (String[]) sourceFiles.clone();\r | |
288 | int extra = 0;\r | |
289 | for (int i = 0; i < libnames.length; i++) {\r | |
290 | String libname = libnames[i];\r | |
291 | for (int j = 0; j < localSources.length; j++) {\r | |
292 | if (localSources[j] != null\r | |
293 | && localSources[j].indexOf(libname) > 0\r | |
294 | && localSources[j].indexOf("lib") > 0) {\r | |
295 | String filename = new File(localSources[j]).getName();\r | |
296 | if (filename.startsWith("lib")\r | |
297 | && filename.substring(3).startsWith(libname)) {\r | |
298 | String extension = filename\r | |
299 | .substring(libname.length() + 3);\r | |
300 | if (extension.equals(".a") || extension.equals(".so")\r | |
301 | || extension.equals(".sl")) {\r | |
302 | localSources[j] = null;\r | |
303 | extra++;\r | |
304 | }\r | |
305 | }\r | |
306 | }\r | |
307 | }\r | |
308 | }\r | |
309 | if (extra == 0) {\r | |
310 | return super.prepareArguments(task, outputDir, outputFile,\r | |
311 | sourceFiles, config);\r | |
312 | }\r | |
313 | String[] finalSources = new String[localSources.length - extra];\r | |
314 | int index = 0;\r | |
315 | for (int i = 0; i < localSources.length; i++) {\r | |
316 | if (localSources[i] != null) {\r | |
317 | finalSources[index++] = localSources[i];\r | |
318 | }\r | |
319 | }\r | |
320 | return super.prepareArguments(task, outputDir, outputFile,\r | |
321 | finalSources, config);\r | |
322 | }\r | |
323 | }\r |