3 * Copyright 2003-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
.cross
.sparc_sun_solaris2
;
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
.CaptureStreamHandler
;
24 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
25 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
26 import net
.sf
.antcontrib
.cpptasks
.gcc
.AbstractLdLinker
;
27 import net
.sf
.antcontrib
.cpptasks
.types
.LibrarySet
;
29 * Adapter for the g++ variant of the GCC linker
31 * @author Stephen M. Webb <stephen.webb@bregmasoft.com>
33 public class GppLinker
extends AbstractLdLinker
{
34 protected static final String
[] discardFiles
= new String
[0];
35 protected static final String
[] objFiles
= new String
[]{".o", ".a", ".lib",
36 ".dll", ".so", ".sl"};
37 private final static String libPrefix
= "libraries: =";
38 protected static final String
[] libtoolObjFiles
= new String
[]{".fo", ".a",
39 ".lib", ".dll", ".so", ".sl"};
40 private static String
[] linkerOptions
= new String
[]{"-bundle", "-dylib",
41 "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",
42 "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};
43 private static final GppLinker dllLinker
= new GppLinker(
44 GccCCompiler
.CMD_PREFIX
+ "gcc", objFiles
, discardFiles
, "lib",
45 ".so", false, new GppLinker(GccCCompiler
.CMD_PREFIX
+ "gcc",
46 objFiles
, discardFiles
, "lib", ".so", true, null));
47 private static final GppLinker instance
= new GppLinker(
48 GccCCompiler
.CMD_PREFIX
+ "gcc", objFiles
, discardFiles
, "", "",
50 private static final GppLinker machDllLinker
= new GppLinker(
51 GccCCompiler
.CMD_PREFIX
+ "gcc", objFiles
, discardFiles
, "lib",
52 ".dylib", false, null);
53 private static final GppLinker machPluginLinker
= new GppLinker(
54 GccCCompiler
.CMD_PREFIX
+ "gcc", objFiles
, discardFiles
, "lib",
55 ".bundle", false, null);
56 public static GppLinker
getInstance() {
59 private File
[] libDirs
;
60 private String runtimeLibrary
;
61 protected GppLinker(String command
, String
[] extensions
,
62 String
[] ignoredExtensions
, String outputPrefix
,
63 String outputSuffix
, boolean isLibtool
, GppLinker libtoolLinker
) {
64 super(command
, "-dumpversion", extensions
, ignoredExtensions
,
65 outputPrefix
, outputSuffix
, isLibtool
, libtoolLinker
);
67 protected void addImpliedArgs(boolean debug
, LinkType linkType
, Vector args
, Boolean defaultflag
) {
68 super.addImpliedArgs(debug
, linkType
, args
, defaultflag
);
69 if (getIdentifier().indexOf("mingw") >= 0) {
70 if (linkType
.isSubsystemConsole()) {
71 args
.addElement("-mconsole");
73 if (linkType
.isSubsystemGUI()) {
74 args
.addElement("-mwindows");
77 if (linkType
.isStaticRuntime()) {
78 String
[] cmdin
= new String
[]{GccCCompiler
.CMD_PREFIX
+ "g++",
79 "-print-file-name=libstdc++.a"};
80 String
[] cmdout
= CaptureStreamHandler
.run(cmdin
);
81 if (cmdout
.length
> 0) {
82 runtimeLibrary
= cmdout
[0];
84 runtimeLibrary
= null;
87 runtimeLibrary
= "-lstdc++";
90 public String
[] addLibrarySets(CCTask task
, LibrarySet
[] libsets
,
91 Vector preargs
, Vector midargs
, Vector endargs
) {
92 String
[] rs
= super.addLibrarySets(task
, libsets
, preargs
, midargs
,
94 if (runtimeLibrary
!= null) {
95 endargs
.addElement(runtimeLibrary
);
100 * Allows drived linker to decorate linker option. Override by GppLinker to
101 * prepend a "-Wl," to pass option to through gcc to linker.
104 * buffer that may be used and abused in the decoration process,
109 public String
decorateLinkerOption(StringBuffer buf
, String arg
) {
110 String decoratedArg
= arg
;
111 if (arg
.length() > 1 && arg
.charAt(0) == '-') {
112 switch (arg
.charAt(1)) {
114 // passed automatically by GCC
128 boolean known
= false;
129 for (int i
= 0; i
< linkerOptions
.length
; i
++) {
130 if (linkerOptions
[i
].equals(arg
)) {
139 decoratedArg
= buf
.toString();
147 * Returns library path.
150 public File
[] getLibraryPath() {
151 if (libDirs
== null) {
152 Vector dirs
= new Vector();
153 // Ask GCC where it will look for its libraries.
154 String
[] args
= new String
[]{GccCCompiler
.CMD_PREFIX
+ "g++",
155 "-print-search-dirs"};
156 String
[] cmdout
= CaptureStreamHandler
.run(args
);
157 for (int i
= 0; i
< cmdout
.length
; ++i
) {
158 int prefixIndex
= cmdout
[i
].indexOf(libPrefix
);
159 if (prefixIndex
>= 0) {
160 // Special case DOS-type GCCs like MinGW or Cygwin
161 int s
= prefixIndex
+ libPrefix
.length();
162 int t
= cmdout
[i
].indexOf(';', s
);
164 dirs
.addElement(cmdout
[i
].substring(s
, t
));
166 t
= cmdout
[i
].indexOf(';', s
);
168 dirs
.addElement(cmdout
[i
].substring(s
));
170 for (; i
< cmdout
.length
; ++i
) {
171 dirs
.addElement(cmdout
[i
]);
175 // Eliminate all but actual directories.
176 String
[] libpath
= new String
[dirs
.size()];
177 dirs
.copyInto(libpath
);
178 int count
= CUtil
.checkDirectoryArray(libpath
);
179 // Build return array.
180 libDirs
= new File
[count
];
182 for (int i
= 0; i
< libpath
.length
; ++i
) {
183 if (libpath
[i
] != null) {
184 libDirs
[index
++] = new File(libpath
[i
]);
190 public Linker
getLinker(LinkType type
) {
191 if (type
.isStaticLibrary()) {
192 return GccLibrarian
.getInstance();
194 if (type
.isPluginModule()) {
195 if (GccProcessor
.getMachine().indexOf("darwin") >= 0) {
196 return machPluginLinker
;
201 if (type
.isSharedLibrary()) {
202 if (GccProcessor
.getMachine().indexOf("darwin") >= 0) {
203 return machDllLinker
;