3 * Copyright 2002-2004 The Ant-Contrib project
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package net
.sf
.antcontrib
.cpptasks
.borland
;
19 import java
.io
.IOException
;
20 import java
.util
.Enumeration
;
21 import java
.util
.Vector
;
23 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
24 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinker
;
25 import net
.sf
.antcontrib
.cpptasks
.compiler
.CommandLineLinkerConfiguration
;
26 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
27 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
28 import net
.sf
.antcontrib
.cpptasks
.types
.LibraryTypeEnum
;
31 * Adapter for the Borland(r) ilink32 linker
35 public final class BorlandLinker
extends CommandLineLinker
{
36 private static final BorlandLinker dllLinker
= new BorlandLinker(".dll");
37 private static final BorlandLinker instance
= new BorlandLinker(".exe");
38 public static BorlandLinker
getInstance() {
41 private BorlandLinker(String outputSuffix
) {
42 super("ilink32", "-r", new String
[]{".obj", ".lib", ".res"},
43 new String
[]{".map", ".pdb", ".lnk"}, outputSuffix
, false, null);
45 protected void addBase(long base
, Vector args
) {
47 String baseAddr
= Long
.toHexString(base
);
48 args
.addElement("-b:" + baseAddr
);
51 protected void addFixed(Boolean fixed
, Vector args
) {
53 protected void addImpliedArgs(boolean debug
, LinkType linkType
, Vector args
, Boolean defaultflag
) {
54 if (linkType
.isExecutable()) {
55 if (linkType
.isSubsystemConsole()) {
56 args
.addElement("/ap");
58 if (linkType
.isSubsystemGUI()) {
59 args
.addElement("/Tpe");
63 if (linkType
.isSharedLibrary()) {
64 args
.addElement("/Tpd");
65 args
.addElement("/Gi");
68 protected void addIncremental(boolean incremental
, Vector args
) {
70 protected void addMap(boolean map
, Vector args
) {
72 args
.addElement("-x");
75 protected void addStack(int stack
, Vector args
) {
77 String stackStr
= Integer
.toHexString(stack
);
78 args
.addElement("-S:" + stackStr
);
82 * @see net.sf.antcontrib.cpptasks.compiler.CommandLineLinker#addEntry(int, java.util.Vector)
84 protected void addEntry(String entry
, Vector args
) {
87 public String
getCommandFileSwitch(String commandFile
) {
88 return "@" + commandFile
;
90 public String
getIdentifier() {
91 return "Borland Linker";
93 public File
[] getLibraryPath() {
94 return BorlandProcessor
.getEnvironmentPath("ilink32", 'L',
95 new String
[]{"..\\lib"});
97 public String
[] getLibraryPatterns(String
[] libnames
, LibraryTypeEnum libType
) {
98 return BorlandProcessor
.getLibraryPatterns(libnames
, libType
);
100 public Linker
getLinker(LinkType type
) {
101 if (type
.isStaticLibrary()) {
102 return BorlandLibrarian
.getInstance();
104 if (type
.isSharedLibrary()) {
109 public int getMaximumCommandLength() {
112 public String
[] getOutputFileSwitch(String outFile
) {
113 return BorlandProcessor
.getOutputFileSwitch(outFile
);
115 protected String
getStartupObject(LinkType linkType
) {
116 if (linkType
.isSharedLibrary()) {
119 if (linkType
.isSubsystemGUI()) {
122 if (linkType
.isSubsystemConsole()) {
127 public boolean isCaseSensitive() {
128 return BorlandProcessor
.isCaseSensitive();
131 * Prepares argument list for exec command.
136 * linker input files (.obj, .o, .res)
139 * @return arguments for runTask
141 protected String
[] prepareArguments(
145 String
[] sourceFiles
,
146 CommandLineLinkerConfiguration config
) {
147 String
[] preargs
= config
.getPreArguments();
148 String
[] endargs
= config
.getEndArguments();
149 Vector execArgs
= new Vector(preargs
.length
+ endargs
.length
+ 10
150 + sourceFiles
.length
);
151 execArgs
.addElement(this.getCommand());
152 for (int i
= 0; i
< preargs
.length
; i
++) {
153 execArgs
.addElement(preargs
[i
]);
155 for (int i
= 0; i
< endargs
.length
; i
++) {
156 execArgs
.addElement(endargs
[i
]);
159 // see if the input files have any known startup obj files
161 String startup
= null;
162 for (int i
= 0; i
< sourceFiles
.length
; i
++) {
163 String filename
= new File(sourceFiles
[i
]).getName().toLowerCase();
164 if (startup
!= null && filename
.substring(0, 2).equals("c0")
165 && filename
.substring(3, 5).equals("32")
166 && filename
.substring(filename
.length() - 4).equals(".obj")) {
167 startup
= sourceFiles
[i
];
171 // c0w32.obj, c0x32.obj or c0d32.obj depending on
173 if (startup
== null) {
174 startup
= config
.getStartupObject();
176 execArgs
.addElement(startup
);
177 Vector resFiles
= new Vector();
178 Vector libFiles
= new Vector();
179 String defFile
= null;
180 StringBuffer buf
= new StringBuffer();
181 for (int i
= 0; i
< sourceFiles
.length
; i
++) {
182 String last4
= sourceFiles
[i
]
183 .substring(sourceFiles
[i
].length() - 4).toLowerCase();
184 if (last4
.equals(".def")) {
185 defFile
= quoteFilename(buf
, sourceFiles
[i
]);
187 if (last4
.equals(".res")) {
188 resFiles
.addElement(quoteFilename(buf
, sourceFiles
[i
]));
190 if (last4
.equals(".lib")) {
191 libFiles
.addElement(quoteFilename(buf
, sourceFiles
[i
]));
193 execArgs
.addElement(quoteFilename(buf
, sourceFiles
[i
]));
201 String outputFileName
= new File(outputDir
, outputName
).toString();
202 execArgs
.addElement("," + quoteFilename(buf
, outputFileName
));
203 if (config
.getMap()) {
204 int lastPeriod
= outputFileName
.lastIndexOf('.');
206 if (lastPeriod
< outputFileName
.length() - 4) {
207 mapName
= outputFileName
+ ".map";
209 mapName
= outputFileName
.substring(0, lastPeriod
) + ".map";
211 execArgs
.addElement("," + quoteFilename(buf
, mapName
) + ",");
213 execArgs
.addElement(",,");
216 // add all the libraries
218 Enumeration libEnum
= libFiles
.elements();
219 boolean hasImport32
= false;
220 boolean hasCw32
= false;
221 while (libEnum
.hasMoreElements()) {
222 String libName
= (String
) libEnum
.nextElement();
223 if (libName
.equalsIgnoreCase("import32.lib")) {
226 if (libName
.equalsIgnoreCase("cw32.lib")) {
229 execArgs
.addElement(quoteFilename(buf
, libName
));
232 execArgs
.addElement(quoteFilename(buf
, "cw32.lib"));
235 execArgs
.addElement(quoteFilename(buf
, "import32.lib"));
237 if (defFile
== null) {
238 execArgs
.addElement(",,");
240 execArgs
.addElement("," + quoteFilename(buf
, defFile
) + ",");
242 Enumeration resEnum
= resFiles
.elements();
243 while (resEnum
.hasMoreElements()) {
244 String resName
= (String
) resEnum
.nextElement();
245 execArgs
.addElement(quoteFilename(buf
, resName
));
247 String
[] execArguments
= new String
[execArgs
.size()];
248 execArgs
.copyInto(execArguments
);
249 return execArguments
;
252 * Prepares argument list to execute the linker using a response file.
257 * output of prepareArguments
258 * @return arguments for runTask
260 protected String
[] prepareResponseFile(File outputFile
, String
[] args
)
262 return BorlandProcessor
.prepareResponseFile(outputFile
, args
, " + \n");