KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jk > ant > SoTask


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jk.ant;
18
19 import java.io.ByteArrayOutputStream JavaDoc;
20 import java.io.File JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.io.PrintStream JavaDoc;
23 import java.util.Enumeration JavaDoc;
24 import java.util.Vector JavaDoc;
25
26 import org.apache.jk.ant.compilers.CcCompiler;
27 import org.apache.jk.ant.compilers.CompilerAdapter;
28 import org.apache.jk.ant.compilers.GcjCompiler;
29 import org.apache.jk.ant.compilers.GcjLinker;
30 import org.apache.jk.ant.compilers.LibtoolCompiler;
31 import org.apache.jk.ant.compilers.LibtoolLinker;
32 import org.apache.jk.ant.compilers.LinkerAdapter;
33 import org.apache.jk.ant.compilers.MsvcCompiler;
34 import org.apache.jk.ant.compilers.MsvcLinker;
35 import org.apache.jk.ant.compilers.MwccCompiler;
36 import org.apache.jk.ant.compilers.MwldLinker;
37 import org.apache.tools.ant.BuildException;
38 import org.apache.tools.ant.DirectoryScanner;
39 import org.apache.tools.ant.Task;
40 import org.apache.tools.ant.taskdefs.Execute;
41 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
42 import org.apache.tools.ant.taskdefs.PumpStreamHandler;
43 import org.apache.tools.ant.types.Commandline;
44 import org.apache.tools.ant.types.FileSet;
45 import org.apache.tools.ant.types.Path;
46 import org.apache.tools.ant.types.PatternSet;
47
48 /** Global properties
49
50     Same idea as in javac, some user .properties will set the local preferences,
51     including machine-specific. If one is not specified we'll guess it. The
52     build file will be clean.
53
54     TODO: can we get configure to generate such a file ?
55
56     build.native.cc=gcc
57     # Path to libtool ( used as a backup )
58     build.native.libtool=
59     # Platform-specific flags for compilation.
60     build.native.extra_cflags=
61 */

62 /* XXX add a optional "compiler" attribute
63     to not guess the compiler based on the executable name
64     present in a global property.
65
66 */

67
68
69 /**
70  * Task to generate a .so file, similar with ( or using ) libtool.
71  * I hate libtool, so long term I would like to replace most of it
72  * with decent java code. Short term it'll just use libtool and
73  * hide some of the ugliness.
74  *
75  * arguments:
76  * <ul>
77  * <li>source
78  * </ul>
79  *
80  * <p>
81  *
82  * @author Costin Manolache
83  * @author Mike Anderson
84  * @author Ignacio J. Ortega
85  */

86 public class SoTask extends Task {
87     protected String JavaDoc apxs;
88     // or FileSet ?
89
protected Vector JavaDoc src; //[FileSet]
90
protected PatternSet includes;
91     protected Path depends;
92     protected Path libs;
93     protected String JavaDoc module;
94     protected String JavaDoc soFile;
95     protected String JavaDoc soExt = ".so";
96     protected String JavaDoc cflags;
97     protected File JavaDoc buildDir;
98     protected int debug;
99
100     protected boolean optG=true;
101     protected boolean optWgcc=true;
102     protected boolean optimize=false;
103     protected boolean profile=false;
104     protected Vector JavaDoc defines = new Vector JavaDoc();
105     protected Vector JavaDoc imports = new Vector JavaDoc(); // used by the NetWare, win32 linkers
106
protected Vector JavaDoc exports = new Vector JavaDoc(); // used by the NetWare, win32 linkers
107
protected Vector JavaDoc modules = new Vector JavaDoc(); // used by the NetWare linker
108
protected Vector JavaDoc linkOpts = new Vector JavaDoc(); // used by the NetWare, win32 linkers
109
protected Vector JavaDoc altSoFiles = new Vector JavaDoc(); // used by the NetWare linker
110
protected Vector JavaDoc resources = new Vector JavaDoc(); // used by the win32 linker
111

112     // Computed fields
113
// protected Vector compileList; // [Source]
114
protected Vector JavaDoc srcList=new Vector JavaDoc();
115     protected CompilerAdapter compiler;
116     // protected GlobPatternMapper co_mapper;
117

118     public SoTask() {};
119
120     // Hack to allow individual compilers/linkers to work
121
// as regular Tasks, independnetly.
122
public void duplicateTo(SoTask so) {
123         // This will act as a proxy for the child task
124
so.project=project;
125         so.target=target;
126         so.location=location;
127         so.taskName=taskName;
128         so.taskType=taskType;
129         
130         so.apxs=apxs;
131         so.src=src;
132         so.includes=includes;
133         so.depends=depends;
134         so.libs=libs;
135         so.module=module;
136         so.soFile=soFile;
137         so.soExt=soExt;
138         so.cflags=cflags;
139         so.buildDir=buildDir;
140         so.debug=debug;
141         so.optG=optG;
142         so.optWgcc=optWgcc;
143         so.optimize=optimize;
144         so.profile=profile;
145         so.defines=defines;
146         so.imports=imports;
147         so.exports=exports;
148         so.resources=resources;
149         so.modules=modules;
150         so.linkOpts=linkOpts;
151         so.srcList=srcList;
152         // so.compileList=compileList;
153
so.compiler=compiler;
154         // so.co_mapper=co_mapper;
155
so.altSoFiles=altSoFiles;
156     }
157
158     /** @deprecated use setTarget
159      */

160     public void setSoFile(String JavaDoc s ) {
161         soFile=s;
162     }
163
164     /** Add debug information
165      */

166     public void setDebug(boolean b) {
167         optG=b;
168     }
169
170     /** Add debug information
171      */

172     public void setOptimize(boolean b) {
173         optimize=b;
174     }
175
176     /** Add profiling information
177      */

178     public void setProfile(boolean b) {
179         profile=b;
180     }
181
182     /** Gcc warnings
183      */

184     public void setGccWarn(boolean b) {
185         optWgcc=b;
186     }
187
188     /** Debug the <so> task
189      */

190     public void setTaskDebug(int i) {
191         debug=i;
192     }
193
194     /** Add a -D option. Note that each define has
195      * an if/unless attribute
196      */

197     public void addDef(Def var ) {
198         var.setProject( project );
199         defines.addElement(var);
200     }
201
202     /**
203      * Add an import file/symbol for NetWare or win32 platform
204      *
205      *
206      */

207     public void addImport(JkData imp) {
208         imp.setProject( project );
209         imports.add(imp);
210     }
211
212     /**
213      * Add an export file/symbol for NetWare or win32 platform
214      *
215      *
216      */

217     public void addExport(JkData exp) {
218         exp.setProject( project );
219         exports.add(exp);
220     }
221
222     /**
223      * Add an resource file on win32 platform
224      *
225      *
226      */

227     public void addResource(JkData res) {
228         res.setProject( project );
229         resources.add(res);
230     }
231
232     /**
233      * Add a link option for NetWare or win32 platform
234      *
235      *
236      */

237     public void addLinkOpt(JkData option) {
238         option.setProject( project );
239         linkOpts.add(option);
240     }
241
242     /**
243      * Add an NLMModule dependancy
244      *
245      *
246      */

247     public void addNLMModule(JkData module) {
248         module.setProject( project );
249         modules.add(module);
250     }
251
252     /**
253      * Add an alternate target since some platforms (NetWare) have file name
254      * limitations.
255      *
256      */

257     public void addAltSoFile(JkData altSo) {
258         altSo.setProject( project );
259         altSoFiles.add(altSo);
260     }
261
262     /** Set the target for this compilation. Don't include any
263      * directory or suffix ( not sure about prefix - we may want
264      * to add lib automatically for unix, and nothing on win/etc ? ).
265      */

266     public void setTarget(String JavaDoc s ) {
267         soFile=s;
268     }
269
270     /** Set the extension for the target. This will depend on the platform
271      * we are compiling for.
272      */

273     public void setExtension(String JavaDoc s ) {
274         soExt=s;
275     }
276
277     /** Directory where intermediary objects will be
278      * generated
279      */

280     public void setBuildDir( File JavaDoc s ) {
281         buildDir=s;
282     }
283
284     public void setCflags(String JavaDoc s ) {
285         cflags=s;
286     }
287     
288     /** Directory where the .so file will be generated
289      */

290     public void setSoDir( String JavaDoc s ) {
291         
292     }
293
294     public void addJniConfig( JniConfig jniCfg ) {
295
296     }
297
298     public void addApacheConfig( ApacheConfig apacheCfg ) {
299
300     }
301     
302     
303     /**
304      * Source files ( .c )
305      *
306      * @return a nested src element.
307      */

308     public void addSrc(FileSet fl) {
309         if( SRC==null ) SRC=new Vector JavaDoc();
310         src.addElement(fl);
311     }
312
313     /**
314      * Include files
315      */

316     public PatternSet createIncludes() {
317         includes=new PatternSet(); //Path(project);
318
return includes;
319     }
320
321     /**
322      * General dependencies. If any of the files is modified
323      * ( i.e. is newer than the oldest .o ) we'll recompile everything.
324      *
325      * This can be used for headers ( until we add support for makedepend)
326      * or any important file that could invalidate the build.
327      * Another example is checking httpd or apxs ( if a new version
328      * was installed, maybe some flags or symbols changed )
329      */

330     public Path createDepends() {
331         depends=new Path(project);
332         return depends;
333     }
334
335     /**
336      * Libraries ( .a, .so or .dll ) files to link to.
337      */

338     public Path createLibs() {
339         libs=new Path(project);
340         return libs;
341     }
342     
343     
344     /**
345      * The name of the target file.
346      * (XXX including extension - this should be automatically added )
347      */

348     public void setModule(String JavaDoc modName) {
349         this.module = modName; // Should be this ?
350
}
351
352     // XXX Add specific code for Netware, Windows and platforms where libtool
353
// is problematic
354

355     // XXX Add specific code for Linux and platforms where things are
356
// clean, libtool should be just a fallback.
357
public void execute() throws BuildException {
358         compiler=findCompilerAdapter();
359         // co_mapper=compiler.getOMapper();
360
LinkerAdapter linker=findLinkerAdapter();
361
362         if( soFile==null )
363             throw new BuildException("No target ( " + soExt + " file )");
364         if (src == null)
365             throw new BuildException("No source files");
366
367         // XXX makedepend-type dependencies - how ??
368
// We could generate a dummy Makefile and parse the content...
369
findSourceFiles();
370
371         // Copy all settings into compiler
372
this.duplicateTo(compiler);
373         compiler.compile( srcList );
374
375         // XXX move this checking to linker
376
File JavaDoc soTarget=new File JavaDoc( buildDir, soFile + soExt );
377         if( compiler.getCompiledFiles().size() == 0 && soTarget.exists()) {
378             // No dependency, no need to relink
379
return;
380         }
381
382         this.duplicateTo(linker);
383         linker.link(srcList);
384     }
385
386     public CompilerAdapter findCompilerAdapter() {
387         CompilerAdapter compilerAdapter;
388         String JavaDoc cc;
389         cc=project.getProperty("build.compiler.cc");
390         if( cc!=null ) {
391             if( "cc".equals( cc ) ) {
392                 compilerAdapter=new CcCompiler();
393                 compilerAdapter.setSoTask( this );
394                 return compilerAdapter;
395             }
396             if( "gcj".equals( cc ) ) {
397                 compilerAdapter=new GcjCompiler();
398                 compilerAdapter.setSoTask( this );
399                 return compilerAdapter;
400             }
401             if( cc.indexOf("mwccnlm") != -1 ) {
402                 compilerAdapter=new MwccCompiler();
403                 compilerAdapter.setSoTask( this );
404                 return compilerAdapter;
405             }
406             if( cc.indexOf("cl") != -1 ) {
407                 compilerAdapter=new MsvcCompiler();
408                 compilerAdapter.setSoTask( this );
409                 return compilerAdapter;
410             }
411         }
412         
413         compilerAdapter=new LibtoolCompiler();
414         compilerAdapter.setSoTask( this );
415         return compilerAdapter;
416    }
417
418     public LinkerAdapter findLinkerAdapter() {
419         LinkerAdapter linkerAdapter;
420         String JavaDoc ld=project.getProperty("build.compiler.ld");
421         if( ld!=null ) {
422             if( ld.indexOf("mwldnlm") != -1 ) {
423                 linkerAdapter=new MwldLinker();
424                 linkerAdapter.setSoTask( this );
425                 return linkerAdapter;
426             }
427             if( ld.indexOf("link") != -1 ) {
428                 linkerAdapter=new MsvcLinker();
429                 linkerAdapter.setSoTask( this );
430                 return linkerAdapter;
431             }
432             // if( "ld".equals( cc ) ) {
433
// linkerAdapter=new LdLinker();
434
// linkerAdapter.setSoTask( this );
435
// return cc;
436
// }
437
}
438
439         String JavaDoc cc=project.getProperty("build.compiler.cc");
440         if( "gcj".equals( cc ) ) {
441             linkerAdapter=new GcjLinker();
442             linkerAdapter.setSoTask( this );
443             return linkerAdapter;
444         }
445
446         
447         linkerAdapter=new LibtoolLinker();
448         linkerAdapter.setSoTask( this );
449         return linkerAdapter;
450    }
451
452     /** Find all source files declared with <src> elements
453      */

454     public void findSourceFiles() {
455         if (buildDir == null) buildDir = project.getBaseDir();
456
457         Enumeration JavaDoc e=src.elements();
458         while( e.hasMoreElements() ) {
459             FileSet fs=(FileSet)e.nextElement();
460             DirectoryScanner ds=fs.getDirectoryScanner( project );
461             String JavaDoc localList[]= ds.getIncludedFiles();
462             if (localList.length == 0)
463                 throw new BuildException("No source files ");
464             for( int i=0; i<localList.length; i++ ) {
465                 srcList.addElement( new Source( fs.getDir(project), localList[i]));
466             }
467         }
468     }
469  
470     /** If any file declared in <depend> element has changed, we'll do
471         a full rebuild.
472     */

473     public boolean checkDepend(long oldestO, File JavaDoc oldestOFile) {
474         if( depends==null )
475             return false;
476         String JavaDoc dependsA[]=depends.list();
477         for( int i=0; i< dependsA.length; i++ ) {
478             File JavaDoc f=new File JavaDoc( dependsA[i] );
479             if( ! f.exists() ) {
480                 log("Depend not found " + f );
481                 return true;
482             }
483             if( f.lastModified() > oldestO ) {
484                 log( "Depend " + f + " newer than " + oldestOFile );
485                 return true;
486             }
487         }
488         return false;
489     }
490     
491     // ==================== Execution utils ====================
492

493     protected ExecuteStreamHandler streamhandler = null;
494     protected ByteArrayOutputStream JavaDoc outputstream = null;
495     protected ByteArrayOutputStream JavaDoc errorstream = null;
496
497     public int execute( Commandline cmd ) throws BuildException
498     {
499         createStreamHandler();
500         Execute exe = new Execute(streamhandler, null);
501         exe.setAntRun(project);
502
503         exe.setWorkingDirectory(buildDir);
504
505         exe.setCommandline(cmd.getCommandline());
506         int result=0;
507         try {
508             result=exe.execute();
509         } catch (IOException JavaDoc e) {
510             throw new BuildException(e, location);
511         }
512         return result;
513     }
514
515     public void createStreamHandler() throws BuildException {
516         // try {
517
outputstream= new ByteArrayOutputStream JavaDoc();
518         errorstream = new ByteArrayOutputStream JavaDoc();
519         
520         streamhandler =
521             new PumpStreamHandler(new PrintStream JavaDoc(outputstream),
522                                   new PrintStream JavaDoc(errorstream));
523         // } catch (IOException e) {
524
// throw new BuildException(e,location);
525
// }
526
}
527
528     public void closeStreamHandler() {
529         try {
530             if (outputstream != null)
531                 outputstream.close();
532             if (errorstream != null)
533                 errorstream.close();
534             outputstream=null;
535             errorstream=null;
536         } catch (IOException JavaDoc e) {}
537     }
538 }
539
540
Popular Tags