To fix EDKT341. Still existing issues for VfrCompile.
[mirror_edk2.git] / Tools / 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 private static String pathName = null;
49
50 public void command(CCTask cctask, UserDefineDef userdefine) {
51 boolean isGccCommand = userdefine.getFamily().equalsIgnoreCase("GCC");
52 File workdir;
53 Project project = cctask.getProject();
54 if (userdefine.getWorkdir() == null) {
55 workdir = new File(".");
56 } else {
57 workdir = userdefine.getWorkdir();
58 }
59
60 //
61 // generate cmdline= command + args + includepath + endargs + outfile
62 //
63 Vector args = new Vector();
64 Vector argsWithoutSpace = new Vector();
65 Vector endargs = new Vector();
66 Vector endargsWithoutSpace = new Vector();
67 Vector includePath = new Vector();
68
69 //
70 // get Args.
71 //
72 CommandLineArgument[] argument = userdefine.getActiveProcessorArgs();
73 for (int j = 0; j < argument.length; j++) {
74 if (argument[j].getLocation() == 0) {
75 args.addElement(argument[j].getValue());
76 } else {
77 endargs.addElement(argument[j].getValue());
78 }
79 }
80
81 //
82 // get include path.
83 //
84 String[] incPath = userdefine.getActiveIncludePaths();
85 for (int j = 0; j < incPath.length; j++) {
86 includePath.addElement(includePathDelimiter + incPath[j]);
87 }
88
89 //
90 // Remove space in args and endargs.
91 //
92 for (int i = 0; i < args.size(); i++) {
93 String str = (String) args.get(i);
94 StringTokenizer st = new StringTokenizer(str, " \t");
95 while (st.hasMoreTokens()) {
96 argsWithoutSpace.addElement(st.nextToken());
97 }
98 }
99 for (int i = 0; i < endargs.size(); i++) {
100 String str = (String) endargs.get(i);
101 StringTokenizer st = new StringTokenizer(str, " \t");
102 while (st.hasMoreTokens()) {
103 endargsWithoutSpace.addElement(st.nextToken());
104 }
105 }
106
107 int cmdLen = 0;
108 //
109 // command + args + endargs + includepath + sourcefile
110 //
111 cmdLen = 1 + argsWithoutSpace.size() + endargsWithoutSpace.size()
112 + includePath.size() + 1;
113 String[] libSet = userdefine.getLibset();
114 if (libSet != null && libSet.length > 0) {
115 cmdLen = cmdLen + libSet.length;
116 if (isGccCommand) {
117 cmdLen += 2; // we need -( and -) to group libs for GCC
118 }
119 }
120
121 //
122 // In gcc the "cr" flag should follow space then add outputfile name,
123 // otherwise
124 // it will pop error.
125 // TBD
126 if (outputDelimiter != null && userdefine.getOutputFile() != null
127 && outputDelimiter.trim().length() > 0) {
128 if (outputDelimiter.trim().equalsIgnoreCase("-cr")) {
129 cmdLen = cmdLen + 2;
130 } else {
131 cmdLen++;
132 }
133 }
134
135 //
136 // for every source file
137 // if file is header file, just skip it (add later)
138 //
139 Vector srcSets = userdefine.getSrcSets();
140
141 //
142 // if have source file append source file in command line.
143 //
144 Set allSrcFiles = new LinkedHashSet();
145
146 for (int i = 0; i < srcSets.size(); i++) {
147 ConditionalFileSet srcSet = (ConditionalFileSet) srcSets
148 .elementAt(i);
149 if (srcSet.isActive()) {
150 //
151 // Find matching source files
152 //
153 DirectoryScanner scanner = srcSet.getDirectoryScanner(project);
154 //
155 // Check each source file - see if it needs compilation
156 //
157 String[] fileNames = scanner.getIncludedFiles();
158 for (int j = 0; j < fileNames.length; j++) {
159 allSrcFiles.add(scanner.getBasedir() + "/" + fileNames[j]);
160 if (isGccCommand) {
161 System.out.println("[" + userdefine.getType() + "] "
162 + fileNames[j]);
163 }
164 }
165 }
166 }
167
168 String[] fileNames = (String[]) allSrcFiles
169 .toArray(new String[allSrcFiles.size()]);
170 String[] cmd = new String[cmdLen - 1 + fileNames.length];
171 int index = 0;
172 cmd[index++] = userdefine.getCmd();
173
174 Iterator iter = argsWithoutSpace.iterator();
175 while (iter.hasNext()) {
176 cmd[index++] = project.replaceProperties((String) iter.next());
177 }
178
179 iter = endargsWithoutSpace.iterator();
180 while (iter.hasNext()) {
181 cmd[index++] = project.replaceProperties((String) iter.next());
182 }
183
184 //
185 // Add outputFileFlag and output file to cmd
186 //
187 if (outputDelimiter != null && userdefine.getOutputFile() != null
188 && outputDelimiter.length() > 0) {
189 if (outputDelimiter.trim().equalsIgnoreCase("-cr")) {
190 cmd[index++] = outputDelimiter;
191 cmd[index++] = userdefine.getOutputFile();
192 } else {
193 cmd[index++] = outputDelimiter + userdefine.getOutputFile();
194 }
195 }
196
197 iter = includePath.iterator();
198 while (iter.hasNext()) {
199 cmd[index++] = (String) iter.next();
200 }
201
202 if (libSet != null && libSet.length > 0) {
203 if (isGccCommand) {
204 cmd[index++] = "-(";
205 }
206 for (int k = 0; k < libSet.length; k++) {
207 cmd[index++] = libSet[k];
208 }
209 if (isGccCommand) {
210 cmd[index++] = "-)";
211 }
212 }
213 for (int j = 0; j < fileNames.length; j++) {
214 cmd[index++] = fileNames[j];
215 }
216
217 // StringBuffer logLine = new StringBuffer();
218 // for(int i = 0; i < cmd.length; i++) {
219 // logLine.append(cmd[i] + " ");
220 // }
221 // project.log(logLine.toString(), Project.MSG_VERBOSE);
222
223 int retval = 0;
224
225 if (userdefine.getDpath() == null || userdefine.getDpath().trim().length() == 0) {
226 retval = runCommand(cctask, workdir, cmd, null);
227 } else {
228 String existPath = System.getenv(getPathName());
229 Environment newEnv = new Environment();
230 Variable var = new Variable();
231 var.setKey(getPathName());
232 var.setPath(new Path(project, userdefine.getDpath() + ";" + existPath));
233 newEnv.addVariable(var);
234 retval = runCommand(cctask, workdir, cmd, newEnv);
235 }
236
237
238 if (retval != 0) {
239 throw new BuildException(userdefine.getCmd()
240 + " failed with return code " + retval, cctask
241 .getLocation());
242 }
243 }
244
245 private String getPathName() {
246 if (pathName != null) {
247 return pathName;
248 }
249 Map allEnv = System.getenv();
250 Iterator iter = allEnv.keySet().iterator();
251 while (iter.hasNext()) {
252 String key = (String)iter.next();
253 if(key.equalsIgnoreCase("PATH")) {
254 pathName = key;
255 break ;
256 }
257 }
258 return pathName;
259 }
260
261 protected int runCommand(CCTask task, File workingDir, String[] cmdline, Environment env)
262 throws BuildException {
263 //
264 // Write command to File
265 //
266 return CUtil.runCommand(task, workingDir, cmdline, false, env);
267
268 }
269 }