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