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 | |
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
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); } |