mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
external compiler: delete output directories on rebuild for all targets
This commit is contained in:
@@ -7,6 +7,7 @@ import org.jetbrains.jps.indices.IgnoredFileIndex;
|
||||
import org.jetbrains.jps.indices.ModuleExcludeIndex;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -44,6 +45,9 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
|
||||
@NotNull
|
||||
public abstract String getPresentableName();
|
||||
|
||||
@Nullable
|
||||
public abstract File getOutputDir(BuildDataPaths paths);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getPresentableName();
|
||||
|
||||
@@ -305,31 +305,19 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
private void clearOutputs(CompileContext context) throws ProjectBuildException, IOException {
|
||||
final MultiMap<File, ModuleBuildTarget> rootsToDelete = new MultiMapBasedOnSet<File, ModuleBuildTarget>();
|
||||
final Set<File> annotationOutputs = new HashSet<File>(); // separate collection because no root intersection checks needed for annotation generated sources
|
||||
final MultiMap<File, BuildTarget<?>> rootsToDelete = new MultiMapBasedOnSet<File,BuildTarget<?>>();
|
||||
final Set<File> allSourceRoots = new HashSet<File>();
|
||||
|
||||
final ProjectPaths paths = context.getProjectPaths();
|
||||
|
||||
for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) {
|
||||
for (ModuleBuildTarget target : context.getProjectDescriptor().getBuildTargetIndex().getAllTargets(type)) {
|
||||
final File out = paths.getModuleOutputDir(target.getModule(), target.isTests());
|
||||
if (out != null) {
|
||||
rootsToDelete.putValue(out, target);
|
||||
}
|
||||
|
||||
final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(target.getModule());
|
||||
if (profile.isEnabled()) {
|
||||
File annotationOut =
|
||||
paths.getAnnotationProcessorGeneratedSourcesOutputDir(target.getModule(), target.isTests(), profile.getGeneratedSourcesDirectoryName());
|
||||
if (annotationOut != null) {
|
||||
annotationOutputs.add(annotationOut);
|
||||
}
|
||||
}
|
||||
ProjectDescriptor projectDescriptor = context.getProjectDescriptor();
|
||||
for (BuildTarget<?> target : projectDescriptor.getBuildTargetIndex().getAllTargets()) {
|
||||
File outputDir = target.getOutputDir(projectDescriptor.dataManager.getDataPaths());
|
||||
if (outputDir != null) {
|
||||
rootsToDelete.putValue(outputDir, target);
|
||||
}
|
||||
}
|
||||
|
||||
ProjectDescriptor projectDescriptor = context.getProjectDescriptor();
|
||||
for (BuildTargetType<?> type : JavaModuleBuildTargetType.ALL_TYPES) {
|
||||
for (BuildTarget<?> target : projectDescriptor.getBuildTargetIndex().getAllTargets(type)) {
|
||||
for (BuildRootDescriptor descriptor : projectDescriptor.getBuildRootIndex().getTargetRoots(target, context)) {
|
||||
@@ -340,7 +328,7 @@ public class IncProjectBuilder {
|
||||
|
||||
// check that output and source roots are not overlapping
|
||||
final List<File> filesToDelete = new ArrayList<File>();
|
||||
for (Map.Entry<File, Collection<ModuleBuildTarget>> entry : rootsToDelete.entrySet()) {
|
||||
for (Map.Entry<File, Collection<BuildTarget<?>>> entry : rootsToDelete.entrySet()) {
|
||||
context.checkCanceled();
|
||||
boolean okToDelete = true;
|
||||
final File outputRoot = entry.getKey();
|
||||
@@ -366,12 +354,24 @@ public class IncProjectBuilder {
|
||||
else {
|
||||
context.processMessage(new CompilerMessage(BUILD_NAME, BuildMessage.Kind.WARNING, "Output path " + outputRoot.getPath() + " intersects with a source root. The output cannot be cleaned."));
|
||||
// clean only those files we are aware of
|
||||
for (ModuleBuildTarget target : entry.getValue()) {
|
||||
for (BuildTarget<?> target : entry.getValue()) {
|
||||
clearOutputFiles(context, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Set<File> annotationOutputs = new HashSet<File>(); // separate collection because no root intersection checks needed for annotation generated sources
|
||||
for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) {
|
||||
for (ModuleBuildTarget target : projectDescriptor.getBuildTargetIndex().getAllTargets(type)) {
|
||||
final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(target.getModule());
|
||||
if (profile.isEnabled()) {
|
||||
File annotationOut = paths.getAnnotationProcessorGeneratedSourcesOutputDir(target.getModule(), target.isTests(), profile.getGeneratedSourcesDirectoryName());
|
||||
if (annotationOut != null) {
|
||||
annotationOutputs.add(annotationOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (File annotationOutput : annotationOutputs) {
|
||||
// do not delete output root itself to avoid lots of unnecessary "roots_changed" events in IDEA
|
||||
final File[] children = annotationOutput.listFiles();
|
||||
@@ -649,26 +649,23 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
private static void createClasspathIndex(final ModuleChunk chunk) {
|
||||
final Set<File> outputPaths = new LinkedHashSet<File>();
|
||||
final Set<File> outputDirs = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
final File outputDir = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), target.isTests());
|
||||
if (outputDir != null) {
|
||||
outputPaths.add(outputDir);
|
||||
}
|
||||
}
|
||||
for (File outputRoot : outputPaths) {
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outputRoot, CLASSPATH_INDEX_FINE_NAME)));
|
||||
File outputDir = target.getOutputDir();
|
||||
if (outputDir != null && outputDirs.add(outputDir)) {
|
||||
try {
|
||||
writeIndex(writer, outputRoot, "");
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outputDir, CLASSPATH_INDEX_FINE_NAME)));
|
||||
try {
|
||||
writeIndex(writer, outputDir, "");
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
catch (IOException e) {
|
||||
// Ignore. Failed to create optional classpath index
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Ignore. Failed to create optional classpath index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,7 +961,7 @@ public class IncProjectBuilder {
|
||||
if (context.isMake()) {
|
||||
if (pd.fsState.markInitialScanPerformed(target)) {
|
||||
boolean forceMarkDirty = false;
|
||||
final File currentOutput = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
|
||||
final File currentOutput = target.getOutputDir();
|
||||
if (currentOutput != null) {
|
||||
final Pair<String, String> outputsPair = pd.dataManager.getOutputRootsLayout().getState(target.getModuleName());
|
||||
if (outputsPair != null) {
|
||||
@@ -1011,7 +1008,7 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
private static void updateOutputRootsLayout(CompileContext context, ModuleBuildTarget target) throws IOException {
|
||||
final File currentOutput = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
|
||||
final File currentOutput = target.getOutputDir();
|
||||
if (currentOutput == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package org.jetbrains.jps.incremental;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.BuildRootIndex;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths;
|
||||
import org.jetbrains.jps.indices.IgnoredFileIndex;
|
||||
import org.jetbrains.jps.indices.ModuleExcludeIndex;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.jps.model.java.JpsJavaDependenciesEnumerator;
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -41,6 +42,17 @@ public class ModuleBuildTarget extends BuildTarget<JavaSourceRootDescriptor> {
|
||||
myModule = module;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public File getOutputDir() {
|
||||
return JpsJavaExtensionService.getInstance().getOutputDirectory(myModule, myTargetType.isTests());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public File getOutputDir(BuildDataPaths paths) {
|
||||
return getOutputDir();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JpsModule getModule() {
|
||||
return myModule;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.jetbrains.jps.incremental.artifacts;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.BuildRootIndex;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
@@ -17,6 +19,7 @@ import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -110,4 +113,11 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
|
||||
public String getPresentableName() {
|
||||
return "Artifact '" + myArtifact.getName() + "'";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public File getOutputDir(BuildDataPaths paths) {
|
||||
String outputPath = myArtifact.getOutputPath();
|
||||
return !StringUtil.isEmpty(outputPath) ? new File(FileUtil.toSystemDependentName(outputPath)) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,11 +368,13 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
instrumentForms(context, chunk, chunkSourcePath, finder, forms, outputSink);
|
||||
JpsUiDesignerConfiguration configuration = JpsUiDesignerExtensionService.getInstance().getUiDesignerConfiguration(
|
||||
pd.getProject());
|
||||
if (configuration != null && configuration.isCopyFormsRuntimeToOutput() && !chunk.containsTests()) {
|
||||
for (JpsModule module : chunk.getModules()) {
|
||||
final File outputDir = paths.getModuleOutputDir(module, false);
|
||||
if (outputDir != null) {
|
||||
CopyResourcesUtil.copyFormsRuntime(outputDir.getAbsolutePath(), false);
|
||||
if (configuration != null && configuration.isCopyFormsRuntimeToOutput()) {
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
if (!target.isTests()) {
|
||||
final File outputDir = target.getOutputDir();
|
||||
if (outputDir != null) {
|
||||
CopyResourcesUtil.copyFormsRuntime(outputDir.getAbsolutePath(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -888,7 +890,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
private static Map<File, Set<File>> buildOutputDirectoriesMap(CompileContext context, ModuleChunk chunk) {
|
||||
final Map<File, Set<File>> map = new LinkedHashMap<File, Set<File>>();
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
final File outputDir = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), target.isTests());
|
||||
final File outputDir = target.getOutputDir();
|
||||
if (outputDir == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+12
-1
@@ -2,10 +2,10 @@ package org.jetbrains.jps.incremental.artifacts;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.util.PathUtil;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.library.JpsLibrary;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.util.JpsPathUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -269,4 +269,15 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testClearOutputOnRebuild() throws IOException {
|
||||
String file = createFile("d/a.txt");
|
||||
JpsArtifact a = addArtifact(root().parentDirCopy(file));
|
||||
buildAll();
|
||||
new File(a.getOutputPath(), "b.txt").createNewFile();
|
||||
buildAllAndAssertUpToDate();
|
||||
assertOutput(a, fs().file("a.txt").file("b.txt"));
|
||||
|
||||
rebuildAll();
|
||||
assertOutput(a, fs().file("a.txt"));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ import java.util.*;
|
||||
public class JpsJavaCompilerConfigurationImpl extends JpsCompositeElementBase<JpsJavaCompilerConfigurationImpl> implements JpsJavaCompilerConfiguration {
|
||||
public static final JpsElementChildRole<JpsJavaCompilerConfiguration> ROLE = JpsElementChildRoleBase.create("compiler configuration");
|
||||
private boolean myAddNotNullAssertions = true;
|
||||
private boolean myClearOutputDirectoryOnRebuild;
|
||||
private boolean myClearOutputDirectoryOnRebuild = true;
|
||||
private JpsCompilerExcludes myCompilerExcludes = new JpsCompilerExcludesImpl();
|
||||
private List<String> myResourcePatterns = new ArrayList<String>();
|
||||
private List<ProcessorConfigProfile> myAnnotationProcessingProfiles = new ArrayList<ProcessorConfigProfile>();
|
||||
|
||||
+8
-1
@@ -29,6 +29,7 @@ import org.jetbrains.jps.indices.ModuleExcludeIndex;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -105,7 +106,13 @@ public class AndroidProjectBuildTarget extends BuildTarget<BuildRootDescriptor>
|
||||
public String getPresentableName() {
|
||||
return "Android " + myKind.name();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public File getOutputDir(BuildDataPaths paths) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class TargetType extends BuildTargetType<AndroidProjectBuildTarget> {
|
||||
public static final TargetType INSTANCE = new TargetType();
|
||||
|
||||
|
||||
+1
-1
@@ -189,7 +189,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
private static Map<ModuleBuildTarget, String> getCanonicalModuleOutputs(CompileContext context, ModuleChunk chunk) {
|
||||
Map<ModuleBuildTarget, String> finalOutputs = new HashMap<ModuleBuildTarget, String>();
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
File moduleOutputDir = context.getProjectPaths().getModuleOutputDir(target.getModule(), target.isTests());
|
||||
File moduleOutputDir = target.getOutputDir();
|
||||
if (moduleOutputDir == null) {
|
||||
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Output directory not specified for module " + target.getModuleName()));
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user