Community
Participate
Working Groups
It would be cool if we could import build options from pkg-config. pkg-config spits out the options you need to use to build a given package for different phases of the build. For example: pkg-config gstreamer-0.6 --cflags which gives the compile flags for the gstreamer-0.6 package.
PR was not targeted to any particular release. Changing target milestone to 2.1
There are other *-config programs too like curl-config for libcurl etc. Currently Eclipse changes the order of words in build flags placed between backticks. For example "`pkg-config --cflags gtkmm-2.4`" became "--cflags gtkmm-2.4` `pkg-config" It should probably recognize them as one flag as if they were placed in quotation marks.
I think it is feasible to support back-ticks. I am less convinced that we can support settings import. I leave it to Leo to decide if this can be done and when.
There is no need to truly import anything, except the list of available pkg-config modules present in the system, which can be done by a simple listing of files from a directory, or from callling `pkg-config --list-all` and parsing the very simple output. pkg-config was designed to work in Makefiles; typically adding `pkg-config --cflags package` to $CFLAGS and `pkg-config --libs package` to $LIBS or $LDFLAGS.
Created attachment 19717 [details] copy of curl.h with the error causing enum commented out
No one is currently looking at this. Help wanted.
Slight correction. I am considering this use case for the new Build model work I'm planning on for CDT 7.
*** Bug 108711 has been marked as a duplicate of this bug. ***
Some kind of plugin for this would be great. My workaround is to run everything from the command line, copy it into a text file, then manually enter the output into the appropriate places in eclipse. I do this so I get the full include search path in eclipse - which is really nice. Really I see 3 things that need to be imported 1) custom gcc switches, 2) include paths 3) libraries and their paths.
Here is a work around this to massage eclipse to parse the correct information. For example I used to have a line in my makefile that would turn .cpp files into .o files as follows: %.o:%.cpp g++ -c $(CXXFLAGS) $(CPPFLAGS) $*.cpp Now I changed it to %.o:%.cpp cmd="g++ -c $(CXXFLAGS) $(CPPFLAGS) $*.cpp";\ eval $$cmd;\ echo $$cmd; so there is an intermediate step where the shell evaluates all the expressions (like pkg-config) in the $$cmd string, then echos it so that eclipse can parse them all.
I started working on this (GSoC 2011). The project (plug-in) is hosted here: http://code.google.com/p/pkg-config-support-for-eclipse-cdt/ Please suggest any requirements you have in your mind so that the plug-in would please most of you. Now is a good time because the implementation plan is not set in stone yet.
How much does it overlap with scanner discovery stuff, i.e. providing include paths -I and predefined macros -D for indexer? I am working on that part (http://wiki.eclipse.org/CDT/ScannerDiscovery61/Stories#Pkg-config_Story) although admittedly pkg-config is not on the hot list (and I am not very much familiar with it). The idea here is to create provider to parse output of pkg-config command to language settings entries. Those are used by indexer and built-in entries get propagated to appropriate MBS tool options.
(In reply to comment #12) > How much does it overlap with scanner discovery stuff, i.e. providing include It doesn't in scanner discovery's current form. The pkg-config info needs to be fed into the build, for generating correct compile and link commands. Scanner Discovery doesn't currently plug into the build, does it Andrew? I've done something very similar to this here using the CExternalSettingProvider interface. It's straightforward to layer some UI on top of that, and that paths will propagate correctly to the MBS and to cdt.core.
> The idea here is to create provider to parse output of pkg-config command to > language settings entries. Those are used by indexer > and built-in entries get propagated to appropriate MBS tool options. err, read *non* built-in entries here
(In reply to comment #14) > > The idea here is to create provider to parse output of pkg-config command to > > language settings entries. Those are used by indexer > > and built-in entries get propagated to appropriate MBS tool options. > err, read *non* built-in entries here Ah, interesting. Using this would block this bug on scanner discovery. All I was saying is that we have API today which does this.
(In reply to comment #15) > (In reply to comment #14) > > > The idea here is to create provider to parse output of pkg-config command to > > > language settings entries. Those are used by indexer > > > and built-in entries get propagated to appropriate MBS tool options. > > err, read *non* built-in entries here > Ah, interesting. Using this would block this bug on scanner discovery. All I > was saying is that we have API today which does this. I am just trying to figure out if it makes sense to integrate with future scanner discovery stuff I am working on. From thinking about it for 5 minutes probably scanner discovery should not be used here as pkg-config needs to deliver some options that language settings entries do not cover. And if there are -I/-D options MBS would provide them in a regular way.
(In reply to comment #16) > I am just trying to figure out if it makes sense to integrate with future > scanner discovery stuff I am working on. The paths need to be store somewhere in cdt.core. Currently there's the horrible external settings manager, if it could be centralised in a generic scanner discover that would be an advantage, in my book -- one less thing to test. We have the same problem with external settings and references. They're settings that get propagated to another config's build settings. The extSettingsManager is so messy that if it's easy for scanner discovery to have some paths that are marked 'non-builtin/for-build-system' then that would be neat.
I made some coding and it is fairly easy to get options that pkg-config utility outputs by using ProcessBuilder. I just gave appropriate OS specific shell name, command and package name as parameters. I also created Pkg-config property page under C/C++ Build and was able to list all packages in a table. Packages can be selected by clicking the checkbox(es) or by double clicking. The --list-all pkg-config outputs descriptions for the packages as well but I created separate methods that parse packages or descriptions so that they can be shown side by side (if wanted). The next thing probably is to think about the best way so that these outputs end up to compiler and linker. My very first idea would be to add a listener to the pkg-config property page that knows if any packages are selected. If not -> nothing needs to be done. If yes -> e.g. environment variable could be created that contains the pkg-config output and that could be appended to compiler/linker flag options. Using scanner discovery in this project has not crossed my mind. Feedback is more than appreciated. If there is a better way to achieve the goal I am more than eager to know it.
Platform should be changed to ALL.
(In reply to comment #18) > If yes -> e.g. environment variable could be created > that contains the pkg-config output and that could be appended to > compiler/linker flag options. Don't use environment variables, as the linker libraries and library search path options in the Tools Settings Tab won't reflect the values that will be passed. You should be able to just set the paths directly into the corresponding Linker Tool's Options. Alternatively go through the writable ICConfigurationDescription and set a LSE on the configuration. The settings will then be correctly reflected on all the other property pages.
Yes I was thinking that the options could be directly placed as well. No intermediate steps needed. I have also code ready that can add/remove values to Tool's options (from LLVM plug-in work) so that should be no-brainer. What else should be included in the plug-in? I was thinking to create pkg-config specific preference page where user could set PKG_CONFIG_PATH etc. What you think? Additionally I think it would be better to check if pkg-config is found from the system and only then show the pkg-config property & preference page. Because GTK+ and gtkmm are so closely related to pkg-config I was also thinking about creating new project wizards for them and selecting the appropriate packages by default. And creating preference page(s) for them etc.
I am not too familiar with the architecture of eclipse / CDT, so bear with me. In an ideal world it would be great if each include/switch/etc were tagged with each thing that put them there. For instance "user input", "pkg-config gtk"... so that if the package is updated, removed, etc. the settings could be updated appropriately without wiping out settings from other packages or the user's input.
Well that was the main reason why I suggested putting the output to some sort of variables so that their values could be changed if needed.
(In reply to comment #22) > In an ideal world it would be great if each include/switch/etc were tagged with > each thing that put them there. For instance "user input", "pkg-config gtk"... > so that if the package is updated, removed, etc. the settings could be updated > appropriately without wiping out settings from other packages or the user's > input. That is an issue with the current architecture that Andrew's SD work should hopefully fix. (In reply to comment #23) > Well that was the main reason why I suggested putting the output to some sort > of variables so that their values could be changed if needed. Only if the Variable interacts well with the rest of the settings. Otherwise there's a special case variable for every integration...
I have now extended PropertyPage and listing packages in CheckboxTableViewer. I am struggling to save the checked state of these package checkboxes after opening the property view again. The problematic part here might be the fact that the amount of packages cannot be predicted neither the names of them. I found that using IResource interface's setPersistentProperty() method can save String values into files but does this solution work here? I have not implemented property page before so I hope someone could share some advices.
(In reply to comment #25) > I have now extended PropertyPage and listing packages in CheckboxTableViewer. I > am struggling to save the checked state of these package checkboxes after > opening the property view again. Ensure your property page is extending AbstractCPropertyTab. ctrl-T on there to see an example of existing CDT tabs. You should probably save the settings into the .cproject. > IResource interface's setPersistentProperty() method can save > String values into files but does this solution work here? That works anywhere, but these settings are local to one user's workspace. As users more than likely check their projects into source control, you need to ensure that all settings are persisted under the project.
Created attachment 196970 [details] Property page Here's a picture of the property page implemented so far.
Any examples how to write to .cproject and read back would now be greatly appreciated. I searched Eclipse forums, Google, Stack Overflow and checked other classes implementing AbstractCPropertyTab quite carefully but didn't find anything.
(In reply to comment #28) In the AbstractCPropertyTab you can: getResDesc().getConfiguration() and then ICConfigurationDescription#getStorage and persist the settings in there. UI pages are meant to persist settings immediately as the user changes them, so that multiple pages may reflect the same consistent content. So if you alter the libs / libpaths, the linker settings page will automatically update. If you do this, you don't need to override #performOK(). You need to copy over any custom settings during the performApply call (as this is used for applying changes for just one page). Any settings which are persisted in other parts of the model (e.g. libs and lib paths) you don't need to persist once you've pushed them into the model. Take a look at the recently added RefreshScopeManager#persistSettings, and open-call-hierarchy to see how it's called from the UI. Your settings should probably be per-configuration, rather than per project description (as should the RSM's settings...), and you don't need to hook it off #performOK.
Thanks James! That worked. I will post my second problem here in case someone knows a solution. I am able to create project-wide environment variables programmatically to Project properties -> C/C++ Build -> Environment page. However when I restart the workspace the environment variables are vanished. I am using similar code found on another implementation of AbstractCPropertyTab. //global variables private ICConfigurationDescription cfgd = null; private final MultiCfgContributedEnvironment ce = new MultiCfgContributedEnvironment(); //inside method ICConfigurationDescription[] cfgs; cfgs = new ICConfigurationDescription[] {cfgd}; for (ICConfigurationDescription cfg : cfgs) { ce.addVariable("PKG_CONFIG_LIBDIR", dir, EnvironmentVariable.ENVVAR_APPEND, SEPARATOR, cfg); }
(In reply to comment #30) > I am able to create project-wide environment variables programmatically to > Project properties -> C/C++ Build -> Environment page. However when I restart > the workspace the environment variables are vanished. Where are you getting the cfgd you're using? And how are you saving its parent project description? If you're doing this in the UI, you should use the shared project desc obtained from #getResDesc() and let the dialog do the saving.
Great! Environment variable issue solved. Clearly the earlier method didn't suit too well but this one does: PreferenceStore.setPkgConfigLibDir(dir); //append to existing values UserDefinedEnvironmentSupplier fUserSupplier = EnvironmentVariableManager.fUserSupplier; StorableEnvironment vars = fUserSupplier.getWorkspaceEnvironmentCopy(); vars.createVariable("PKG_CONFIG_PATH", PreferenceStore.getPkgConfigPath()); fUserSupplier.setWorkspaceEnvironment(vars);
(In reply to comment #32) > Great! Environment variable issue solved. Clearly the earlier method didn't > suit too well but this one does: > > PreferenceStore.setPkgConfigLibDir(dir); //append to existing values > UserDefinedEnvironmentSupplier fUserSupplier = > EnvironmentVariableManager.fUserSupplier; > StorableEnvironment vars = fUserSupplier.getWorkspaceEnvironmentCopy(); > vars.createVariable("PKG_CONFIG_PATH", PreferenceStore.getPkgConfigPath()); > fUserSupplier.setWorkspaceEnvironment(vars); Sorry pasted wrong first line. PreferenceStore.appendPkgConfigPath(dir); //append to existing values UserDefinedEnvironmentSupplier fUserSupplier = EnvironmentVariableManager.fUserSupplier; StorableEnvironment vars = fUserSupplier.getWorkspaceEnvironmentCopy(); vars.createVariable("PKG_CONFIG_LIBDIR", dir); fUserSupplier.setWorkspaceEnvironment(vars);
I have observed rather strange behavior when trying to add includes & libraries to Tool's Options. If the same code is called from the preference page it works fine but doesn't when called from the property page (AbstractCPropertyTab to be precise). The Tool Settings tab and Pkg-config tab are both under Settings if this matters. Do I have to refresh the property page/tab somehow or what?
The previous issue was solved by implementing updateData(), performApply() etc. Now the plug-in actually works somewhat. It takes a while for the indexer to resolve the new includes and symbols etc. but this should be normal (~5s for GTK+ hello world). I still have to ensure that the removal of a package doesn't remove flags that other packages are dependent on.
(In reply to comment #35) > The previous issue was solved by implementing updateData(), performApply() etc. > > Now the plug-in actually works somewhat. It takes a while for the indexer to > resolve the new includes and symbols etc. but this should be normal (~5s for > GTK+ hello world). I still have to ensure that the removal of a package doesn't > remove flags that other packages are dependent on. Excellent, Thanks Petri! I should be almost done my Indigo tasks my mid-week. You're next on my list :). I'll give it a try then and get you some feedback.
(In reply to comment #36) > (In reply to comment #35) > > The previous issue was solved by implementing updateData(), performApply() etc. > > > > Now the plug-in actually works somewhat. It takes a while for the indexer to > > resolve the new includes and symbols etc. but this should be normal (~5s for > > GTK+ hello world). I still have to ensure that the removal of a package doesn't > > remove flags that other packages are dependent on. > > Excellent, Thanks Petri! I should be almost done my Indigo tasks my mid-week. > You're next on my list :). I'll give it a try then and get you some feedback. Better yet, now only those flags are removed (when unchecking package(s) from the property page) that are not needed by other packages. Didn't notice a performance overhead which was a bit of a surprise. However 'other flags' that are set (such as -mms-bitfields for Windows) will currently disappear after a workspace restart and I am working on that.
Currently the Indexer must be refreshed manually by end-user after checking packages from the property page. How can I call Indexer to refresh all files in the project? Similarly as right clicking a project and selecting Index -> Freshen All Files.
(In reply to comment #38) > Currently the Indexer must be refreshed manually by end-user after checking > packages from the property page. > > How can I call Indexer to refresh all files in the project? > Similarly as right clicking a project and selecting Index -> Freshen All Files. Got it to work with the following code (probably not bulletproof but better than nothing): private void freshenIndex() { ISelection fSelection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getSelection(); if (!(fSelection instanceof IStructuredSelection)) return; IStructuredSelection cElements = SelectionConverter.convertSelectionToCElements(fSelection); Object[] cElementsArray = cElements.toArray(); ArrayList<ICElement> tuSelection = new ArrayList<ICElement>(); for (Object o : cElementsArray) { if (o instanceof ICProject || o instanceof ICContainer || o instanceof ITranslationUnit) { tuSelection.add((ICElement) o); } } ICElement[] tuArray = tuSelection.toArray(new ICElement[tuSelection.size()]); try { CCorePlugin.getIndexManager().update(tuArray, IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT); } catch (CoreException e) { CUIPlugin.log(e); } }
If you find the implementation for the rebuild index action, you could confirm the correct approach. It's in the cdt.ui plug-in somewhere.
Always wondered what the difference was betweeen freshen and rebuild. I usually do a rebuild when I'm worried about the indexer not being set up correctly.
Basically the code is slightly modified version of AbstractUpdateIndexAction#run. It seems this shorter version I wrote would be equivalent for functionality and is not dependent on the ISelection state (even though the project is kept selected when visiting it's property pages and therefore works similarly). private void freshenIndex() { ICProject cproject = CoreModel.getDefault().getCModel().getCProject(page.getProject().getName()); ArrayList<ICElement> tuSelection = new ArrayList<ICElement>(); tuSelection.add((ICElement) cproject); ICElement[] tuArray = tuSelection.toArray(new ICElement[tuSelection.size()]); try { CCorePlugin.getIndexManager().update(tuArray, IIndexManager.UPDATE_ALL | IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT); } catch (CoreException e) { CUIPlugin.log(e); } } IIndexManager#update is for 'Freshen All Files' and 'Update with Modified Files' and IIndexManager#reindex for 'Rebuild'. The Actions org.eclipse.cdt.internal.ui.actions.FreshenIndexAction org.eclipse.cdt.internal.ui.actions.UpdateIndexWithModifiedFilesAction org.eclipse.cdt.internal.ui.actions.RebuildIndexAction only differ by calling IIndexManager#update or IIndexManager#reindex with different options.
Actually the only way it works is to rebuild the index when pressing Ok button. protected void performOK() { ICProject cproject = CoreModel.getDefault().getCModel().getCProject(page.getProject().getName()); CCorePlugin.getIndexManager().reindex((ICProject) cproject); }
Encountered quite strange problem. GTK+-2.0 package check state is not saved because the name contains + symbol. ICStorageElement#setAttribute(String name, String value) produces INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. if name parameter contains +
(In reply to comment #44) > Encountered quite strange problem. > > GTK+-2.0 package check state is not saved because the name contains + symbol. > > ICStorageElement#setAttribute(String name, String value) produces > INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. > if name parameter contains + Fixed. Set attributes to ICStorageElement by replacing "+" in package names with "plus" and when initializing the check state of the table items the value from ICStorageElement is get by replacing "+" with "plus" if the table item contains "+". The actual name of the table item was never changed. Only temporary variable given to ICStorageElement as a parameter.
Now other flags do not disappear after a workspace restart. Wrote initial help documentation. Created hello world templates for GTK+ and gtkmm. This is a great feature to test the plug-in. I have tested on Linux and Windows and seems to work now rather well. Adding/removing dozens of packages at a time can take some time though (seconds).
Hi Petri, can you place the URL where the source is into the URL field in this bug. Thanks!
Created an Eclipse marketplace entry: http://marketplace.eclipse.org/content/pkg-config-support-eclipse-cdt This is meanwhile the pkg-config support gets integrated to CDT. Aimed mainly for those who need this already, but at the same time the plug-in will be tested properly. It is also always interesting to see how much popularity the plug-in gains through the Eclipse marketplace.
Created attachment 197832 [details] Screenshot of GTK+ project.
Created attachment 197833 [details] Property page.
I have now tried to implement an External Settings Provider, but some things are a bit unclear to me. 1) How External Settings Provider adjusts to different locations in different machines? Does this happen automatically or if not then what checks or tricks should one implement? 2) Pkg-config outputs OS-specific paths so does External Settings Provider work cross-platform as well? 3) How to add a value to "Other flags" field in Compiler's Miscellaneous group? ICSettingEntry doesn't exist for that. 4) For some reason ICConfigurationDescription#setExternalSettingsProviderIds doesn't have effect on AbstractCPropertyTab#updateData but works via preference page or pop-up menuitem etc. Any ideas what's wrong? As a side note this approach seem to take more time.
(In reply to comment #51) I replied on list: http://dev.eclipse.org/mhonarc/lists/cdt-dev/msg22187.html
Now external setting provider is implemented in experimental branch. Although for some reason adding/removing a package will duplicate library files. I feel this is a strange behavior, because after a consecutive adding and removal of the same package the library list stays same. Adding other package(s) with similar libraries will also duplicate and never have I seen a same library name three times. Then there is this bug 349791 which this bug entry depends on. A blocker really.
Documentation available at http://pkg-config-support-for-eclipse-cdt.googlecode.com/files/Pkg-config%20support%20for%20Eclipse%20CDT%20documentation.pdf
Created attachment 207886 [details] Finished project.
I hope that someone could take a look at the attached project source. I am not sure what needs to be done so that it would be part of CDT. Hopefully someone (committer) can now take this further. The project has been 'ready' for a while. It has been installed 457 times according to Eclipse Marketplace. Haven't received any complains so I believe it has been field tested. I did some modifications since Google Summer of Code which are: includes are added to G++ also, removed unnecessary code and comments etc and updated help. Most common end-user fault has been to specify wrong path to PKG_CONFIG_PATH in Preference page. However it can be left blank as long as pkg-config utility is in PATH environment variable. This plug-in requires Eclipse 3.7 and CDT 8.x. Project site: http://code.google.com/p/pkg-config-support-for-eclipse-cdt/
It's still on my TODO list. Should get some time to look at this over the next few weeks. We probably have until Feb to add it for Juno.
Now includes Cross compilation environment support (per-project configuration rather than a global configuration), per-toolchain specified pkg-config binary, Tycho support for automated build and update site, default and custom pkg-config path options from dialog and other changes. Thanks to Mélanie Bats for these changes. More info might be added later into project website: https://code.google.com/p/pkg-config-support-for-eclipse-cdt/
In addition, project uses now Git.
Updated repository's URL which was expired long ago (Google Code -> Github). I haven't had time to keep it up-to-date with current Eclipse CDT versions unfortunately.