]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/GccLinker.java
Changed spelling to manifest
[mirror_edk2.git] / Tools / Source / Cpptasks / net / sf / antcontrib / cpptasks / gcc / GccLinker.java
CommitLineData
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
17package net.sf.antcontrib.cpptasks.gcc;\r
18import java.io.File;\r
19import java.util.Vector;\r
20\r
21import net.sf.antcontrib.cpptasks.CUtil;\r
22import net.sf.antcontrib.cpptasks.compiler.LinkType;\r
23import 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
29public 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