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
.userdefine
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashSet
;
24 import java
.util
.StringTokenizer
;
25 import java
.util
.Vector
;
27 import net
.sf
.antcontrib
.cpptasks
.CCTask
;
28 import net
.sf
.antcontrib
.cpptasks
.CUtil
;
29 import net
.sf
.antcontrib
.cpptasks
.types
.CommandLineArgument
;
30 import net
.sf
.antcontrib
.cpptasks
.types
.ConditionalFileSet
;
32 import org
.apache
.tools
.ant
.BuildException
;
33 import org
.apache
.tools
.ant
.DirectoryScanner
;
34 import org
.apache
.tools
.ant
.Project
;
35 import org
.apache
.tools
.ant
.types
.Environment
;
36 import org
.apache
.tools
.ant
.types
.Path
;
37 import org
.apache
.tools
.ant
.types
.Environment
.Variable
;
42 public class CommandLineUserDefine
{
44 String includePathDelimiter
= null;
46 String outputDelimiter
= null;
48 public void command(CCTask cctask
, UserDefineDef userdefine
) {
49 boolean isGccCommand
= userdefine
.getFamily().equalsIgnoreCase("GCC");
51 Project project
= cctask
.getProject();
52 if (userdefine
.getWorkdir() == null) {
53 workdir
= new File(".");
55 workdir
= userdefine
.getWorkdir();
59 // generate cmdline= command + args + includepath + endargs + outfile
61 Vector args
= new Vector();
62 Vector argsWithoutSpace
= new Vector();
63 Vector endargs
= new Vector();
64 Vector endargsWithoutSpace
= new Vector();
65 Vector includePath
= new Vector();
70 CommandLineArgument
[] argument
= userdefine
.getActiveProcessorArgs();
71 for (int j
= 0; j
< argument
.length
; j
++) {
72 if (argument
[j
].getLocation() == 0) {
73 args
.addElement(argument
[j
].getValue());
75 endargs
.addElement(argument
[j
].getValue());
82 String
[] incPath
= userdefine
.getActiveIncludePaths();
83 for (int j
= 0; j
< incPath
.length
; j
++) {
84 includePath
.addElement(includePathDelimiter
+ incPath
[j
]);
88 // Remove space in args and endargs.
90 for (int i
= 0; i
< args
.size(); i
++) {
91 String str
= (String
) args
.get(i
);
92 StringTokenizer st
= new StringTokenizer(str
, " \t");
93 while (st
.hasMoreTokens()) {
94 argsWithoutSpace
.addElement(st
.nextToken());
97 for (int i
= 0; i
< endargs
.size(); i
++) {
98 String str
= (String
) endargs
.get(i
);
99 StringTokenizer st
= new StringTokenizer(str
, " \t");
100 while (st
.hasMoreTokens()) {
101 endargsWithoutSpace
.addElement(st
.nextToken());
107 // command + args + endargs + includepath + sourcefile
109 cmdLen
= 1 + argsWithoutSpace
.size() + endargsWithoutSpace
.size()
110 + includePath
.size() + 1;
111 String
[] libSet
= userdefine
.getLibset();
112 if (libSet
!= null && libSet
.length
> 0) {
113 cmdLen
= cmdLen
+ libSet
.length
;
115 cmdLen
+= 2; // we need -( and -) to group libs for GCC
120 // In gcc the "cr" flag should follow space then add outputfile name,
122 // it will pop error.
124 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
125 && outputDelimiter
.trim().length() > 0) {
126 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
134 // for every source file
135 // if file is header file, just skip it (add later)
137 Vector srcSets
= userdefine
.getSrcSets();
140 // if have source file append source file in command line.
142 Set allSrcFiles
= new LinkedHashSet();
144 for (int i
= 0; i
< srcSets
.size(); i
++) {
145 ConditionalFileSet srcSet
= (ConditionalFileSet
) srcSets
147 if (srcSet
.isActive()) {
149 // Find matching source files
151 DirectoryScanner scanner
= srcSet
.getDirectoryScanner(project
);
153 // Check each source file - see if it needs compilation
155 String
[] fileNames
= scanner
.getIncludedFiles();
156 for (int j
= 0; j
< fileNames
.length
; j
++) {
157 allSrcFiles
.add(scanner
.getBasedir() + "/" + fileNames
[j
]);
159 System
.out
.println("[" + userdefine
.getType() + "] "
166 String
[] fileNames
= (String
[]) allSrcFiles
167 .toArray(new String
[allSrcFiles
.size()]);
168 String
[] cmd
= new String
[cmdLen
- 1 + fileNames
.length
];
170 cmd
[index
++] = userdefine
.getCmd();
172 Iterator iter
= argsWithoutSpace
.iterator();
173 while (iter
.hasNext()) {
174 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
177 iter
= endargsWithoutSpace
.iterator();
178 while (iter
.hasNext()) {
179 cmd
[index
++] = project
.replaceProperties((String
) iter
.next());
183 // Add outputFileFlag and output file to cmd
185 if (outputDelimiter
!= null && userdefine
.getOutputFile() != null
186 && outputDelimiter
.length() > 0) {
187 if (outputDelimiter
.trim().equalsIgnoreCase("-cr")) {
188 cmd
[index
++] = outputDelimiter
;
189 cmd
[index
++] = userdefine
.getOutputFile();
191 cmd
[index
++] = outputDelimiter
+ userdefine
.getOutputFile();
195 iter
= includePath
.iterator();
196 while (iter
.hasNext()) {
197 cmd
[index
++] = (String
) iter
.next();
200 if (libSet
!= null && libSet
.length
> 0) {
204 for (int k
= 0; k
< libSet
.length
; k
++) {
205 cmd
[index
++] = libSet
[k
];
211 for (int j
= 0; j
< fileNames
.length
; j
++) {
212 cmd
[index
++] = fileNames
[j
];
215 // StringBuffer logLine = new StringBuffer();
216 // for(int i = 0; i < cmd.length; i++) {
217 // logLine.append(cmd[i] + " ");
219 // project.log(logLine.toString(), Project.MSG_VERBOSE);
221 Environment newEnv
= new Environment();
224 // Prepare for environment variable PATH
226 if (userdefine
.getDpath() != null && userdefine
.getDpath().trim().length() != 0) {
227 String pathName
= getPathName("PATH");
228 String existPath
= System
.getenv(pathName
);
230 Variable var
= new Variable();
231 var
.setKey(pathName
);
232 var
.setPath(new Path(project
, userdefine
.getDpath() + ";" + existPath
));
233 newEnv
.addVariable(var
);
237 // Prepare for environment variable LIB
239 if (userdefine
.getLibpath() != null && userdefine
.getLibpath().trim().length() != 0) {
240 String pathName
= getPathName("LIB");
241 String existPath
= System
.getenv(pathName
);
242 Variable var
= new Variable();
243 var
.setKey(pathName
);
244 if (existPath
== null) {
245 var
.setPath(new Path(project
, userdefine
.getLibpath()));
247 var
.setPath(new Path(project
, userdefine
.getLibpath() + ";" + existPath
));
249 newEnv
.addVariable(var
);
253 // Prepare for environment variable INCLUDE
255 if (userdefine
.getInclude() != null && userdefine
.getInclude().trim().length() != 0) {
256 String pathName
= getPathName("INCLUDE");
257 String existPath
= System
.getenv(pathName
);
258 Variable var
= new Variable();
259 var
.setKey(pathName
);
260 if (existPath
== null) {
261 var
.setPath(new Path(project
, userdefine
.getInclude()));
263 var
.setPath(new Path(project
, userdefine
.getInclude() + ";" + existPath
));
265 newEnv
.addVariable(var
);
268 int retval
= runCommand(cctask
, workdir
, cmd
, newEnv
);
271 throw new BuildException(userdefine
.getCmd()
272 + " failed with return code " + retval
, cctask
277 private String
getPathName(String variableName
) {
278 Map allEnv
= System
.getenv();
279 Iterator iter
= allEnv
.keySet().iterator();
280 while (iter
.hasNext()) {
281 String key
= (String
)iter
.next();
282 if(key
.equalsIgnoreCase(variableName
)) {
289 protected int runCommand(CCTask task
, File workingDir
, String
[] cmdline
, Environment env
)
290 throws BuildException
{
292 // Write command to File
294 return CUtil
.runCommand(task
, workingDir
, cmdline
, false, env
);