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.borland;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Enumeration;
25 import java.util.Vector;
26
27 import com.github.maven_nar.cpptasks.CCTask;
28 import com.github.maven_nar.cpptasks.TargetMatcher;
29 import com.github.maven_nar.cpptasks.VersionInfo;
30 import com.github.maven_nar.cpptasks.compiler.CommandLineLinker;
31 import com.github.maven_nar.cpptasks.compiler.CommandLineLinkerConfiguration;
32 import com.github.maven_nar.cpptasks.compiler.LinkType;
33 import com.github.maven_nar.cpptasks.compiler.Linker;
34 import com.github.maven_nar.cpptasks.platforms.WindowsPlatform;
35 import com.github.maven_nar.cpptasks.types.LibraryTypeEnum;
36
37
38
39
40
41
42 public final class BorlandLinker extends CommandLineLinker {
43 private static final BorlandLinker dllLinker = new BorlandLinker(".dll");
44 private static final BorlandLinker instance = new BorlandLinker(".exe");
45
46 public static BorlandLinker getInstance() {
47 return instance;
48 }
49
50 private BorlandLinker(final String outputSuffix) {
51 super("ilink32", "-r", new String[] {
52 ".obj", ".lib", ".res"
53 }, new String[] {
54 ".map", ".pdb", ".lnk"
55 }, outputSuffix, false, null);
56 }
57
58 protected void addBase(final long base, final Vector<String> args) {
59 if (base >= 0) {
60 final String baseAddr = Long.toHexString(base);
61 args.addElement("-b:" + baseAddr);
62 }
63 }
64
65 protected void addEntry(final String entry, final Vector<String> args) {
66 }
67
68 protected void addFixed(final Boolean fixed, final Vector<String> args) {
69 }
70
71 protected void addImpliedArgs(final boolean debug, final LinkType linkType, final Vector<String> args) {
72 if (linkType.isExecutable()) {
73 if (linkType.isSubsystemConsole()) {
74 args.addElement("/ap");
75 } else {
76 if (linkType.isSubsystemGUI()) {
77 args.addElement("/Tpe");
78 }
79 }
80 }
81 if (linkType.isSharedLibrary()) {
82 args.addElement("/Tpd");
83 args.addElement("/Gi");
84 }
85 if (debug) {
86 args.addElement("-v");
87 }
88 }
89
90 protected void addIncremental(final boolean incremental, final Vector<String> args) {
91 }
92
93 protected void addMap(final boolean map, final Vector<String> args) {
94 if (!map) {
95 args.addElement("-x");
96 }
97 }
98
99 protected void addStack(final int stack, final Vector<String> args) {
100 if (stack >= 0) {
101 final String stackStr = Integer.toHexString(stack);
102 args.addElement("-S:" + stackStr);
103 }
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 @Override
124 public void addVersionFiles(final VersionInfo versionInfo, final LinkType linkType, final File outputFile,
125 final boolean isDebug, final File objDir, final TargetMatcher matcher) throws IOException {
126 WindowsPlatform.addVersionFiles(versionInfo, linkType, outputFile, isDebug, objDir, matcher);
127 }
128
129 @Override
130 public String getCommandFileSwitch(final String commandFile) {
131 return "@" + commandFile;
132 }
133
134 @Override
135 public String getIdentifier() {
136 return "Borland Linker";
137 }
138
139 @Override
140 public File[] getLibraryPath() {
141 return BorlandProcessor.getEnvironmentPath("ilink32", 'L', new String[] {
142 "..\\lib"
143 });
144 }
145
146 @Override
147 public String[] getLibraryPatterns(final String[] libnames, final LibraryTypeEnum libType) {
148 return BorlandProcessor.getLibraryPatterns(libnames, libType);
149 }
150
151 @Override
152 public Linker getLinker(final LinkType type) {
153 if (type.isStaticLibrary()) {
154 return BorlandLibrarian.getInstance();
155 }
156 if (type.isSharedLibrary()) {
157 return dllLinker;
158 }
159 return instance;
160 }
161
162 @Override
163 public int getMaximumCommandLength() {
164 return 1024;
165 }
166
167 @Override
168 public String[] getOutputFileSwitch(final String outFile) {
169 return BorlandProcessor.getOutputFileSwitch(outFile);
170 }
171
172 @Override
173 protected String getStartupObject(final LinkType linkType) {
174 if (linkType.isSharedLibrary()) {
175 return "c0d32.obj";
176 }
177 if (linkType.isSubsystemGUI()) {
178 return "c0w32.obj";
179 }
180 if (linkType.isSubsystemConsole()) {
181 return "c0x32.obj";
182 }
183 return null;
184 }
185
186 @Override
187 public boolean isCaseSensitive() {
188 return BorlandProcessor.isCaseSensitive();
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 @Override
205 protected String[] prepareArguments(final CCTask task, final String outputDir, final String outputName,
206 final String[] sourceFiles, final CommandLineLinkerConfiguration config) {
207 final String[] preargs = config.getPreArguments();
208 final String[] endargs = config.getEndArguments();
209 final Vector<String> execArgs = new Vector<>(preargs.length + endargs.length + 10 + sourceFiles.length);
210 execArgs.addElement(this.getCommand());
211 for (final String prearg : preargs) {
212 execArgs.addElement(prearg);
213 }
214 for (final String endarg : endargs) {
215 execArgs.addElement(endarg);
216 }
217
218
219
220 String startup = null;
221 for (final String sourceFile : sourceFiles) {
222 final String filename = new File(sourceFile).getName().toLowerCase();
223 if (startup != null && filename.substring(0, 2).equals("c0") && filename.substring(3, 5).equals("32")
224 && filename.substring(filename.length() - 4).equals(".obj")) {
225 startup = sourceFile;
226 }
227 }
228
229
230
231 if (startup == null) {
232 startup = config.getStartupObject();
233 }
234 execArgs.addElement(startup);
235 final Vector<String> resFiles = new Vector<>();
236 final Vector<String> libFiles = new Vector<>();
237 String defFile = null;
238 final StringBuffer buf = new StringBuffer();
239 for (final String sourceFile : sourceFiles) {
240 final String last4 = sourceFile.substring(sourceFile.length() - 4).toLowerCase();
241 if (last4.equals(".def")) {
242 defFile = quoteFilename(buf, sourceFile);
243 } else {
244 if (last4.equals(".res")) {
245 resFiles.addElement(quoteFilename(buf, sourceFile));
246 } else {
247 if (last4.equals(".lib")) {
248 libFiles.addElement(quoteFilename(buf, sourceFile));
249 } else {
250 execArgs.addElement(quoteFilename(buf, sourceFile));
251 }
252 }
253 }
254 }
255
256
257
258 final String outputFileName = new File(outputDir, outputName).toString();
259 execArgs.addElement("," + quoteFilename(buf, outputFileName));
260 if (config.getMap()) {
261 final int lastPeriod = outputFileName.lastIndexOf('.');
262 String mapName;
263 if (lastPeriod < outputFileName.length() - 4) {
264 mapName = outputFileName + ".map";
265 } else {
266 mapName = outputFileName.substring(0, lastPeriod) + ".map";
267 }
268 execArgs.addElement("," + quoteFilename(buf, mapName) + ",");
269 } else {
270 execArgs.addElement(",,");
271 }
272
273
274
275 final Enumeration<String> libEnum = libFiles.elements();
276 boolean hasImport32 = false;
277 final boolean hasCw32 = false;
278 while (libEnum.hasMoreElements()) {
279 final String libName = libEnum.nextElement();
280 if (libName.equalsIgnoreCase("import32.lib")) {
281 hasImport32 = true;
282 }
283 if (libName.equalsIgnoreCase("cw32.lib")) {
284 hasImport32 = true;
285 }
286 execArgs.addElement(quoteFilename(buf, libName));
287 }
288 if (!hasCw32) {
289 execArgs.addElement(quoteFilename(buf, "cw32.lib"));
290 }
291 if (!hasImport32) {
292 execArgs.addElement(quoteFilename(buf, "import32.lib"));
293 }
294 if (defFile == null) {
295 execArgs.addElement(",,");
296 } else {
297 execArgs.addElement("," + quoteFilename(buf, defFile) + ",");
298 }
299 final Enumeration<String> resEnum = resFiles.elements();
300 while (resEnum.hasMoreElements()) {
301 final String resName = resEnum.nextElement();
302 execArgs.addElement(quoteFilename(buf, resName));
303 }
304 final String[] execArguments = new String[execArgs.size()];
305 execArgs.copyInto(execArguments);
306 return execArguments;
307 }
308
309
310
311
312
313
314
315
316
317
318 @Override
319 protected String[] prepareResponseFile(final File outputFile, final String[] args) throws IOException {
320 final String cmdargs[] = BorlandProcessor.prepareResponseFile(outputFile, args, " + \n");
321 cmdargs[cmdargs.length - 1] = getCommandFileSwitch(cmdargs[cmdargs.length - 1]);
322 return cmdargs;
323 }
324
325 }