英文:
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";
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论