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