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