]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Tools/Java/Source/GenBuild/org/tianocore/build/FfsProcess.java
Add genDigest() method to class FfsProcess to generate MD5 digest value for the FFS...
[mirror_edk2.git] / Tools / Java / Source / GenBuild / org / tianocore / build / FfsProcess.java
index 26b93909019cd75dce831bb3af1f4970d8a950be..f63b7d95f0bdaba9af05666454dfa42175106ecc 100644 (file)
@@ -14,6 +14,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 package org.tianocore.build;\r
 \r
 import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.FileReader;\r
+import java.io.FileWriter;\r
+import java.security.MessageDigest;\r
 import java.util.Vector;\r
 \r
 import javax.xml.namespace.QName;\r
@@ -55,6 +60,7 @@ public class FfsProcess {
 \r
     private BuildOptionsDocument.BuildOptions.Ffs ffsXmlObject;\r
 \r
+    private Project project = null;\r
     ///\r
     /// ANT script to call GenFfs\r
     ///\r
@@ -113,6 +119,7 @@ public class FfsProcess {
               If can't find FFS Layout in FPD.\r
     **/\r
     public boolean initSections(String buildType, Project project, FpdModuleIdentification fpdModuleId) throws BuildException {\r
+        this.project = project;\r
         //\r
         // Try to find Ffs layout from FPD file\r
         //\r
@@ -121,6 +128,7 @@ public class FfsProcess {
         for (int i = 0; i < ffsArray.length; i++) {\r
             if (isMatch(ffsArray[i].getFfsKey(), buildType)) {\r
                 ffsXmlObject = ffsArray[i];\r
+                genDigest();\r
                 return true;\r
             }\r
         }\r
@@ -186,14 +194,25 @@ public class FfsProcess {
         //\r
         Element outofdateEle = document.createElement("OnDependency");\r
         Element sourceEle = document.createElement("sourcefiles");\r
-        String[] result = new String[sectionList.size()];\r
+        Vector<String> sections = new Vector<String>();\r
         for (int i = 0; i < sectionList.size(); i++) {\r
-            result[i] = (String) sectionList.get(i);\r
+            String section = (String) sectionList.get(i);\r
+            if (isSectionType(section)) {\r
+                sections.addElement(section);\r
+            }\r
             Element pathEle = document.createElement("file");\r
-            pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename\r
-                                         + getSectionExt(result[i]));\r
+            pathEle.setAttribute("name", getSectionFile(basename, section));\r
             sourceEle.appendChild(pathEle);\r
         }\r
+        //\r
+        // add FFS layout digest into the source file list\r
+        // \r
+        Element pathEle = document.createElement("file");\r
+        pathEle.setAttribute("name", "${DEST_DIR_OUTPUT}" + File.separator + "ffs.md5");\r
+        sourceEle.appendChild(pathEle);\r
+\r
+        String[] result = sections.toArray(new String[sections.size()]);\r
+\r
         outofdateEle.appendChild(sourceEle);\r
         Element targetEle = document.createElement("targetfiles");\r
         Element fileEle = document.createElement("file");\r
@@ -343,6 +362,7 @@ public class FfsProcess {
     **/\r
     private void dealSection(int mode, Document doc, Element root, XmlCursor cursor, Vector<String> list) {\r
         String type = cursor.getAttributeText(new QName("SectionType"));\r
+        String alignment = cursor.getAttributeText(new QName("Alignment"));\r
         \r
         //\r
         // Judge if file is specified? Yes, just use the file, else call Build Macro\r
@@ -370,16 +390,19 @@ public class FfsProcess {
         \r
         if (fileName == null) {\r
             list.addElement(type);\r
+        } else {\r
+            list.addElement(fileName);\r
         }\r
+\r
         if (mode == MODE_GUID_DEFINED) {\r
             //\r
             // <input file="${DEST_DIR_OUTPUT}\Bds.pe32"/>\r
             //\r
             Element ele = doc.createElement("input");\r
             if (fileName == null) {\r
-                ele.setAttribute("file", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+                ele.setAttribute("file", getSectionFile(basename, type));\r
             } else {\r
-                ele.setAttribute("file", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
+                ele.setAttribute("file", fileName);\r
             }\r
             root.appendChild(ele);\r
         } else {\r
@@ -388,9 +411,12 @@ public class FfsProcess {
             //\r
             Element ele = doc.createElement("sectFile");\r
             if (fileName == null) {\r
-                ele.setAttribute("fileName", "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + getSectionExt(type));\r
+                ele.setAttribute("fileName", getSectionFile(basename, type));\r
             } else {\r
-                ele.setAttribute("fileName", "${PLATFORM_DIR}" + File.separatorChar + fileName);\r
+                ele.setAttribute("fileName", fileName);\r
+            }\r
+            if (alignment != null) {\r
+                ele.setAttribute("Alignment", alignment);\r
             }\r
             root.appendChild(ele);\r
         }\r
@@ -402,13 +428,22 @@ public class FfsProcess {
       @param type Section type\r
       @return Corresponding section file extension\r
     **/\r
-    private String getSectionExt(String type) {\r
+    private String getSectionFile(String basename, String type) {\r
+        for (int i = 0; i < sectionExt.length; i++) {\r
+            if (sectionExt[i][0].equalsIgnoreCase(type)) {\r
+                return "${DEST_DIR_OUTPUT}" + File.separatorChar + basename + sectionExt[i][1];\r
+            }\r
+        }\r
+        return type;\r
+    }\r
+\r
+    private boolean isSectionType(String type) {\r
         for (int i = 0; i < sectionExt.length; i++) {\r
             if (sectionExt[i][0].equalsIgnoreCase(type)) {\r
-                return sectionExt[i][1];\r
+                return true;\r
             }\r
         }\r
-        return ".sec";\r
+        return false;\r
     }\r
 \r
     /**\r
@@ -419,4 +454,73 @@ public class FfsProcess {
     public Element getFfsNode() {\r
         return ffsNode;\r
     }\r
+\r
+    private void genDigest() {\r
+        String digestFilePath = project.getProperty("DEST_DIR_OUTPUT");\r
+        if (digestFilePath == null) {\r
+            EdkLog.log(EdkLog.EDK_WARNING, "Warning: cannot get DEST_DIR_OUTPUT!");\r
+            return;\r
+        }\r
+\r
+        //\r
+        // use MD5 algorithm\r
+        // \r
+        MessageDigest md5 = null;\r
+        try {\r
+            md5 = MessageDigest.getInstance("MD5");\r
+            //\r
+            // convert the FFS layout XML DOM tree into string and use it to\r
+            // calculate its MD5 digest value\r
+            // \r
+            md5.update(ffsXmlObject.xmlText().getBytes());\r
+        } catch (Exception e) {\r
+            EdkLog.log(EdkLog.EDK_WARNING, "Warning: " + e.getMessage());\r
+            return;\r
+        }\r
+\r
+        //\r
+        // get the MD5 digest value\r
+        // \r
+        byte[] digest = md5.digest();\r
+\r
+        //\r
+        // put the digest in a file named "ffs.md5" if it doesn't exist, otherwise\r
+        // we will compare the digest in the file with the one just calculated\r
+        // \r
+        digestFilePath += File.separator + "ffs.md5";\r
+        File digestFile = new File(digestFilePath);\r
+        if (digestFile.exists()) {\r
+            byte[] oldDigest = new byte[digest.length];\r
+            try {\r
+                FileInputStream fIn = new FileInputStream(digestFile);\r
+                fIn.read(oldDigest);\r
+                fIn.close();\r
+            } catch (Exception e) {\r
+                throw new BuildException(e.getMessage());\r
+            }\r
+\r
+            boolean noChange = true;\r
+            for (int i = 0; i < oldDigest.length; ++i) {\r
+                if (digest[i] != oldDigest[i]) {\r
+                    noChange = false;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if (noChange) {\r
+                return;\r
+            }\r
+        }\r
+\r
+        //\r
+        // update the "ffs.md5" file content with new digest value\r
+        // \r
+        try {\r
+            FileOutputStream fOut = new FileOutputStream(digestFile);\r
+            fOut.write(digest);\r
+            fOut.close();\r
+        } catch (Exception e) {\r
+            throw new BuildException(e.getMessage());\r
+        }\r
+    }\r
 }\r