Eclipse .cproject程序化创建

huangapple go评论81阅读模式
英文:

Eclipse .cproject programmatic creation

问题

我有一个Eclipse插件代码,用于以编程方式创建Eclipse项目。其要点在这里:https://stackoverflow.com/questions/75833893/programmatic-creation-of-eclipse-project-in-the-eclipse-workspace(此帖子上显示的代码与我当前询问的项目相同)。

在我的使用情况下,创建的项目始终是C/C++项目。

起初,我认为只需将CNature添加到IProjectDescription的实例中,当它分配给IProject的实例时就足够了,但似乎并不足够。代码运行无误(没有错误),但我 rightly or wrongly 期望也创建一个.cproject文件。我尝试了各种方法来创建它,包括这个:

IProject newProject = workspace.getRoot().getProject(projectName);
try {
       newProject.create(newProjectDescription, monitor);  // create Eclipse project
       CoreModel model = CoreModel.getDefault();           // get default CDT model
       ICProject cproject = model.create(newProject);      // create CDT model for project
    } catch (CoreException ex) {
       // <snipped - does some logging>
    }

...然后是这个...

try {
        newProject.open(monitor);
        newProject.setDescription(newProjectDescription, null);
        cproject.save(null, true);  
    } catch (CoreException e) {
        // <snipped - does some loggging>
    }

...但都没有成功。

以编程方式创建的项目是现有项目的副本。现有项目是使用“将现有项目导入工作区...”选项导入到Eclipse中的。我没有为它指定工具链。它的结构中也没有像Makefile这样的东西,只有C和C++文件。然而,当我右键单击每个项目并查看上下文菜单时,手动导入的原始项目有“构建项目”、“清理项目”和“制作目标”。同样,如果我比较属性,原始项目有一个“C/C++构建”部分,但以编程方式创建的项目没有这个部分。同样的情况也适用于原始项目有一个.cproject文件,而以编程方式创建的项目没有。

我希望它们是相同的,以便以编程方式创建的项目具有我提到的当前缺少的项目,以便具有相同的上下文菜单、“C/C++构建”属性部分和重要的.cproject文件。

我怀疑.cproject文件的存在使IDE行为不同,我想知道如何确保也创建该文件。

更新1:

基于@nitind的想法,我已经发现.cproject文件是从包org.eclipse.cdt.internal.core.settings.model.xml和类DesSerializationRunnable中编写的,该类具有以下函数(因为它实现了Runnable):

public void run(IProgressMonitor monitor) throws CoreException {
  JobChangeAdapter notifyJobCanceller = new NotifyJobCanceller((NotifyJobCanceller)null);
  try {
	Job.getJobManager().addJobChangeListener(notifyJobCanceller);
	ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
		}
	}, (ISchedulingRule)null, 1, (IProgressMonitor)null);
	XmlProjectDescriptionStorage.this.serializingLock.acquire();
	LanguageSettingsProvidersSerializer.serializeLanguageSettings(this.fDes);
	XmlProjectDescriptionStorage.this.projectModificaitonStamp = XmlProjectDescriptionStorage.this.serialize(this.fDes.getProject(), ".cproject", this.fElement);
	((ContributedEnvironment)CCorePlugin.getDefault().getBuildEnvironmentManager().getContributedEnvironment()).serialize(this.fDes);
  } finally {
	XmlProjectDescriptionStorage.this.serializingLock.release();
	Job.getJobManager().removeJobChangeListener(notifyJobCanceller);
  }
}

具体来说,与".cproject"相关的那一行编写了该文件。

我现在只需要看看如何调用这个函数,并推断是否可以在我的情况下模仿它,或者更好的是,找到一种重复使用这个Eclipse代码的方法。

英文:

I've got Eclipse plugin code that programmatically creates an Eclipse project. The gist of it is here: https://stackoverflow.com/questions/75833893/programmatic-creation-of-eclipse-project-in-the-eclipse-workspace (the code shown on this post is the same coding project as I am currently asking about).

In my use-cases, the projects created are always C/C++ projects.

I initially thought just adding a CNature to the instance of IProjectDescription would suffice when it is assigned to the instance of an IProject but this does not appear to be enough. The code runs seemlessly (no errors), but I'm rightly or wrongly expecting a .cproject file to be created also. I've tried various things to create this, including this:

IProject newProject = workspace.getRoot().getProject(projectName);
try {
       newProject.create(newProjectDescription, monitor);  // create Eclipse project
       CoreModel model = CoreModel.getDefault();           // get default CDT model
       ICProject cproject = model.create(newProject);      // create CDT model for project
    } catch (CoreException ex) {
       // <snipped - does some logging>
    }

...with this later...

try {
        newProject.open(monitor);
        newProject.setDescription(newProjectDescription, null);
        cproject.save(null, true);  
    } catch (CoreException e) {
        // <snipped - does some loggging>
    }

...to no avail.

The programmatically created project is a duplicate of an existing project. The existing project was imported in to Eclipse using the "Existing Projects into Workspace..." option. I did not specify a toolchain for it. Neither does it actually have anything like make files in its structure, it's purely C and C++ files only. Yet, when I right-click on each and examine the context menu, the original manually imported one has "Build Project", "Clean Project" and "Make Targets". Similarly, if I compare properties, the original has a "C/C++ Build" section, but the programmatically created one lacks this. The same is true in that the original has a .cproject file and the programmatically created one does not.

I wish them to be identical such that the programmatically created one has the items I mention it currently lacks, in order to have the same context menu, "C/C++ Build" section in its properties and the important .cproject file.

I suspect it is the presence of the .cproject file that makes the difference in IDE behaviour, and I wish to know how to ensure that gets created also.

UPDATE 1:

Based on @nitind idea of tracing in to Eclipse code, I have discovered that the .cproject file is written from package org.eclipse.cdt.internal.core.settings.model.xml and class DesSerializationRunnable, which has the following function (given it implements Runnable):

public void run(IProgressMonitor monitor) throws CoreException {
  JobChangeAdapter notifyJobCanceller = new NotifyJobCanceller((NotifyJobCanceller)null);
  try {
	Job.getJobManager().addJobChangeListener(notifyJobCanceller);
	ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
		public void run(IProgressMonitor monitor) throws CoreException {
		}
	}, (ISchedulingRule)null, 1, (IProgressMonitor)null);
	XmlProjectDescriptionStorage.this.serializingLock.acquire();
	LanguageSettingsProvidersSerializer.serializeLanguageSettings(this.fDes);
	XmlProjectDescriptionStorage.this.projectModificaitonStamp = XmlProjectDescriptionStorage.this.serialize(this.fDes.getProject(), ".cproject", this.fElement);
	((ContributedEnvironment)CCorePlugin.getDefault().getBuildEnvironmentManager().getContributedEnvironment()).serialize(this.fDes);
  } finally {
	XmlProjectDescriptionStorage.this.serializingLock.release();
	Job.getJobManager().removeJobChangeListener(notifyJobCanceller);
  }
}

and specifically the line referring to ".cproject" writes the file.

I now just need to see how this gets called, and deduce if I can mimic it in my scenario, or better still, find a way to re-use this Eclipse code.

答案1

得分: 0

好的,以下是翻译好的部分:

"OK, so after as much tracing in to Eclipse as I could do, I found some but not all things that I needed to directly create a project with a .cproject file.

However, after finding that there are some project conversion functions on the Eclipse CCorePlugin class, I decided to try those (at the time mixed in with some other code). Ultimately, I only needed to call a single method after calling open(...) on my IProject reference.

I discovered that converting to a CProjectNature is only suitable for C and that I need to also cover C++. Converting solely to a CCProjectNature (note the extra C at the front) would add both types of nature to the project. It also ultimately calls the code I put in my question update, so writes the .cproject file. I checked the context menus and and the project properties and they now match what the Eclipse import wizard was producing.

So short version is this original code:

try {
      newProject.open(monitor);
    } catch (CoreException e) {
      // <snipped - do some logging>
}
return newProject; 

...becomes...

try {
      newProject.open(monitor);
      cdtCorePlugin.convertProjectToNewCC(newProject, DEFAULT_PREFERENCE_CONFIG, monitor);
    } catch (CoreException e) {
      // <snipped - do some logging>
}
return newProject; 

where cdtCorePlugin is simply defined earlier as:

CCorePlugin cdtCorePlugin = CCorePlugin.getDefault();

and DEFAULT_PREFERENCE_CONFIG is a constant defined as:

private static final String DEFAULT_PREFERENCE_CONFIG = "org.eclipse.cdt.managedbuilder.core.configurationDataProvider";
英文:

OK, so after as much tracing in to Eclipse as I could do, I found some but not all things that I needed to directly create a project with a .cproject file.

However, after finding that there are some project conversion functions on the Eclipse CCorePlugin class, I decided to try those (at the time mixed in with some other code). Ultimately, I only needed to call a single method after calling open(...) on my IProject reference.

I discovered that converting to a CProjectNature is only suitable for C and that I need to also cover C++. Converting solely to a CCProjectNature (note the extra C at the front) would add both types of nature to the project. It also ultimately calls the code I put in my question update, so writes the .cproject file. I checked the context menus and and the project properties and they now match what the Eclipse import wizard was producing.

So short version is this original code:

try {
      newProject.open(monitor);
    } catch (CoreException e) {
      // <snipped - do some logging>
}
return newProject; 

...becomes...

try {
      newProject.open(monitor);
      cdtCorePlugin.convertProjectToNewCC(newProject, DEFAULT_PREFERENCE_CONFIG, monitor);
    } catch (CoreException e) {
      // <snipped - do some logging>
}
return newProject; 

where cdtCorePlugin is simply defined earlier as:

CCorePlugin cdtCorePlugin = CCorePlugin.getDefault();

and DEFAULT_PREFERENCE_CONFIG is a constant defined as:

private static final String DEFAULT_PREFERENCE_CONFIG = "org.eclipse.cdt.managedbuilder.core.configurationDataProvider";

huangapple
  • 本文由 发表于 2023年7月31日 20:37:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76803705.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定