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.mozilla;
21  
22  import java.io.File;
23  import java.util.Vector;
24  
25  import org.apache.tools.ant.BuildException;
26  import org.apache.tools.ant.types.Environment;
27  
28  import com.github.maven_nar.cpptasks.CCTask;
29  import com.github.maven_nar.cpptasks.CUtil;
30  import com.github.maven_nar.cpptasks.OptimizationEnum;
31  import com.github.maven_nar.cpptasks.VersionInfo;
32  import com.github.maven_nar.cpptasks.compiler.CommandLineCompiler;
33  import com.github.maven_nar.cpptasks.compiler.CommandLineCompilerConfiguration;
34  import com.github.maven_nar.cpptasks.compiler.LinkType;
35  import com.github.maven_nar.cpptasks.compiler.Linker;
36  import com.github.maven_nar.cpptasks.compiler.Processor;
37  import com.github.maven_nar.cpptasks.compiler.ProgressMonitor;
38  import com.github.maven_nar.cpptasks.gcc.LdLinker;
39  import com.github.maven_nar.cpptasks.parser.CParser;
40  import com.github.maven_nar.cpptasks.parser.Parser;
41  
42  /**
43   * Adapter for the Mozilla Xpidl Compiler.
44   *
45   * @author Curt Arnold
46   */
47  public final class XpidlCompiler extends CommandLineCompiler {
48    /**
49     * Singleton instance.
50     */
51    private static final XpidlCompiler INSTANCE = new XpidlCompiler(false, null);
52  
53    /**
54     * Gets singleton instance of compiler.
55     * 
56     * @return XpidlCompiler singleton instance
57     */
58    public static XpidlCompiler getInstance() {
59      return INSTANCE;
60    }
61  
62    /**
63     * Constructor.
64     * 
65     * @param newEnvironment
66     *          boolean establish an new environment.
67     * @param env
68     *          Environment environment.
69     */
70    private XpidlCompiler(final boolean newEnvironment, final Environment env) {
71      super("xpidl", null, new String[] {
72          ".idl", ".xpidl"
73      }, new String[0], ".xpt", false, null, newEnvironment, env);
74    }
75  
76    /**
77     * Add arguments for debug, etc.
78     * 
79     * @param args
80     *          Vector command argument list
81     * @param debug
82     *          boolean build for debug if true
83     * @param multithreaded
84     *          boolean build for multithreading if true
85     * @param exceptions
86     *          boolean enable exceptions if true
87     * @param linkType
88     *          LinkType output and runtime type
89     * @param rtti
90     *          Boolean enable run-time type identification if true
91     * @param optimization
92     *          OptimizationEnum optimization
93     */
94    @Override
95    protected void addImpliedArgs(final Vector<String> args, final boolean debug, final boolean multithreaded,
96        final boolean exceptions, final LinkType linkType, final Boolean rtti, final OptimizationEnum optimization) {
97    }
98  
99    /**
100    * Adds command line arguments for include paths.
101    *
102    * @param baseDirPath
103    *          String base directory
104    * @param includeDirs
105    *          File[] include directories
106    * @param args
107    *          Vector command line arguments
108    * @param relativeArgs
109    *          Vector arguments for configuration identification
110    * @param includePathId
111    *          StringBuffer buffer for configuration identification
112    */
113   protected void addIncludes(final String baseDirPath, final File[] includeDirs, final Vector<String> args,
114       final Vector<String> relativeArgs, final StringBuffer includePathId) {
115     //
116     // requires space between switch and path
117     //
118     for (final File includeDir : includeDirs) {
119       args.addElement("-I");
120       args.addElement(includeDir.getAbsolutePath());
121       if (relativeArgs != null) {
122         final String relative = CUtil.getRelativePath(baseDirPath, includeDir);
123         relativeArgs.addElement("-I");
124         relativeArgs.addElement(relative);
125         if (includePathId != null) {
126           if (includePathId.length() == 0) {
127             includePathId.append("-I ");
128           } else {
129             includePathId.append(" -I ");
130           }
131           includePathId.append(relative);
132         }
133       }
134     }
135   }
136 
137   /**
138    * Add arguments for specified warning level.
139    * 
140    * @param args
141    *          Vector command line arguments
142    * @param level
143    *          int warning level value
144    */
145   @Override
146   protected void addWarningSwitch(final Vector<String> args, final int level) {
147   }
148 
149   /**
150    * Change enviroment (deprecated).
151    * 
152    * @param newEnvironment
153    *          boolean use new environment.
154    * @param env
155    *          Environment environment
156    * @return Processor modified processor
157    */
158   @Override
159   public Processor changeEnvironment(final boolean newEnvironment, final Environment env) {
160     return this;
161   }
162 
163   /**
164    * Compiles an .idl file into the corresponding .h and .xpt files.
165    * 
166    * @param task
167    *          current cc task
168    * @param outputDir
169    *          output directory
170    * @param sourceFiles
171    *          source files
172    * @param args
173    *          command line arguments that appear before input files
174    * @param endArgs
175    *          command line arguments that appear after input files
176    * @param relentless
177    *          if true, do not stop at first compilation error
178    * @param config
179    *          compiler configuration
180    * @param monitor
181    *          progress monitor
182    */
183   @Override
184   public void compile(final CCTask task, final File outputDir, final String[] sourceFiles, final String[] args,
185       final String[] endArgs, final boolean relentless, final CommandLineCompilerConfiguration config,
186       final ProgressMonitor monitor) {
187 
188     BuildException exc = null;
189     final String[] thisSource = new String[1];
190     final String[] tlbCommand = new String[args.length + endArgs.length + 6];
191     tlbCommand[0] = "xpidl";
192     tlbCommand[1] = "-m";
193     tlbCommand[2] = "typelib";
194     final String[] headerCommand = new String[args.length + endArgs.length + 6];
195     headerCommand[0] = "xpidl";
196     headerCommand[1] = "-m";
197     headerCommand[2] = "header";
198     for (int i = 0; i < args.length; i++) {
199       tlbCommand[i + 3] = args[i];
200       headerCommand[i + 3] = args[i];
201     }
202     tlbCommand[args.length + 3] = "-e";
203     headerCommand[args.length + 3] = "-e";
204 
205     int tlbIndex = args.length + 6;
206     int headerIndex = args.length + 6;
207     for (final String endArg : endArgs) {
208       tlbCommand[tlbIndex++] = endArg;
209       headerCommand[headerIndex++] = endArg;
210     }
211     for (final String sourceFile : sourceFiles) {
212       tlbIndex = args.length + 4;
213       headerIndex = args.length + 4;
214       final String[] outputFileNames = getOutputFileNames(sourceFile, null);
215 
216       tlbCommand[tlbIndex++] = outputFileNames[0];
217       tlbCommand[tlbIndex++] = sourceFile;
218 
219       headerCommand[headerIndex++] = outputFileNames[1];
220       headerCommand[headerIndex++] = sourceFile;
221 
222       int retval = runCommand(task, outputDir, tlbCommand);
223       if (retval == 0) {
224         retval = runCommand(task, outputDir, headerCommand);
225       }
226       if (monitor != null) {
227         thisSource[0] = sourceFile;
228         monitor.progress(thisSource);
229       }
230       //
231       // if the process returned a failure code and
232       // we aren't holding an exception from an earlier
233       // interation
234       if (retval != 0 && exc == null) {
235         //
236         // construct the exception
237         //
238         exc = new BuildException(this.getCommand() + " failed with return code " + retval, task.getLocation());
239         //
240         // and throw it now unless we are relentless
241         //
242         if (!relentless) {
243           throw exc;
244         }
245       }
246     }
247     //
248     // if the compiler returned a failure value earlier
249     // then throw an exception
250     if (exc != null) {
251       throw exc;
252     }
253   }
254 
255   /**
256    * Gets dependency parser.
257    * 
258    * @param source
259    *          source file
260    * @return parser
261    */
262   @Override
263   protected Parser createParser(final File source) {
264     return new CParser();
265   }
266 
267   /**
268    * Gets number of command line arguments per input file.
269    * 
270    * @return int number of command line arguments per input file.
271    */
272   @Override
273   protected int getArgumentCountPerInputFile() {
274     return 3;
275   }
276 
277   /**
278    * Gets switch to define preprocessor macro.
279    * 
280    * @param buffer
281    *          StringBuffer command line argument
282    * @param define
283    *          String macro name
284    * @param value
285    *          String macro value, may be null.
286    */
287   @Override
288   protected void getDefineSwitch(final StringBuffer buffer, final String define, final String value) {
289   }
290 
291   /**
292    * Gets standard include paths.
293    * 
294    * @return File[] standard include paths
295    */
296   @Override
297   protected File[] getEnvironmentIncludePath() {
298     return new File[0];
299   }
300 
301   /**
302    * Gets compiler identifier.
303    * 
304    * @return String compiler identification string
305    */
306   @Override
307   public String getIdentifier() {
308     return "Mozilla xpidl";
309   }
310 
311   /**
312    * Gets include directory switch.
313    * 
314    * @param includeDir
315    *          String include directory
316    * @return String command switch to add specified directory to search path
317    */
318   @Override
319   protected String getIncludeDirSwitch(final String includeDir) {
320     return "-I" + includeDir;
321   }
322 
323   /**
324    * Gets input file arguments.
325    * 
326    * @param outputDir
327    *          File output directory
328    * @param filename
329    *          String input file name.
330    * @param index
331    *          int argument index,
332    *          0 to getNumberOfArgumentsPerInputFile() -1
333    * @return String input file argument
334    */
335   @Override
336   protected String getInputFileArgument(final File outputDir, final String filename, final int index) {
337     return "";
338   }
339 
340   /**
341    * Gets linker associated with this type.
342    * 
343    * @param type
344    *          LinkType linker, returns ld.
345    * @return Linker
346    */
347   @Override
348   public Linker getLinker(final LinkType type) {
349     return LdLinker.getInstance();
350   }
351 
352   /**
353    * Gets maximum length of command line.
354    * 
355    * @return int maximum length of command line
356    */
357   @Override
358   public int getMaximumCommandLength() {
359     return 1024;
360   }
361 
362   /**
363    * Gets maximum number of input files processed per command.
364    * 
365    * @return int maximum number of input files processed per command.
366    */
367   @Override
368   protected int getMaximumInputFilesPerCommand() {
369     return 1;
370   }
371 
372   /**
373    * Gets output file names.
374    * 
375    * @param inputFile
376    *          String input file name
377    * @param versionInfo
378    *          version info, not used by this compiler.
379    * @return String[] output file names
380    */
381   @Override
382   public String[] getOutputFileNames(final String inputFile, final VersionInfo versionInfo) {
383     //
384     // if a recognized input file
385     //
386     final String baseName = getBaseOutputName(inputFile);
387     return new String[] {
388         baseName + ".xpt", baseName + ".h"
389     };
390   }
391 
392   /**
393    * Get total command line length due to the input file.
394    * 
395    * @param outputDir
396    *          File output directory
397    * @param inputFile
398    *          String input file
399    * @return int characters added to command line for the input file.
400    */
401   @Override
402   protected int getTotalArgumentLengthForInputFile(final File outputDir, final String inputFile) {
403     return 0;
404   }
405 
406   /**
407    * Gets switch to undefine preprocessor macro.
408    * 
409    * @param buffer
410    *          StringBuffer command line argument
411    * @param define
412    *          String macro name
413    */
414   @Override
415   protected void getUndefineSwitch(final StringBuffer buffer, final String define) {
416   }
417 
418 }