How to programmatically change the Eclipse CDT tool settings for a file?

I want to programmatically (from the plugin) change the "Other flags" field in the "Miscellaneous" settings on the "Tool parameters" tab for an individual file in a managed CDT build project. (See this Eclipse documentation page for a screenshot and a brief description of how this change will be made using the user interface.)

Note. I updated it twice now when I come to a solution. But instead of adding an update to the end (as for shorter questions), I am reviewing the whole question. If this helps to see crackers leading to where I am now, you can read the story.

The following code will lead to the settings written to the .cproject file (I will talk more about this below), but when I open the "Properties" dialog box for the file and click "C / C ++ Build-> Settings and then" Miscellaneous ", change do not appear in the Other Flags field (as with a change in a dialog box).

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); 

I looked at the differences between the .cproject file, where I changed the tool parameters manually and in another .cproject file after running the above code. Below are the corresponding bits from each.

Here is the XML from the .cproject file where the tool parameters were manually changed:

 <?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> ... 

And here is the XML from the .cproject file, where they were changed programmatically:

 <?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> ... 

Besides the numbers that I assume are a kind of GUID, there are three differences:

  • For some reason, the id attribute of the fileInfo element in programmatic changes contains the file path, including the project name: id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"

  • The value of the resourcePath attribute of the fileInfo element contains the name of the project, only in software changes: resourcePath="test3/src/code.cpp" .

  • The option element in the fileInfo element as a name attribute ( name="Other flags" ), which corresponds to the field in the dialog box, is only in manual changes.

I assume that one or all of these differences do not allow my software changes to be "compatible" with manual ones (therefore, they are displayed in a dialog box). I am trying to figure out how to create IFileInfo, IOption (and ITool?) Objects without causing these differences. I am trying to find how these objects are created for dialogue, but not yet.

Any suggestions appreciated.

Update: I received a response from Doug Schaefer to my question about the cdt-dev mailing list . He suggested that I "find breakpoints in places and see how the user interface does it." I wrote:

I'm doing it. I set a breakpoint in org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.setOption(IResourceInfo, IHoldsOptions, IOption, String) and it starts when I open the Properties dialog box for the file, expand "C / C ++ Build" , select "Settings" and then "Miscellaneous" on the "Tool Options" tab. I can see the arguments and, presumably, if I can call setOption with the same arguments, I get the same results in the .cproject file. But I could not figure out how to do this. Do you have any suggestions on how I determine where these objects are created, so I can set breakpoints there?

Update # 2: Vladimir answer solved my problem. While I was more interested in difference 3 in the two fragments of the .cproject file above, the key was difference 2 and including the project name in difference 1.

I changed the code to create an IFileInfo object IFileInfo that:

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

..., as a result of which the fileInfo element does not have a project name:

 <fileInfo id="com.company.product.toolchain.configuration.changed.838214286.src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.2027651356.1970239371"> 

... and, most importantly, led to the appearance of programmatic changes in the "Other flags" field in the "Miscellaneous" settings on the "Tool options" tab for a single file. (I think other differences in .cproject files are not important.)

+6
source share
2 answers

I suspect there might be a problem creating IFileInfo. Here is the code we use to get IResourceInfo for the translation unit to set the parameters for each file:

 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; } 

Pay attention to this line, in particular:

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

Perhaps all you need is to use getProjectRelativePath () in your code?

+2
source

As a rule, you can set a parameter for different objects, that is, a configuration (if you want the option to apply to all files of a given type in the configuration) or a resource (if you want the option to apply only to files in a folder or in one file) .

setOption () has several prototypes; it looks like you used the one that applies to the file share.

In my GNU ARM Eclipse plug-in, I successfully used a different version:

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

You can see an example in this file , line 583.

I think this will work in your case too.

+1
source

Source: https://habr.com/ru/post/958351/


All Articles