]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/Cpptasks/net/sf/antcontrib/cpptasks/gcc/cross/GppLinker.java
Changed spelling to manifest
[mirror_edk2.git] / Tools / Source / Cpptasks / net / sf / antcontrib / cpptasks / gcc / cross / GppLinker.java
1 /*
2 *
3 * Copyright 2003-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
21 import net.sf.antcontrib.cpptasks.CCTask;
22 import net.sf.antcontrib.cpptasks.CUtil;
23 import net.sf.antcontrib.cpptasks.LinkerParam;
24 import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;
25 import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;
26 import net.sf.antcontrib.cpptasks.compiler.LinkType;
27 import net.sf.antcontrib.cpptasks.compiler.Linker;
28 import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;
29 import net.sf.antcontrib.cpptasks.types.LibrarySet;
30
31 import org.apache.tools.ant.BuildException;
32 /**
33 * Adapter for the g++ variant of the GCC linker
34 *
35 * @author Stephen M. Webb <stephen.webb@bregmasoft.com>
36 */
37 public class GppLinker extends AbstractLdLinker {
38 protected static final String[] discardFiles = new String[0];
39 protected static final String[] objFiles = new String[]{".o", ".a", ".lib",
40 ".dll", ".so", ".sl"};
41 private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,
42 discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,
43 discardFiles, "lib", ".so", true, null));
44 private final static String libPrefix = "libraries: =";
45 protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",
46 ".lib", ".dll", ".so", ".sl"};
47 private static String[] linkerOptions = new String[]{"-bundle", "-dylib",
48 "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",
49 "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};
50 private static final GppLinker instance = new GppLinker("gcc", objFiles,
51 discardFiles, "", "", false, null);
52 private static final GppLinker machDllLinker = new GppLinker("gcc",
53 objFiles, discardFiles, "lib", ".dylib", false, null);
54 private static final GppLinker machPluginLinker = new GppLinker("gcc",
55 objFiles, discardFiles, "lib", ".bundle", false, null);
56 public static GppLinker getInstance() {
57 return instance;
58 }
59 private File[] libDirs;
60 private String runtimeLibrary;
61 protected GppLinker(String command, String[] extensions,
62 String[] ignoredExtensions, String outputPrefix,
63 String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {
64 super(command, "-dumpversion", extensions, ignoredExtensions,
65 outputPrefix, outputSuffix, isLibtool, libtoolLinker);
66 }
67 protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {
68 super.addImpliedArgs(debug, linkType, args, defaultflag);
69 if (getIdentifier().indexOf("mingw") >= 0) {
70 if (linkType.isSubsystemConsole()) {
71 args.addElement("-mconsole");
72 }
73 if (linkType.isSubsystemGUI()) {
74 args.addElement("-mwindows");
75 }
76 }
77 if (linkType.isStaticRuntime()) {
78 String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};
79 String[] cmdout = CaptureStreamHandler.run(cmdin);
80 if (cmdout.length > 0) {
81 runtimeLibrary = cmdout[0];
82 } else {
83 runtimeLibrary = null;
84 }
85 } else {
86 runtimeLibrary = "-lstdc++";
87 }
88 }
89 public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,
90 Vector preargs, Vector midargs, Vector endargs) {
91 String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,
92 endargs);
93 if (runtimeLibrary != null) {
94 endargs.addElement(runtimeLibrary);
95 }
96 return rs;
97 }
98 protected Object clone() throws CloneNotSupportedException {
99 GppLinker clone = (GppLinker) super.clone();
100 return clone;
101 }
102 /**
103 * Allows drived linker to decorate linker option. Override by GppLinker to
104 * prepend a "-Wl," to pass option to through gcc to linker.
105 *
106 * @param buf
107 * buffer that may be used and abused in the decoration process,
108 * must not be null.
109 * @param arg
110 * linker argument
111 */
112 public String decorateLinkerOption(StringBuffer buf, String arg) {
113 String decoratedArg = arg;
114 if (arg.length() > 1 && arg.charAt(0) == '-') {
115 switch (arg.charAt(1)) {
116 //
117 // passed automatically by GCC
118 //
119 case 'g' :
120 case 'f' :
121 case 'F' :
122 /* Darwin */
123 case 'm' :
124 case 'O' :
125 case 'W' :
126 case 'l' :
127 case 'L' :
128 case 'u' :
129 break;
130 default :
131 boolean known = false;
132 for (int i = 0; i < linkerOptions.length; i++) {
133 if (linkerOptions[i].equals(arg)) {
134 known = true;
135 break;
136 }
137 }
138 if (!known) {
139 buf.setLength(0);
140 buf.append("-Wl,");
141 buf.append(arg);
142 decoratedArg = buf.toString();
143 }
144 break;
145 }
146 }
147 return decoratedArg;
148 }
149 /**
150 * Returns library path.
151 *
152 */
153 public File[] getLibraryPath() {
154 if (libDirs == null) {
155 Vector dirs = new Vector();
156 // Ask GCC where it will look for its libraries.
157 String[] args = new String[]{"g++", "-print-search-dirs"};
158 String[] cmdout = CaptureStreamHandler.run(args);
159 for (int i = 0; i < cmdout.length; ++i) {
160 int prefixIndex = cmdout[i].indexOf(libPrefix);
161 if (prefixIndex >= 0) {
162 // Special case DOS-type GCCs like MinGW or Cygwin
163 int s = prefixIndex + libPrefix.length();
164 int t = cmdout[i].indexOf(';', s);
165 while (t > 0) {
166 dirs.addElement(cmdout[i].substring(s, t));
167 s = t + 1;
168 t = cmdout[i].indexOf(';', s);
169 }
170 dirs.addElement(cmdout[i].substring(s));
171 ++i;
172 for (; i < cmdout.length; ++i) {
173 dirs.addElement(cmdout[i]);
174 }
175 }
176 }
177 // Eliminate all but actual directories.
178 String[] libpath = new String[dirs.size()];
179 dirs.copyInto(libpath);
180 int count = CUtil.checkDirectoryArray(libpath);
181 // Build return array.
182 libDirs = new File[count];
183 int index = 0;
184 for (int i = 0; i < libpath.length; ++i) {
185 if (libpath[i] != null) {
186 libDirs[index++] = new File(libpath[i]);
187 }
188 }
189 }
190 return libDirs;
191 }
192 public Linker getLinker(LinkType type) {
193 if (type.isStaticLibrary()) {
194 return GccLibrarian.getInstance();
195 }
196 if (type.isPluginModule()) {
197 if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
198 return machPluginLinker;
199 } else {
200 return dllLinker;
201 }
202 }
203 if (type.isSharedLibrary()) {
204 if (GccProcessor.getMachine().indexOf("darwin") >= 0) {
205 return machDllLinker;
206 } else {
207 return dllLinker;
208 }
209 }
210 return instance;
211 }
212 public void link(CCTask task, File outputFile, String[] sourceFiles,
213 CommandLineLinkerConfiguration config) throws BuildException {
214 try {
215 GppLinker clone = (GppLinker) this.clone();
216 LinkerParam param = config.getParam("target");
217 if (param != null)
218 clone.setCommand(param.getValue() + "-" + this.getCommand());
219 clone.superlink(task, outputFile, sourceFiles, config);
220 } catch (CloneNotSupportedException e) {
221 superlink(task, outputFile, sourceFiles, config);
222 }
223 }
224 private void superlink(CCTask task, File outputFile, String[] sourceFiles,
225 CommandLineLinkerConfiguration config) throws BuildException {
226 super.link(task, outputFile, sourceFiles, config);
227 }
228 }