如何以编程方式更改文件的Eclipse CDT工具设置?

我想以编程方式(从插件)更改CDT托管构建项目中单个文件的“工具设置”选项卡中“其他设置”中的“其他标志”字段。 (有关如何使用UI进行此更改的屏幕截图和简要说明,请参阅此Eclipse文档页面 。)

注意:在我接近解决方案时,我已经更新了两次。 但不是在最后添加更新(就像我对较短的问题所做的那样),我正在修改整个问题。 如果看到面包屑导致我现在的位置有帮助,您可以阅读历史记录。

以下代码将导致写入.cproject文件的设置(我将在下面详细介绍),但是当我打开文件的Properties对话框,然后单击C / C ++ Build-> Settings然后单击Miscellaneous,更改不会出现在“其他标志”字段中(就像我使用对话框进行更改时一样)。

IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow workbenchwindow = workbench.getActiveWorkbenchWindow(); IWorkbenchPage workbenchpage = workbenchwindow.getActivePage(); IEditorPart editorpart = workbenchpage.getActiveEditor(); IEditorInput editorinput = editorpart.getEditorInput(); IResource file = ((IFileEditorInput)editorinput).getFile(); IProject project = file.getProject(); IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project); IConfiguration[] configurations = buildInfo.getManagedProject().getConfigurations(); IConfiguration conf = configurations[0]; IFileInfo fileInfo = conf.createFileInfo(file.getFullPath()); ITool[] tools = fileInfo.getTools(); ITool tool = tools[0]; IOption option = tool.getOptionById("my.gnu.compiler.misc.other"); String oldOptionValue = option.getDefaultValue().toString(); String newOptionValue = oldOptionValue + " -eg"; ManagedBuildManager.setOption(fileInfo, tool, option, newOptionValue); ManagedBuildManager.saveBuildInfo(project, true); 

我查看了手动更改工具设置的.cproject文件与运行上述代码后的其他.cproject文件之间的差异。 以下是各自的相关位。

以下是.cproject文件中的XML,其中手动更改了工具设置:

     ...   ...        ... 

这是来自.cproject文件的XML,它们以编程方式进行了更改:

     ...   ...        ... 

除了我认为是某种GUID的数字之外,还有三个不同之处:

  1. 出于某种原因,编程更改中fileInfo元素的id属性包含文件的路径,包括项目名称: id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"

  2. fileInfo元素的resourcePath属性值包含项目名称,仅在程序更改中: resourcePath="test3/src/code.cpp"

  3. fileInfo元素中的option元素作为名称属性( name="Other flags" )与对话框中的字段匹配,仅在手动更改中。

我猜测这些差异中的一个或全部阻止我的程序化更改与手动更改“兼容”(因此它们显示在对话框中)。 我试图找出如何创建IFileInfo,IOption(和ITool?)对象而不会导致这些差异。 我正在尝试找到如何为对话框创建这些对象,但还没有。

任何建议赞赏。

更新:我从Doug Schaefer那里得到了关于cdt-dev邮件列表的问题的答案 。 他建议我“在某些地方坚持断点,看看用户界面是如何做到的。” 我回信说:

我一直这样做。 我在org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.setOption(IResourceInfo, IHoldsOptions, IOption, String)设置了一个断点,当我打开文件的Properties对话框时,它会触发,展开“C / C ++ Build”,选择“在“工具设置”选项卡中设置“,然后”其他“。 我可以看到参数,并且假设我可以使用相同的参数调用setOption,我将在.cproject文件中获得相同的结果。 但我一直无法弄清楚如何做到这一点。 您对如何确定这些对象的创建位置有什么建议吗?我可以在那里设置断点吗?

更新#2: 弗拉基米尔的回答解决了我的问题。 虽然我更关心上面两个.cproject文件片段中的差异编号3,但关键是差异2并且项目名称包含在差异1中。

我更改了代码以创建IFileInfo对象:

 IFileInfo fileInfo = conf.createFileInfo(file.getProjectRelativePath()); 

…导致fileInfo元素没有项目名称:

  

…最重要的是,导致程序化更改显示在单个文件的“工具设置”选项卡的“其他设置”字段中的“其他标志”字段中。 (我猜.cproject文件中的其他差异并不重要。)

我怀疑你的IFileInfo创建可能有问题。 这是我们用于获取IResourceInfo的代码,以便翻译单元设置每个文件选项:

 protected IResourceInfo getResourceInfo(ITranslationUnit translationUnit, ICProjectDescription prjDescription) { ICProject cProject = translationUnit.getCProject(); if (cProject != null) { ICConfigurationDescription cfgDescription = prjDescription.getActiveConfiguration(); IConfiguration configuration = ManagedBuildManager.getConfigurationForDescription(cfgDescription); IPath projectPath = translationUnit.getResource().getProjectRelativePath(); IResourceInfo ri = configuration.getResourceInfo(projectPath, true); if (ri == null) { ri = configuration.createFileInfo(projectPath); } return ri; } return null; } 

请注意这一行,特别是:

 IPath projectPath = translationUnit.getResource().getProjectRelativePath(); 

也许,您只需要在代码中使用getProjectRelativePath()?

通常,您可以为不同的对象设置选项,即配置(如果您希望该选项适用于配置中给定类型的所有文件)或资源(如果您希望该选项仅应用于文件夹中的文件)或单个文件)。

setOption()有多个原型; 看起来你使用了适用于文件资源的那个。

在我的GNU ARM Eclipse插件中,我成功使用了另一个版本:

 setOption(IConfiguration config, IHoldsOptions holder, IOption option, String value) 

您可以在此文件中看到第583行的示例。

我想这也适用于你的情况。