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.sparc_sun_solaris2;
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.CaptureStreamHandler;
28 import com.github.maven_nar.cpptasks.compiler.LinkType;
29 import com.github.maven_nar.cpptasks.compiler.Linker;
30 import com.github.maven_nar.cpptasks.gcc.AbstractLdLinker;
31 import com.github.maven_nar.cpptasks.types.LibrarySet;
32
33
34
35
36
37
38 public class GppLinker extends AbstractLdLinker {
39 protected static final String[] discardFiles = new String[0];
40 protected static final String[] objFiles = new String[] {
41 ".o", ".a", ".lib", ".dll", ".so", ".sl"
42 };
43 private final static String libPrefix = "libraries: =";
44 protected static final String[] libtoolObjFiles = new String[] {
45 ".fo", ".a", ".lib", ".dll", ".so", ".sl"
46 };
47 private static String[] linkerOptions = new String[] {
48 "-bundle", "-dylib", "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s", "-static",
49 "-shared", "-symbolic", "-Xlinker"
50 };
51 private static final GppLinker dllLinker = new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles,
52 "lib", ".so", false, new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "lib", ".so", true,
53 null));
54 private static final GppLinker instance = new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles, "",
55 "", false, null);
56 private static final GppLinker machDllLinker = new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", objFiles, discardFiles,
57 "lib", ".dylib", false, null);
58 private static final GppLinker machPluginLinker = new GppLinker(GccCCompiler.CMD_PREFIX + "gcc", objFiles,
59 discardFiles, "lib", ".bundle", false, null);
60
61 public static GppLinker getInstance() {
62 return instance;
63 }
64
65 private File[] libDirs;
66 private String runtimeLibrary;
67
68 protected GppLinker(final String command, final String[] extensions, final String[] ignoredExtensions,
69 final String outputPrefix, final String outputSuffix, final boolean isLibtool, final GppLinker libtoolLinker) {
70 super(command, "-dumpversion", extensions, ignoredExtensions, outputPrefix, outputSuffix, isLibtool, libtoolLinker);
71 }
72
73 @Override
74 protected void addImpliedArgs(final CCTask task, final boolean debug, final LinkType linkType,
75 final Vector<String> args) {
76 super.addImpliedArgs(task, debug, linkType, args);
77 if (getIdentifier().contains("mingw")) {
78 if (linkType.isSubsystemConsole()) {
79 args.addElement("-mconsole");
80 }
81 if (linkType.isSubsystemGUI()) {
82 args.addElement("-mwindows");
83 }
84 }
85 if (linkType.isStaticRuntime()) {
86 final String[] cmdin = new String[] {
87 GccCCompiler.CMD_PREFIX + "g++", "-print-file-name=libstdc++.a"
88 };
89 final String[] cmdout = CaptureStreamHandler.run(cmdin);
90 if (cmdout.length > 0) {
91 this.runtimeLibrary = cmdout[0];
92 } else {
93 this.runtimeLibrary = null;
94 }
95 } else {
96 this.runtimeLibrary = "-lstdc++";
97 }
98 }
99
100 @Override
101 public String[] addLibrarySets(final CCTask task, final LibrarySet[] libsets, final Vector<String> preargs,
102 final Vector<String> midargs, final Vector<String> endargs) {
103 final String[] rs = super.addLibrarySets(task, libsets, preargs, midargs, endargs);
104 if (this.runtimeLibrary != null) {
105 endargs.addElement(this.runtimeLibrary);
106 }
107 return rs;
108 }
109
110
111
112
113
114
115
116
117
118
119
120 @Override
121 public String decorateLinkerOption(final StringBuffer buf, final String arg) {
122 String decoratedArg = arg;
123 if (arg.length() > 1 && arg.charAt(0) == '-') {
124 switch (arg.charAt(1)) {
125
126
127
128 case 'g':
129 case 'f':
130 case 'F':
131
132 case 'm':
133 case 'O':
134 case 'W':
135 case 'l':
136 case 'L':
137 case 'u':
138 break;
139 default:
140 boolean known = false;
141 for (final String linkerOption : linkerOptions) {
142 if (linkerOption.equals(arg)) {
143 known = true;
144 break;
145 }
146 }
147 if (!known) {
148 buf.setLength(0);
149 buf.append("-Wl,");
150 buf.append(arg);
151 decoratedArg = buf.toString();
152 }
153 break;
154 }
155 }
156 return decoratedArg;
157 }
158
159
160
161
162
163 @Override
164 public File[] getLibraryPath() {
165 if (this.libDirs == null) {
166 final Vector<String> dirs = new Vector<>();
167
168 final String[] args = new String[] {
169 GccCCompiler.CMD_PREFIX + "g++", "-print-search-dirs"
170 };
171 final String[] cmdout = CaptureStreamHandler.run(args);
172 for (int i = 0; i < cmdout.length; ++i) {
173 final int prefixIndex = cmdout[i].indexOf(libPrefix);
174 if (prefixIndex >= 0) {
175
176 int s = prefixIndex + libPrefix.length();
177 int t = cmdout[i].indexOf(';', s);
178 while (t > 0) {
179 dirs.addElement(cmdout[i].substring(s, t));
180 s = t + 1;
181 t = cmdout[i].indexOf(';', s);
182 }
183 dirs.addElement(cmdout[i].substring(s));
184 ++i;
185 for (; i < cmdout.length; ++i) {
186 dirs.addElement(cmdout[i]);
187 }
188 }
189 }
190
191 final String[] libpath = new String[dirs.size()];
192 dirs.copyInto(libpath);
193 final int count = CUtil.checkDirectoryArray(libpath);
194
195 this.libDirs = new File[count];
196 int index = 0;
197 for (final String element : libpath) {
198 if (element != null) {
199 this.libDirs[index++] = new File(element);
200 }
201 }
202 }
203 return this.libDirs;
204 }
205
206 @Override
207 public Linker getLinker(final LinkType type) {
208 if (type.isStaticLibrary()) {
209 return GccLibrarian.getInstance();
210 }
211 if (type.isPluginModule()) {
212 if (GccProcessor.getMachine().contains("darwin")) {
213 return machPluginLinker;
214 } else {
215 return dllLinker;
216 }
217 }
218 if (type.isSharedLibrary()) {
219 if (GccProcessor.getMachine().contains("darwin")) {
220 return machDllLinker;
221 } else {
222 return dllLinker;
223 }
224 }
225 return instance;
226 }
227 }