878ddf1f |
1 | /*\r |
2 | * \r |
3 | * Copyright 2001-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.cross.sparc_sun_solaris2;\r |
18 | import java.io.File;\r |
19 | import java.util.Vector;\r |
20 | \r |
21 | import net.sf.antcontrib.cpptasks.CUtil;\r |
22 | import net.sf.antcontrib.cpptasks.compiler.LinkType;\r |
23 | import net.sf.antcontrib.cpptasks.compiler.Linker;\r |
24 | import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;\r |
25 | /**\r |
26 | * Adapter for the GCC linker\r |
27 | * \r |
28 | * @author Adam Murdoch\r |
29 | */\r |
30 | public class GccLinker extends AbstractLdLinker {\r |
31 | private static final String[] discardFiles = new String[0];\r |
32 | private static final String[] objFiles = new String[]{".o", ".a", ".lib",\r |
33 | ".dll", ".so", ".sl"};\r |
34 | private static final String[] libtoolObjFiles = new String[]{".fo", ".a",\r |
35 | ".lib", ".dll", ".so", ".sl"};\r |
36 | private static String[] linkerOptions = new String[]{"-bundle",\r |
37 | "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",\r |
38 | "-static", "-shared", "-symbolic", "-Xlinker",\r |
39 | "--export-all-symbols", "-static-libgcc",};\r |
40 | private static final GccLinker dllLinker = new GccLinker(\r |
41 | GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",\r |
42 | ".so", false, new GccLinker(GccCCompiler.CMD_PREFIX + "gcc",\r |
43 | objFiles, discardFiles, "lib", ".so", true, null));\r |
44 | private static final GccLinker instance = new GccLinker(\r |
45 | GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "", "",\r |
46 | false, null);\r |
47 | private static final GccLinker machBundleLinker = new GccLinker(\r |
48 | GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",\r |
49 | ".bundle", false, null);\r |
50 | private static final GccLinker machDllLinker = new GccLinker(\r |
51 | GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib",\r |
52 | ".dylib", false, null);\r |
53 | public static GccLinker getInstance() {\r |
54 | return instance;\r |
55 | }\r |
56 | private File[] libDirs;\r |
57 | protected GccLinker(String command, String[] extensions,\r |
58 | String[] ignoredExtensions, String outputPrefix,\r |
59 | String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {\r |
60 | super(command, "-dumpversion", extensions, ignoredExtensions,\r |
61 | outputPrefix, outputSuffix, isLibtool, libtoolLinker);\r |
62 | }\r |
63 | protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {\r |
64 | super.addImpliedArgs(debug, linkType, args, defaultflag);\r |
65 | if (getIdentifier().indexOf("mingw") >= 0) {\r |
66 | if (linkType.isSubsystemConsole()) {\r |
67 | args.addElement("-mconsole");\r |
68 | }\r |
69 | if (linkType.isSubsystemGUI()) {\r |
70 | args.addElement("-mwindows");\r |
71 | }\r |
72 | }\r |
73 | }\r |
74 | /**\r |
75 | * Allows drived linker to decorate linker option. Override by GccLinker to\r |
76 | * prepend a "-Wl," to pass option to through gcc to linker.\r |
77 | * \r |
78 | * @param buf\r |
79 | * buffer that may be used and abused in the decoration process,\r |
80 | * must not be null.\r |
81 | * @param arg\r |
82 | * linker argument\r |
83 | */\r |
84 | public String decorateLinkerOption(StringBuffer buf, String arg) {\r |
85 | String decoratedArg = arg;\r |
86 | if (arg.length() > 1 && arg.charAt(0) == '-') {\r |
87 | switch (arg.charAt(1)) {\r |
88 | //\r |
89 | // passed automatically by GCC\r |
90 | //\r |
91 | case 'g' :\r |
92 | case 'f' :\r |
93 | case 'F' :\r |
94 | /* Darwin */\r |
95 | case 'm' :\r |
96 | case 'O' :\r |
97 | case 'W' :\r |
98 | case 'l' :\r |
99 | case 'L' :\r |
100 | case 'u' :\r |
101 | case 'v' :\r |
102 | break;\r |
103 | default :\r |
104 | boolean known = false;\r |
105 | for (int i = 0; i < linkerOptions.length; i++) {\r |
106 | if (linkerOptions[i].equals(arg)) {\r |
107 | known = true;\r |
108 | break;\r |
109 | }\r |
110 | }\r |
111 | if (!known) {\r |
112 | buf.setLength(0);\r |
113 | buf.append("-Wl,");\r |
114 | buf.append(arg);\r |
115 | decoratedArg = buf.toString();\r |
116 | }\r |
117 | break;\r |
118 | }\r |
119 | }\r |
120 | return decoratedArg;\r |
121 | }\r |
122 | /**\r |
123 | * Returns library path.\r |
124 | * \r |
125 | */\r |
126 | public File[] getLibraryPath() {\r |
127 | if (libDirs == null) {\r |
128 | //\r |
129 | // construct gcc lib path from machine and version\r |
130 | //\r |
131 | StringBuffer buf = new StringBuffer("/lib/gcc-lib/");\r |
132 | buf.append(GccProcessor.getMachine());\r |
133 | buf.append('/');\r |
134 | buf.append(GccProcessor.getVersion());\r |
135 | //\r |
136 | // build default path from gcc and system /lib and /lib/w32api\r |
137 | //\r |
138 | String[] impliedLibPath = new String[]{buf.toString(),\r |
139 | "/lib/w32api", "/lib"};\r |
140 | //\r |
141 | // read gcc specs file for other library paths\r |
142 | //\r |
143 | String[] specs = GccProcessor.getSpecs();\r |
144 | String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",\r |
145 | new String[]{"%q"});\r |
146 | String[] libpath;\r |
147 | if (libpaths[0].length > 0) {\r |
148 | libpath = new String[libpaths[0].length + 3];\r |
149 | int i = 0;\r |
150 | for (; i < libpaths[0].length; i++) {\r |
151 | libpath[i] = libpaths[0][i];\r |
152 | }\r |
153 | libpath[i++] = buf.toString();\r |
154 | libpath[i++] = "/lib/w32api";\r |
155 | libpath[i++] = "/lib";\r |
156 | } else {\r |
157 | //\r |
158 | // if a failure to find any matches then\r |
159 | // use some default values for lib path entries\r |
160 | libpath = new String[]{"/usr/local/lib/mingw",\r |
161 | "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",\r |
162 | "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};\r |
163 | }\r |
164 | for (int i = 0; i < libpath.length; i++) {\r |
165 | if (libpath[i].indexOf("mingw") >= 0) {\r |
166 | libpath[i] = null;\r |
167 | }\r |
168 | }\r |
169 | //\r |
170 | // if cygwin then\r |
171 | // we have to prepend location of gcc32\r |
172 | // and .. to start of absolute filenames to\r |
173 | // have something that will exist in the\r |
174 | // windows filesystem\r |
175 | if (GccProcessor.isCygwin()) {\r |
176 | GccProcessor.convertCygwinFilenames(libpath);\r |
177 | }\r |
178 | //\r |
179 | // check that remaining entries are actual directories\r |
180 | //\r |
181 | int count = CUtil.checkDirectoryArray(libpath);\r |
182 | //\r |
183 | // populate return array with remaining entries\r |
184 | //\r |
185 | libDirs = new File[count];\r |
186 | int index = 0;\r |
187 | for (int i = 0; i < libpath.length; i++) {\r |
188 | if (libpath[i] != null) {\r |
189 | libDirs[index++] = new File(libpath[i]);\r |
190 | }\r |
191 | }\r |
192 | }\r |
193 | return libDirs;\r |
194 | }\r |
195 | public Linker getLinker(LinkType type) {\r |
196 | if (type.isStaticLibrary()) {\r |
197 | return GccLibrarian.getInstance();\r |
198 | }\r |
199 | if (type.isPluginModule()) {\r |
200 | if (isDarwin()) {\r |
201 | return machBundleLinker;\r |
202 | } else {\r |
203 | return dllLinker;\r |
204 | }\r |
205 | }\r |
206 | if (type.isSharedLibrary()) {\r |
207 | if (isDarwin()) {\r |
208 | return machDllLinker;\r |
209 | } else {\r |
210 | return dllLinker;\r |
211 | }\r |
212 | }\r |
213 | return instance;\r |
214 | }\r |
215 | }\r |