--- /dev/null
+/*\r
+ * \r
+ * Copyright 2001-2004 The Ant-Contrib project\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package net.sf.antcontrib.cpptasks.gcc.cross;\r
+import java.io.File;\r
+import java.util.Vector;\r
+import net.sf.antcontrib.cpptasks.CCTask;\r
+import net.sf.antcontrib.cpptasks.CUtil;\r
+import net.sf.antcontrib.cpptasks.CompilerParam;\r
+import net.sf.antcontrib.cpptasks.compiler.CommandLineCompilerConfiguration;\r
+import net.sf.antcontrib.cpptasks.compiler.LinkType;\r
+import net.sf.antcontrib.cpptasks.compiler.Linker;\r
+import net.sf.antcontrib.cpptasks.compiler.Processor;\r
+import net.sf.antcontrib.cpptasks.compiler.ProgressMonitor;\r
+import net.sf.antcontrib.cpptasks.gcc.GccCompatibleCCompiler;\r
+import net.sf.antcontrib.cpptasks.parser.CParser;\r
+import net.sf.antcontrib.cpptasks.parser.FortranParser;\r
+import net.sf.antcontrib.cpptasks.parser.Parser;\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.tools.ant.types.Environment;\r
+import net.sf.antcontrib.cpptasks.OptimizationEnum;\r
+\r
+/**\r
+ * Adapter for the GCC C/C++ compiler\r
+ * \r
+ * @author Adam Murdoch\r
+ */\r
+public final class GccCCompiler extends GccCompatibleCCompiler {\r
+ private final static String[] headerExtensions = new String[]{".h", ".hpp",\r
+ ".inl"};\r
+ private final static String[] sourceExtensions = new String[]{".c", /* C */\r
+ ".cc", /* C++ */\r
+ ".cpp", /* C++ */\r
+ ".cxx", /* C++ */\r
+ ".c++", /* C++ */\r
+ ".i", /* preprocessed C */\r
+ ".ii", /* preprocessed C++ */\r
+ ".f", /* FORTRAN */\r
+ ".for", /* FORTRAN */\r
+ ".m", /* Objective-C */\r
+ ".mm", /* Objected-C++ */\r
+ ".s" /* Assembly */\r
+ };\r
+ private static final GccCCompiler cppInstance = new GccCCompiler("c++",\r
+ sourceExtensions, headerExtensions, false,\r
+ new GccCCompiler("c++", sourceExtensions, headerExtensions, true,\r
+ null, false, null), false, null);\r
+ private static final GccCCompiler g77Instance = new GccCCompiler("g77",\r
+ sourceExtensions, headerExtensions, false,\r
+ new GccCCompiler("g77", sourceExtensions, headerExtensions, true,\r
+ null, false, null), false, null);\r
+ private static final GccCCompiler gppInstance = new GccCCompiler("g++",\r
+ sourceExtensions, headerExtensions, false,\r
+ new GccCCompiler("g++", sourceExtensions, headerExtensions, true,\r
+ null, false, null), false, null);\r
+ private static final GccCCompiler instance = new GccCCompiler("gcc",\r
+ sourceExtensions, headerExtensions, false,\r
+ new GccCCompiler("gcc", sourceExtensions, headerExtensions, true,\r
+ null, false, null), false, null);\r
+ /**\r
+ * Gets c++ adapter\r
+ */\r
+ public static GccCCompiler getCppInstance() {\r
+ return cppInstance;\r
+ }\r
+ /**\r
+ * Gets g77 adapter\r
+ */\r
+ public static GccCCompiler getG77Instance() {\r
+ return g77Instance;\r
+ }\r
+ /**\r
+ * Gets gpp adapter\r
+ */\r
+ public static GccCCompiler getGppInstance() {\r
+ return gppInstance;\r
+ }\r
+ /**\r
+ * Gets gcc adapter\r
+ */\r
+ public static GccCCompiler getInstance() {\r
+ return instance;\r
+ }\r
+ private String identifier;\r
+ private File[] includePath;\r
+ private boolean isPICMeaningful = true;\r
+ /**\r
+ * Private constructor. Use GccCCompiler.getInstance() to get singleton\r
+ * instance of this class.\r
+ */\r
+ private GccCCompiler(String command, String[] sourceExtensions,\r
+ String[] headerExtensions, boolean isLibtool,\r
+ GccCCompiler libtoolCompiler, boolean newEnvironment,\r
+ Environment env) {\r
+ super(command, null, sourceExtensions, headerExtensions, isLibtool,\r
+ libtoolCompiler, newEnvironment, env);\r
+ isPICMeaningful = System.getProperty("os.name").indexOf("Windows") < 0;\r
+ }\r
+ public void addImpliedArgs(final Vector args, \r
+ final boolean debug,\r
+ final boolean multithreaded, \r
+ final boolean exceptions, \r
+ final LinkType linkType,\r
+ final Boolean rtti,\r
+ final OptimizationEnum optimization,\r
+ final Boolean defaultflag) {\r
+ super.addImpliedArgs(args, debug, multithreaded, \r
+ exceptions, linkType, rtti, optimization, defaultflag);\r
+ if (isPICMeaningful && linkType.isSharedLibrary()) {\r
+ args.addElement("-fPIC");\r
+ }\r
+ }\r
+ public Processor changeEnvironment(boolean newEnvironment, Environment env) {\r
+ if (newEnvironment || env != null) {\r
+ return new GccCCompiler(getCommand(), this.getSourceExtensions(),\r
+ this.getHeaderExtensions(), this.getLibtool(),\r
+ (GccCCompiler) this.getLibtoolCompiler(), newEnvironment,\r
+ env);\r
+ }\r
+ return this;\r
+ }\r
+ protected Object clone() throws CloneNotSupportedException {\r
+ GccCCompiler clone = (GccCCompiler) super.clone();\r
+ return clone;\r
+ }\r
+ public void compile(CCTask task, File outputDir, String[] sourceFiles,\r
+ String[] args, String[] endArgs, boolean relentless,\r
+ CommandLineCompilerConfiguration config, ProgressMonitor monitor)\r
+ throws BuildException {\r
+ try {\r
+ GccCCompiler clone = (GccCCompiler) this.clone();\r
+ CompilerParam param = config.getParam("target");\r
+ if (param != null)\r
+ clone.setCommand(param.getValue() + "-" + this.getCommand());\r
+ clone.supercompile(task, outputDir, sourceFiles, args, endArgs,\r
+ relentless, config, monitor);\r
+ } catch (CloneNotSupportedException e) {\r
+ supercompile(task, outputDir, sourceFiles, args, endArgs,\r
+ relentless, config, monitor);\r
+ }\r
+ }\r
+ /**\r
+ * Create parser to determine dependencies.\r
+ * \r
+ * Will create appropriate parser (C++, FORTRAN) based on file extension.\r
+ * \r
+ */\r
+ protected Parser createParser(File source) {\r
+ if (source != null) {\r
+ String sourceName = source.getName();\r
+ int lastDot = sourceName.lastIndexOf('.');\r
+ if (lastDot >= 0 && lastDot + 1 < sourceName.length()) {\r
+ char afterDot = sourceName.charAt(lastDot + 1);\r
+ if (afterDot == 'f' || afterDot == 'F') {\r
+ return new FortranParser();\r
+ }\r
+ }\r
+ }\r
+ return new CParser();\r
+ }\r
+ public File[] getEnvironmentIncludePath() {\r
+ if (includePath == null) {\r
+ //\r
+ // construct default include path from machine id and version id\r
+ //\r
+ String[] defaultInclude = new String[1];\r
+ StringBuffer buf = new StringBuffer("/lib/");\r
+ buf.append(GccProcessor.getMachine());\r
+ buf.append('/');\r
+ buf.append(GccProcessor.getVersion());\r
+ buf.append("/include");\r
+ defaultInclude[0] = buf.toString();\r
+ //\r
+ // read specs file and look for -istart and -idirafter\r
+ //\r
+ String[] specs = GccProcessor.getSpecs();\r
+ String[][] optionValues = GccProcessor.parseSpecs(specs, "*cpp:",\r
+ new String[]{"-isystem ", "-idirafter "});\r
+ //\r
+ // if no entries were found, then use a default path\r
+ //\r
+ if (optionValues[0].length == 0 && optionValues[1].length == 0) {\r
+ optionValues[0] = new String[]{"/usr/local/include",\r
+ "/usr/include", "/usr/include/win32api"};\r
+ }\r
+ //\r
+ // remove mingw entries.\r
+ // For MinGW compiles this will mean the\r
+ // location of the sys includes will be\r
+ // wrong in dependencies.xml\r
+ // but that should have no significant effect\r
+ for (int i = 0; i < optionValues.length; i++) {\r
+ for (int j = 0; j < optionValues[i].length; j++) {\r
+ if (optionValues[i][j].indexOf("mingw") > 0) {\r
+ optionValues[i][j] = null;\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // if cygwin then\r
+ // we have to prepend location of gcc32\r
+ // and .. to start of absolute filenames to\r
+ // have something that will exist in the\r
+ // windows filesystem\r
+ if (GccProcessor.isCygwin()) {\r
+ GccProcessor.convertCygwinFilenames(optionValues[0]);\r
+ GccProcessor.convertCygwinFilenames(optionValues[1]);\r
+ GccProcessor.convertCygwinFilenames(defaultInclude);\r
+ }\r
+ int count = CUtil.checkDirectoryArray(optionValues[0]);\r
+ count += CUtil.checkDirectoryArray(optionValues[1]);\r
+ count += CUtil.checkDirectoryArray(defaultInclude);\r
+ includePath = new File[count];\r
+ int index = 0;\r
+ for (int i = 0; i < optionValues.length; i++) {\r
+ for (int j = 0; j < optionValues[i].length; j++) {\r
+ if (optionValues[i][j] != null) {\r
+ includePath[index++] = new File(optionValues[i][j]);\r
+ }\r
+ }\r
+ }\r
+ for (int i = 0; i < defaultInclude.length; i++) {\r
+ if (defaultInclude[i] != null) {\r
+ includePath[index++] = new File(defaultInclude[i]);\r
+ }\r
+ }\r
+ }\r
+ return (File[]) includePath.clone();\r
+ }\r
+ public String getIdentifier() throws BuildException {\r
+ if (identifier == null) {\r
+ StringBuffer buf;\r
+ if (getLibtool()) {\r
+ buf = new StringBuffer("libtool ");\r
+ } else {\r
+ buf = new StringBuffer(' ');\r
+ }\r
+ buf.append(getCommand());\r
+ buf.append(' ');\r
+ buf.append(GccProcessor.getVersion());\r
+ buf.append(' ');\r
+ buf.append(GccProcessor.getMachine());\r
+ identifier = buf.toString();\r
+ }\r
+ return identifier;\r
+ }\r
+ public Linker getLinker(LinkType linkType) {\r
+ return GccLinker.getInstance().getLinker(linkType);\r
+ }\r
+ public int getMaximumCommandLength() {\r
+ return Integer.MAX_VALUE;\r
+ }\r
+ private void supercompile(CCTask task, File outputDir,\r
+ String[] sourceFiles, String[] args, String[] endArgs,\r
+ boolean relentless, CommandLineCompilerConfiguration config,\r
+ ProgressMonitor monitor) throws BuildException {\r
+ super.compile(task, outputDir, sourceFiles, args, endArgs, relentless,\r
+ config, monitor);\r
+ }\r
+}\r