001: /*
002: * Library.java
003: *
004: *
005: * Copyright (c) 2003 Rimfaxe ApS (www.rimfaxe.com).
006: * All rights reserved.
007: *
008: * This package is written by Lars Andersen <lars@rimfaxe.com>
009: * and licensed by Rimfaxe ApS.
010: *
011: * Redistribution and use in source and binary forms, with or without
012: * modification, are permitted provided that the following conditions
013: * are met:
014: *
015: * 1. Redistributions of source code must retain the above copyright
016: * notice, this list of conditions and the following disclaimer.
017: *
018: * 2. Redistributions in binary form must reproduce the above copyright
019: * notice, this list of conditions and the following disclaimer in
020: * the documentation and/or other materials provided with the
021: * distribution.
022: *
023: * 3. The end-user documentation included with the redistribution, if
024: * any, must include the following acknowlegement:
025: * "This product includes software developed by Rimfaxe ApS
026: (www.rimfaxe.com)"
027: * Alternately, this acknowlegement may appear in the software itself,
028: * if and wherever such third-party acknowlegements normally appear.
029: *
030: * 4. The names "Rimfaxe", "Rimfaxe Software", "Lars Andersen" and
031: * "Rimfaxe WebServer" must not be used to endorse or promote products
032: * derived from this software without prior written permission. For written
033: * permission, please contact info@rimfaxe.com
034: *
035: * 5. Products derived from this software may not be called "Rimfaxe"
036: * nor may "Rimfaxe" appear in their names without prior written
037: * permission of the Rimfaxe ApS.
038: *
039: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
040: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
041: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
042: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
043: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
044: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
045: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
046: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
047: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
048: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
049: * SUCH DAMAGE.
050: *
051: */
052:
053: package com.rimfaxe.webserver.compiler;
054:
055: import java.util.*;
056:
057: /**
058: *
059: * @author Lars Andersen
060: */
061: public class Library {
062: public final int JAR_SOURCE = 0;
063: public final int CLASS_SOURCE = 1;
064: public final int JAVA_SOURCE = 2;
065: public final int OBJECT_SOURCE = 3;
066: public final int MIXED_SOURCE = 4;
067:
068: int source = 0;
069:
070: com.rimfaxe.webserver.Configuration configuration = com.rimfaxe.webserver.ObjectStore
071: .getConfiguration();
072:
073: String RWSlibrarydir = configuration.getHome() + "/lib";
074: String RWSshareddir = configuration.getHome() + "/shared";
075: String RWSextdir = configuration.getHome() + "/source";
076:
077: Vector inputfiles = new Vector();
078: Vector resourcefiles = new Vector();
079:
080: Vector compileoptions = new Vector();
081:
082: Vector linkoptions = new Vector();
083:
084: String inputdir = "/";
085: String outputdir = "/";
086: String outputfile = "libext.so";
087:
088: int optimizations = 0;
089: int opt_G = 1;
090:
091: String compiler = configuration.getGCJ();
092:
093: /** Creates a new instance of Library */
094: public Library() {
095: }
096:
097: public void addCompileOption(String opt) {
098: compileoptions.addElement(opt);
099: }
100:
101: public void addLinkOption(String opt) {
102: linkoptions.addElement(opt);
103: }
104:
105: public void setOutputFile(String val) {
106: outputfile = val;
107: }
108:
109: public void setOutputDir(String val) {
110: outputdir = val;
111: }
112:
113: public void setInputDir(String val) {
114: inputdir = val;
115: }
116:
117: public void setInputFiles(Vector val) {
118: this .inputfiles = val;
119: }
120:
121: public void setResourceFiles(Vector val) {
122: this .resourcefiles = val;
123: }
124:
125: public void setSource(int i) {
126: source = i;
127: }
128:
129: /**
130: * The jars is compiled to object files, and then linked into a dynamic so file.
131: * Link against RWS shared lib.
132: */
133: public void compile()
134: throws NativeCompilationException, NativeLinkException
135: {
136:
137: linkoptions.addElement("-shared");
138: linkoptions.addElement("-L"+RWSlibrarydir);
139: linkoptions.addElement("-L"+RWSshareddir);
140:
141: linkoptions.addElement("-lrws");
142:
143: Enumeration enum = configuration.getSharedLibs();
144: while (enum.hasMoreElements())
145: {
146: linkoptions.addElement("-l"+enum.nextElement());
147: }
148: //compileoptions.addElement("-fno-assume-compiled");
149:
150: compileoptions.addElement("--encoding="+com.rimfaxe.webserver.ObjectStore.getConfiguration().getJavaEncoding());
151: compileoptions.addElement("-O"+optimizations);
152: compileoptions.addElement("-I"+RWSextdir);
153: compileoptions.addElement("-c");
154: compileoptions.addElement("-g"+opt_G);
155:
156:
157: if (source==this .JAR_SOURCE)
158: {
159: compileJARS();
160: }
161: else if (source==this .JAVA_SOURCE)
162: {
163: compileJAVA();
164: }
165: else if (source==this .CLASS_SOURCE)
166: {
167: compileJAVA();
168: }
169:
170: }
171:
172: private void compileJARS()
173: throws NativeCompilationException, NativeLinkException
174: {
175: // compile each of the object files
176: Enumeration enum = inputfiles.elements();
177: while (enum.hasMoreElements())
178: {
179: String sourcefile = ""+enum.nextElement();
180:
181: StringBuffer buf = new StringBuffer();
182: buf.append(compiler+" ");
183: appendCompileOptions(buf);
184: appendClasspath(buf,inputfiles);
185:
186: buf.append(""+sourcefile+" ");
187: buf.append("-o "+sourcefile+".o");
188:
189: executeCommand(""+buf,"compile");
190: System.out.println("Library->compile {"+buf+"}");
191: }
192:
193: // Link phase
194:
195: StringBuffer buf = new StringBuffer();
196: buf.append(compiler+" ");
197: appendLinkOptions(buf);
198: buf.append("-o "+outputdir+"/"+outputfile+" ");
199:
200: enum = inputfiles.elements();
201: while (enum.hasMoreElements())
202: {
203: String objfile = ""+enum.nextElement()+".o";
204: buf.append(objfile);
205: }
206: executeCommand(""+buf,"link");
207: //System.out.println("Library->link {"+buf+"}");
208:
209: }
210:
211: private void compileJAVA()
212: throws NativeCompilationException, NativeLinkException
213: {
214: // compile each of the object files
215:
216: Enumeration enum = inputfiles.elements();
217: while (enum.hasMoreElements())
218: {
219: String sourcefile = ""+enum.nextElement();
220:
221: StringBuffer buf = new StringBuffer();
222: buf.append(compiler+" ");
223: appendCompileOptions(buf);
224:
225:
226: buf.append(""+sourcefile+" ");
227: buf.append("-o "+sourcefile+".o");
228:
229: java.io.File src = new java.io.File( sourcefile );
230: java.io.File obj = new java.io.File( sourcefile+".o" );
231:
232: if ( (obj.exists()) && (obj.lastModified()>src.lastModified()) )
233: {
234: //System.out.println("No need to compile "+sourcefile);
235: }
236: else
237: {
238: //System.out.println("Has to compile "+sourcefile);
239: executeCommand(""+buf, "compile");
240: //System.out.println("Library->compile {"+buf+"}");
241: }
242: }
243:
244: enum = resourcefiles.elements();
245: while (enum.hasMoreElements())
246: {
247: String resfile = ""+enum.nextElement();
248:
249: String packname = resfile.substring(inputdir.length()+1);
250: StringBuffer buf = new StringBuffer();
251: buf.append(compiler+" ");
252:
253:
254: buf.append("-c --resource "+packname+" "+resfile+" ");
255: buf.append("-o "+resfile+".o");
256:
257: java.io.File src = new java.io.File( resfile );
258: java.io.File obj = new java.io.File( resfile+".o" );
259:
260: if ( (obj.exists()) && (obj.lastModified()>src.lastModified()) )
261: {
262: //System.out.println("No need to compile "+sourcefile);
263: }
264: else
265: {
266: //System.out.println("Has to compile "+sourcefile);
267: executeCommand(""+buf,"compile");
268: //System.out.println("Library->compile {"+buf+"}");
269: }
270:
271:
272: }
273:
274:
275: // Link phase
276:
277: StringBuffer buf = new StringBuffer();
278: buf.append(compiler+" ");
279: appendLinkOptions(buf);
280: buf.append("-o "+outputdir+"/"+outputfile+" ");
281:
282: buf.append("\\\n");
283:
284: enum = inputfiles.elements();
285: while (enum.hasMoreElements())
286: {
287: String objfile = ""+enum.nextElement()+".o \\\n";
288: buf.append(objfile);
289: }
290:
291: enum = resourcefiles.elements();
292: while (enum.hasMoreElements())
293: {
294: String objfile = ""+enum.nextElement()+".o \\\n";
295: buf.append(objfile);
296: }
297: executeCommand(""+buf,"link");
298: //System.out.println("Library->link {"+buf+"}");
299:
300: }
301:
302: private void appendCompileOptions(StringBuffer buf)
303: {
304: Enumeration enum = compileoptions.elements();
305: while (enum.hasMoreElements())
306: {
307: buf.append(""+enum.nextElement()+" ");
308: }
309: }
310:
311: private void appendLinkOptions(StringBuffer buf)
312: {
313: Enumeration enum = linkoptions.elements();
314: while (enum.hasMoreElements())
315: {
316: buf.append(""+enum.nextElement()+" ");
317: }
318: }
319:
320: private void executeCommand(String cmd, String phase)
321: throws NativeCompilationException, NativeLinkException {
322: int exitcode = 0;
323: String res = "";
324: try {
325: System.out.print(".");
326: //System.out.println("run command -> \n\n"+cmd+"\n\n");
327:
328: Process p_gcj = null;
329:
330: if (phase.equalsIgnoreCase("link")) {
331: com.rimfaxe.util.RimfaxeFile file = new com.rimfaxe.util.RimfaxeFile(
332: "work/" + phase + ".sh");
333: file.rewrite("" + cmd);
334:
335: p_gcj = Runtime.getRuntime().exec(
336: "sh work/" + phase + ".sh");
337: } else {
338: p_gcj = Runtime.getRuntime().exec(cmd);
339: }
340:
341: java.io.InputStream is = p_gcj.getErrorStream();
342: com.rimfaxe.util.RimfaxeFile rf = new com.rimfaxe.util.RimfaxeFile(
343: "uu");
344:
345: exitcode = p_gcj.waitFor();
346:
347: res = rf.read(is);
348:
349: } catch (Exception e) {
350: // TODO
351: }
352:
353: if (exitcode != 0) {
354: StringBuffer error_msg = new StringBuffer();
355: error_msg.append("\n\nrun command -> \n\n" + cmd + "\n\n");
356: error_msg.append("Compile phase : " + phase + "\n");
357: error_msg
358: .append("Errors compiling sources, bailing out...\n");
359: error_msg.append("GCJ exitcode = " + exitcode + "\n");
360: error_msg.append("GCJ outputs : \n" + res + "\n");
361:
362: System.out.println("Compile phase : " + phase);
363:
364: if (phase.equalsIgnoreCase("compile"))
365: throw new NativeCompilationException("" + error_msg);
366: if (phase.equalsIgnoreCase("link"))
367: throw new NativeLinkException("" + error_msg);
368: }
369:
370: }
371:
372: private void appendClasspath(StringBuffer buf, Vector files)
373: {
374: buf.append("--classpath=");
375: Enumeration enum = files.elements();
376: while (enum.hasMoreElements())
377: {
378: String file = ""+enum.nextElement();
379: buf.append(file);
380: if (enum.hasMoreElements())
381: buf.append(":");
382: }
383: buf.append(" ");
384: }
385: }
|