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.gcc.cross.sparc_sun_solaris2;
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.CUtil;
29  import com.github.maven_nar.cpptasks.OptimizationEnum;
30  import com.github.maven_nar.cpptasks.compiler.LinkType;
31  import com.github.maven_nar.cpptasks.compiler.Linker;
32  import com.github.maven_nar.cpptasks.compiler.Processor;
33  import com.github.maven_nar.cpptasks.gcc.GccCompatibleCCompiler;
34  import com.github.maven_nar.cpptasks.parser.CParser;
35  import com.github.maven_nar.cpptasks.parser.FortranParser;
36  import com.github.maven_nar.cpptasks.parser.Parser;
37  
38  /**
39   * Adapter for the GCC C/C++ compiler
40   *
41   * @author Adam Murdoch
42   */
43  public final class GccCCompiler extends GccCompatibleCCompiler {
44    private final static String[] sourceExtensions = new String[] {
45        ".c", /* C */
46        ".cc", /* C++ */
47        ".cpp", /* C++ */
48        ".cxx", /* C++ */
49        ".c++", /* C++ */
50        ".i", /* preprocessed C */
51        ".ii", /* preprocessed C++ */
52        ".f", /* FORTRAN */
53        ".for", /* FORTRAN */
54        ".f90", /* FORTRAN 90 */
55        ".m", /* Objective-C */
56        ".mm", /* Objected-C++ */
57        ".s" /* Assembly */
58    };
59    private final static String[] headerExtensions = new String[] {
60        ".h", ".hpp", ".inl"
61    };
62    public static final String CMD_PREFIX = "sparc-sun-solaris2-";
63    private static final GccCCompiler cppInstance = new GccCCompiler(CMD_PREFIX + "c++", sourceExtensions,
64        headerExtensions, false, new GccCCompiler(CMD_PREFIX + "c++", sourceExtensions, headerExtensions, true, null,
65            false, null), false, null);
66    private static final GccCCompiler g77Instance = new GccCCompiler(CMD_PREFIX + "g77", sourceExtensions,
67        headerExtensions, false, new GccCCompiler(CMD_PREFIX + "g77", sourceExtensions, headerExtensions, true, null,
68            false, null), false, null);
69    private static final GccCCompiler gppInstance = new GccCCompiler(CMD_PREFIX + "g++", sourceExtensions,
70        headerExtensions, false, new GccCCompiler(CMD_PREFIX + "g++", sourceExtensions, headerExtensions, true, null,
71            false, null), false, null);
72    private static final GccCCompiler instance = new GccCCompiler(CMD_PREFIX + "gcc", sourceExtensions, headerExtensions,
73        false, new GccCCompiler(CMD_PREFIX + "gcc", sourceExtensions, headerExtensions, true, null, false, null), false,
74        null);
75  
76    /**
77     * Gets c++ adapter
78     */
79    public static GccCCompiler getCppInstance() {
80      return cppInstance;
81    }
82  
83    /**
84     * Gets g77 adapter
85     */
86    public static GccCCompiler getG77Instance() {
87      return g77Instance;
88    }
89  
90    /**
91     * Gets gpp adapter
92     */
93    public static GccCCompiler getGppInstance() {
94      return gppInstance;
95    }
96  
97    /**
98     * Gets gcc adapter
99     */
100   public static GccCCompiler getInstance() {
101     return instance;
102   }
103 
104   private String identifier;
105   private File[] includePath;
106   private boolean isPICMeaningful = true;
107 
108   /**
109    * Private constructor. Use GccCCompiler.getInstance() to get singleton
110    * instance of this class.
111    */
112   private GccCCompiler(final String command, final String[] sourceExtensions, final String[] headerExtensions,
113       final boolean isLibtool, final GccCCompiler libtoolCompiler, final boolean newEnvironment, final Environment env) {
114     super(command, null, sourceExtensions, headerExtensions, isLibtool, libtoolCompiler, newEnvironment, env);
115     this.isPICMeaningful = !System.getProperty("os.name").contains("Windows");
116   }
117 
118   @Override
119   public void addImpliedArgs(final Vector<String> args, final boolean debug, final boolean multithreaded,
120       final boolean exceptions, final LinkType linkType, final Boolean rtti, final OptimizationEnum optimization) {
121     super.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization);
122     if (this.isPICMeaningful && linkType.isSharedLibrary()) {
123       args.addElement("-fPIC");
124     }
125   }
126 
127   @Override
128   public Processor changeEnvironment(final boolean newEnvironment, final Environment env) {
129     if (newEnvironment || env != null) {
130       return new GccCCompiler(getCommand(), this.getSourceExtensions(), this.getHeaderExtensions(), this.getLibtool(),
131           (GccCCompiler) this.getLibtoolCompiler(), newEnvironment, env);
132     }
133     return this;
134   }
135 
136   /**
137    * Create parser to determine dependencies.
138    * 
139    * Will create appropriate parser (C++, FORTRAN) based on file extension.
140    * 
141    */
142   @Override
143   protected Parser createParser(final File source) {
144     if (source != null) {
145       final String sourceName = source.getName();
146       final int lastDot = sourceName.lastIndexOf('.');
147       if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
148         final char afterDot = sourceName.charAt(lastDot + 1);
149         if (afterDot == 'f' || afterDot == 'F') {
150           return new FortranParser();
151         }
152       }
153     }
154     return new CParser();
155   }
156 
157   @Override
158   public File[] getEnvironmentIncludePath() {
159     if (this.includePath == null) {
160       //
161       // construct default include path from machine id and version id
162       //
163       final String[] defaultInclude = new String[1];
164       final String buf = "/lib/" + GccProcessor.getMachine() +
165           '/' +
166           GccProcessor.getVersion() +
167           "/include";
168       defaultInclude[0] = buf;
169       //
170       // read specs file and look for -istart and -idirafter
171       //
172       final String[] specs = GccProcessor.getSpecs();
173       final String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:", new String[] {
174           "-isystem ", "-idirafter "
175       });
176       //
177       // if no entries were found, then use a default path
178       //
179       if (optionValues[0].length == 0 && optionValues[1].length == 0) {
180         optionValues[0] = new String[] {
181             "/usr/local/include", "/usr/include", "/usr/include/win32api"
182         };
183       }
184       //
185       // remove mingw entries.
186       // For MinGW compiles this will mean the
187       // location of the sys includes will be
188       // wrong in dependencies.xml
189       // but that should have no significant effect
190       for (int i = 0; i < optionValues.length; i++) {
191         for (int j = 0; j < optionValues[i].length; j++) {
192           if (optionValues[i][j].indexOf("mingw") > 0) {
193             optionValues[i][j] = null;
194           }
195         }
196       }
197       //
198       // if cygwin then
199       // we have to prepend location of gcc32
200       // and .. to start of absolute filenames to
201       // have something that will exist in the
202       // windows filesystem
203       if (GccProcessor.isCygwin()) {
204         GccProcessor.convertCygwinFilenames(optionValues[0]);
205         GccProcessor.convertCygwinFilenames(optionValues[1]);
206         GccProcessor.convertCygwinFilenames(defaultInclude);
207       }
208       int count = CUtil.checkDirectoryArray(optionValues[0]);
209       count += CUtil.checkDirectoryArray(optionValues[1]);
210       count += CUtil.checkDirectoryArray(defaultInclude);
211       this.includePath = new File[count];
212       int index = 0;
213       for (final String[] optionValue : optionValues) {
214         for (final String anOptionValue : optionValue) {
215           if (anOptionValue != null) {
216             this.includePath[index++] = new File(anOptionValue);
217           }
218         }
219       }
220       for (final String element : defaultInclude) {
221         if (element != null) {
222           this.includePath[index++] = new File(element);
223         }
224       }
225     }
226     return this.includePath.clone();
227   }
228 
229   @Override
230   public String getIdentifier() throws BuildException {
231     if (this.identifier == null) {
232       StringBuffer buf;
233       if (getLibtool()) {
234         buf = new StringBuffer("libtool ");
235       } else {
236         buf = new StringBuffer(" ");
237       }
238       buf.append(getCommand());
239       buf.append(' ');
240       buf.append(GccProcessor.getVersion());
241       buf.append(' ');
242       buf.append(GccProcessor.getMachine());
243       this.identifier = buf.toString();
244     }
245     return this.identifier;
246   }
247 
248   @Override
249   public Linker getLinker(final LinkType linkType) {
250     return GccLinker.getInstance().getLinker(linkType);
251   }
252 
253   @Override
254   public int getMaximumCommandLength() {
255     return Integer.MAX_VALUE;
256   }
257 }