]> git.saurik.com Git - android/aapt.git/commitdiff
Add dependency generation to Aapt for R.java
authorJosiah Gaskin <josiahgaskin@google.com>
Tue, 14 Jun 2011 20:57:09 +0000 (13:57 -0700)
committerJosiah Gaskin <josiahgaskin@google.com>
Mon, 27 Jun 2011 23:44:57 +0000 (16:44 -0700)
Make Aapt generate a dependency file in the location specified
by RClassDir for R.java if the --generate-dependencies flag is set.
This dependency file is then read by the ant exec loop task
to see whether to recreate R.java.

Change-Id: I7152dac86b6ea0e448ef65e3a95694afe233c789

AaptAssets.cpp
AaptAssets.h
Bundle.h
Command.cpp
Main.cpp
Main.h
Resource.cpp
ZipFile.h

index 2b2ec7b3e9a7c1c6ec458c4e5a60c279ebd106ba..9c5a51400465f66f7ae77b5e1adaa742dbf14066 100644 (file)
@@ -1393,10 +1393,10 @@ status_t AaptDir::addLeafFile(const String8& leafName, const sp<AaptFile>& file)
 }
 
 ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
-                            const AaptGroupEntry& kind, const String8& resType)
+                            const AaptGroupEntry& kind, const String8& resType,
+                            sp<FilePathStore>& fullResPaths)
 {
     Vector<String8> fileNames;
-
     {
         DIR* dir = NULL;
 
@@ -1419,9 +1419,14 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
             if (isHidden(srcDir.string(), entry->d_name))
                 continue;
 
-            fileNames.add(String8(entry->d_name));
+            String8 name(entry->d_name);
+            fileNames.add(name);
+            // Add fully qualified path for dependency purposes
+            // if we're collecting them
+            if (fullResPaths != NULL) {
+                fullResPaths->add(srcDir.appendPathCopy(name));
+            }
         }
-
         closedir(dir);
     }
 
@@ -1448,7 +1453,7 @@ ssize_t AaptDir::slurpFullTree(Bundle* bundle, const String8& srcDir,
                 notAdded = true;
             }
             ssize_t res = subdir->slurpFullTree(bundle, pathName, kind,
-                                                resType);
+                                                resType, fullResPaths);
             if (res < NO_ERROR) {
                 return res;
             }
@@ -1680,7 +1685,7 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
         sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));
         AaptGroupEntry group;
         count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,
-                                            String8());
+                                            String8(), mFullResPaths);
         if (count < 0) {
             totalCount = count;
             goto bail;
@@ -1711,6 +1716,7 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
                     sp<AaptAssets> nextOverlay = new AaptAssets();
                     current->setOverlay(nextOverlay);
                     current = nextOverlay;
+                    current->setFullResPaths(mFullResPaths);
                 }
                 count = current->slurpResourceTree(bundle, String8(res));
 
@@ -1753,7 +1759,7 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
          * guarantees about ordering, so we're okay with an inorder search
          * using whatever order the OS happens to hand back to us.
          */
-        count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8());
+        count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullResPaths);
         if (count < 0) {
             /* failure; report error and remove archive */
             totalCount = count;
@@ -1779,9 +1785,10 @@ bail:
 
 ssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir,
                                     const AaptGroupEntry& kind,
-                                    const String8& resType)
+                                    const String8& resType,
+                                    sp<FilePathStore>& fullResPaths)
 {
-    ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType);
+    ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths);
     if (res > 0) {
         mGroupEntries.add(kind);
     }
@@ -1843,7 +1850,7 @@ ssize_t AaptAssets::slurpResourceTree(Bundle* bundle, const String8& srcDir)
         if (type == kFileTypeDirectory) {
             sp<AaptDir> dir = makeDir(String8(entry->d_name));
             ssize_t res = dir->slurpFullTree(bundle, subdirName, group,
-                                                resType);
+                                                resType, mFullResPaths);
             if (res < 0) {
                 count = res;
                 goto bail;
index eeb00c0be1ba0fe813b5cb0bcba3eecbfb82aeb2..cdde5adc77aa5b2e91a04f1d5c38d440c8eb508c 100644 (file)
@@ -130,6 +130,7 @@ inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry&
 }
 
 class AaptGroup;
+class FilePathStore;
 
 /**
  * A single asset file we know about.
@@ -259,7 +260,8 @@ public:
     virtual ssize_t slurpFullTree(Bundle* bundle,
                                   const String8& srcDir,
                                   const AaptGroupEntry& kind,
-                                  const String8& resType);
+                                  const String8& resType,
+                                  sp<FilePathStore>& fullResPaths);
 
     /*
      * Perform some sanity checks on the names of files and directories here.
@@ -474,6 +476,14 @@ public:
     ResourceTypeSet();
 };
 
+// Storage for lists of fully qualified paths for
+// resources encountered during slurping.
+class FilePathStore : public RefBase,
+                      public Vector<String8>
+{
+public:
+    FilePathStore();
+};
 
 /**
  * Asset hierarchy being operated on.
@@ -507,7 +517,8 @@ public:
     virtual ssize_t slurpFullTree(Bundle* bundle,
                                   const String8& srcDir,
                                   const AaptGroupEntry& kind,
-                                  const String8& resType);
+                                  const String8& resType,
+                                  sp<FilePathStore>& fullResPaths);
 
     ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);
     ssize_t slurpResourceZip(Bundle* bundle, const char* filename);
@@ -535,6 +546,10 @@ public:
     inline void 
         setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; }
 
+    inline sp<FilePathStore>& getFullResPaths() { return mFullResPaths; }
+    inline void
+        setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; }
+
 private:
     String8 mPackage;
     SortedVector<AaptGroupEntry> mGroupEntries;
@@ -548,6 +563,8 @@ private:
 
     sp<AaptAssets> mOverlay;
     KeyedVector<String8, sp<ResourceTypeSet> >* mRes;
+
+    sp<FilePathStore> mFullResPaths;
 };
 
 #endif // __AAPT_ASSETS_H
index a32aa7f5c97ec8f6cd464a48ba38458d907d8bd4..56fe5249f0184531bf1d987e3b5bff1581883bee 100644 (file)
--- a/Bundle.h
+++ b/Bundle.h
@@ -41,7 +41,8 @@ public:
           mCompressionMethod(0), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
           mIsOverlayPackage(false),
-          mAutoAddOverlay(false), mAssetSourceDir(NULL), mProguardFile(NULL),
+          mAutoAddOverlay(false), mGenDependencies(false),
+          mAssetSourceDir(NULL), mProguardFile(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
@@ -97,6 +98,8 @@ public:
     void setIsOverlayPackage(bool val) { mIsOverlayPackage = val; }
     bool getAutoAddOverlay() { return mAutoAddOverlay; }
     void setAutoAddOverlay(bool val) { mAutoAddOverlay = val; }
+    bool getGenDependencies() { return mGenDependencies; }
+    void setGenDependencies(bool val) { mGenDependencies = val; }
 
     /*
      * Input options.
@@ -226,6 +229,7 @@ private:
     const char* mInstrumentationPackageNameOverride;
     bool        mIsOverlayPackage;
     bool        mAutoAddOverlay;
+    bool        mGenDependencies;
     const char* mAssetSourceDir;
     const char* mProguardFile;
     const char* mAndroidManifestFile;
index c7dfb8fdf362069ad3bdf02ca56c023dd01f49b3..89f45df1b853f817986e7c23c2d98a64412711b2 100644 (file)
@@ -1353,6 +1353,8 @@ int doPackage(Bundle* bundle)
     status_t err;
     sp<AaptAssets> assets;
     int N;
+    FILE* fp;
+    String8 dependencyFile;
 
     // -c zz_ZZ means do pseudolocalization
     ResourceFilter filter;
@@ -1387,6 +1389,13 @@ int doPackage(Bundle* bundle)
 
     // Load the assets.
     assets = new AaptAssets();
+
+    // Set up the resource gathering in assets if we're trying to make R.java
+    if (bundle->getGenDependencies()) {
+        sp<FilePathStore> pathStore = new FilePathStore;
+        assets->setFullResPaths(pathStore);
+    }
+
     err = assets->slurpFromArgs(bundle);
     if (err < 0) {
         goto bail;
@@ -1396,7 +1405,7 @@ int doPackage(Bundle* bundle)
         assets->print();
     }
 
-    // If they asked for any files that need to be compiled, do so.
+    // If they asked for any fileAs that need to be compiled, do so.
     if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {
         err = buildResources(bundle, assets);
         if (err != 0) {
@@ -1410,18 +1419,26 @@ int doPackage(Bundle* bundle)
         goto bail;
     }
 
+    if (bundle->getGenDependencies()) {
+        dependencyFile = String8(bundle->getRClassDir());
+        // Make sure we have a clean dependency file to start with
+        dependencyFile.appendPath("R.d");
+        fp = fopen(dependencyFile, "w");
+        fclose(fp);
+    }
+
     // Write out R.java constants
     if (assets->getPackage() == assets->getSymbolsPrivatePackage()) {
         if (bundle->getCustomPackage() == NULL) {
             err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
             // Copy R.java for libraries
             if (bundle->getExtraPackages() != NULL) {
-                // Split on semicolon
+                // Split on colon
                 String8 libs(bundle->getExtraPackages());
-                char* packageString = strtok(libs.lockBuffer(libs.length()), ";");
+                char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
                 while (packageString != NULL) {
                     err = writeResourceSymbols(bundle, assets, String8(packageString), true);
-                    packageString = strtok(NULL, ";");
+                    packageString = strtok(NULL, ":");
                 }
                 libs.unlockBuffer();
             }
@@ -1443,6 +1460,19 @@ int doPackage(Bundle* bundle)
         }
     }
 
+    if (bundle->getGenDependencies()) {
+        // Now that writeResourceSymbols has taken care of writing the
+        // dependency targets to the dependencyFile, we'll write the
+        // pre-requisites.
+        fp = fopen(dependencyFile, "a+");
+        fprintf(fp, " : ");
+        err = writeDependencyPreReqs(bundle, assets, fp);
+
+        // Also manually add the AndroidManifeset since it's a non-asset
+        fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
+        fclose(fp);
+    }
+
     // Write out the ProGuard file
     err = writeProguardFile(bundle, assets);
     if (err < 0) {
index 732541d7f4b0ac52ce54f5d8019d8911f350c722..8edb5b53b194c96cddad9efcbbf4fad44add09af 100644 (file)
--- a/Main.cpp
+++ b/Main.cpp
@@ -146,7 +146,9 @@ void usage(void)
         "   --custom-package\n"
         "       generates R.java into a different package.\n"
         "   --extra-packages\n"
-        "       generate R.java for libraries. Separate libraries with ';'.\n"
+        "       generate R.java for libraries. Separate libraries with ':'.\n"
+        "   --generate-dependencies\n"
+        "       generate a dependency file for R.java.\n"
         "   --auto-add-overlay\n"
         "       Automatically add resources that are only in overlays.\n"
         "   --rename-manifest-package\n"
@@ -486,6 +488,8 @@ int main(int argc, char* const argv[])
                         goto bail;
                     }
                     bundle.setExtraPackages(argv[0]);
+                } else if (strcmp(cp, "-generate-dependencies") == 0) {
+                    bundle.setGenDependencies(true);
                 } else if (strcmp(cp, "-utf16") == 0) {
                     bundle.setWantUTF16(true);
                 } else if (strcmp(cp, "-rename-manifest-package") == 0) {
diff --git a/Main.h b/Main.h
index 3ba4f39062f81aeb71a23d494ce65ad7432baa43..1df114430fd3869ff8b1f1d3f20bf01825786860 100644 (file)
--- a/Main.h
+++ b/Main.h
@@ -46,4 +46,5 @@ int dumpResources(Bundle* bundle);
 String8 getAttribute(const ResXMLTree& tree, const char* ns,
                             const char* attr, String8* outError);
 
+status_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp);
 #endif // __MAIN_H
index 0a4f24f26df217860a9c3bea381debae888bfd9f..a603314709ab9c1c1a31da4a052e5f3e77d8da4b 100644 (file)
@@ -51,6 +51,12 @@ ResourceTypeSet::ResourceTypeSet()
 {
 }
 
+FilePathStore::FilePathStore()
+    :RefBase(),
+     Vector<String8>()
+{
+}
+
 class ResourceDirIterator
 {
 public:
@@ -1849,6 +1855,16 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
             return err;
         }
         fclose(fp);
+
+        if (bundle->getGenDependencies()) {
+            // Add this R.java to the dependency file
+            String8 dependencyFile(bundle->getRClassDir());
+            dependencyFile.appendPath("R.d");
+
+            fp = fopen(dependencyFile.string(), "a");
+            fprintf(fp,"%s \\\n", dest.string());
+            fclose(fp);
+        }
     }
 
     return NO_ERROR;
@@ -2170,3 +2186,16 @@ writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)
 
     return err;
 }
+
+status_t
+writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp)
+{
+    status_t deps = -1;
+    sp<FilePathStore> files = assets->getFullResPaths();
+    for (size_t file_i = 0; file_i < files->size(); ++file_i) {
+        // Add the full file path to the dependency file
+        fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
+        deps++;
+    }
+    return deps;
+}
\ No newline at end of file
index dbbd072d1692decfe2b79e855d5026f95ca2c8a2..78775502884bba157c7be86b88f6c3d9fd7e561f 100644 (file)
--- a/ZipFile.h
+++ b/ZipFile.h
@@ -57,7 +57,7 @@ public:
     /*
      * Open a new or existing archive.
      */
-    typedef enum {
+    enum {
         kOpenReadOnly   = 0x01,
         kOpenReadWrite  = 0x02,
         kOpenCreate     = 0x04,     // create if it doesn't exist