1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.github.maven_nar.cpptasks.gcc;
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.parser.CParser;
34 import com.github.maven_nar.cpptasks.parser.FortranParser;
35 import com.github.maven_nar.cpptasks.parser.Parser;
36
37
38
39
40
41
42 public final class GccCCompiler extends GccCompatibleCCompiler {
43 private final static String[] sourceExtensions = new String[] {
44 ".c",
45 ".cc",
46 ".cpp",
47 ".cxx",
48 ".c++",
49 ".i",
50 ".ii",
51 ".f",
52 ".for",
53 ".f90",
54 ".m",
55 ".mm",
56 ".s"
57 };
58 private final static String[] headerExtensions = new String[] {
59 ".h", ".hpp", ".inl"
60 };
61 private static final GccCCompiler cppInstance = new GccCCompiler("c++", sourceExtensions, headerExtensions, false,
62 new GccCCompiler("c++", sourceExtensions, headerExtensions, true, null, false, null), false, null);
63 private static final GccCCompiler g77Instance = new GccCCompiler("g77", sourceExtensions, headerExtensions, false,
64 new GccCCompiler("g77", sourceExtensions, headerExtensions, true, null, false, null), false, null);
65
66 private static final GccCCompiler gfortranInstance = new GccCCompiler("gfortran", sourceExtensions, headerExtensions,
67 false, new GccCCompiler("gfortran", sourceExtensions, headerExtensions, true, null, false, null), false, null);
68 private static final GccCCompiler gppInstance = new GccCCompiler("g++", sourceExtensions, headerExtensions, false,
69 new GccCCompiler("g++", sourceExtensions, headerExtensions, true, null, false, null), false, null);
70 private static final GccCCompiler instance = new GccCCompiler("gcc", sourceExtensions, headerExtensions, false,
71 new GccCCompiler("gcc", sourceExtensions, headerExtensions, true, null, false, null), false, null);
72 private static final GccCCompiler clangInstance = new GccCCompiler("clang", sourceExtensions, headerExtensions,
73 false, new GccCCompiler("clang", sourceExtensions, headerExtensions, true, null, false, null), false, null);
74 private static final GccCCompiler cpplangInstance = new GccCCompiler("clang++", sourceExtensions, headerExtensions,
75 false, new GccCCompiler("clang++", sourceExtensions, headerExtensions, true, null, false, null), false, null);
76
77
78
79
80 public static GccCCompiler getCLangInstance() {
81 return clangInstance;
82 }
83
84
85
86
87 public static GccCCompiler getCLangppInstance() {
88 return cpplangInstance;
89 }
90
91
92
93
94 public static GccCCompiler getCppInstance() {
95 return cppInstance;
96 }
97
98
99
100
101 public static GccCCompiler getG77Instance() {
102 return g77Instance;
103 }
104
105
106
107
108
109 public static GccCCompiler getGFortranInstance() {
110 return gfortranInstance;
111 }
112
113
114
115
116
117 public static GccCCompiler getGppInstance() {
118 return gppInstance;
119 }
120
121
122
123
124 public static GccCCompiler getInstance() {
125 return instance;
126 }
127
128 private String identifier;
129 private File[] includePath;
130 private boolean isPICMeaningful = true;
131
132
133
134
135
136 private GccCCompiler(final String command, final String[] sourceExtensions, final String[] headerExtensions,
137 final boolean isLibtool, final GccCCompiler libtoolCompiler, final boolean newEnvironment, final Environment env) {
138 super(command, null, sourceExtensions, headerExtensions, isLibtool, libtoolCompiler, newEnvironment, env);
139 this.isPICMeaningful = !System.getProperty("os.name").contains("Windows");
140 }
141
142 @Override
143 public void addImpliedArgs(final Vector args, final boolean debug, final boolean multithreaded,
144 final boolean exceptions, final LinkType linkType, final Boolean rtti, final OptimizationEnum optimization) {
145 super.addImpliedArgs(args, debug, multithreaded, exceptions, linkType, rtti, optimization);
146 if (this.isPICMeaningful && linkType.isSharedLibrary()) {
147 args.addElement("-fPIC");
148 }
149
150
151 if (!getCommand().equals("g77") && !getCommand().equals("gcc") && rtti != null && !rtti.booleanValue()) {
152
153 args.addElement("-fno-rtti");
154 }
155
156 }
157
158 @Override
159 public Processor changeEnvironment(final boolean newEnvironment, final Environment env) {
160 if (newEnvironment || env != null) {
161 return new GccCCompiler(getCommand(), this.getSourceExtensions(), this.getHeaderExtensions(), this.getLibtool(),
162 (GccCCompiler) this.getLibtoolCompiler(), newEnvironment, env);
163 }
164 return this;
165 }
166
167
168
169
170
171
172
173 @Override
174 protected Parser createParser(final File source) {
175 if (source != null) {
176 final String sourceName = source.getName();
177 final int lastDot = sourceName.lastIndexOf('.');
178 if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {
179 final char afterDot = sourceName.charAt(lastDot + 1);
180 if (afterDot == 'f' || afterDot == 'F') {
181 return new FortranParser();
182 }
183 }
184 }
185 return new CParser();
186 }
187
188 @Override
189 public File[] getEnvironmentIncludePath() {
190 if (this.includePath == null) {
191
192
193
194 final String[] defaultInclude = new String[1];
195 final String buf = "/lib/" + GccProcessor.getMachine() +
196 '/' +
197 GccProcessor.getVersion() +
198 "/include";
199 defaultInclude[0] = buf;
200
201
202
203 final String[] specs = GccProcessor.getSpecs();
204 final String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:", new String[] {
205 "-isystem ", "-idirafter "
206 });
207
208
209
210 if (optionValues[0].length == 0 && optionValues[1].length == 0) {
211 optionValues[0] = new String[] {
212 "/usr/local/include", "/usr/include", "/usr/include/win32api"
213 };
214 }
215
216
217
218
219
220
221 for (int i = 0; i < optionValues.length; i++) {
222 for (int j = 0; j < optionValues[i].length; j++) {
223 if (optionValues[i][j].indexOf("mingw") > 0) {
224 optionValues[i][j] = null;
225 }
226 }
227 }
228
229
230
231
232
233
234 if (GccProcessor.isCygwin()) {
235 GccProcessor.convertCygwinFilenames(optionValues[0]);
236 GccProcessor.convertCygwinFilenames(optionValues[1]);
237 GccProcessor.convertCygwinFilenames(defaultInclude);
238 }
239 int count = CUtil.checkDirectoryArray(optionValues[0]);
240 count += CUtil.checkDirectoryArray(optionValues[1]);
241 count += CUtil.checkDirectoryArray(defaultInclude);
242 this.includePath = new File[count];
243 int index = 0;
244 for (final String[] optionValue : optionValues) {
245 for (final String anOptionValue : optionValue) {
246 if (anOptionValue != null) {
247 this.includePath[index++] = new File(anOptionValue);
248 }
249 }
250 }
251 for (final String element : defaultInclude) {
252 if (element != null) {
253 this.includePath[index++] = new File(element);
254 }
255 }
256 }
257 return this.includePath.clone();
258 }
259
260 @Override
261 public String getIdentifier() throws BuildException {
262 if (this.identifier == null) {
263 StringBuffer buf;
264 if (getLibtool()) {
265 buf = new StringBuffer("libtool ");
266 } else {
267 buf = new StringBuffer(" ");
268 }
269 buf.append(getCommand());
270 buf.append(' ');
271 buf.append(GccProcessor.getVersion());
272 buf.append(' ');
273 buf.append(GccProcessor.getMachine());
274 this.identifier = buf.toString();
275 }
276 return this.identifier;
277 }
278
279 @Override
280 public Linker getLinker(final LinkType linkType) {
281 return GccLinker.getInstance().getLinker(linkType);
282 }
283
284
285 @Override
286 public int getMaximumCommandLength() {
287 return isWindows() ? 20000 : Integer.MAX_VALUE;
288 }
289
290 }