3 * Copyright 2001-2004 The Ant-Contrib project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 package net
.sf
.antcontrib
.cpptasks
.gcc
.cross
.sparc_sun_solaris2
;
19 import java
.util
.Vector
;
21 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
22 import net
.sf
.antcontrib
.cpptasks
.compiler
.LinkType
;
23 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
24 import net
.sf
.antcontrib
.cpptasks
.compiler
.Processor
;
25 import net
.sf
.antcontrib
.cpptasks
.gcc
.GccCompatibleCCompiler
;
26 import net
.sf
.antcontrib
.cpptasks
.parser
.CParser
;
27 import net
.sf
.antcontrib
.cpptasks
.parser
.FortranParser
;
28 import net
.sf
.antcontrib
.cpptasks
.parser
.Parser
;
30 import org
.apache
.tools
.ant
.BuildException
;
31 import org
.apache
.tools
.ant
.types
.Environment
;
32 import net
.sf
.antcontrib
.cpptasks
.OptimizationEnum
;
35 * Adapter for the GCC C/C++ compiler
37 * @author Adam Murdoch
39 public final class GccCCompiler
extends GccCompatibleCCompiler
{
40 private final static String
[] sourceExtensions
= new String
[]{".c", /* C */
45 ".i", /* preprocessed C */
46 ".ii", /* preprocessed C++ */
49 ".m", /* Objective-C */
50 ".mm", /* Objected-C++ */
53 private final static String
[] headerExtensions
= new String
[]{".h", ".hpp",
55 public static final String CMD_PREFIX
= "sparc-sun-solaris2-";
56 private static final GccCCompiler cppInstance
= new GccCCompiler(CMD_PREFIX
57 + "c++", sourceExtensions
, headerExtensions
, false,
58 new GccCCompiler(CMD_PREFIX
+ "c++", sourceExtensions
,
59 headerExtensions
, true, null, false, null), false, null);
60 private static final GccCCompiler g77Instance
= new GccCCompiler(CMD_PREFIX
61 + "g77", sourceExtensions
, headerExtensions
, false,
62 new GccCCompiler(CMD_PREFIX
+ "g77", sourceExtensions
,
63 headerExtensions
, true, null, false, null), false, null);
64 private static final GccCCompiler gppInstance
= new GccCCompiler(CMD_PREFIX
65 + "g++", sourceExtensions
, headerExtensions
, false,
66 new GccCCompiler(CMD_PREFIX
+ "g++", sourceExtensions
,
67 headerExtensions
, true, null, false, null), false, null);
68 private static final GccCCompiler instance
= new GccCCompiler(CMD_PREFIX
69 + "gcc", sourceExtensions
, headerExtensions
, false,
70 new GccCCompiler(CMD_PREFIX
+ "gcc", sourceExtensions
,
71 headerExtensions
, true, null, false, null), false, null);
75 public static GccCCompiler
getCppInstance() {
81 public static GccCCompiler
getG77Instance() {
87 public static GccCCompiler
getGppInstance() {
93 public static GccCCompiler
getInstance() {
96 private String identifier
;
97 private File
[] includePath
;
98 private boolean isPICMeaningful
= true;
100 * Private constructor. Use GccCCompiler.getInstance() to get singleton
101 * instance of this class.
103 private GccCCompiler(String command
, String
[] sourceExtensions
,
104 String
[] headerExtensions
, boolean isLibtool
,
105 GccCCompiler libtoolCompiler
, boolean newEnvironment
,
107 super(command
, null, sourceExtensions
, headerExtensions
, isLibtool
,
108 libtoolCompiler
, newEnvironment
, env
);
109 isPICMeaningful
= System
.getProperty("os.name").indexOf("Windows") < 0;
111 public void addImpliedArgs(final Vector args
,
113 final boolean multithreaded
,
114 final boolean exceptions
,
115 final LinkType linkType
,
117 final OptimizationEnum optimization
,
118 final Boolean defaultflag
) {
119 super.addImpliedArgs(args
, debug
, multithreaded
,
120 exceptions
, linkType
, rtti
, optimization
, defaultflag
);
121 if (isPICMeaningful
&& linkType
.isSharedLibrary()) {
122 args
.addElement("-fPIC");
125 public Processor
changeEnvironment(boolean newEnvironment
, Environment env
) {
126 if (newEnvironment
|| env
!= null) {
127 return new GccCCompiler(getCommand(), this.getSourceExtensions(),
128 this.getHeaderExtensions(), this.getLibtool(),
129 (GccCCompiler
) this.getLibtoolCompiler(), newEnvironment
,
135 * Create parser to determine dependencies.
137 * Will create appropriate parser (C++, FORTRAN) based on file extension.
140 protected Parser
createParser(File source
) {
141 if (source
!= null) {
142 String sourceName
= source
.getName();
143 int lastDot
= sourceName
.lastIndexOf('.');
144 if (lastDot
>= 0 && lastDot
+ 1 < sourceName
.length()) {
145 char afterDot
= sourceName
.charAt(lastDot
+ 1);
146 if (afterDot
== 'f' || afterDot
== 'F') {
147 return new FortranParser();
151 return new CParser();
153 public File
[] getEnvironmentIncludePath() {
154 if (includePath
== null) {
156 // construct default include path from machine id and version id
158 String
[] defaultInclude
= new String
[1];
159 StringBuffer buf
= new StringBuffer("/lib/");
160 buf
.append(GccProcessor
.getMachine());
162 buf
.append(GccProcessor
.getVersion());
163 buf
.append("/include");
164 defaultInclude
[0] = buf
.toString();
166 // read specs file and look for -istart and -idirafter
168 String
[] specs
= GccProcessor
.getSpecs();
169 String
[][] optionValues
= GccProcessor
.parseSpecs(specs
, "*cpp:",
170 new String
[]{"-isystem ", "-idirafter "});
172 // if no entries were found, then use a default path
174 if (optionValues
[0].length
== 0 && optionValues
[1].length
== 0) {
175 optionValues
[0] = new String
[]{"/usr/local/include",
176 "/usr/include", "/usr/include/win32api"};
179 // remove mingw entries.
180 // For MinGW compiles this will mean the
181 // location of the sys includes will be
182 // wrong in dependencies.xml
183 // but that should have no significant effect
184 for (int i
= 0; i
< optionValues
.length
; i
++) {
185 for (int j
= 0; j
< optionValues
[i
].length
; j
++) {
186 if (optionValues
[i
][j
].indexOf("mingw") > 0) {
187 optionValues
[i
][j
] = null;
193 // we have to prepend location of gcc32
194 // and .. to start of absolute filenames to
195 // have something that will exist in the
196 // windows filesystem
197 if (GccProcessor
.isCygwin()) {
198 GccProcessor
.convertCygwinFilenames(optionValues
[0]);
199 GccProcessor
.convertCygwinFilenames(optionValues
[1]);
200 GccProcessor
.convertCygwinFilenames(defaultInclude
);
202 int count
= CUtil
.checkDirectoryArray(optionValues
[0]);
203 count
+= CUtil
.checkDirectoryArray(optionValues
[1]);
204 count
+= CUtil
.checkDirectoryArray(defaultInclude
);
205 includePath
= new File
[count
];
207 for (int i
= 0; i
< optionValues
.length
; i
++) {
208 for (int j
= 0; j
< optionValues
[i
].length
; j
++) {
209 if (optionValues
[i
][j
] != null) {
210 includePath
[index
++] = new File(optionValues
[i
][j
]);
214 for (int i
= 0; i
< defaultInclude
.length
; i
++) {
215 if (defaultInclude
[i
] != null) {
216 includePath
[index
++] = new File(defaultInclude
[i
]);
220 return (File
[]) includePath
.clone();
222 public String
getIdentifier() throws BuildException
{
223 if (identifier
== null) {
226 buf
= new StringBuffer("libtool ");
228 buf
= new StringBuffer(' ');
230 buf
.append(getCommand());
232 buf
.append(GccProcessor
.getVersion());
234 buf
.append(GccProcessor
.getMachine());
235 identifier
= buf
.toString();
239 public Linker
getLinker(LinkType linkType
) {
240 return GccLinker
.getInstance().getLinker(linkType
);
242 public int getMaximumCommandLength() {
243 return Integer
.MAX_VALUE
;