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
.types
;
20 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
21 import net
.sf
.antcontrib
.cpptasks
.FileVisitor
;
22 import net
.sf
.antcontrib
.cpptasks
.compiler
.Linker
;
24 import org
.apache
.tools
.ant
.BuildException
;
25 import org
.apache
.tools
.ant
.DirectoryScanner
;
26 import org
.apache
.tools
.ant
.Project
;
27 import org
.apache
.tools
.ant
.ProjectComponent
;
28 import org
.apache
.tools
.ant
.types
.FileSet
;
29 import org
.apache
.tools
.ant
.types
.PatternSet
;
31 * A set of library names. Libraries can also be added to a link by specifying
34 * For most Unix-like compilers, libset will result in a series of -l and -L
35 * linker arguments. For Windows compilers, the library names will be used to
36 * locate the appropriate library files which will be added to the linkers
37 * input file list as if they had been specified in a fileset.
39 * @author Mark A Russell <a
40 * href="mailto:mark_russell@csgsystems.com">mark_russell@csg_systems.com
42 * @author Adam Murdoch
45 public class LibrarySet
extends ProjectComponent
{
46 private String dataset
;
47 private boolean explicitCaseSensitive
;
48 private String ifCond
;
49 private String
[] libnames
;
50 private final FileSet set
= new FileSet();
51 private String unlessCond
;
52 private LibraryTypeEnum libraryType
;
54 libnames
= new String
[0];
56 public void execute() throws org
.apache
.tools
.ant
.BuildException
{
57 throw new org
.apache
.tools
.ant
.BuildException(
58 "Not an actual task, but looks like one for documentation purposes");
61 * Gets the dataset. Used on OS390 if the libs are in a dataset.
63 * @return Returns a String
65 public String
getDataset() {
68 public File
getDir(Project project
) {
69 return set
.getDir(project
);
71 protected FileSet
getFileSet() {
74 public String
[] getLibs() {
75 String
[] retval
= (String
[]) libnames
.clone();
80 * Gets preferred library type
82 * @return library type, may be null.
84 public LibraryTypeEnum
getType() {
88 * Returns true if the define's if and unless conditions (if any) are
91 public boolean isActive(org
.apache
.tools
.ant
.Project p
) {
93 throw new NullPointerException("p");
96 String ifValue
= p
.getProperty(ifCond
);
97 if (ifValue
!= null) {
98 if (ifValue
.equals("no") || ifValue
.equals("false")) {
99 throw new BuildException(
102 + " used as if condition has value "
104 + " which suggests a misunderstanding of if attributes");
110 if (unlessCond
!= null) {
111 String unlessValue
= p
.getProperty(unlessCond
);
112 if (unlessValue
!= null) {
113 if (unlessValue
.equals("no") || unlessValue
.equals("false")) {
114 throw new BuildException(
117 + " used as unless condition has value "
119 + " which suggests a misunderstanding of unless attributes");
124 if (libnames
.length
== 0) {
125 p
.log("libnames not specified or empty.", Project
.MSG_WARN
);
131 * Sets case sensitivity of the file system. If not set, will default to
132 * the linker's case sensitivity.
134 * @param isCaseSensitive
135 * "true"|"on"|"yes" if file system is case sensitive,
136 * "false"|"off"|"no" when not.
138 public void setCaseSensitive(boolean isCaseSensitive
) {
139 explicitCaseSensitive
= true;
140 set
.setCaseSensitive(isCaseSensitive
);
143 * Sets the dataset. Used on OS390 if the libs are in a dataset.
148 public void setDataset(String dataset
) {
149 this.dataset
= dataset
;
158 public void setDir(File dir
) throws BuildException
{
162 * Sets the property name for the 'if' condition.
164 * The library set will be ignored unless the property is defined.
166 * The value of the property is insignificant, but values that would imply
167 * misinterpretation ("false", "no") will throw an exception when
173 public void setIf(String propName
) {
177 * Comma-separated list of library names without leading prefixes, such as
178 * "lib", or extensions, such as ".so" or ".a".
181 public void setLibs(CUtil
.StringArrayBuilder libs
) throws BuildException
{
182 libnames
= libs
.getValue();
183 // If this is not active.. then it's ok if the lib names are invalid.
184 // so we can do a: <libset if="x.lib" dir="." libs="${x.lib}"/>
185 if (!isActive(getProject()))
187 for (int i
= 0; i
< libnames
.length
; i
++) {
188 int lastDot
= libnames
[i
].lastIndexOf('.');
190 String extension
= libnames
[i
].substring(lastDot
);
191 if (extension
.equalsIgnoreCase(".lib")
192 || extension
.equalsIgnoreCase(".so")
193 || extension
.equalsIgnoreCase(".a")) {
195 "Suspicious library name ending with \""
196 + extension
+ "\": " + libnames
[i
], Project
.MSG_DEBUG
);
199 if (libnames
[i
].length() >= 3
200 && libnames
[i
].substring(0, 3).equalsIgnoreCase("lib")) {
202 "Suspicious library name starting with \"lib\": "
203 + libnames
[i
], Project
.MSG_DEBUG
);
207 public void setProject(Project project
) {
208 set
.setProject(project
);
209 super.setProject(project
);
212 * Set the property name for the 'unless' condition.
214 * If named property is set, the library set will be ignored.
216 * The value of the property is insignificant, but values that would imply
217 * misinterpretation ("false", "no") of the behavior will throw an
218 * exception when evaluated.
223 public void setUnless(String propName
) {
224 unlessCond
= propName
;
228 * Sets the preferred library type. Supported values "shared", "static", and
229 * "framework". "framework" is equivalent to "shared" on non-Darwin platforms.
231 public void setType(LibraryTypeEnum type
) {
232 this.libraryType
= type
;
235 public void visitLibraries(Project project
, Linker linker
, File
[] libpath
,
236 FileVisitor visitor
) throws BuildException
{
237 FileSet localSet
= (FileSet
) set
.clone();
239 // unless explicitly set
240 // will default to the linker case sensitivity
242 if (!explicitCaseSensitive
) {
243 boolean linkerCaseSensitive
= linker
.isCaseSensitive();
244 localSet
.setCaseSensitive(linkerCaseSensitive
);
247 // if there was a libs attribute then
248 // add the corresponding patterns to the FileSet
250 if (libnames
!= null && libnames
.length
> 0) {
251 String
[] patterns
= linker
.getLibraryPatterns(libnames
, libraryType
);
253 // if no patterns, then linker does not support libraries
255 if (patterns
.length
> 0) {
256 for (int i
= 0; i
< patterns
.length
; i
++) {
257 PatternSet
.NameEntry entry
= localSet
.createInclude();
258 entry
.setName(patterns
[i
]);
261 // if there was no specified directory then
262 // run through the libpath backwards
264 if (localSet
.getDir(project
) == null) {
266 // scan libpath in reverse order
267 // to give earlier entries priority
269 for (int j
= libpath
.length
- 1; j
>= 0; j
--) {
270 FileSet clone
= (FileSet
) localSet
.clone();
271 clone
.setDir(libpath
[j
]);
272 DirectoryScanner scanner
= clone
.getDirectoryScanner(project
);
273 File basedir
= scanner
.getBasedir();
274 String
[] files
= scanner
.getIncludedFiles();
275 for (int k
= 0; k
< files
.length
; k
++) {
276 visitor
.visit(basedir
, files
[k
]);
280 DirectoryScanner scanner
= localSet
.getDirectoryScanner(project
);
281 File basedir
= scanner
.getBasedir();
282 String
[] files
= scanner
.getIncludedFiles();
283 for (int k
= 0; k
< files
.length
; k
++) {
284 visitor
.visit(basedir
, files
[k
]);