4 GenFvImageTask is to call GenFvImage.exe to generate FvImage.
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 package org
.tianocore
.framework
.tasks
;
18 import org
.apache
.tools
.ant
.BuildException
;
19 import org
.apache
.tools
.ant
.Project
;
20 import org
.apache
.tools
.ant
.Task
;
21 import org
.apache
.tools
.ant
.taskdefs
.Execute
;
22 import org
.apache
.tools
.ant
.taskdefs
.LogStreamHandler
;
23 import org
.apache
.tools
.ant
.types
.Commandline
;
26 import java
.io
.InputStreamReader
;
27 import java
.lang
.ProcessBuilder
;
28 import java
.util
.LinkedList
;
29 import java
.util
.regex
.Matcher
;
30 import java
.util
.regex
.Pattern
;
31 import java
.util
.List
;
32 import java
.util
.StringTokenizer
;
33 import java
.util
.Iterator
;
34 import java
.io
.BufferedReader
;
35 import java
.io
.FileReader
;
37 import org
.tianocore
.common
.logger
.EdkLog
;
42 GenFvImageTask is to call GenFvImage.exe to generate the FvImage.
45 public class GenFvImageTask
extends Task
implements EfiDefine
{
49 static final private String toolName
= "GenFvImage";
51 // Pattern to match the section header (e.g. [options], [files])
53 static final private Pattern sectionHeader
= Pattern
.compile("\\[([^\\[\\]]+)\\]");
55 // The name of input inf file
57 private FileArg infFile
= new FileArg();
61 private String outputDir
= ".";
66 GenFvImageTask execute is to assemble tool command line & execute tool
69 public void execute() throws BuildException
{
70 Project project
= this.getOwningTarget().getProject();
71 String path
= project
.getProperty("env.FRAMEWORK_TOOLS_PATH");
74 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, infFile
.toFileList() + " is uptodate!");
82 command
= path
+ File
.separator
+ toolName
;
85 String argument
= "" + infFile
;
91 Commandline cmdline
= new Commandline();
92 cmdline
.setExecutable(command
);
93 cmdline
.createArgument().setLine(argument
);
95 LogStreamHandler streamHandler
= new LogStreamHandler(this,
96 Project
.MSG_INFO
, Project
.MSG_WARN
);
97 Execute runner
= new Execute(streamHandler
, null);
99 runner
.setAntRun(project
);
100 runner
.setCommandline(cmdline
.getCommandline());
101 runner
.setWorkingDirectory(new File(outputDir
));
103 // log command line string.
105 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, Commandline
.toString(cmdline
.getCommandline()));
106 EdkLog
.log(this, infFile
.toFileList());
108 exitCode
= runner
.execute();
110 EdkLog
.log(this, "ERROR = " + Integer
.toHexString(exitCode
));
112 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, "GenFvImage succeeded!");
114 } catch (Exception e
) {
115 throw new BuildException(e
.getMessage());
118 throw new BuildException("GenFvImage: failed to generate FV file!");
125 This function is to get class member of infFile
126 @return String name of infFile
128 public String
getInfFile() {
129 return infFile
.getValue();
135 This function is to set class member of infFile.
137 @param infFile name of infFile
139 public void setInfFile(String infFile
) {
140 this.infFile
.setArg(" -I ", infFile
);
146 This function is to get output directory.
148 @return Path of output directory.
150 public String
getOutputDir() {
157 This function is to set output directory.
159 @param outputDir The output direcotry.
161 public void setOutputDir(String outputDir
) {
162 this.outputDir
= outputDir
;
168 private boolean isUptodate() {
169 String infName
= this.infFile
.getValue();
171 List
<String
> ffsFiles
= new LinkedList
<String
>();
172 File inf
= new File(infName
);
175 FileReader reader
= new FileReader(inf
);
176 BufferedReader in
= new BufferedReader(reader
);
180 // Read the inf file line by line
182 boolean inFiles
= false;
183 boolean inOptions
= false;
184 while ((str
= in
.readLine()) != null) {
186 if (str
.length() == 0) {
190 Matcher matcher
= sectionHeader
.matcher(str
);
191 if (matcher
.find()) {
193 // We take care of only "options" and "files" section
195 String sectionName
= str
.substring(matcher
.start(1), matcher
.end(1));
196 if (sectionName
.equalsIgnoreCase("options")) {
199 } else if (sectionName
.equalsIgnoreCase("files")) {
212 int equalMarkPos
= str
.indexOf("=");
213 if (equalMarkPos
< 0) {
218 // we have only interest in EFI_FILE_NAME
220 String fileNameFlag
= str
.substring(0, equalMarkPos
).trim();
221 String fileName
= str
.substring(equalMarkPos
+ 1).trim();
222 if (!fileNameFlag
.equalsIgnoreCase("EFI_FILE_NAME")
223 || fileName
.length() == 0) {
229 // files specified beneath the [files] section are source files
231 ffsFiles
.add(fileName
);
232 } else if (inOptions
) {
234 // file specified beneath the [options] section is the target file
236 fvName
= outputDir
+ File
.separator
+ fileName
;
239 } catch (Exception ex
) {
240 throw new BuildException(ex
.getMessage());
244 // if destionation file doesn't exist, we need to generate it.
246 File fvFile
= new File(fvName
);
247 if (!fvFile
.exists()) {
248 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, fvName
+ " doesn't exist!");
253 // the inf file itself will be taken as source file, check its timestamp
254 // against the target file
256 long fvFileTimeStamp
= fvFile
.lastModified();
257 if (inf
.lastModified() > fvFileTimeStamp
) {
258 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, infName
+ " has been changed since last build!");
263 // no change in the inf file, we need to check each source files in it
264 // against the target file
266 for (Iterator it
= ffsFiles
.iterator(); it
.hasNext(); ) {
267 String fileName
= (String
)it
.next();
268 File file
= new File(fileName
);
269 if (file
.lastModified() > fvFileTimeStamp
) {
270 EdkLog
.log(this, EdkLog
.EDK_VERBOSE
, fileName
+ " has been changed since last build!");