]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | /*\r |
2 | * \r | |
3 | * Copyright 2003-2004 The Ant-Contrib project\r | |
4 | *\r | |
5 | * Licensed under the Apache License, Version 2.0 (the "License");\r | |
6 | * you may not use this file except in compliance with the License.\r | |
7 | * You may obtain a copy of the License at\r | |
8 | *\r | |
9 | * http://www.apache.org/licenses/LICENSE-2.0\r | |
10 | *\r | |
11 | * Unless required by applicable law or agreed to in writing, software\r | |
12 | * distributed under the License is distributed on an "AS IS" BASIS,\r | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r | |
14 | * See the License for the specific language governing permissions and\r | |
15 | * limitations under the License.\r | |
16 | */\r | |
17 | package net.sf.antcontrib.cpptasks.gcc;\r | |
18 | import java.io.File;\r | |
19 | import java.util.Vector;\r | |
20 | \r | |
21 | import net.sf.antcontrib.cpptasks.CCTask;\r | |
22 | import net.sf.antcontrib.cpptasks.CUtil;\r | |
23 | import net.sf.antcontrib.cpptasks.compiler.CaptureStreamHandler;\r | |
24 | import net.sf.antcontrib.cpptasks.compiler.LinkType;\r | |
25 | import net.sf.antcontrib.cpptasks.compiler.Linker;\r | |
26 | import net.sf.antcontrib.cpptasks.types.LibrarySet;\r | |
27 | /**\r | |
28 | * Adapter for the g++ variant of the GCC linker\r | |
29 | * \r | |
30 | * @author Stephen M. Webb <stephen.webb@bregmasoft.com>\r | |
31 | */\r | |
32 | public class GppLinker extends AbstractLdLinker {\r | |
33 | protected static final String[] discardFiles = new String[0];\r | |
34 | protected static final String[] objFiles = new String[]{".o", ".a", ".lib",\r | |
35 | ".dll", ".so", ".sl"};\r | |
36 | private static final GppLinker dllLinker = new GppLinker("gcc", objFiles,\r | |
37 | discardFiles, "lib", ".so", false, new GppLinker("gcc", objFiles,\r | |
38 | discardFiles, "lib", ".so", true, null));\r | |
39 | private final static String libPrefix = "libraries: =";\r | |
40 | protected static final String[] libtoolObjFiles = new String[]{".fo", ".a",\r | |
41 | ".lib", ".dll", ".so", ".sl"};\r | |
42 | private static String[] linkerOptions = new String[]{"-bundle", "-dylib",\r | |
43 | "-dynamic", "-dynamiclib", "-nostartfiles", "-nostdlib",\r | |
44 | "-prebind", "-s", "-static", "-shared", "-symbolic", "-Xlinker"};\r | |
45 | private static final GppLinker instance = new GppLinker("gcc", objFiles,\r | |
46 | discardFiles, "", "", false, null);\r | |
47 | private static final GppLinker machDllLinker = new GppLinker("gcc",\r | |
48 | objFiles, discardFiles, "lib", ".dylib", false, null);\r | |
49 | private static final GppLinker machPluginLinker = new GppLinker("gcc",\r | |
50 | objFiles, discardFiles, "lib", ".bundle", false, null);\r | |
51 | public static GppLinker getInstance() {\r | |
52 | return instance;\r | |
53 | }\r | |
54 | private File[] libDirs;\r | |
55 | private String runtimeLibrary;\r | |
56 | protected GppLinker(String command, String[] extensions,\r | |
57 | String[] ignoredExtensions, String outputPrefix,\r | |
58 | String outputSuffix, boolean isLibtool, GppLinker libtoolLinker) {\r | |
59 | super(command, "-dumpversion", extensions, ignoredExtensions,\r | |
60 | outputPrefix, outputSuffix, isLibtool, libtoolLinker);\r | |
61 | }\r | |
62 | protected void addImpliedArgs(boolean debug, LinkType linkType, Vector args, Boolean defaultflag) {\r | |
63 | super.addImpliedArgs(debug, linkType, args, defaultflag);\r | |
64 | if (getIdentifier().indexOf("mingw") >= 0) {\r | |
65 | if (linkType.isSubsystemConsole()) {\r | |
66 | args.addElement("-mconsole");\r | |
67 | }\r | |
68 | if (linkType.isSubsystemGUI()) {\r | |
69 | args.addElement("-mwindows");\r | |
70 | }\r | |
71 | }\r | |
72 | if (linkType.isStaticRuntime()) {\r | |
73 | String[] cmdin = new String[]{"g++", "-print-file-name=libstdc++.a"};\r | |
74 | String[] cmdout = CaptureStreamHandler.run(cmdin);\r | |
75 | if (cmdout.length > 0) {\r | |
76 | runtimeLibrary = cmdout[0];\r | |
77 | } else {\r | |
78 | runtimeLibrary = null;\r | |
79 | }\r | |
80 | } else {\r | |
81 | runtimeLibrary = "-lstdc++";\r | |
82 | }\r | |
83 | }\r | |
84 | public String[] addLibrarySets(CCTask task, LibrarySet[] libsets,\r | |
85 | Vector preargs, Vector midargs, Vector endargs) {\r | |
86 | String[] rs = super.addLibrarySets(task, libsets, preargs, midargs,\r | |
87 | endargs);\r | |
88 | if (runtimeLibrary != null) {\r | |
89 | endargs.addElement(runtimeLibrary);\r | |
90 | }\r | |
91 | return rs;\r | |
92 | }\r | |
93 | /**\r | |
94 | * Allows drived linker to decorate linker option. Override by GppLinker to\r | |
95 | * prepend a "-Wl," to pass option to through gcc to linker.\r | |
96 | * \r | |
97 | * @param buf\r | |
98 | * buffer that may be used and abused in the decoration process,\r | |
99 | * must not be null.\r | |
100 | * @param arg\r | |
101 | * linker argument\r | |
102 | */\r | |
103 | public String decorateLinkerOption(StringBuffer buf, String arg) {\r | |
104 | String decoratedArg = arg;\r | |
105 | if (arg.length() > 1 && arg.charAt(0) == '-') {\r | |
106 | switch (arg.charAt(1)) {\r | |
107 | //\r | |
108 | // passed automatically by GCC\r | |
109 | //\r | |
110 | case 'g' :\r | |
111 | case 'f' :\r | |
112 | case 'F' :\r | |
113 | /* Darwin */\r | |
114 | case 'm' :\r | |
115 | case 'O' :\r | |
116 | case 'W' :\r | |
117 | case 'l' :\r | |
118 | case 'L' :\r | |
119 | case 'u' :\r | |
120 | break;\r | |
121 | default :\r | |
122 | boolean known = false;\r | |
123 | for (int i = 0; i < linkerOptions.length; i++) {\r | |
124 | if (linkerOptions[i].equals(arg)) {\r | |
125 | known = true;\r | |
126 | break;\r | |
127 | }\r | |
128 | }\r | |
129 | if (!known) {\r | |
130 | buf.setLength(0);\r | |
131 | buf.append("-Wl,");\r | |
132 | buf.append(arg);\r | |
133 | decoratedArg = buf.toString();\r | |
134 | }\r | |
135 | break;\r | |
136 | }\r | |
137 | }\r | |
138 | return decoratedArg;\r | |
139 | }\r | |
140 | /**\r | |
141 | * Returns library path.\r | |
142 | * \r | |
143 | */\r | |
144 | public File[] getLibraryPath() {\r | |
145 | if (libDirs == null) {\r | |
146 | Vector dirs = new Vector();\r | |
147 | // Ask GCC where it will look for its libraries.\r | |
148 | String[] args = new String[]{"g++", "-print-search-dirs"};\r | |
149 | String[] cmdout = CaptureStreamHandler.run(args);\r | |
150 | for (int i = 0; i < cmdout.length; ++i) {\r | |
151 | int prefixIndex = cmdout[i].indexOf(libPrefix);\r | |
152 | if (prefixIndex >= 0) {\r | |
153 | // Special case DOS-type GCCs like MinGW or Cygwin\r | |
154 | int s = prefixIndex + libPrefix.length();\r | |
155 | int t = cmdout[i].indexOf(';', s);\r | |
156 | while (t > 0) {\r | |
157 | dirs.addElement(cmdout[i].substring(s, t));\r | |
158 | s = t + 1;\r | |
159 | t = cmdout[i].indexOf(';', s);\r | |
160 | }\r | |
161 | dirs.addElement(cmdout[i].substring(s));\r | |
162 | ++i;\r | |
163 | for (; i < cmdout.length; ++i) {\r | |
164 | dirs.addElement(cmdout[i]);\r | |
165 | }\r | |
166 | }\r | |
167 | }\r | |
168 | // Eliminate all but actual directories.\r | |
169 | String[] libpath = new String[dirs.size()];\r | |
170 | dirs.copyInto(libpath);\r | |
171 | int count = CUtil.checkDirectoryArray(libpath);\r | |
172 | // Build return array.\r | |
173 | libDirs = new File[count];\r | |
174 | int index = 0;\r | |
175 | for (int i = 0; i < libpath.length; ++i) {\r | |
176 | if (libpath[i] != null) {\r | |
177 | libDirs[index++] = new File(libpath[i]);\r | |
178 | }\r | |
179 | }\r | |
180 | }\r | |
181 | return libDirs;\r | |
182 | }\r | |
183 | public Linker getLinker(LinkType type) {\r | |
184 | if (type.isStaticLibrary()) {\r | |
185 | return GccLibrarian.getInstance();\r | |
186 | }\r | |
187 | if (type.isPluginModule()) {\r | |
188 | if (GccProcessor.getMachine().indexOf("darwin") >= 0) {\r | |
189 | return machPluginLinker;\r | |
190 | } else {\r | |
191 | return dllLinker;\r | |
192 | }\r | |
193 | }\r | |
194 | if (type.isSharedLibrary()) {\r | |
195 | if (GccProcessor.getMachine().indexOf("darwin") >= 0) {\r | |
196 | return machDllLinker;\r | |
197 | } else {\r | |
198 | return dllLinker;\r | |
199 | }\r | |
200 | }\r | |
201 | return instance;\r | |
202 | }\r | |
203 | }\r |