diff options
| author | Xavier Ducrohet <xav@android.com> | 2011-10-19 12:24:40 -0700 | 
|---|---|---|
| committer | Xavier Ducrohet <xav@android.com> | 2011-10-28 10:34:22 -0700 | 
| commit | 16ed545d6175d2afde14b9585eed1feb28ce6364 (patch) | |
| tree | 767c4722ba06c5a6b74f213f155517056f5db971 /eclipse | |
| parent | 3affaa9a49c7877de7c352d6021318b5fb51e178 (diff) | |
| download | sdk-16ed545d6175d2afde14b9585eed1feb28ce6364.zip sdk-16ed545d6175d2afde14b9585eed1feb28ce6364.tar.gz sdk-16ed545d6175d2afde14b9585eed1feb28ce6364.tar.bz2 | |
Fix to library projects in Eclipse.
- Properly setup source attachment for library jar files.
- Force refresh the bin folder of libraries to make sure main projects
  pick up the changes.
- Force update the library container of parent projects when a library is
  recompile. This makes sure the parent projects are recompiled when a library
  code change.
- Fix how we check the libraries' res folders exist. This ensures we pick up
  all the res folders even if Eclipse isn't aware of them due to refresh issues.
Change-Id: Ie4b7ae770cfc782589a983ec654a11a1dfa4ef2d
Diffstat (limited to 'eclipse')
3 files changed, 92 insertions, 23 deletions
| diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java index 3209ec1..dad3c5c 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BuildHelper.java @@ -214,27 +214,30 @@ public class BuildHelper {              assetsFolder = null;          } -        IPath cacheLocation = cacheFolder.getLocation(); +        // list of res folder (main project + maybe libraries) +        ArrayList<String> osResPaths = new ArrayList<String>(); +          IPath resLocation = resFolder.getLocation();          IPath manifestLocation = manifestFile.getLocation();          if (resLocation != null && manifestLocation != null) { -            // list of res folder (main project + maybe libraries) -            ArrayList<String> osResPaths = new ArrayList<String>(); -            osResPaths.add(cacheLocation.toOSString()); // PNG crunch cache -            osResPaths.add(resLocation.toOSString()); //main project -            // libraries? +            // png cache folder first. +            addFolderToList(osResPaths, cacheFolder); + +            // regular res folder next. +            osResPaths.add(resLocation.toOSString()); + +            // then libraries              if (libProjects != null) {                  for (IProject lib : libProjects) { +                    // png cache folder first                      IFolder libCacheFolder = lib.getFolder(AdtConstants.WS_CRUNCHCACHE); -                    if (libCacheFolder.exists()) { -                        osResPaths.add(libCacheFolder.getLocation().toOSString()); -                    } +                    addFolderToList(osResPaths, libCacheFolder); + +                    // regular res folder next.                      IFolder libResFolder = lib.getFolder(AdtConstants.WS_RESOURCES); -                    if (libResFolder.exists()) { -                        osResPaths.add(libResFolder.getLocation().toOSString()); -                    } +                    addFolderToList(osResPaths, libResFolder);                  }              } @@ -260,6 +263,19 @@ public class BuildHelper {      }      /** +     * Adds os path of a folder to a list only if the folder actually exists. +     * @param pathList +     * @param folder +     */ +    private void addFolderToList(List<String> pathList, IFolder folder) { +        // use a File instead of the IFolder API to ignore workspace refresh issue. +        File testFile = new File(folder.getLocation().toOSString()); +        if (testFile.isDirectory()) { +            pathList.add(testFile.getAbsolutePath()); +        } +    } + +    /**       * Makes a final package signed with the debug key.       *       * Packages the dex files, the temporary resource file into the final package file. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java index 6c2af35..f3d546a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PostCompilerBuilder.java @@ -31,6 +31,7 @@ import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;  import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;  import com.android.ide.eclipse.adt.internal.project.ApkInstallManager;  import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.LibraryClasspathContainerInitializer;  import com.android.ide.eclipse.adt.internal.project.ProjectHelper;  import com.android.ide.eclipse.adt.internal.sdk.ProjectState;  import com.android.ide.eclipse.adt.internal.sdk.Sdk; @@ -294,6 +295,7 @@ public class PostCompilerBuilder extends BaseBuilder {              // get the android output folder              IFolder androidOutputFolder = BaseProjectHelper.getAndroidOutputFolder(project); +            IFolder resOutputFolder = androidOutputFolder.getFolder(SdkConstants.FD_RES);              // now we need to get the classpath list              List<IPath> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject); @@ -410,6 +412,18 @@ public class PostCompilerBuilder extends BaseBuilder {                      mConvertToDex = true;                  } +                // also update the crunch cache if needed. +                if (mUpdateCrunchCache) { +                    BuildHelper helper = new BuildHelper(project, +                            mOutStream, mErrStream, +                            true /*debugMode*/, +                            AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE); +                    updateCrunchCache(project, helper); + +                    // refresh recursively bin/res folder +                    resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor); +                } +                  if (mConvertToDex) { // in this case this means some class files changed and                                       // we need to update the jar file.                      IFolder javaOutputFolder = BaseProjectHelper.getJavaOutputFolder(project); @@ -417,15 +431,15 @@ public class PostCompilerBuilder extends BaseBuilder {                      writeLibraryPackage(jarIFile, project, javaOutputFolder,                              referencedJavaProjects);                      saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX, mConvertToDex = false); -                } -                // also update the crunch cache if needed. -                if (mUpdateCrunchCache) { -                    BuildHelper helper = new BuildHelper(project, -                            mOutStream, mErrStream, -                            true /*debugMode*/, -                            AdtPrefs.getPrefs().getBuildVerbosity() == BuildVerbosity.VERBOSE); -                    updateCrunchCache(project, helper); +                    // refresh the bin folder content with no recursion to update the library +                    // jar file. +                    androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor); + +                    // Also update the projects. The only way to force recompile them is to +                    // reset the library container. +                    List<ProjectState> parentProjects = projectState.getParentProjects(); +                    LibraryClasspathContainerInitializer.updateProject(parentProjects);                  }                  return allRefProjects; @@ -549,6 +563,9 @@ public class PostCompilerBuilder extends BaseBuilder {                      if (updateCrunchCache(project, helper) == false) {                          return allRefProjects;                      } + +                    // refresh recursively bin/res folder +                    resOutputFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);                  }                  // Check if we need to package the resources. @@ -690,7 +707,7 @@ public class PostCompilerBuilder extends BaseBuilder {                  // we are done. -                // get the resource to bin +                // refresh the bin folder content with no recursion.                  androidOutputFolder.refreshLocal(IResource.DEPTH_ONE, monitor);                  // build has been done. reset the state of the builder diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java index 6540038..e31d70d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/LibraryClasspathContainerInitializer.java @@ -24,6 +24,8 @@ import com.android.ide.eclipse.adt.internal.sdk.Sdk;  import org.eclipse.core.resources.IFile;  import org.eclipse.core.resources.IFolder;  import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin;  import org.eclipse.core.runtime.CoreException;  import org.eclipse.core.runtime.IPath;  import org.eclipse.core.runtime.NullProgressMonitor; @@ -70,6 +72,26 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit          }      } +    /** +     * Updates the {@link IJavaProject} objects with new library. +     * @param androidProjects the projects to update. +     * @return <code>true</code> if success, <code>false</code> otherwise. +     */ +    public static boolean updateProject(List<ProjectState> projects) { +        List<IJavaProject> javaProjectList = new ArrayList<IJavaProject>(projects.size()); +        for (ProjectState p : projects) { +            IJavaProject javaProject = JavaCore.create(p.getProject()); +            if (javaProject != null) { +                javaProjectList.add(javaProject); +            } +        } + +        IJavaProject[] javaProjects = javaProjectList.toArray( +                new IJavaProject[javaProjectList.size()]); + +        return updateProjects(javaProjects); +    } +      @Override      public void initialize(IPath containerPath, IJavaProject project) throws CoreException {          if (AdtConstants.CONTAINER_LIBRARIES.equals(containerPath.toString())) { @@ -132,6 +154,8 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit          List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(); +        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); +          List<IProject> libProjects = state.getFullLibraryProjects();          for (IProject libProject : libProjects) {              // get the project output @@ -141,10 +165,22 @@ public class LibraryClasspathContainerInitializer extends ClasspathContainerInit                  IFile jarIFile = outputFolder.getFile(libProject.getName().toLowerCase() +                          AdtConstants.DOT_JAR); +                // get the source folder for the library project +                List<IPath> srcs = BaseProjectHelper.getSourceClasspaths(libProject); +                // find the first non-derived source folder. +                IPath sourceFolder = null; +                for (IPath src : srcs) { +                    IFolder srcFolder = workspaceRoot.getFolder(src); +                    if (srcFolder.isDerived() == false) { +                        sourceFolder = src; +                        break; +                    } +                } +                  IClasspathEntry entry = JavaCore.newLibraryEntry(                          jarIFile.getLocation(), -                        libProject.getLocation(), // source attachment path -                        null);                    // default source attachment root path. +                        sourceFolder, // source attachment path +                        null);        // default source attachment root path.                  entries.add(entry);              } | 
