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