mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
standalone JPS distribution
This commit is contained in:
Generated
+1
@@ -76,6 +76,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/model-api/jps-model-api.iml" filepath="$PROJECT_DIR$/jps/model-api/jps-model-api.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" filepath="$PROJECT_DIR$/jps/model-impl/jps-model-impl.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" filepath="$PROJECT_DIR$/jps/model-serialization/jps-model-serialization.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" filepath="$PROJECT_DIR$/jps/standalone-builder/jps-standalone-builder.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/jps/jps-tests.iml" filepath="$PROJECT_DIR$/jps/jps-tests.iml" group="jps" />
|
||||
<module fileurl="file://$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-base-openapi/jsp-base-openapi.iml" group="java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" filepath="$PROJECT_DIR$/java/jsp-openapi/jsp-openapi.iml" group="java" />
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<orderEntry type="library" scope="PROVIDED" name="Groovy" level="project" />
|
||||
<orderEntry type="library" name="Ant" level="project" />
|
||||
<orderEntry type="library" name="JPS" level="project" />
|
||||
<orderEntry type="module" module-name="jps-model-api" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ target('default': "Developers update") {
|
||||
ant.delete(dir: patchedDescriptorDir)
|
||||
}
|
||||
|
||||
target('build-jps': 'Build JPS standalone distribution') {
|
||||
println("Building jps standalone distribution")
|
||||
layout_jps("$home/build/lib/jps")
|
||||
}
|
||||
|
||||
String appInfoFileName() {
|
||||
return "idea/IdeaApplicationInfo.xml"
|
||||
}
|
||||
@@ -492,6 +497,32 @@ def reorder(String home, String targetDirectory) {
|
||||
}
|
||||
}
|
||||
|
||||
def layout_jps(String target) {
|
||||
layout(target) {
|
||||
jar("util.jar") {
|
||||
module("annotations")
|
||||
module("util-rt")
|
||||
module("util")
|
||||
}
|
||||
jar("jps-model.jar") {
|
||||
module("jps-model")
|
||||
module("jps-model-api")
|
||||
module("jps-model-impl")
|
||||
module("jps-model-serialization")
|
||||
}
|
||||
jar("jps-builders.jar") {
|
||||
module("forms_rt")
|
||||
module("forms-compiler")
|
||||
module("instrumentation-util")
|
||||
module("jps-builders")
|
||||
module("jps-standalone-builder")
|
||||
}
|
||||
jar("jps-groovy-plugin.jar") {
|
||||
module("groovy_rt")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def layout_core(String home, String target) {
|
||||
layout(target) {
|
||||
jar("intellij-core.jar") {
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
package org.jetbrains.jps.cmdline;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ParameterizedRunnable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.ether.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.Project;
|
||||
import org.jetbrains.jps.api.BuildType;
|
||||
import org.jetbrains.jps.api.CanceledStatus;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoader;
|
||||
import org.jetbrains.jps.idea.SystemOutErrorReporter;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.RootDescriptor;
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||
import org.jetbrains.jps.incremental.storage.BuildDataManager;
|
||||
import org.jetbrains.jps.incremental.storage.ProjectTimestamps;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.JpsElementFactory;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class BuildRunner {
|
||||
public static final String IDEA_PROJECT_DIRNAME = ".idea";
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildRunner");
|
||||
private final String myProjectPath;
|
||||
// globals
|
||||
private final Map<String, String> myPathVars;
|
||||
private final String myGlobalEncoding;
|
||||
private final String myIgnorePatterns;
|
||||
// build params
|
||||
private final Set<String> myModules;
|
||||
private BuildType myBuildType;
|
||||
private final List<String> myArtifacts;
|
||||
private final List<String> myFilePaths;
|
||||
private final Map<String, String> myBuilderParams;
|
||||
private final String myGlobalOptionsPath;
|
||||
private boolean myForceCleanCaches;
|
||||
private ParameterizedRunnable<JpsModel> myModelInitializer;
|
||||
|
||||
public BuildRunner(String projectPath, String globalOptionsPath, Map<String, String> pathVars,
|
||||
String globalEncoding,
|
||||
String ignorePatterns,
|
||||
Set<String> modules,
|
||||
BuildType buildType,
|
||||
List<String> artifacts, List<String> filePaths, Map<String, String> builderParams) {
|
||||
myProjectPath = projectPath;
|
||||
myGlobalOptionsPath = globalOptionsPath;
|
||||
myPathVars = pathVars;
|
||||
myGlobalEncoding = globalEncoding;
|
||||
myIgnorePatterns = ignorePatterns;
|
||||
myModules = modules;
|
||||
myBuildType = buildType;
|
||||
myArtifacts = artifacts;
|
||||
myFilePaths = filePaths;
|
||||
myBuilderParams = builderParams;
|
||||
}
|
||||
|
||||
public void setModelInitializer(ParameterizedRunnable<JpsModel> modelInitializer) {
|
||||
myModelInitializer = modelInitializer;
|
||||
}
|
||||
|
||||
public ProjectDescriptor load(MessageHandler msgHandler, File dataStorageRoot, BuildFSState fsState) throws IOException {
|
||||
if (!dataStorageRoot.exists()) {
|
||||
// invoked the very first time for this project. Force full rebuild
|
||||
myBuildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
|
||||
final boolean inMemoryMappingsDelta = System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null;
|
||||
ProjectTimestamps projectTimestamps = null;
|
||||
BuildDataManager dataManager = null;
|
||||
try {
|
||||
projectTimestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta);
|
||||
if (dataManager.versionDiffers()) {
|
||||
myForceCleanCaches = true;
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// second try
|
||||
LOG.info(e);
|
||||
if (projectTimestamps != null) {
|
||||
projectTimestamps.close();
|
||||
}
|
||||
if (dataManager != null) {
|
||||
dataManager.close();
|
||||
}
|
||||
myForceCleanCaches = true;
|
||||
FileUtil.delete(dataStorageRoot);
|
||||
projectTimestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta);
|
||||
// second attempt succeded
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage()));
|
||||
}
|
||||
|
||||
final JpsModel jpsModel = loadJpsModel();
|
||||
final Project project = loadProject();
|
||||
return new ProjectDescriptor(project, jpsModel, fsState, projectTimestamps, dataManager, BuildLoggingManager.DEFAULT);
|
||||
}
|
||||
|
||||
private JpsModel loadJpsModel() {
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
final JpsModel model = JpsElementFactory.getInstance().createModel();
|
||||
try {
|
||||
if (myGlobalOptionsPath != null) {
|
||||
JpsGlobalLoader.loadGlobalSettings(model.getGlobal(), myPathVars, myGlobalOptionsPath);
|
||||
}
|
||||
JpsProjectLoader.loadProject(model.getProject(), myPathVars, myProjectPath);
|
||||
if (myModelInitializer != null) {
|
||||
myModelInitializer.run(model);
|
||||
}
|
||||
LOG.info("New JPS model: " + model.getProject().getModules().size() + " modules, " + model.getProject().getLibraryCollection().getLibraries().size() + " libraries");
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
finally {
|
||||
final long loadTime = System.currentTimeMillis() - start;
|
||||
LOG.info("New JPS model: project " + myProjectPath + " loaded in " + loadTime + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
private Project loadProject() {
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
final Project project = new Project();
|
||||
|
||||
final File projectFile = new File(myProjectPath);
|
||||
|
||||
final String loadPath = isDirectoryBased(projectFile) ? new File(projectFile, IDEA_PROJECT_DIRNAME).getPath() : myProjectPath;
|
||||
IdeaProjectLoader.loadFromPath(project, loadPath, myPathVars, null, new SystemOutErrorReporter(false));
|
||||
final String globalEncoding = myGlobalEncoding;
|
||||
if (!StringUtil.isEmpty(globalEncoding) && project.getProjectCharset() == null) {
|
||||
project.setProjectCharset(globalEncoding);
|
||||
}
|
||||
project.getIgnoredFilePatterns().loadFromString(myIgnorePatterns);
|
||||
return project;
|
||||
}
|
||||
finally {
|
||||
final long loadTime = System.currentTimeMillis() - start;
|
||||
LOG.info("Project " + myProjectPath + " loaded in " + loadTime + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
public void runBuild(ProjectDescriptor pd, CanceledStatus cs, @Nullable Callbacks.ConstantAffectionResolver constantSearch,
|
||||
MessageHandler msgHandler) throws Exception {
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
if (myForceCleanCaches && myModules.isEmpty() && myFilePaths.isEmpty()) {
|
||||
// if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation
|
||||
myBuildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
|
||||
final CompileScope compileScope = createCompilationScope(myBuildType, pd, myModules, myArtifacts, myFilePaths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch);
|
||||
builder.addMessageHandler(msgHandler);
|
||||
try {
|
||||
switch (myBuildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true, myForceCleanCaches);
|
||||
break;
|
||||
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false, myForceCleanCaches);
|
||||
break;
|
||||
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false, myForceCleanCaches);
|
||||
break;
|
||||
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
}
|
||||
break; // break attempts loop
|
||||
}
|
||||
catch (RebuildRequestedException e) {
|
||||
if (attempt == 0) {
|
||||
LOG.info(e);
|
||||
myForceCleanCaches = true;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BuildType getBuildType() {
|
||||
return myBuildType;
|
||||
}
|
||||
|
||||
private static boolean isDirectoryBased(File projectFile) {
|
||||
return !(projectFile.isFile() && projectFile.getName().endsWith(".ipr"));
|
||||
}
|
||||
|
||||
private static CompileScope createCompilationScope(BuildType buildType,
|
||||
ProjectDescriptor pd,
|
||||
Set<String> modules,
|
||||
Collection<String> artifactNames,
|
||||
Collection<String> paths) throws Exception {
|
||||
final Timestamps timestamps = pd.timestamps.getStorage();
|
||||
Set<JpsArtifact> artifacts = new HashSet<JpsArtifact>();
|
||||
if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) {
|
||||
artifacts.addAll(JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false));
|
||||
}
|
||||
else {
|
||||
for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)) {
|
||||
if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) {
|
||||
artifacts.add(artifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final CompileScope compileScope;
|
||||
if (buildType == BuildType.PROJECT_REBUILD || (modules.isEmpty() && paths.isEmpty())) {
|
||||
compileScope = new AllProjectScope(pd.project, pd.jpsProject, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
else {
|
||||
final Set<JpsModule> forcedModules;
|
||||
if (!modules.isEmpty()) {
|
||||
forcedModules = new HashSet<JpsModule>();
|
||||
for (JpsModule m : pd.jpsProject.getModules()) {
|
||||
if (modules.contains(m.getName())) {
|
||||
forcedModules.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
forcedModules = Collections.emptySet();
|
||||
}
|
||||
|
||||
final Map<String, Set<File>> filesToCompile;
|
||||
if (!paths.isEmpty()) {
|
||||
filesToCompile = new HashMap<String, Set<File>>();
|
||||
for (String path : paths) {
|
||||
final File file = new File(path);
|
||||
final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(null, file);
|
||||
if (rd != null) {
|
||||
Set<File> files = filesToCompile.get(rd.module);
|
||||
if (files == null) {
|
||||
files = new HashSet<File>();
|
||||
filesToCompile.put(rd.module, files);
|
||||
}
|
||||
files.add(file);
|
||||
if (buildType == BuildType.FORCED_COMPILATION) {
|
||||
pd.fsState.markDirty(null, file, rd, timestamps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
filesToCompile = Collections.emptyMap();
|
||||
}
|
||||
|
||||
if (filesToCompile.isEmpty()) {
|
||||
compileScope = new ModulesScope(pd.project, pd.jpsProject, forcedModules, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
else {
|
||||
compileScope = new ModulesAndFilesScope(pd.project, pd.jpsProject, forcedModules, filesToCompile, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
}
|
||||
return compileScope;
|
||||
}
|
||||
}
|
||||
@@ -5,32 +5,20 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.io.DataOutputStream;
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.jboss.netty.channel.Channels;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.ether.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.Project;
|
||||
import org.jetbrains.jps.api.*;
|
||||
import org.jetbrains.jps.idea.IdeaProjectLoader;
|
||||
import org.jetbrains.jps.idea.SystemOutErrorReporter;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
import org.jetbrains.jps.incremental.MessageHandler;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.artifacts.ArtifactSourceTimestampStorage;
|
||||
import org.jetbrains.jps.incremental.artifacts.JpsBuilderArtifactService;
|
||||
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactRootDescriptor;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.RootDescriptor;
|
||||
import org.jetbrains.jps.incremental.messages.*;
|
||||
import org.jetbrains.jps.incremental.storage.BuildDataManager;
|
||||
import org.jetbrains.jps.incremental.storage.ProjectTimestamps;
|
||||
import org.jetbrains.jps.incremental.storage.Timestamps;
|
||||
import org.jetbrains.jps.model.JpsElementFactory;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
|
||||
import org.jetbrains.jps.model.serialization.JpsProjectLoader;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@@ -46,21 +34,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
*/
|
||||
final class BuildSession implements Runnable, CanceledStatus {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildSession");
|
||||
public static final String IDEA_PROJECT_DIRNAME = ".idea";
|
||||
private static final String FS_STATE_FILE = "fs_state.dat";
|
||||
private final UUID mySessionId;
|
||||
private final Channel myChannel;
|
||||
private volatile boolean myCanceled = false;
|
||||
// globals
|
||||
private final Map<String, String> myPathVars;
|
||||
private final String myGlobalEncoding;
|
||||
private final String myIgnorePatterns;
|
||||
// build params
|
||||
private final BuildType myBuildType;
|
||||
private final Set<String> myModules;
|
||||
private final List<String> myArtifacts;
|
||||
private final List<String> myFilePaths;
|
||||
private final Map<String, String> myBuilderParams;
|
||||
private String myProjectPath;
|
||||
@Nullable
|
||||
private CmdlineRemoteProto.Message.ControllerMessage.FSEvent myInitialFSDelta;
|
||||
@@ -70,8 +47,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
private volatile ProjectDescriptor myProjectDescriptor;
|
||||
private final Map<Pair<String, String>, ConstantSearchFuture> mySearchTasks = Collections.synchronizedMap(new HashMap<Pair<String, String>, ConstantSearchFuture>());
|
||||
private final ConstantSearch myConstantSearch = new ConstantSearch();
|
||||
private final String myGlobalOptiosnPath;
|
||||
|
||||
private final BuildRunner myBuildRunner;
|
||||
|
||||
BuildSession(UUID sessionId,
|
||||
Channel channel,
|
||||
@@ -81,26 +57,27 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
myChannel = channel;
|
||||
|
||||
// globals
|
||||
myPathVars = new HashMap<String, String>();
|
||||
Map<String, String> pathVars = new HashMap<String, String>();
|
||||
final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = params.getGlobalSettings();
|
||||
for (CmdlineRemoteProto.Message.KeyValuePair variable : globals.getPathVariableList()) {
|
||||
myPathVars.put(variable.getKey(), variable.getValue());
|
||||
pathVars.put(variable.getKey(), variable.getValue());
|
||||
}
|
||||
myGlobalEncoding = globals.hasGlobalEncoding()? globals.getGlobalEncoding() : null;
|
||||
myIgnorePatterns = globals.hasIgnoredFilesPatterns()? globals.getIgnoredFilesPatterns() : null;
|
||||
String globalEncoding = globals.hasGlobalEncoding() ? globals.getGlobalEncoding() : null;
|
||||
String ignorePatterns = globals.hasIgnoredFilesPatterns() ? globals.getIgnoredFilesPatterns() : null;
|
||||
|
||||
// session params
|
||||
myProjectPath = FileUtil.toCanonicalPath(params.getProjectId());
|
||||
myGlobalOptiosnPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath());
|
||||
myBuildType = convertCompileType(params.getBuildType());
|
||||
myModules = new HashSet<String>(params.getModuleNameList());
|
||||
myArtifacts = params.getArtifactNameList();
|
||||
myFilePaths = params.getFilePathList();
|
||||
myBuilderParams = new HashMap<String, String>();
|
||||
String globalOptionsPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath());
|
||||
BuildType myBuildType = convertCompileType(params.getBuildType());
|
||||
Set<String> modules = new HashSet<String>(params.getModuleNameList());
|
||||
List<String> artifacts = params.getArtifactNameList();
|
||||
List<String> filePaths = params.getFilePathList();
|
||||
Map<String, String> builderParams = new HashMap<String, String>();
|
||||
for (CmdlineRemoteProto.Message.KeyValuePair pair : params.getBuilderParameterList()) {
|
||||
myBuilderParams.put(pair.getKey(), pair.getValue());
|
||||
builderParams.put(pair.getKey(), pair.getValue());
|
||||
}
|
||||
myInitialFSDelta = delta;
|
||||
myBuildRunner = new BuildRunner(myProjectPath, globalOptionsPath, pathVars, globalEncoding, ignorePatterns, modules, myBuildType, artifacts, filePaths, builderParams);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
@@ -108,7 +85,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
final Ref<Boolean> hasErrors = new Ref<Boolean>(false);
|
||||
final Ref<Boolean> markedFilesUptodate = new Ref<Boolean>(false);
|
||||
try {
|
||||
runBuild(myBuildType, myModules, myArtifacts, myBuilderParams, myFilePaths, new MessageHandler() {
|
||||
runBuild(new MessageHandler() {
|
||||
public void processMessage(BuildMessage buildMessage) {
|
||||
final CmdlineRemoteProto.Message.BuilderMessage response;
|
||||
if (buildMessage instanceof FileGeneratedEvent) {
|
||||
@@ -155,10 +132,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
}
|
||||
}
|
||||
|
||||
private void runBuild(BuildType buildType, Set<String> modules, Collection<String> artifacts, Map<String, String> builderParams,
|
||||
Collection<String> paths, final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{
|
||||
boolean forceCleanCaches = false;
|
||||
|
||||
private void runBuild(final MessageHandler msgHandler, CanceledStatus cs) throws Throwable{
|
||||
final File dataStorageRoot = Utils.getDataStorageRoot(myProjectPath);
|
||||
if (dataStorageRoot == null) {
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.ERROR, "Cannot determine build data storage root for project " +
|
||||
@@ -169,49 +143,14 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
|
||||
try {
|
||||
final boolean shouldApplyEvent = loadFsState(fsState, dataStorageRoot, myInitialFSDelta);
|
||||
if (shouldApplyEvent && buildType == BuildType.MAKE && !containsChanges(myInitialFSDelta) && !fsState.hasWorkToDo()) {
|
||||
if (shouldApplyEvent && myBuildRunner.getBuildType() == BuildType.MAKE && !containsChanges(myInitialFSDelta) && !fsState.hasWorkToDo()) {
|
||||
applyFSEvent(null, myInitialFSDelta);
|
||||
return;
|
||||
}
|
||||
if (!dataStorageRoot.exists()) {
|
||||
// invoked the very first time for this project. Force full rebuild
|
||||
buildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
|
||||
final boolean inMemoryMappingsDelta = System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null;
|
||||
ProjectTimestamps projectTimestamps = null;
|
||||
BuildDataManager dataManager = null;
|
||||
try {
|
||||
projectTimestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta);
|
||||
if (dataManager.versionDiffers()) {
|
||||
forceCleanCaches = true;
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Dependency data format has changed, project rebuild required"));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
// second try
|
||||
LOG.info(e);
|
||||
if (projectTimestamps != null) {
|
||||
projectTimestamps.close();
|
||||
}
|
||||
if (dataManager != null) {
|
||||
dataManager.close();
|
||||
}
|
||||
forceCleanCaches = true;
|
||||
FileUtil.delete(dataStorageRoot);
|
||||
projectTimestamps = new ProjectTimestamps(dataStorageRoot);
|
||||
dataManager = new BuildDataManager(dataStorageRoot, inMemoryMappingsDelta);
|
||||
// second attempt succeded
|
||||
msgHandler.processMessage(new CompilerMessage("build", BuildMessage.Kind.INFO, "Project rebuild forced: " + e.getMessage()));
|
||||
}
|
||||
|
||||
final JpsModel jpsModel = loadJpsModel();
|
||||
final Project project = loadProject();
|
||||
final ProjectDescriptor pd = new ProjectDescriptor(project, jpsModel, fsState, projectTimestamps, dataManager, BuildLoggingManager.DEFAULT);
|
||||
ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState);
|
||||
myProjectDescriptor = pd;
|
||||
if (shouldApplyEvent) {
|
||||
applyFSEvent(pd, myInitialFSDelta);
|
||||
applyFSEvent(myProjectDescriptor, myInitialFSDelta);
|
||||
}
|
||||
|
||||
|
||||
@@ -220,46 +159,7 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
// ensure events from controller are processed after FSState initialization
|
||||
myEventsProcessor.startProcessing();
|
||||
|
||||
for (int attempt = 0; attempt < 2; attempt++) {
|
||||
if (forceCleanCaches && modules.isEmpty() && paths.isEmpty()) {
|
||||
// if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation
|
||||
buildType = BuildType.PROJECT_REBUILD;
|
||||
}
|
||||
|
||||
final CompileScope compileScope = createCompilationScope(buildType, pd, modules, artifacts, paths);
|
||||
final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), builderParams, cs, myConstantSearch);
|
||||
builder.addMessageHandler(msgHandler);
|
||||
try {
|
||||
switch (buildType) {
|
||||
case PROJECT_REBUILD:
|
||||
builder.build(compileScope, false, true, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case FORCED_COMPILATION:
|
||||
builder.build(compileScope, false, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case MAKE:
|
||||
builder.build(compileScope, true, false, forceCleanCaches);
|
||||
break;
|
||||
|
||||
case CLEAN:
|
||||
//todo[nik]
|
||||
// new ProjectBuilder(new GantBinding(), project).clean();
|
||||
break;
|
||||
}
|
||||
break; // break attempts loop
|
||||
}
|
||||
catch (RebuildRequestedException e) {
|
||||
if (attempt == 0) {
|
||||
LOG.info(e);
|
||||
forceCleanCaches = true;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler);
|
||||
}
|
||||
finally {
|
||||
saveData(fsState, dataStorageRoot);
|
||||
@@ -514,122 +414,6 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
return myCanceled;
|
||||
}
|
||||
|
||||
private JpsModel loadJpsModel() {
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
final JpsModel model = JpsElementFactory.getInstance().createModel();
|
||||
try {
|
||||
JpsGlobalLoader.loadGlobalSettings(model.getGlobal(), myPathVars, myGlobalOptiosnPath);
|
||||
JpsProjectLoader.loadProject(model.getProject(), myPathVars, myProjectPath);
|
||||
LOG.info("New JPS model: " + model.getProject().getModules().size() + " modules, " + model.getProject().getLibraryCollection().getLibraries().size() + " libraries");
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
finally {
|
||||
final long loadTime = System.currentTimeMillis() - start;
|
||||
LOG.info("New JPS model: project " + myProjectPath + " loaded in " + loadTime + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
private Project loadProject() {
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
final Project project = new Project();
|
||||
|
||||
final File projectFile = new File(myProjectPath);
|
||||
|
||||
final String loadPath = isDirectoryBased(projectFile) ? new File(projectFile, IDEA_PROJECT_DIRNAME).getPath() : myProjectPath;
|
||||
IdeaProjectLoader.loadFromPath(project, loadPath, myPathVars, null, new SystemOutErrorReporter(false));
|
||||
final String globalEncoding = myGlobalEncoding;
|
||||
if (!StringUtil.isEmpty(globalEncoding) && project.getProjectCharset() == null) {
|
||||
project.setProjectCharset(globalEncoding);
|
||||
}
|
||||
project.getIgnoredFilePatterns().loadFromString(myIgnorePatterns);
|
||||
return project;
|
||||
}
|
||||
finally {
|
||||
final long loadTime = System.currentTimeMillis() - start;
|
||||
LOG.info("Project " + myProjectPath + " loaded in " + loadTime + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDirectoryBased(File projectFile) {
|
||||
return !(projectFile.isFile() && projectFile.getName().endsWith(".ipr"));
|
||||
}
|
||||
|
||||
private static CompileScope createCompilationScope(BuildType buildType,
|
||||
ProjectDescriptor pd,
|
||||
Set<String> modules,
|
||||
Collection<String> artifactNames,
|
||||
Collection<String> paths) throws Exception {
|
||||
final Timestamps timestamps = pd.timestamps.getStorage();
|
||||
Set<JpsArtifact> artifacts = new HashSet<JpsArtifact>();
|
||||
if (artifactNames.isEmpty() && buildType == BuildType.PROJECT_REBUILD) {
|
||||
artifacts.addAll(JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false));
|
||||
}
|
||||
else {
|
||||
for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(pd.jpsModel, false)) {
|
||||
if (artifactNames.contains(artifact.getName()) && !StringUtil.isEmpty(artifact.getOutputPath())) {
|
||||
artifacts.add(artifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final CompileScope compileScope;
|
||||
if (buildType == BuildType.PROJECT_REBUILD || (modules.isEmpty() && paths.isEmpty())) {
|
||||
compileScope = new AllProjectScope(pd.project, pd.jpsProject, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
else {
|
||||
final Set<JpsModule> forcedModules;
|
||||
if (!modules.isEmpty()) {
|
||||
forcedModules = new HashSet<JpsModule>();
|
||||
for (JpsModule m : pd.jpsProject.getModules()) {
|
||||
if (modules.contains(m.getName())) {
|
||||
forcedModules.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
forcedModules = Collections.emptySet();
|
||||
}
|
||||
|
||||
final Map<String, Set<File>> filesToCompile;
|
||||
if (!paths.isEmpty()) {
|
||||
filesToCompile = new HashMap<String, Set<File>>();
|
||||
for (String path : paths) {
|
||||
final File file = new File(path);
|
||||
final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(null, file);
|
||||
if (rd != null) {
|
||||
Set<File> files = filesToCompile.get(rd.module);
|
||||
if (files == null) {
|
||||
files = new HashSet<File>();
|
||||
filesToCompile.put(rd.module, files);
|
||||
}
|
||||
files.add(file);
|
||||
if (buildType == BuildType.FORCED_COMPILATION) {
|
||||
pd.fsState.markDirty(null, file, rd, timestamps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
filesToCompile = Collections.emptyMap();
|
||||
}
|
||||
|
||||
if (filesToCompile.isEmpty()) {
|
||||
compileScope = new ModulesScope(pd.project, pd.jpsProject, forcedModules, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
else {
|
||||
compileScope = new ModulesAndFilesScope(pd.project, pd.jpsProject, forcedModules, filesToCompile, artifacts, buildType != BuildType.MAKE);
|
||||
}
|
||||
}
|
||||
return compileScope;
|
||||
}
|
||||
|
||||
|
||||
private static BuildType convertCompileType(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type compileType) {
|
||||
switch (compileType) {
|
||||
case CLEAN: return BuildType.CLEAN;
|
||||
|
||||
@@ -64,8 +64,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
|
||||
protected JpsSdk<JpsDummyElement> initJdk(final String name, final String path) {
|
||||
String homePath = System.getProperty("java.home");
|
||||
String versionString = System.getProperty("java.version");
|
||||
JpsTypedLibrary<JpsSdk<JpsDummyElement>> jdk = myModel.getGlobal().addSdk(name, homePath, versionString, JpsJavaSdkType.INSTANCE,
|
||||
JpsElementFactory.getInstance().createDummyElement());
|
||||
JpsTypedLibrary<JpsSdk<JpsDummyElement>> jdk = myModel.getGlobal().addSdk(name, homePath, versionString, JpsJavaSdkType.INSTANCE);
|
||||
jdk.addRoot(JpsPathUtil.pathToUrl(path), JpsOrderRootType.COMPILED);
|
||||
return jdk.getProperties();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ public interface JpsGlobal extends JpsCompositeElement, JpsReferenceableElement<
|
||||
<P extends JpsElement, LibraryType extends JpsLibraryType<P> & JpsElementTypeWithDefaultProperties<P>>
|
||||
JpsLibrary addLibrary(@NotNull LibraryType libraryType, final @NotNull String name);
|
||||
|
||||
<P extends JpsElement, SdkType extends JpsSdkType<P> & JpsElementTypeWithDefaultProperties<P>>
|
||||
JpsTypedLibrary<JpsSdk<P>> addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString, @NotNull SdkType type);
|
||||
|
||||
<P extends JpsElement>
|
||||
JpsTypedLibrary<JpsSdk<P>> addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString,
|
||||
@NotNull JpsSdkType<P> type, @NotNull P properties);
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
package org.jetbrains.jps.model.java;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.JpsDummyElement;
|
||||
import org.jetbrains.jps.model.JpsElementFactory;
|
||||
import org.jetbrains.jps.model.JpsElementTypeWithDefaultProperties;
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdkType;
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdk;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class JpsJavaSdkType extends JpsSdkType<JpsDummyElement> {
|
||||
public class JpsJavaSdkType extends JpsSdkType<JpsDummyElement> implements JpsElementTypeWithDefaultProperties<JpsDummyElement> {
|
||||
public static final JpsJavaSdkType INSTANCE = new JpsJavaSdkType();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JpsDummyElement createDefaultProperties() {
|
||||
return JpsElementFactory.getInstance().createDummyElement();
|
||||
}
|
||||
|
||||
public static String getJavaExecutable(JpsSdk<?> sdk) {
|
||||
return sdk.getHomePath() + "/bin/java";
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ public class JpsGlobalImpl extends JpsRootElementBase<JpsGlobalImpl> implements
|
||||
return sdk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <P extends JpsElement, SdkType extends JpsSdkType<P> & JpsElementTypeWithDefaultProperties<P>> JpsTypedLibrary<JpsSdk<P>>
|
||||
addSdk(@NotNull String name, @Nullable String homePath, @Nullable String versionString, @NotNull SdkType type) {
|
||||
return addSdk(name, homePath, versionString, type, type.createDefaultProperties());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JpsLibraryCollection getLibraryCollection() {
|
||||
|
||||
@@ -105,7 +105,7 @@ public class JpsModuleTest extends JpsModelTestCase {
|
||||
}
|
||||
|
||||
public void testSdkDependency() {
|
||||
JpsSdk<JpsDummyElement> sdk = myModel.getGlobal().addSdk("sdk", null, null, JpsJavaSdkType.INSTANCE, JpsElementFactory.getInstance().createDummyElement()).getProperties();
|
||||
JpsSdk<JpsDummyElement> sdk = myModel.getGlobal().addSdk("sdk", null, null, JpsJavaSdkType.INSTANCE).getProperties();
|
||||
final JpsModule module = myModel.getProject().addModule("m", JpsJavaModuleType.INSTANCE);
|
||||
module.getSdkReferencesTable().setSdkReference(JpsJavaSdkType.INSTANCE, sdk.createReference());
|
||||
module.getDependenciesList().addSdkDependency(JpsJavaSdkType.INSTANCE);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Groovy" level="project" />
|
||||
<orderEntry type="module" module-name="jps-builders" />
|
||||
<orderEntry type="module" module-name="jps-model-api" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../lib/gant-1.9.5_groovy-1.7.10.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="cli-parser" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
Reference in New Issue
Block a user