001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jk.ant.compilers;
018:
019: import java.io.File;
020: import java.io.FileWriter;
021: import java.io.IOException;
022: import java.io.PrintWriter;
023: import java.util.Enumeration;
024: import java.util.Vector;
025:
026: import org.apache.jk.ant.JkData;
027: import org.apache.jk.ant.SoTask;
028: import org.apache.jk.ant.Source;
029: import org.apache.tools.ant.BuildException;
030: import org.apache.tools.ant.types.Commandline;
031: import org.apache.tools.ant.util.GlobPatternMapper;
032:
033: /**
034: * Link using MSVC Linker
035: *
036: * @author Costin Manolache
037: * @author Ignacio J. Ortega
038: * @author Mike Anderson
039: * @author Larry Isaacs
040: */
041: public class MsvcLinker extends LinkerAdapter {
042: SoTask so;
043: GlobPatternMapper co_mapper = new GlobPatternMapper();
044:
045: public MsvcLinker() {
046: so = this ;
047: co_mapper.setFrom("*.c");
048: co_mapper.setTo("*.obj");
049: }
050:
051: public void setSoTask(SoTask so) {
052: this .so = so;
053: so.setExtension(".dll");
054: so.duplicateTo(this );
055: project.setProperty("win32", "true");
056: if (optG)
057: project.setProperty("win32.debug", "true");
058: else
059: project.setProperty("win32.release", "true");
060: }
061:
062: public void execute() throws BuildException {
063: findSourceFiles();
064: link(this .srcList);
065: }
066:
067: public boolean link(Vector srcList) throws BuildException {
068: Commandline cmd = new Commandline();
069: File linkOpt = new File(buildDir, "link.opt");
070: File linkDef = new File(buildDir, "link.def");
071:
072: String libtool = project.getProperty("build.compiler.ld");
073: if (libtool == null)
074: libtool = "link";
075:
076: cmd.setExecutable(libtool);
077:
078: // All .obj files must be included
079: project.log("Linking " + buildDir + "/" + soFile + ".dll");
080:
081: // create a .opt file and a .def file
082: PrintWriter linkOptPw = null;
083: PrintWriter linkDefPw = null;
084: try {
085: linkOptPw = new PrintWriter(new FileWriter(linkOpt));
086: linkDefPw = new PrintWriter(new FileWriter(linkDef));
087:
088: // write the imports to link with to the .opt file
089: linkOptPw.print(" ");
090: Enumeration imps = imports.elements();
091: while (imps.hasMoreElements()) {
092: JkData imp = (JkData) imps.nextElement();
093: String name = imp.getValue();
094: if (name == null)
095: continue;
096: linkOptPw.print(name + " ");
097: }
098:
099: // write the link flags out
100:
101: linkOptPw.print("/machine:I386 ");
102: linkOptPw.print("/out:" + soFile + ".dll ");
103: linkOptPw.print("/nologo ");
104: linkOptPw.print("/dll ");
105: linkOptPw.print("/incremental:no ");
106:
107: // write out any additional link options
108: Enumeration opts = linkOpts.elements();
109: while (opts.hasMoreElements()) {
110: JkData opt = (JkData) opts.nextElement();
111: String option = opt.getValue();
112: if (option == null)
113: continue;
114: linkOptPw.println(option);
115: }
116:
117: // add debug information in if requested
118: if (optG) {
119: linkOptPw.print("/debug ");
120: }
121: // def file
122: linkOptPw.println("/def:link.def");
123: // write the objects to link with to the .opt file
124: for (int i = 0; i < srcList.size(); i++) {
125: Source source = (Source) srcList.elementAt(i);
126: File srcF = source.getFile();
127: String name = srcF.getName();
128: String targetNA[] = co_mapper.mapFileName(name);
129: if (targetNA != null)
130: linkOptPw.println(targetNA[0]);
131: }
132: // Write the resources to link to .opt file
133: Enumeration ress = resources.elements();
134: while (ress.hasMoreElements()) {
135: JkData res = (JkData) ress.nextElement();
136: String name = res.getValue();
137: if (name == null)
138: continue;
139: linkOptPw.println(name);
140: }
141:
142: // Write the library name to the def file
143: linkDefPw.println("LIBRARY\t\"" + soFile + "\"");
144:
145: // write the exported symbols to the .def file
146: Enumeration exps = exports.elements();
147: if (exps.hasMoreElements()) {
148: linkDefPw.println("EXPORTS");
149: while (exps.hasMoreElements()) {
150: JkData exp = (JkData) exps.nextElement();
151: String name = exp.getValue();
152: if (name == null)
153: continue;
154: linkDefPw.println("\t" + name);
155: }
156: }
157: } catch (IOException ioe) {
158: System.out.println("Caught IOException");
159: } finally {
160: if (linkOptPw != null) {
161: linkOptPw.close();
162: }
163:
164: if (linkDefPw != null) {
165: linkDefPw.close();
166: }
167: }
168:
169: cmd.createArgument().setValue("@link.opt");
170: int result = execute(cmd);
171: if (result != 0) {
172: log("Link failed " + result);
173: log("Command:" + cmd.toString());
174: log("Output:");
175: if (outputstream != null)
176: log(outputstream.toString());
177: log("StdErr:");
178: if (errorstream != null)
179: log(errorstream.toString());
180:
181: throw new BuildException("Link failed " + soFile);
182: }
183: // linkOpt.delete();
184: // linkDef.delete();
185: closeStreamHandler();
186: return true;
187: }
188: }
|