+++ /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.LinkerParam;\r
-import net.sf.antcontrib.cpptasks.compiler.CommandLineLinkerConfiguration;\r
-import net.sf.antcontrib.cpptasks.compiler.LinkType;\r
-import net.sf.antcontrib.cpptasks.compiler.Linker;\r
-import net.sf.antcontrib.cpptasks.gcc.AbstractLdLinker;\r
-import org.apache.tools.ant.BuildException;\r
-/**\r
- * Adapter for the GCC linker\r
- * \r
- * @author Adam Murdoch\r
- */\r
-public class GccLinker extends AbstractLdLinker {\r
- private static final String[] discardFiles = new String[0];\r
- private static final String[] objFiles = new String[]{".o", ".a", ".lib",\r
- ".dll", ".so", ".sl"};\r
- private static final GccLinker dllLinker = new GccLinker("gcc", objFiles,\r
- discardFiles, "lib", ".so", false, new GccLinker("gcc", objFiles,\r
- discardFiles, "lib", ".so", true, null));\r
- private static final GccLinker instance = new GccLinker("gcc", objFiles,\r
- discardFiles, "", "", false, null);\r
- private static final String[] libtoolObjFiles = new String[]{".fo", ".a",\r
- ".lib", ".dll", ".so", ".sl"};\r
- private static String[] linkerOptions = new String[]{"-bundle",\r
- "-dynamiclib", "-nostartfiles", "-nostdlib", "-prebind", "-s",\r
- "-static", "-shared", "-symbolic", "-Xlinker",\r
- "--export-all-symbols", "-static-libgcc",};\r
- private static final GccLinker machBundleLinker = new GccLinker("gcc",\r
- objFiles, discardFiles, "lib", ".bundle", false, null);\r
- private static final GccLinker machDllLinker = new GccLinker("gcc",\r
- objFiles, discardFiles, "lib", ".dylib", false, null);\r
- public static GccLinker getInstance() {\r
- return instance;\r
- }\r
- private File[] libDirs;\r
- protected GccLinker(String command, String[] extensions,\r
- String[] ignoredExtensions, String outputPrefix,\r
- String outputSuffix, boolean isLibtool, GccLinker libtoolLinker) {\r
- super(command, "-dumpversion", extensions, ignoredExtensions,\r
- outputPrefix, outputSuffix, isLibtool, libtoolLinker);\r
- }\r
- protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {\r
- super.addImpliedArgs(debug, linkType, args, defaultflag);\r
- if (getIdentifier().indexOf("mingw") >= 0) {\r
- if (linkType.isSubsystemConsole()) {\r
- args.addElement("-mconsole");\r
- }\r
- if (linkType.isSubsystemGUI()) {\r
- args.addElement("-mwindows");\r
- }\r
- }\r
- }\r
- protected Object clone() throws CloneNotSupportedException {\r
- GccLinker clone = (GccLinker) super.clone();\r
- return clone;\r
- }\r
- /**\r
- * Allows drived linker to decorate linker option. Override by GccLinker to\r
- * prepend a "-Wl," to pass option to through gcc to linker.\r
- * \r
- * @param buf\r
- * buffer that may be used and abused in the decoration process,\r
- * must not be null.\r
- * @param arg\r
- * linker argument\r
- */\r
- public String decorateLinkerOption(StringBuffer buf, String arg) {\r
- String decoratedArg = arg;\r
- if (arg.length() > 1 && arg.charAt(0) == '-') {\r
- switch (arg.charAt(1)) {\r
- //\r
- // passed automatically by GCC\r
- //\r
- case 'g' :\r
- case 'f' :\r
- case 'F' :\r
- /* Darwin */\r
- case 'm' :\r
- case 'O' :\r
- case 'W' :\r
- case 'l' :\r
- case 'L' :\r
- case 'u' :\r
- case 'v' :\r
- break;\r
- default :\r
- boolean known = false;\r
- for (int i = 0; i < linkerOptions.length; i++) {\r
- if (linkerOptions[i].equals(arg)) {\r
- known = true;\r
- break;\r
- }\r
- }\r
- if (!known) {\r
- buf.setLength(0);\r
- buf.append("-Wl,");\r
- buf.append(arg);\r
- decoratedArg = buf.toString();\r
- }\r
- break;\r
- }\r
- }\r
- return decoratedArg;\r
- }\r
- /**\r
- * Returns library path.\r
- * \r
- */\r
- public File[] getLibraryPath() {\r
- if (libDirs == null) {\r
- //\r
- // construct gcc lib path from machine and version\r
- //\r
- StringBuffer buf = new StringBuffer("/lib/gcc-lib/");\r
- buf.append(GccProcessor.getMachine());\r
- buf.append('/');\r
- buf.append(GccProcessor.getVersion());\r
- //\r
- // build default path from gcc and system /lib and /lib/w32api\r
- //\r
- String[] impliedLibPath = new String[]{buf.toString(),\r
- "/lib/w32api", "/lib"};\r
- //\r
- // read gcc specs file for other library paths\r
- //\r
- String[] specs = GccProcessor.getSpecs();\r
- String[][] libpaths = GccProcessor.parseSpecs(specs, "*link:",\r
- new String[]{"%q"});\r
- String[] libpath;\r
- if (libpaths[0].length > 0) {\r
- libpath = new String[libpaths[0].length + 3];\r
- int i = 0;\r
- for (; i < libpaths[0].length; i++) {\r
- libpath[i] = libpaths[0][i];\r
- }\r
- libpath[i++] = buf.toString();\r
- libpath[i++] = "/lib/w32api";\r
- libpath[i++] = "/lib";\r
- } else {\r
- //\r
- // if a failure to find any matches then\r
- // use some default values for lib path entries\r
- libpath = new String[]{"/usr/local/lib/mingw",\r
- "/usr/local/lib", "/usr/lib/w32api", "/usr/lib/mingw",\r
- "/usr/lib", buf.toString(), "/lib/w32api", "/lib"};\r
- }\r
- for (int i = 0; i < libpath.length; i++) {\r
- if (libpath[i].indexOf("mingw") >= 0) {\r
- libpath[i] = null;\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(libpath);\r
- }\r
- //\r
- // check that remaining entries are actual directories\r
- //\r
- int count = CUtil.checkDirectoryArray(libpath);\r
- //\r
- // populate return array with remaining entries\r
- //\r
- libDirs = new File[count];\r
- int index = 0;\r
- for (int i = 0; i < libpath.length; i++) {\r
- if (libpath[i] != null) {\r
- libDirs[index++] = new File(libpath[i]);\r
- }\r
- }\r
- }\r
- return libDirs;\r
- }\r
- public Linker getLinker(LinkType type) {\r
- if (type.isStaticLibrary()) {\r
- return GccLibrarian.getInstance();\r
- }\r
- if (type.isPluginModule()) {\r
- if (isDarwin()) {\r
- return machBundleLinker;\r
- } else {\r
- return dllLinker;\r
- }\r
- }\r
- if (type.isSharedLibrary()) {\r
- if (isDarwin()) {\r
- return machDllLinker;\r
- } else {\r
- return dllLinker;\r
- }\r
- }\r
- return instance;\r
- }\r
- public void link(CCTask task, File outputFile, String[] sourceFiles,\r
- CommandLineLinkerConfiguration config) throws BuildException {\r
- try {\r
- GccLinker clone = (GccLinker) this.clone();\r
- LinkerParam param = config.getParam("target");\r
- if (param != null)\r
- clone.setCommand(param.getValue() + "-" + this.getCommand());\r
- clone.superlink(task, outputFile, sourceFiles, config);\r
- } catch (CloneNotSupportedException e) {\r
- superlink(task, outputFile, sourceFiles, config);\r
- }\r
- }\r
- private void superlink(CCTask task, File outputFile, String[] sourceFiles,\r
- CommandLineLinkerConfiguration config) throws BuildException {\r
- super.link(task, outputFile, sourceFiles, config);\r
- }\r
-}\r