1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.github.maven_nar.cpptasks.gcc.cross;
21
22 import java.io.File;
23 import java.util.Vector;
24
25 import org.apache.tools.ant.BuildException;
26
27 import com.github.maven_nar.cpptasks.CCTask;
28 import com.github.maven_nar.cpptasks.CUtil;
29 import com.github.maven_nar.cpptasks.LinkerParam;
30 import com.github.maven_nar.cpptasks.compiler.CommandLineLinkerConfiguration;
31 import com.github.maven_nar.cpptasks.compiler.LinkType;
32 import com.github.maven_nar.cpptasks.compiler.Linker;
33 import com.github.maven_nar.cpptasks.gcc.AbstractLdLinker;
34
35
36
37
38
39
40 public class GccLinker extends AbstractLdLinker {
41 private static final String[] discardFiles = new String[0];
42 private static final String[] objFiles = new String[] {
43 ".o", ".a", ".lib", ".dll", ".so", ".sl"
44 };
45 private static final GccLinker dllLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".so", false,
46 new GccLinker("gcc", objFiles, discardFiles, "lib", ".so", true, null));
47 private static final GccLinker instance = new GccLinker("gcc", objFiles, discardFiles, "", "", false, null);
48 private static final String[] libtoolObjFiles = new String[] {
49 ".fo", ".a", ".lib", ".dll", ".so", ".sl"
50 };
51 private static String[] linkerOptions = new String[] {
52 "-bundle", "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", "-static", "-shared", "-symbolic",
53 "-Xlinker", "--export-all-symbols", "-static-libgcc",
54 };
55 private static final GccLinker machBundleLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".bundle",
56 false, null);
57 private static final GccLinker machDllLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".dylib", false,
58 null);
59
60 public static GccLinker getInstance() {
61 return instance;
62 }
63
64 private File[] libDirs;
65
66 protected GccLinker(final String command, final String[] extensions, final String[] ignoredExtensions,
67 final String outputPrefix, final String outputSuffix, final boolean isLibtool, final GccLinker libtoolLinker) {
68 super(command, "-dumpversion", extensions, ignoredExtensions, outputPrefix, outputSuffix, isLibtool, libtoolLinker);
69 }
70
71 @Override
72 protected void addImpliedArgs(final CCTask task, final boolean debug, final LinkType linkType,
73 final Vector<String> args) {
74 super.addImpliedArgs(task, debug, linkType, args);
75 if (getIdentifier().contains("mingw")) {
76 if (linkType.isSubsystemConsole()) {
77 args.addElement("-mconsole");
78 }
79 if (linkType.isSubsystemGUI()) {
80 args.addElement("-mwindows");
81 }
82 }
83 }
84
85 @Override
86 protected Object clone() throws CloneNotSupportedException {
87 final GccLinker clone = (GccLinker) super.clone();
88 return clone;
89 }
90
91
92
93
94
95
96
97
98
99
100
101 @Override
102 public String decorateLinkerOption(final StringBuffer buf, final String arg) {
103 String decoratedArg = arg;
104 if (arg.length() > 1 && arg.charAt(0) == '-') {
105 switch (arg.charAt(1)) {
106
107
108
109 case 'g':
110 case 'f':
111 case 'F':
112
113 case 'm':
114 case 'O':
115 case 'W':
116 case 'l':
117 case 'L':
118 case 'u':
119 case 'v':
120 break;
121 default:
122 boolean known = false;
123 for (final String linkerOption : linkerOptions) {
124 if (linkerOption.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
142
143
144
145 @Override
146 public File[] getLibraryPath() {
147 if (this.libDirs == null) {
148
149
150
151 final StringBuffer buf = new StringBuffer("/lib/gcc-lib/");
152 buf.append(GccProcessor.getMachine());
153 buf.append('/');
154 buf.append(GccProcessor.getVersion());
155
156
157
158 final String[] impliedLibPath = new String[] {
159 buf.toString(), "/lib/w32api", "/lib"
160 };
161
162
163
164 final String[] specs = GccProcessor.getSpecs();
165 final String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:", new String[] {
166 "%q"
167 });
168 String[] libpath;
169 if (libpaths[0].length > 0) {
170 libpath = new String[libpaths[0].length + 3];
171 int i = 0;
172 for (; i < libpaths[0].length; i++) {
173 libpath[i] = libpaths[0][i];
174 }
175 libpath[i++] = buf.toString();
176 libpath[i++] = "/lib/w32api";
177 libpath[i++] = "/lib";
178 } else {
179
180
181
182 libpath = new String[] {
183 "/usr/local/lib/mingw", "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw", "/usr/lib", buf.toString(),
184 "/lib/w32api", "/lib"
185 };
186 }
187 for (int i = 0; i < libpath.length; i++) {
188 if (libpath[i].contains("mingw")) {
189 libpath[i] = null;
190 }
191 }
192
193
194
195
196
197
198 if (GccProcessor.isCygwin()) {
199 GccProcessor.convertCygwinFilenames(libpath);
200 }
201
202
203
204 final int count = CUtil.checkDirectoryArray(libpath);
205
206
207
208 this.libDirs = new File[count];
209 int index = 0;
210 for (final String element : libpath) {
211 if (element != null) {
212 this.libDirs[index++] = new File(element);
213 }
214 }
215 }
216 return this.libDirs;
217 }
218
219 @Override
220 public Linker getLinker(final LinkType type) {
221 if (type.isStaticLibrary()) {
222 return GccLibrarian.getInstance();
223 }
224 if (type.isPluginModule()) {
225 if (isDarwin()) {
226 return machBundleLinker;
227 } else {
228 return dllLinker;
229 }
230 }
231 if (type.isSharedLibrary()) {
232 if (isDarwin()) {
233 return machDllLinker;
234 } else {
235 return dllLinker;
236 }
237 }
238 return instance;
239 }
240
241 @Override
242 public void link(final CCTask task, final File outputFile, final String[] sourceFiles,
243 final CommandLineLinkerConfiguration config) throws BuildException {
244 try {
245 final GccLinker clone = (GccLinker) this.clone();
246 final LinkerParam param = config.getParam("target");
247 if (param != null) {
248 clone.setCommand(param.getValue() + "-" + this.getCommand());
249 }
250 clone.superlink(task, outputFile, sourceFiles, config);
251 } catch (final CloneNotSupportedException e) {
252 superlink(task, outputFile, sourceFiles, config);
253 }
254 }
255
256 private void superlink(final CCTask task, final File outputFile, final String[] sourceFiles,
257 final CommandLineLinkerConfiguration config) throws BuildException {
258 super.link(task, outputFile, sourceFiles, config);
259 }
260 }