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;
21
22 import java.io.File;
23 import java.util.Vector;
24
25 import com.github.maven_nar.cpptasks.CCTask;
26 import com.github.maven_nar.cpptasks.CUtil;
27 import com.github.maven_nar.cpptasks.compiler.LinkType;
28 import com.github.maven_nar.cpptasks.compiler.Linker;
29
30
31
32
33
34
35 public class GccLinker extends AbstractLdLinker {
36 private static final String[] discardFiles = new String[0];
37 private static final String[] objFiles = new String[] {
38 ".o", ".a", ".lib", ".dll", ".so", ".sl"
39 };
40 private static final String[] libtoolObjFiles = new String[] {
41 ".fo", ".a", ".lib", ".dll", ".so", ".sl"
42 };
43 private static String[] linkerOptions = new String[] {
44 "-bundle",
45
46 "-dynamic", "-arch", "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", "-static", "-shared",
47 "-symbolic", "-Xlinker", "--export-all-symbols", "-static-libgcc", "-p", "-pg", "-pthread"
48 };
49
50 private static final GccLinker soLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".so", false,
51 new GccLinker("gcc", objFiles, discardFiles, "lib", ".so", true, null));
52 private static final GccLinker instance = new GccLinker("gcc", objFiles, discardFiles, "", "", false, null);
53 private static final GccLinker clangInstance = new GccLinker("clang", objFiles, discardFiles, "", "", false, null);
54 private static final GccLinker machBundleLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".bundle",
55 false, null);
56 private static final GccLinker machDllLinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".dylib", false,
57 null);
58 private static final GccLinker machJNILinker = new GccLinker("gcc", objFiles, discardFiles, "lib", ".jnilib", false,
59 null);
60
61 private static final GccLinker dllLinker = new GccLinker("gcc", objFiles, discardFiles, "", ".dll", false, null);
62
63 public static GccLinker getCLangInstance() {
64 return clangInstance;
65 }
66
67 public static GccLinker getInstance() {
68 return instance;
69 }
70
71 private File[] libDirs;
72
73 protected GccLinker(final String command, final String[] extensions, final String[] ignoredExtensions,
74 final String outputPrefix, final String outputSuffix, final boolean isLibtool, final GccLinker libtoolLinker) {
75 super(command, "-dumpversion", extensions, ignoredExtensions, outputPrefix, outputSuffix, isLibtool, libtoolLinker);
76 }
77
78 @Override
79 protected void addImpliedArgs(final CCTask task, final boolean debug, final LinkType linkType,
80 final Vector<String> args) {
81 super.addImpliedArgs(task, debug, linkType, args);
82 if (getIdentifier().contains("mingw")) {
83 if (linkType.isSubsystemConsole()) {
84 args.addElement("-mconsole");
85 }
86 if (linkType.isSubsystemGUI()) {
87 args.addElement("-mwindows");
88 }
89 }
90 }
91
92
93
94
95
96
97
98
99
100
101
102 @Override
103 public String decorateLinkerOption(final StringBuffer buf, final String arg) {
104 String decoratedArg = arg;
105 if (arg.length() > 1 && arg.charAt(0) == '-') {
106 switch (arg.charAt(1)) {
107
108
109
110 case 'g':
111 case 'f':
112 case 'F':
113
114 case 'm':
115 case 'O':
116 case 'W':
117 case 'l':
118 case 'L':
119 case 'u':
120 case 'v':
121 break;
122 default:
123 boolean known = false;
124 for (final String linkerOption : linkerOptions) {
125 if (linkerOption.equals(arg)) {
126 known = true;
127 break;
128 }
129 }
130 if (!known) {
131 buf.setLength(0);
132 buf.append("-Wl,");
133 buf.append(arg);
134 decoratedArg = buf.toString();
135 }
136 break;
137 }
138 }
139 return decoratedArg;
140 }
141
142
143
144
145
146 @Override
147 public File[] getLibraryPath() {
148 if (this.libDirs == null) {
149
150
151
152 final StringBuffer buf = new StringBuffer("/lib/gcc-lib/");
153 buf.append(GccProcessor.getMachine());
154 buf.append('/');
155 buf.append(GccProcessor.getVersion());
156
157
158
159 final String[] impliedLibPath = new String[] {
160 buf.toString(), "/lib/w32api", "/lib"
161 };
162
163
164
165 final String[] specs = GccProcessor.getSpecs();
166 final String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:", new String[] {
167 "%q"
168 });
169 String[] libpath;
170 if (libpaths[0].length > 0) {
171 libpath = new String[libpaths[0].length + 3];
172 int i = 0;
173 for (; i < libpaths[0].length; i++) {
174 libpath[i] = libpaths[0][i];
175 }
176 libpath[i++] = buf.toString();
177 libpath[i++] = "/lib/w32api";
178 libpath[i++] = "/lib";
179 } else {
180
181
182
183 libpath = new String[] {
184 "/usr/local/lib/mingw", "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw", "/usr/lib", buf.toString(),
185 "/lib/w32api", "/lib"
186 };
187 }
188 for (int i = 0; i < libpath.length; i++) {
189 if (libpath[i].contains("mingw")) {
190 libpath[i] = null;
191 }
192 }
193
194
195
196
197
198
199 if (GccProcessor.isCygwin()) {
200 GccProcessor.convertCygwinFilenames(libpath);
201 }
202
203
204
205 final int count = CUtil.checkDirectoryArray(libpath);
206
207
208
209 this.libDirs = new File[count];
210 int index = 0;
211 for (final String element : libpath) {
212 if (element != null) {
213 this.libDirs[index++] = new File(element);
214 }
215 }
216 }
217 return this.libDirs;
218 }
219
220 @Override
221 public Linker getLinker(final LinkType type) {
222 if (type.isStaticLibrary()) {
223 return GccLibrarian.getInstance();
224 }
225
226 if (type.isJNIModule()) {
227 return isDarwin() ? machJNILinker : isWindows() ? dllLinker : soLinker;
228 }
229 if (type.isPluginModule()) {
230 return isDarwin() ? machBundleLinker : isWindows() ? dllLinker : soLinker;
231 }
232 if (type.isSharedLibrary()) {
233 return isDarwin() ? machDllLinker : isWindows() ? dllLinker : soLinker;
234 }
235
236 return instance;
237 }
238 }