Support two more attribute LIBPATH and INCLUDEPATH in tools_def file.
[mirror_edk2.git] / Tools / Java / Source / Cpptasks / net / sf / antcontrib / cpptasks / userdefine / CommandLineUserDefine.java
1 /*
2 *
3 * Copyright 2001-2004 The Ant-Contrib project
4 *
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
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 */
17 package net.sf.antcontrib.cpptasks.userdefine;
18
19 import java.io.File;
20 import java.util.Iterator;
21 import java.util.LinkedHashSet;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.StringTokenizer;
25 import java.util.Vector;
26
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;
31
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;
38
39 /**
40 *
41 */
42 public class CommandLineUserDefine {
43
44 String includePathDelimiter = null;
45
46 String outputDelimiter = null;
47
48 public void command(CCTask cctask, UserDefineDef userdefine) {
49 boolean isGccCommand = userdefine.getFamily().equalsIgnoreCase("GCC");
50 File workdir;
51 Project project = cctask.getProject();
52 if (userdefine.getWorkdir() == null) {
53 workdir = new File(".");
54 } else {
55 workdir = userdefine.getWorkdir();
56 }
57
58 //
59 // generate cmdline= command + args + includepath + endargs + outfile
60 //
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();
66
67 //
68 // get Args.
69 //
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());
74 } else {
75 endargs.addElement(argument[j].getValue());
76 }
77 }
78
79 //
80 // get include path.
81 //
82 String[] incPath = userdefine.getActiveIncludePaths();
83 for (int j = 0; j < incPath.length; j++) {
84 includePath.addElement(includePathDelimiter + incPath[j]);
85 }
86
87 //
88 // Remove space in args and endargs.
89 //
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());
95 }
96 }
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());
102 }
103 }
104
105 int cmdLen = 0;
106 //
107 // command + args + endargs + includepath + sourcefile
108 //
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;
114 if (isGccCommand) {
115 cmdLen += 2; // we need -( and -) to group libs for GCC
116 }
117 }
118
119 //
120 // In gcc the "cr" flag should follow space then add outputfile name,
121 // otherwise
122 // it will pop error.
123 // TBD
124 if (outputDelimiter != null && userdefine.getOutputFile() != null
125 && outputDelimiter.trim().length() > 0) {
126 if (outputDelimiter.trim().equalsIgnoreCase("-cr")) {
127 cmdLen = cmdLen + 2;
128 } else {
129 cmdLen++;
130 }
131 }
132
133 //
134 // for every source file
135 // if file is header file, just skip it (add later)
136 //
137 Vector srcSets = userdefine.getSrcSets();
138
139 //
140 // if have source file append source file in command line.
141 //
142 Set allSrcFiles = new LinkedHashSet();
143
144 for (int i = 0; i < srcSets.size(); i++) {
145 ConditionalFileSet srcSet = (ConditionalFileSet) srcSets
146 .elementAt(i);
147 if (srcSet.isActive()) {
148 //
149 // Find matching source files
150 //
151 DirectoryScanner scanner = srcSet.getDirectoryScanner(project);
152 //
153 // Check each source file - see if it needs compilation
154 //
155 String[] fileNames = scanner.getIncludedFiles();
156 for (int j = 0; j < fileNames.length; j++) {
157 allSrcFiles.add(scanner.getBasedir() + "/" + fileNames[j]);
158 if (isGccCommand) {
159 System.out.println("[" + userdefine.getType() + "] "
160 + fileNames[j]);
161 }
162 }
163 }
164 }
165
166 String[] fileNames = (String[]) allSrcFiles
167 .toArray(new String[allSrcFiles.size()]);
168 String[] cmd = new String[cmdLen - 1 + fileNames.length];
169 int index = 0;
170 cmd[index++] = userdefine.getCmd();
171
172 Iterator iter = argsWithoutSpace.iterator();
173 while (iter.hasNext()) {
174 cmd[index++] = project.replaceProperties((String) iter.next());
175 }
176
177 iter = endargsWithoutSpace.iterator();
178 while (iter.hasNext()) {
179 cmd[index++] = project.replaceProperties((String) iter.next());
180 }
181
182 //
183 // Add outputFileFlag and output file to cmd
184 //
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();
190 } else {
191 cmd[index++] = outputDelimiter + userdefine.getOutputFile();
192 }
193 }
194
195 iter = includePath.iterator();
196 while (iter.hasNext()) {
197 cmd[index++] = (String) iter.next();
198 }
199
200 if (libSet != null && libSet.length > 0) {
201 if (isGccCommand) {
202 cmd[index++] = "-(";
203 }
204 for (int k = 0; k < libSet.length; k++) {
205 cmd[index++] = libSet[k];
206 }
207 if (isGccCommand) {
208 cmd[index++] = "-)";
209 }
210 }
211 for (int j = 0; j < fileNames.length; j++) {
212 cmd[index++] = fileNames[j];
213 }
214
215 // StringBuffer logLine = new StringBuffer();
216 // for(int i = 0; i < cmd.length; i++) {
217 // logLine.append(cmd[i] + " ");
218 // }
219 // project.log(logLine.toString(), Project.MSG_VERBOSE);
220
221 Environment newEnv = new Environment();
222
223 //
224 // Prepare for environment variable PATH
225 //
226 if (userdefine.getDpath() != null && userdefine.getDpath().trim().length() != 0) {
227 String pathName = getPathName("PATH");
228 String existPath = System.getenv(pathName);
229
230 Variable var = new Variable();
231 var.setKey(pathName);
232 var.setPath(new Path(project, userdefine.getDpath() + ";" + existPath));
233 newEnv.addVariable(var);
234 }
235
236 //
237 // Prepare for environment variable LIB
238 //
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()));
246 } else {
247 var.setPath(new Path(project, userdefine.getLibpath() + ";" + existPath));
248 }
249 newEnv.addVariable(var);
250 }
251
252 //
253 // Prepare for environment variable INCLUDE
254 //
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()));
262 } else {
263 var.setPath(new Path(project, userdefine.getInclude() + ";" + existPath));
264 }
265 newEnv.addVariable(var);
266 }
267
268 int retval = runCommand(cctask, workdir, cmd, newEnv);
269
270 if (retval != 0) {
271 throw new BuildException(userdefine.getCmd()
272 + " failed with return code " + retval, cctask
273 .getLocation());
274 }
275 }
276
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)) {
283 return key;
284 }
285 }
286 return variableName;
287 }
288
289 protected int runCommand(CCTask task, File workingDir, String[] cmdline, Environment env)
290 throws BuildException {
291 //
292 // Write command to File
293 //
294 return CUtil.runCommand(task, workingDir, cmdline, false, env);
295
296 }
297 }