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