Как программно изменить настройки инструмента 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, есть три различия:

  1. по какой-то причине, атрибут id fileInfo элемент в программных изменений содержит путь к файлу, включая имя проекта: id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"

  2. на resourcePath значение атрибута fileInfo элемент содержит имя проекта, только в изменения: resourcePath="test3/src/code.cpp".

  3. на 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.

Я думаю, это будет работать в вашем случае тоже.