Как программно изменить настройки инструмента Eclipse CDT для файла?
я хочу программно (из плагина) изменить поле "другие флаги" в разных настройках на вкладке настройки инструмента для отдельного файла в проекте управляемой сборки CDT. (См.эта страница документации Eclipse для скриншота и краткого описания того, как это изменение будет сделано с помощью пользовательского интерфейса.)
Примечание: я обновил это дважды сейчас, когда я приближаюсь к решению. Но вместо добавления обновления в конец (как я делаю для более короткого вопросы), я пересматриваю весь вопрос. Если это поможет увидеть хлебные крошки, ведущие туда, где я сейчас, вы можете прочитать историю.
следующий код приведет к настройкам, записанным в .файл cproject (я подробно расскажу об этом ниже), но когда я открываю диалоговое окно свойств для файла и нажимаю на 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 файл после запуска вышеуказанного кода. Ниже приведены соответствующие биты от каждого.
вот XML из .файл cproject, в котором настройки инструмента были изменены вручную:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.1964078554">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.1964078554" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.1964078554.915152327" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1643348654.1411455203">
<tool id="com.company.product.toolchain.compiler.1643348654.1411455203" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1643348654">
<option id="company.gnu.compiler.misc.other.789167779" name="Other flags" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.877052163" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1390394900" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
и вот XML из .cproject файл, где они были изменены программно:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.2057644715">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.2057644715" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="test3/src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1482360042.1005761865">
<tool id="com.company.product.toolchain.compiler.1482360042.1005761865" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1482360042">
<option id="company.gnu.compiler.misc.other.999025984" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.1253686787" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1141524787" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
помимо числа, которые я предполагаю, являются своего рода GUIDs, есть три различия:
по какой-то причине, атрибут id
fileInfo
элемент в программных изменений содержит путь к файлу, включая имя проекта:id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"
на
resourcePath
значение атрибутаfileInfo
элемент содержит имя проекта, только в изменения:resourcePath="test3/src/code.cpp"
.на
option
элементfileInfo
элемент в качестве атрибута name (name="Other flags"
), который соответствует полю в диалоговом окне, только в ручных изменениях.
Я предполагаю, что одно или все эти различия мешают моим программным изменениям быть "совместимыми" с ручными (поэтому они появляются в диалоговом окне). Я пытаюсь понять, как создать IFileInfo, IOption (и ITool?) объекты, не вызывающие этих различий. Я пытаюсь найти, как эти объекты создаются для диалог, но еще нет.
любые предложения приветствуются.
обновление: я получил ответ от Дуга Шефера на мой вопрос о список рассылки cdt-dev. Он предложил мне " придерживаться точек останова в местах и посмотреть, как это делает пользовательский интерфейс. Я ответил:
я делал это. Я установил точку останова в org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.setOption(IResourceInfo, IHoldsOptions, IOption, String)
и он запускается, когда я открываю диалоговое окно свойств для файла, разверните "C / C++ Build", выберите " Настройки", а затем "разное" на вкладке "настройки инструмента". Я вижу Аргументы, и предположительно, если я могу вызвать setOption с теми же аргументами, я получу те же результаты .cproject файл. Но я не смог понять, как это сделать. У вас есть какие-либо предложения о том, как выяснить, где создаются эти объекты, чтобы я мог установить точки останова там?
обновление #2: Владимирответ решил мою проблему. Хотя меня больше волнует отличие номер 3 в двух .фрагменты файла cproject выше, ключ был разницей 2 и включение имени проекта в разнице 1.
я изменил код, чтобы создать
2 ответов
Я подозреваю, что у вас может быть проблема с созданием 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.
Я думаю, это будет работать в вашем случае тоже.