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