View Javadoc

1   /*
2    * #%L
3    * Native ARchive plugin for Maven
4    * %%
5    * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   * http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.github.maven_nar.cpptasks;
21  
22  import java.util.Enumeration;
23  import java.util.List;
24  import java.util.Vector;
25  
26  import org.apache.tools.ant.BuildException;
27  import org.apache.tools.ant.Project;
28  
29  import com.github.maven_nar.cpptasks.compiler.CommandLineCompiler;
30  import com.github.maven_nar.cpptasks.compiler.Compiler;
31  import com.github.maven_nar.cpptasks.compiler.Processor;
32  import com.github.maven_nar.cpptasks.gcc.GccCCompiler;
33  import com.github.maven_nar.cpptasks.types.CompilerArgument;
34  import com.github.maven_nar.cpptasks.types.ConditionalPath;
35  import com.github.maven_nar.cpptasks.types.DefineSet;
36  import com.github.maven_nar.cpptasks.types.IncludePath;
37  import com.github.maven_nar.cpptasks.types.SystemIncludePath;
38  import com.github.maven_nar.cpptasks.types.UndefineArgument;
39  import java.io.File;
40  
41  /**
42   * A compiler definition. compiler elements may be placed either as children of
43   * a cc element or the project element. A compiler element with an id attribute
44   * may be referenced from compiler elements with refid or extends attributes.
45   *
46   * @author Adam Murdoch
47   */
48  public final class CompilerDef extends ProcessorDef {
49    /** The source file sets. */
50    private final Vector defineSets = new Vector();
51    private Boolean ccache = false;
52    private Boolean exceptions;
53    private Boolean rtti;
54    private final Vector includePaths = new Vector();
55    private Boolean multithreaded;
56    private final Vector precompileDefs = new Vector();
57    private final Vector sysIncludePaths = new Vector();
58    private OptimizationEnum optimization;
59    private int warnings = -1;
60    private List<String> order;
61    private String toolPath;
62    private String compilerPrefix;
63    private File workDir;
64  
65    private boolean clearDefaultOptions;
66  
67    public CompilerDef() {
68    }
69  
70    /**
71     * Adds a compiler command-line arg.
72     */
73    public void addConfiguredCompilerArg(final CompilerArgument arg) {
74      if (isReference()) {
75        throw noChildrenAllowed();
76      }
77      addConfiguredProcessorArg(arg);
78    }
79  
80    /**
81     * Adds a compiler command-line arg.
82     */
83    public void addConfiguredCompilerParam(final CompilerParam param) {
84      if (isReference()) {
85        throw noChildrenAllowed();
86      }
87      addConfiguredProcessorParam(param);
88    }
89  
90    /**
91     * Adds a defineset.
92     */
93    public void addConfiguredDefineset(final DefineSet defs) {
94      if (defs == null) {
95        throw new NullPointerException("defs");
96      }
97      if (isReference()) {
98        throw noChildrenAllowed();
99      }
100     this.defineSets.addElement(defs);
101   }
102 
103   /**
104    * Creates an include path.
105    */
106   public IncludePath createIncludePath() {
107     final Project p = getProject();
108     if (p == null) {
109       throw new java.lang.IllegalStateException("project must be set");
110     }
111     if (isReference()) {
112       throw noChildrenAllowed();
113     }
114     final IncludePath path = new IncludePath(p);
115     this.includePaths.addElement(path);
116     return path;
117   }
118 
119   /**
120    * Specifies precompilation prototype file and exclusions.
121    * 
122    */
123   public PrecompileDef createPrecompile() throws BuildException {
124     final Project p = getProject();
125     if (isReference()) {
126       throw noChildrenAllowed();
127     }
128     final PrecompileDef precomp = new PrecompileDef();
129     precomp.setProject(p);
130     this.precompileDefs.addElement(precomp);
131     return precomp;
132   }
133 
134   /**
135    * Creates a system include path. Locations and timestamps of files located
136    * using the system include paths are not used in dependency analysis.
137    * 
138    * 
139    * Standard include locations should not be specified. The compiler
140    * adapters should recognized the settings from the appropriate environment
141    * variables or configuration files.
142    */
143   public SystemIncludePath createSysIncludePath() {
144     final Project p = getProject();
145     if (p == null) {
146       throw new java.lang.IllegalStateException("project must be set");
147     }
148     if (isReference()) {
149       throw noChildrenAllowed();
150     }
151     final SystemIncludePath path = new SystemIncludePath(p);
152     this.sysIncludePaths.addElement(path);
153     return path;
154   }
155 
156   public void execute() throws org.apache.tools.ant.BuildException {
157     throw new org.apache.tools.ant.BuildException("Not an actual task, but looks like one for documentation purposes");
158   }
159 
160   public UndefineArgument[] getActiveDefines() {
161     final Project p = getProject();
162     if (p == null) {
163       throw new java.lang.IllegalStateException("project must be set before this call");
164     }
165     if (isReference()) {
166       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getActiveDefines();
167     }
168     final Vector actives = new Vector();
169     for (int i = 0; i < this.defineSets.size(); i++) {
170       final DefineSet currentSet = (DefineSet) this.defineSets.elementAt(i);
171       final UndefineArgument[] defines = currentSet.getDefines();
172       for (final UndefineArgument define : defines) {
173         if (define.isActive(p)) {
174           actives.addElement(define);
175         }
176       }
177     }
178     final UndefineArgument[] retval = new UndefineArgument[actives.size()];
179     actives.copyInto(retval);
180     return retval;
181   }
182 
183   /**
184    * Returns the compiler-specific include path.
185    */
186   public String[] getActiveIncludePaths() {
187     if (isReference()) {
188       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getActiveIncludePaths();
189     }
190     return getActivePaths(this.includePaths);
191   }
192 
193   private String[] getActivePaths(final Vector paths) {
194     final Project p = getProject();
195     if (p == null) {
196       throw new java.lang.IllegalStateException("project not set");
197     }
198     final Vector activePaths = new Vector(paths.size());
199     for (int i = 0; i < paths.size(); i++) {
200       final ConditionalPath path = (ConditionalPath) paths.elementAt(i);
201       if (path.isActive(p)) {
202         final String[] pathEntries = path.list();
203         for (final String pathEntrie : pathEntries) {
204           activePaths.addElement(pathEntrie);
205         }
206       }
207     }
208     final String[] pathNames = new String[activePaths.size()];
209     activePaths.copyInto(pathNames);
210     return pathNames;
211   }
212 
213   public PrecompileDef getActivePrecompile(final CompilerDef ccElement) {
214     if (isReference()) {
215       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getActivePrecompile(ccElement);
216     }
217     PrecompileDef current = null;
218     final Enumeration iter = this.precompileDefs.elements();
219     while (iter.hasMoreElements()) {
220       current = (PrecompileDef) iter.nextElement();
221       if (current.isActive()) {
222         return current;
223       }
224     }
225     final CompilerDef extendedDef = (CompilerDef) getExtends();
226     if (extendedDef != null) {
227       current = extendedDef.getActivePrecompile(null);
228       if (current != null) {
229         return current;
230       }
231     }
232     if (ccElement != null && getInherit()) {
233       return ccElement.getActivePrecompile(null);
234     }
235     return null;
236   }
237 
238   public String[] getActiveSysIncludePaths() {
239     if (isReference()) {
240       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getActiveSysIncludePaths();
241     }
242     return getActivePaths(this.sysIncludePaths);
243   }
244 
245   public Boolean getCcache() {
246     return this.ccache;
247   }
248 
249   public final boolean getExceptions(final CompilerDef[] defaultProviders, final int index) {
250     if (isReference()) {
251       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getExceptions(defaultProviders, index);
252     }
253     if (this.exceptions != null) {
254       return this.exceptions.booleanValue();
255     } else {
256       if (defaultProviders != null && index < defaultProviders.length) {
257         return defaultProviders[index].getExceptions(defaultProviders, index + 1);
258       }
259     }
260     return false;
261   }
262 
263   public boolean getMultithreaded(final CompilerDef[] defaultProviders, final int index) {
264     if (isReference()) {
265       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getMultithreaded(defaultProviders, index);
266     }
267     if (this.multithreaded != null) {
268       return this.multithreaded.booleanValue();
269     } else {
270       if (defaultProviders != null && index < defaultProviders.length) {
271         return defaultProviders[index].getMultithreaded(defaultProviders, index + 1);
272       }
273     }
274     return true;
275   }
276 
277   public final OptimizationEnum getOptimization(final CompilerDef[] defaultProviders, final int index) {
278     if (isReference()) {
279       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getOptimization(defaultProviders, index);
280     }
281     if (this.optimization != null) {
282       return this.optimization;
283     } else {
284       if (defaultProviders != null && index < defaultProviders.length) {
285         return defaultProviders[index].getOptimization(defaultProviders, index + 1);
286       }
287     }
288     return null;
289   }
290 
291   public List<String> getOrder() {
292     return this.order;
293   }
294 
295   @Override
296   public Processor getProcessor() {
297     Processor processor = super.getProcessor();
298     if (processor == null) {
299       processor = GccCCompiler.getInstance();
300     }
301     if (getLibtool() && processor instanceof CommandLineCompiler) {
302       final CommandLineCompiler compiler = (CommandLineCompiler) processor;
303       processor = compiler.getLibtoolCompiler();
304     }
305     return processor;
306   }
307 
308   public final Boolean getRtti(final CompilerDef[] defaultProviders, final int index) {
309     if (isReference()) {
310       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getRtti(defaultProviders, index);
311     }
312     if (this.rtti != null) {
313       return this.rtti;
314     } else {
315       if (defaultProviders != null && index < defaultProviders.length) {
316         return defaultProviders[index].getRtti(defaultProviders, index + 1);
317       }
318     }
319     return null;
320   }
321 
322   public String getToolPath() {
323     return this.toolPath;
324   }
325 
326   public String getCompilerPrefix() {
327     return this.compilerPrefix;
328   }
329 
330   public File getWorkDir() {
331       return this.workDir;
332   }
333   
334   public int getWarnings(final CompilerDef[] defaultProviders, final int index) {
335     if (isReference()) {
336       return ((CompilerDef) getCheckedRef(CompilerDef.class, "CompilerDef")).getWarnings(defaultProviders, index);
337     }
338     if (this.warnings == -1) {
339       if (defaultProviders != null && index < defaultProviders.length) {
340         return defaultProviders[index].getWarnings(defaultProviders, index + 1);
341       }
342     }
343     return this.warnings;
344   }
345 
346   public boolean isClearDefaultOptions() {
347     return this.clearDefaultOptions;
348   }
349 
350   public void setCcache(final Boolean ccache) {
351     this.ccache = ccache;
352   }
353 
354   /**
355    * Sets the default compiler adapter. Use the "name" attribute when the
356    * compiler is a supported compiler.
357    * 
358    * @param classname
359    *          fully qualified classname which implements CompilerAdapter
360    */
361   @Override
362   public void setClassname(final String classname) throws BuildException {
363     if (isReference()) {
364       throw tooManyAttributes();
365     }
366     super.setClassname(classname);
367     final Processor proc = getProcessor();
368     if (!(proc instanceof Compiler)) {
369       throw new BuildException(classname + " does not implement Compiler");
370     }
371   }
372 
373   public void setClearDefaultOptions(final boolean clearDefaultOptions) {
374     this.clearDefaultOptions = clearDefaultOptions;
375   }
376 
377   /**
378    * Enables or disables exception support.
379    * 
380    * @param exceptions
381    *          if true, exceptions are supported.
382    * 
383    */
384   public void setExceptions(final boolean exceptions) {
385     if (isReference()) {
386       throw tooManyAttributes();
387     }
388     this.exceptions = booleanValueOf(exceptions);
389   }
390 
391   /**
392    * Enables or disables generation of multithreaded code. Unless specified,
393    * multithreaded code generation is enabled.
394    * 
395    * @param multithreaded
396    *          If true, generated code may be multithreaded.
397    */
398   public void setMultithreaded(final boolean multithreaded) {
399     if (isReference()) {
400       throw tooManyAttributes();
401     }
402     this.multithreaded = booleanValueOf(multithreaded);
403   }
404 
405   /**
406    * Sets compiler type.
407    * 
408    * 
409    * <table width="100%" border="1">
410    * <thead>Supported compilers </thead>
411    * <tr>
412    * <td>gcc (default)</td>
413    * <td>GCC C++ compiler</td>
414    * </tr>
415    * <tr>
416    * <td>g++</td>
417    * <td>GCC C++ compiler</td>
418    * </tr>
419    * <tr>
420    * <td>c++</td>
421    * <td>GCC C++ compiler</td>
422    * </tr>
423    * <tr>
424    * <td>g77</td>
425    * <td>GNU Fortran compiler</td>
426    * </tr>
427    * <tr>
428    * <td>msvc</td>
429    * <td>Microsoft Visual C++</td>
430    * </tr>
431    * <tr>
432    * <td>bcc</td>
433    * <td>Borland C++ Compiler</td>
434    * </tr>
435    * <tr>
436    * <td>msrc</td>
437    * <td>Microsoft Resource Compiler</td>
438    * </tr>
439    * <tr>
440    * <td>brc</td>
441    * <td>Borland Resource Compiler</td>
442    * </tr>
443    * <tr>
444    * <td>df</td>
445    * <td>Compaq Visual Fortran Compiler</td>
446    * </tr>
447    * <tr>
448    * <td>midl</td>
449    * <td>Microsoft MIDL Compiler</td>
450    * </tr>
451    * <tr>
452    * <td>icl</td>
453    * <td>Intel C++ compiler for Windows (IA-32)</td>
454    * </tr>
455    * <tr>
456    * <td>ecl</td>
457    * <td>Intel C++ compiler for Windows (IA-64)</td>
458    * </tr>
459    * <tr>
460    * <td>icc</td>
461    * <td>Intel C++ compiler for Linux (IA-32)</td>
462    * </tr>
463    * <tr>
464    * <td>ecc</td>
465    * <td>Intel C++ compiler for Linux (IA-64)</td>
466    * </tr>
467    * <tr>
468    * <td>CC</td>
469    * <td>Sun ONE C++ compiler</td>
470    * </tr>
471    * <tr>
472    * <td>aCC</td>
473    * <td>HP aC++ C++ Compiler</td>
474    * </tr>
475    * <tr>
476    * <td>os390</td>
477    * <td>OS390 C Compiler</td>
478    * </tr>
479    * <tr>
480    * <td>os400</td>
481    * <td>Icc Compiler</td>
482    * </tr>
483    * <tr>
484    * <td>sunc89</td>
485    * <td>Sun C89 C Compiler</td>
486    * </tr>
487    * <tr>
488    * <td>xlC</td>
489    * <td>VisualAge C Compiler</td>
490    * </tr>
491    * <tr>
492    * <td>uic</td>
493    * <td>Qt user interface compiler</td>
494    * </tr>
495    * <tr>
496    * <td>moc</td>
497    * <td>Qt meta-object compiler</td>
498    * </tr>
499    * <tr>
500    * <td>wcl</td>
501    * <td>OpenWatcom C/C++ compiler</td>
502    * </tr>
503    * <tr>
504    * <td>wfl</td>
505    * <td>OpenWatcom FORTRAN compiler</td>
506    * </tr>
507    * </table>
508    * 
509    */
510   public void setName(final CompilerEnum name) throws BuildException {
511     if (isReference()) {
512       throw tooManyAttributes();
513     }
514     final Compiler compiler = name.getCompiler();
515     setProcessor(compiler);
516   }
517 
518   /**
519    * Sets optimization level.
520    * 
521    * @param value
522    *          optimization level
523    */
524   public void setOptimize(final OptimizationEnum value) {
525     if (isReference()) {
526       throw tooManyAttributes();
527     }
528     this.optimization = value;
529   }
530 
531   // FREEHEP
532   /**
533    * List of source filenames without extensions
534    * 
535    * @param asList
536    */
537   public void setOrder(final List<String> order) {
538     this.order = order;
539   }
540 
541   @Override
542   protected void setProcessor(final Processor proc) throws BuildException {
543     try {
544       super.setProcessor(proc);
545     } catch (final ClassCastException ex) {
546       throw new BuildException(ex);
547     }
548   }
549 
550   /**
551    * Enables or disables run-time type information.
552    *
553    * @param rtti
554    *          if true, run-time type information is supported.
555    * 
556    */
557   public void setRtti(final boolean rtti) {
558     if (isReference()) {
559       throw tooManyAttributes();
560     }
561     this.rtti = booleanValueOf(rtti);
562   }
563 
564   public void setToolPath(final String path) {
565     this.toolPath = path;
566   }
567 
568   public void setCompilerPrefix(final String prefix) {
569     this.compilerPrefix = prefix;
570   }
571 
572   public void setWorkDir(final File workDir) {
573       this.workDir = workDir;
574   }
575   
576   /**
577    * Enumerated attribute with the values "none", "severe", "default",
578    * "production", "diagnostic", and "aserror".
579    */
580   public void setWarnings(final WarningLevelEnum level) {
581     this.warnings = level.getIndex();
582   }
583 }