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
.CUtil
;
22 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
23 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
25 * Adapter for the GCC linker
27 * @author Adam Murdoch
29 public class GccLinker
extends AbstractLdLinker
{
30 private static final String
[] discardFiles
= new String
[0];
31 private static final String
[] objFiles
= new String
[]{".o", ".a", ".lib",
32 ".dll", ".so", ".sl"};
33 private static final String
[] libtoolObjFiles
= new String
[]{".fo", ".a",
34 ".lib", ".dll", ".so", ".sl"};
35 private static String
[] linkerOptions
= new String
[]{"-bundle",
36 "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",
37 "-static", "-shared", "-symbolic", "-Xlinker",
38 "--export-all-symbols", "-static-libgcc",};
39 private static final GccLinker dllLinker
= new GccLinker("gcc", objFiles
,
40 discardFiles
, "lib", ".so", false, new GccLinker("gcc", objFiles
,
41 discardFiles
, "lib", ".so", true, null));
42 private static final GccLinker instance
= new GccLinker("gcc", objFiles
,
43 discardFiles
, "", "", false, null);
44 private static final GccLinker machBundleLinker
= new GccLinker("gcc",
45 objFiles
, discardFiles
, "lib", ".bundle", false, null);
46 private static final GccLinker machDllLinker
= new GccLinker("gcc",
47 objFiles
, discardFiles
, "lib", ".dylib", false, null);
48 public static GccLinker
getInstance() {
51 private File
[] libDirs
;
52 protected GccLinker(String command
, String
[] extensions
,
53 String
[] ignoredExtensions
, String outputPrefix
,
54 String outputSuffix
, boolean isLibtool
, GccLinker libtoolLinker
) {
55 super(command
, "-dumpversion", extensions
, ignoredExtensions
,
56 outputPrefix
, outputSuffix
, isLibtool
, libtoolLinker
);
58 protected void addImpliedArgs(boolean debug
, LinkType linkType
, Vector args
, Boolean defaultflag
) {
59 super.addImpliedArgs(debug
, linkType
, args
, defaultflag
);
60 if (getIdentifier().indexOf("mingw") >= 0) {
61 if (linkType
.isSubsystemConsole()) {
62 args
.addElement("-mconsole");
64 if (linkType
.isSubsystemGUI()) {
65 args
.addElement("-mwindows");
70 * Allows drived linker to decorate linker option. Override by GccLinker to
71 * prepend a "-Wl," to pass option to through gcc to linker.
74 * buffer that may be used and abused in the decoration process,
79 public String
decorateLinkerOption(StringBuffer buf
, String arg
) {
80 String decoratedArg
= arg
;
81 if (arg
.length() > 1 && arg
.charAt(0) == '-') {
82 switch (arg
.charAt(1)) {
84 // passed automatically by GCC
99 boolean known
= false;
100 for (int i
= 0; i
< linkerOptions
.length
; i
++) {
101 if (linkerOptions
[i
].equals(arg
)) {
110 decoratedArg
= buf
.toString();
118 * Returns library path.
121 public File
[] getLibraryPath() {
122 if (libDirs
== null) {
124 // construct gcc lib path from machine and version
126 StringBuffer buf
= new StringBuffer("/lib/gcc-lib/");
127 buf
.append(GccProcessor
.getMachine());
129 buf
.append(GccProcessor
.getVersion());
131 // build default path from gcc and system /lib and /lib/w32api
133 String
[] impliedLibPath
= new String
[]{buf
.toString(),
134 "/lib/w32api", "/lib"};
136 // read gcc specs file for other library paths
138 String
[] specs
= GccProcessor
.getSpecs();
139 String
[][] libpaths
= GccProcessor
.parseSpecs(specs
, "*link:",
142 if (libpaths
[0].length
> 0) {
143 libpath
= new String
[libpaths
[0].length
+ 3];
145 for (; i
< libpaths
[0].length
; i
++) {
146 libpath
[i
] = libpaths
[0][i
];
148 libpath
[i
++] = buf
.toString();
149 libpath
[i
++] = "/lib/w32api";
150 libpath
[i
++] = "/lib";
153 // if a failure to find any matches then
154 // use some default values for lib path entries
155 libpath
= new String
[]{"/usr/local/lib/mingw",
156 "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",
157 "/usr/lib", buf
.toString(), "/lib/w32api", "/lib"};
159 for (int i
= 0; i
< libpath
.length
; i
++) {
160 if (libpath
[i
].indexOf("mingw") >= 0) {
166 // we have to prepend location of gcc32
167 // and .. to start of absolute filenames to
168 // have something that will exist in the
169 // windows filesystem
170 if (GccProcessor
.isCygwin()) {
171 GccProcessor
.convertCygwinFilenames(libpath
);
174 // check that remaining entries are actual directories
176 int count
= CUtil
.checkDirectoryArray(libpath
);
178 // populate return array with remaining entries
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()) {
196 return machBundleLinker
;
201 if (type
.isSharedLibrary()) {
203 return machDllLinker
;