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