Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 350206 - Add scanner config discovery for cmake projects using -CMAKE_EXPORT_COMPILE_COMMANDS=On flag
Summary: Add scanner config discovery for cmake projects using -CMAKE_EXPORT_COMPILE_C...
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-build (show other bugs)
Version: 8.0   Edit
Hardware: All Linux
: P3 enhancement with 3 votes (vote)
Target Milestone: ---   Edit
Assignee: cdt-build-inbox@eclipse.org CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-23 19:53 EDT by Sergey Prigogin CLA
Modified: 2020-09-04 15:16 EDT (History)
7 users (show)

See Also:


Attachments
An example of json file produced by cmake (1016.55 KB, text/plain)
2011-06-23 19:54 EDT, Sergey Prigogin CLA
eclipse.sprigogin: iplog-
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Prigogin CLA 2011-06-23 19:53:48 EDT
The latest cmake from head supports -CMAKE_EXPORT_COMPILE_COMMANDS=On command line option that can be used to obtain compiler commands in structural form (json) without running the build.

It would be nice to support scanner configuration discovery using the json files produced by cmake.

Here is a pointer to cmake code where the feature is implemented: http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmGlobalUnixMakefileGenerator3.cxx#l202

En example of code that reads cmake json file is in:
https://github.com/klimek/clang-indent/blob/topic-refactoring/include/clang/Tooling/Tooling.h#L133
Comment 1 Sergey Prigogin CLA 2011-06-23 19:54:40 EDT
Created attachment 198506 [details]
An example of json file produced by cmake
Comment 2 Doug Schaefer CLA 2011-06-23 20:34:27 EDT
Very cool. I've been talking to them about the need for this. Good to see them get a solution together quickly. Let's make sure we do this.
Comment 3 Martin Runge CLA 2014-01-29 09:48:41 EST
I started working on this supported by my empolyer. I also got the permission to contribute the code to CDT. But I have a few questions, maybe someone can point me to an answer :-)

I see two possible approaches:

1) Reuse the compiler commandline parser code in Scanner Config discovery
- Where to feed the compiler invocation lines from the json file into the existing parser without going through a console?

2) Extend the LanguagSettingsProvider extension point
- I see getSettingEntries() called when information is needed, so I could read the cmake generated json file on demand and cache the parsing results.
- How can I call the existing parser in scanner config from here?

In both cases:
- CMake can output the json file when generating the Makefile, so actually we could parse it before building or without building the project at all. It should also be possible to parse an "imported" file, e.g. generated by an integration process somewhere else. This should make it possible to navigate large projects without needing to build them locally first.
- Is there a way to trigger Makefile generation and scanner config without a build?
- Which json parser implementation should I use? (for now, I started with a copy of minimal_json / com.eclipsesource.json)
Comment 4 Marc-André Laperle CLA 2014-02-05 18:44:07 EST
(In reply to Martin Runge from comment #3)
> I started working on this supported by my empolyer. I also got the
> permission to contribute the code to CDT. But I have a few questions, maybe
> someone can point me to an answer :-)
> 
> I see two possible approaches:
> 
> 1) Reuse the compiler commandline parser code in Scanner Config discovery
> - Where to feed the compiler invocation lines from the json file into the
> existing parser without going through a console?
> 
> 2) Extend the LanguagSettingsProvider extension point
> - I see getSettingEntries() called when information is needed, so I could
> read the cmake generated json file on demand and cache the parsing results.
> - How can I call the existing parser in scanner config from here?

I think for sure you need a new language settings provider. I'm not sure how to reuse the parser but if it's not possible with the current API I think it would be worth changing the API. GCCBuildCommandParser might help here?

> In both cases:
> - CMake can output the json file when generating the Makefile, so actually
> we could parse it before building or without building the project at all. It
> should also be possible to parse an "imported" file, e.g. generated by an
> integration process somewhere else. This should make it possible to navigate
> large projects without needing to build them locally first.

That sounds really great! I've been thinking about CMake integration and I'm not sure how everything would fit together. I think it would be worth looking at how the Autotools integration works because it's also a generator like CMake. I think it adds a builder in addition to the "regular" CDT builder, maybe that's where the new provider could be triggered (as well as on demand). Similarly to autotools, I'm thinking there should be a new project type that would enable the CMake JSon language settings provider by default for you. It could also ask for the generator (Makefiles, Ninja, NMake, etc). This can all come later though.

> - Is there a way to trigger Makefile generation and scanner config without a
> build?

I think so. For example, I believe the built-in compiler settings language settings provider gets triggered when you create a new project and also when you change its settings (command line, etc) so I would look at how it's done there.

> - Which json parser implementation should I use? (for now, I started with a
> copy of minimal_json / com.eclipsesource.json)

What about org.json ? It's in Eclipse Orbit already so it won't need to go through a long legal process. See
http://download.eclipse.org/tools/orbit/downloads/
Comment 5 Doug Schaefer CLA 2014-02-05 22:48:27 EST
I am also looking at makefile generators, in my case qmake. We do need a generic strategy to deal with them. Autotools was shoehorned into the build model, but I don't think that's the best way.

These systems are managed make systems, and should probably be at that level in the grand scheme of things. I'll give this some thought as well.
Comment 6 Martin Runge CLA 2014-02-11 12:01:47 EST
I set up a github repository to share my current state: 
https://github.com/rungemar/cmake4cdt
By now, I have a new project type "CMake Project" with an additional "cmakeNature". For CMake projects, a menu entry is shown in project explorer's popup menu (right click). Don't be surprised if the code looks similar to autotools.

Comments are welcome.

What Namespace should I develop the plugin in? For the start I used my company's name, or should I use a different one from beginning on?

Next steps will be:
- provide a makefile generator as "buildfileGernerator" property of "builder"
- trigger this buildfileGenerator also from right click project menu
- language settings provider (have a prototype already)
Comment 7 John Eblen CLA 2014-03-12 16:00:30 EDT
I have also been working on this using a different strategy that reads the XML output of the CMake CDT4 generator. I think the json approach discussed here is better, though, because the output contains more information. Specifically, it indicates the file for each discovered symbol and include path, so you will be able to store settings at file level. Note that CMake has multiple generators for other IDEs, such as CodeBlocks, but they all seem to be lacking compared to the json output.

I have uploaded my code to github, in case it may be helpful:

https://github.com/eblen/Eclipse-CMake-language-settings-provider

This code does not create a new project type but only a new language settings provider. It contains an abstract XML provider class, which the CMake provider and another generic XML provider extend. So this might give some ideas for a more generic strategy, as mentioned by Doug.

Other notes:
1) Even though CMake runs separately from the actual build, I found it necessary to inherit from ICBuildOutputParser so I could store the config description (in startup method). I couldn't find any other way to get the config.

2) Figuring out the language for which the settings apply is tricky, because internally the language names are based on the compiler. See:

http://cdt-devel-faq.wikidot.com/#toc25
Comment 8 Marc-André Laperle CLA 2014-03-12 22:20:00 EDT
(In reply to Martin Runge from comment #6)
> I set up a github repository to share my current state: 
> https://github.com/rungemar/cmake4cdt
> By now, I have a new project type "CMake Project" with an additional
> "cmakeNature". For CMake projects, a menu entry is shown in project
> explorer's popup menu (right click). Don't be surprised if the code looks
> similar to autotools.
> 
> Comments are welcome.
> 
> What Namespace should I develop the plugin in? For the start I used my
> company's name, or should I use a different one from beginning on?

How about org.eclipse.cdt.cmake ? Make sure you add the copyrights header to your files as well.
Comment 9 Martin Runge CLA 2014-06-25 09:56:46 EDT
I introduced a CMakeNature to mark cmake projects. New projects get this cmake nature added from a template process, which works fine. But how can I get rid of the default "Empty Project" entry? I cannot ovveride it and it does not include CMakenature to the project.
Comment 10 Martin Runge CLA 2014-07-08 11:32:54 EDT
I managed to use GCCBuildCommandParser to parse the compile commands that cmake placed in the file compile_commands.json. This works well to a certain degree, but two things remain unsolved and I don't know how to solve them with the current API of AbstractBuildCommandParser:


First the easy one: 

I feed each compile command into the parseLine method of AbstractBuildCommandParser and get the parsing done. But the result is stored inside of the private internals/base classes. There are only getters by IResource, not for the whole list. I would like to cleanup the list when parsing is finished to put all common setting into ResourceScope.PROJECT and those common to a folder into ResourceScope.FOLDER. They are then presented in project properties. By now, I get the settings by file. To see them, I need to go into file properties.


The second one, that is a little more complicated:

A CMakelLists.txt file may contain source files that are no Eclipse resources, e.g. a source file outside of the project root:

set(SOURCES  main.cpp ../other/file.cpp)

CMake will generate a working Makefile an you will be able to build such projects. But GCCBuildCommandParser (AbstractBuildCommandParser) will ignore such source files, because they are no project resources.

As possible solutions I see:
1) would be to generate a virtual Folder with all these "out-of-project sources" as linked files. Indexer will find the sources then, but what about SCM plugins?

2) As this is not a clean project structure, I would like to add a diagnose possibility like: "search files outside of project". Similar to the Indexer's "search for unresolved includes". Provide the user information to allow him to clean up his project.


To get this working, I need to iterate over all files compiled by cmake, especially those that are not yet Eclipse Resources. But the LanguageSettingsProvider works the other way around: It provides the settings for a specific resource. Files outside the project that are no Eclipse resource will never go through this.


Right now, I see no other solution than to copy the GCCBuildCommandParser and 
a) build in a possibility to get a single line parsed and retrieve the settingsEntries resulting from this line directly afterwards
b) Add the possibility to iterate over the whole content of a provider _and_ do not ignore compile commands on files that are no resources.


I am very interested in your comments / suggestions about this.
Comment 11 Andrew Gvozdev CLA 2014-07-08 17:05:07 EDT
(In reply to comment #10)
> First the easy one:
> I feed each compile command into the parseLine method of
> AbstractBuildCommandParser and get the parsing done. But the result is stored
> inside of the private internals/base classes. There are only getters by
> IResource, not for the whole list. I would like to cleanup the list when parsing
> is finished to put all common setting into ResourceScope.PROJECT and those
> common to a folder into ResourceScope.FOLDER. They are then presented in project
> properties. By now, I get the settings by file. To see them, I need to go into
> file properties.
There is shutdown() method. If you override it you get a chance to cleanup your list before serialization and triggering language settings change event. You can keep non-resources in your own list.
 
> The second one, that is a little more complicated:
> A CMakelLists.txt file may contain source files that are no Eclipse resources,
> e.g. a source file outside of the project root:
First you need to figure out how to get the settings to the indexer. The indexer uses IScannerInfoProvider mechanism to get settings for files. Language Settings Providers are designed to feed the indexer through that channel. IScannerInfoProvider can only provide for IResource. I do not know if the indexer is able to take settings for non-IResource files outside a project but if it can it's gotta be a different channel.
Comment 12 Martin Runge CLA 2015-07-21 06:33:13 EDT
I try to make this a complete CMake plugin, which is more complicated than I expected. Here is why:

1) CMake keeps the project model apart from the toolchain definition. This is very handy when having a project, that will be built with different cross compilers or on different platforms like Windows, Linux. 

There are built-in toolchain definitions that come with a CMake-installation and there are toolchain-files used to describe cross-compilers.

Unfortunately, CDT does not support this very well. You can see what I mean in the new project wizard, where you have to choose a toolchain before adding a single source file.
It would be nice, if one could change the toolchain on the fly like switching between Debug and Release.

2) The ScannerConfig and most other things act per build configuration. You can set different include paths for Debug and Release.

-> This let me to the idea of having many build configurations, one for each toolchain/cross compiler:

debug_x86
release_x86
debug_x86_64
release_x86_64
debug_ppc
release_ppc
debug_arm
release_arm
...

As each toolchain usually has its own set of system headers, possibly supporting different language standards like C99, c++03, C++11, C++14..., the indexer has to keep them apart from each other.

Obviously, there could be many permutations between classical build configs (Debug/Release/relWithDebugInfo/Size) and the toolchains used. This will keep the indexer busy for a long time... 

-> I thought about generating build configurations on the fly: the user can choose from a matrix of known Debug/Release/Coverage/MinimalSize configs and known toolchains and reduce number of permutations.

At the end, I had written a lot of settings dialogs that replace already existing ones, leaving the user with a very confusing UI. If there are more places to add build configrations, how can the user know, which is the right one?

Any Ideas how to get further with this? 

What about the plans for CDT9 and https://wiki.eclipse.org/CDT/ProjectsAndBuildWorkingGroup ?
Comment 13 Marc-André Laperle CLA 2015-07-21 11:35:08 EDT
(In reply to Martin Runge from comment #12)

Hi Martin. As you have seen, I have started looking at the plugin a bit and I hope we can add it to CDT eventually. I have not gone very far in using it though so my comments my not be 100% relevant.

> -> I thought about generating build configurations on the fly: the user can
> choose from a matrix of known Debug/Release/Coverage/MinimalSize configs and
> known toolchains and reduce number of permutations.
> 
> At the end, I had written a lot of settings dialogs that replace already
> existing ones, leaving the user with a very confusing UI. If there are more
> places to add build configrations, how can the user know, which is the right
> one?
> 
> Any Ideas how to get further with this? 

I think it would be good to keep it as simple as possible and make it fit with the current build model in CDT. What I have in mind is that it would generate build configurations targeting the host by default. The *CMake* toolchain could be changed per in the configuration in build settings, in its own page. For example, a hello world project created on Windows 64 bit with MinGW installed would have debug_mingw_x86_64 and release_mingw_x86_64. Then, if the user wants to add Linux cross compiling, the user would add a new configuration using the normal UI in the project settings and change the toolchain build option.
This is more or less what I did before to support multiple targets, except that I was not changing the CMake toolchain but just the CDT toolchain (it was not built with CMake).

Perhaps later, an optional page in the wizard could help the user add more configurations based on:
1. The toolchain (MinGW, Linux GCC, Clang...)
2. The "variant" (Debug, Release, relWithDebugInfo...)

Those could be two separate choices (or more?) in other to reduce the number of permutations that the user has to choose. So in this example, it would generate 9 configurations.

> What about the plans for CDT9 and
> https://wiki.eclipse.org/CDT/ProjectsAndBuildWorkingGroup ?

I think it's still very much open to discussion. If you have ideas you would like to discuss, maybe you could post on the mailing list?

Also, if you don't know about it already, I'd like to point out the Launch Bar that has been available for a while. It looks similar to the UI you have added in the tool bar. Perhaps the CMake plugin could integrate with that, but I don't know much about it.
https://wiki.eclipse.org/CDT/User/NewIn87#Launch_Bar
https://wiki.eclipse.org/CDT/LaunchBar
https://git.eclipse.org/c/cdt/org.eclipse.launchbar.git/
Comment 14 Doug Schaefer CLA 2015-07-21 12:24:23 EDT
> > What about the plans for CDT9 and
> > https://wiki.eclipse.org/CDT/ProjectsAndBuildWorkingGroup ?
> 
> I think it's still very much open to discussion. If you have ideas you would
> like to discuss, maybe you could post on the mailing list?

Yes, we should get started on this. As I plough through some Arduino things where I plan to generate Makefiles based on some metadata the Arduino SDKs provide me, I think the role of the Builder can be expanded to manage the workflows for a build for a given configuration. And it should be able to extract the data we need for scanner discovery.

Right now the ToolChain picks the Builder which is backwards IMHO. You may use multiple toolchains with a given project but the same Builder. That's the beauty of CMake, qmake, etc. Even my Arduino thing.

But yes, whatever we do for CMake, I'd like to have available for qmake for Qt. There are some concepts that are common here. And we also want to make sure we're following CDT UI guidelines. I haven't looked at the CMake plug-ins but I'm very surprised there's toolbar items for it. The whole LaunchBar philosophy is that given a launch mode and a target, we should be able to figure out how to build for the launch.
Comment 15 Martin Runge CLA 2015-07-22 10:08:48 EDT
Hi Marc-Andre, I can follow your suggestion up to "change the toolchain build option". If I didn't miss anything, I would need to have these toolchains predefined in the plugin to be able to choose them in the combo box? How Can I add a new toolchain on the fly, without extending the plugin?

By now, I defined a single toolchain via XML in the plugin called "CMake provided toolchain" and let the builder call cmake with different -DCMAKE_TOOLCHAIN_FILE options. I like the idea, that the project model does not keep any details about the toolchain used. But on the other hand, if the builder does not know the compiler itself (its just some magic behind calling cmake and make afterwards), CDT does not know at first which error parsers to activate, which built-in compiler settings to query and which build-output parser to use to inspect the cmake_compile_commands.json file. It has to guess from the commands seen in the compile_commands file.


@Doug: I agree. cmake with toolchain file behaves nearly exacltly like qmake with mkspecs. Maybe we could even handle these both with a single implementation...

The current toolbar contribution of the CMake plugin is more "left over from previous prototypes" than something to stay. For example, it does not influence the launch at all which already led to irritated users here. I needed some of the functionality the launch bar seems to provide now that was not yet available when I started.
Comment 16 Doug Schaefer CLA 2015-07-22 10:25:15 EDT
CDT will always need to know at least something about the toolchain. For the launch bar to work, we need to know whether a toolchain can create executables for a given target type (os/arch). We also need to be able to pick out built-in compiler settings so the indexer can do it's thing and properly parse the source.

Maybe we can deduce that information by looking at the CMAKE_TOOLCHAIN_FILE or assume reasonable defaults. But it still needs to be captured somewhere.
Comment 17 Marc-André Laperle CLA 2015-07-22 10:40:34 EDT
(In reply to Martin Runge from comment #15)
> Hi Marc-Andre, I can follow your suggestion up to "change the toolchain
> build option". If I didn't miss anything, I would need to have these
> toolchains predefined in the plugin to be able to choose them in the combo
> box? How Can I add a new toolchain on the fly, without extending the plugin?

By toolchain build option, I meant the cmake toolchain (-DCMAKE_TOOLCHAIN_FILE), not the toolchain in CDT terms. Sorry that wasn't clear at all.

> By now, I defined a single toolchain via XML in the plugin called "CMake
> provided toolchain" and let the builder call cmake with different
> -DCMAKE_TOOLCHAIN_FILE options.

I think that sounds OK. It looks like creating toolchains on the fly would not be feasible with the current build model.
Comment 18 Doug Schaefer CLA 2015-07-22 11:03:28 EDT
(In reply to Marc-Andre Laperle from comment #17)
> > By now, I defined a single toolchain via XML in the plugin called "CMake
> > provided toolchain" and let the builder call cmake with different
> > -DCMAKE_TOOLCHAIN_FILE options.
> 
> I think that sounds OK. It looks like creating toolchains on the fly would
> not be feasible with the current build model.

Have some ideas on my whiteboard on how to address this for CDT 9.0. Will write it up ;)
Comment 19 Marc-André Laperle CLA 2015-07-22 15:28:55 EDT
(In reply to Doug Schaefer from comment #18)
> (In reply to Marc-Andre Laperle from comment #17)
> > > By now, I defined a single toolchain via XML in the plugin called "CMake
> > > provided toolchain" and let the builder call cmake with different
> > > -DCMAKE_TOOLCHAIN_FILE options.
> > 
> > I think that sounds OK. It looks like creating toolchains on the fly would
> > not be feasible with the current build model.
> 
> Have some ideas on my whiteboard on how to address this for CDT 9.0. Will
> write it up ;)

Sounds good! I was hopping to add CMake support for 8.8 though. Even if it means a less natural fit into the build model, like autotools. Then we could make it better for 9.0. Also, if the new build is not ready for 9.0, we would still have a working CMake integration until then.
Comment 20 Doug Schaefer CLA 2015-07-22 19:52:40 EDT
Agreed. Discussion on new model moved to the wiki. I do want to make CMake one of our key offerings with CDT 9. It's got to be good.
Comment 21 Martin Runge CLA 2015-07-24 08:52:37 EDT
I changed the current implementation to follow Marc-Andre's suggestion.
I can now add new configurations via the given "Manage Build Configurations" UI and then change the CMake toolchain file option in the builder settings for each configuration.
This works fine for a single project: I tried with two configurations: 

- debug: build with the toolchain, cmake chooses as default when given no toolchain file
- debug_arm: using a cross compiler specified by a toolchain file

Each build puts its output in its own subdirectoy of the project (there is a preference page to influence that). I can quickly switch like debug and release without any further changes.

This approach nicely solves the "too many permutations" problem. But how can I solve the following inconvenience:

1) I can only add new configurations for a single project at a time. We often have 20 or more projects open at a time, how can I easily add a new configuration to multiple projects? Or sync build configurations between (selected) projects incl. name and description?

2) The build configurations go into .cproject which is under version control and therefore transported from one developer/machine to the other. This can lead to build configurations being offered on machines where they are not applicable (Linux build offered on a windows machine, a cross build offered on a machine where the needed cross compiler is missing).
On the other hand, not every developer in a team has to add the same build configurations again.
Comment 22 Martin Runge CLA 2015-08-14 10:48:28 EDT
Concerning 8.8 release:

Hi Marc-Andre, Hi Doug,

Obviously, I am not the person to decide whether the CMake plugin can go into the CDT 8.8 release. So if you can find the time to have a look at it so close before feature freeze, please use latest version from github, tagged ver_0.1 (or any later version).

I stripped down the functionality to what already works and can be used:
- create new CMake "hello world" projects via New->Project->C/C++->CMake Project
- build
- create new configurations via the classic GUI and set CMake settings per configration 
  -- cmake build type for debug, release, etc
  -- cmake toolchain file to specify cross toolchains

I had the scanner Discovery working in the past, too, but that code got broken again in the meantime. maybe, I can get it to work again for release.

By now, I tested it all on Linux with gcc and some of our cross toolchains. Maybe I can also test Windows/MinGW by/on Monday.

A lot of my questions got answered in the last weeks, which allowed me to make some progress. Thank you for that. The things left are more or less just to be implemented and cleaned up.
Comment 23 Marc-André Laperle CLA 2015-08-14 11:05:20 EDT
(In reply to Martin Runge from comment #22)
> Concerning 8.8 release:
> 
> Hi Marc-Andre, Hi Doug,
> 
> Obviously, I am not the person to decide whether the CMake plugin can go
> into the CDT 8.8 release. So if you can find the time to have a look at it
> so close before feature freeze, please use latest version from github,
> tagged ver_0.1 (or any later version).

Unfortunately, I don't think this will make it in 8.8. I got too busy and the feature freeze came faster than I expected (like always!). We could get this in fairly early in the CDT 9.0 cycle once we're confident enough in the basic functionality and then we can make more improvements.

> I stripped down the functionality to what already works and can be used:
> - create new CMake "hello world" projects via New->Project->C/C++->CMake
> Project
> - build
> - create new configurations via the classic GUI and set CMake settings per
> configration 
>   -- cmake build type for debug, release, etc
>   -- cmake toolchain file to specify cross toolchains
> 
> I had the scanner Discovery working in the past, too, but that code got
> broken again in the meantime. maybe, I can get it to work again for release.
> 
> By now, I tested it all on Linux with gcc and some of our cross toolchains.
> Maybe I can also test Windows/MinGW by/on Monday.

One problem I had when I tried it is that it did not automatically detect the MinGW toolchain when I created a Hello World. I'm not sure if this is fixed in your new version, I'll have to try. I think it's worth it to make sure things work fairly out of the box when in the presence of toolchains that CDT has supported traditionally, like Linux GCC, MinGW, Mac GCC, maybe Cygwin.
Comment 24 Marc-André Laperle CLA 2015-08-14 11:22:18 EDT
(In reply to Martin Runge from comment #21)
> I changed the current implementation to follow Marc-Andre's suggestion.
> I can now add new configurations via the given "Manage Build Configurations"
> UI and then change the CMake toolchain file option in the builder settings
> for each configuration.
> This works fine for a single project: I tried with two configurations: 
> 
> - debug: build with the toolchain, cmake chooses as default when given no
> toolchain file
> - debug_arm: using a cross compiler specified by a toolchain file
> 
> Each build puts its output in its own subdirectoy of the project (there is a
> preference page to influence that). I can quickly switch like debug and
> release without any further changes.
> 
> This approach nicely solves the "too many permutations" problem. But how can
> I solve the following inconvenience:
> 
> 1) I can only add new configurations for a single project at a time. We
> often have 20 or more projects open at a time, how can I easily add a new
> configuration to multiple projects? Or sync build configurations between
> (selected) projects incl. name and description?


I think this is a problem of the CDT configuration UI in general. If I remember correctly, Visual Studio has property sheets that you can use to share things between projects and configurations, which makes things easier to maintain and sync.

> 2) The build configurations go into .cproject which is under version control
> and therefore transported from one developer/machine to the other. This can
> lead to build configurations being offered on machines where they are not
> applicable (Linux build offered on a windows machine, a cross build offered
> on a machine where the needed cross compiler is missing).
> On the other hand, not every developer in a team has to add the same build
> configurations again.

I think having configurations that are not usable depending on the environment/OS/etc is OK I think, to a certain extent. What wouldn't be ideal though is storing full paths to toolchains in the configuration. For example, if I have MinGW in D:\MinGW instead of C:\MinGW, and I create a CMake project that I intend to put in version control, I think it should be able to work for someone with MinGW in C:\. In situations where the team has a very standardized development environment, it might be perfectly OK to store full paths.
Comment 25 Doug Schaefer CLA 2015-08-14 12:21:14 EDT
(In reply to Marc-Andre Laperle from comment #23)
> (In reply to Martin Runge from comment #22)
> > Concerning 8.8 release:
> > 
> > Hi Marc-Andre, Hi Doug,
> > 
> > Obviously, I am not the person to decide whether the CMake plugin can go
> > into the CDT 8.8 release. So if you can find the time to have a look at it
> > so close before feature freeze, please use latest version from github,
> > tagged ver_0.1 (or any later version).
> 
> Unfortunately, I don't think this will make it in 8.8. I got too busy and
> the feature freeze came faster than I expected (like always!). We could get
> this in fairly early in the CDT 9.0 cycle once we're confident enough in the
> basic functionality and then we can make more improvements.

Hmm, that is unfortunate. As I mentioned earlier, my plan is to support CMake with the new build infrastructure in CDT 9.0. I'll first be doing qmake. Maybe once I have a good understanding of that we can move your work in the same direction.
Comment 26 Martin Runge CLA 2015-08-17 04:21:08 EDT
In response to comment 24:

I got it working with MinGW yesterday, if cmake.exe, gcc.exe and mingw32-make.exe are in the Path. I want to add the possibility to select the cmake installation in the preference page (the cmake installer on windows lets the user choose, wether he wants to add cmake to the path so there may be installations around where it is not).
How are the MinGW executables normally found? Is the installation path given in a CDT GUI or is it necessary to put them inside the Path environment variable when installing MinGW?
Actually, cmake itself needs to find them. So if they are not inside the system path, CDT needs to add the MinGW installation directory to the Path variable before calling cmake (or use a cmake toolchain file).

On Linux the situation is much easier: system-cmake, -gcc and -make are found in the PATH. Other (cross-) toolchains are specified via a toolchain file.

I don't have access to a Mac, so I can't test on OSX.
Comment 27 Martin Runge CLA 2015-08-17 05:06:09 EDT
(In reply to Doug Schaefer from comment #25)
> (In reply to Marc-Andre Laperle from comment #23)
> > (In reply to Martin Runge from comment #22)
> > > Concerning 8.8 release:
> > > 
> > > Hi Marc-Andre, Hi Doug,
> > > 
> > > Obviously, I am not the person to decide whether the CMake plugin can go
> > > into the CDT 8.8 release. So if you can find the time to have a look at it
> > > so close before feature freeze, please use latest version from github,
> > > tagged ver_0.1 (or any later version).
> > 
> > Unfortunately, I don't think this will make it in 8.8. I got too busy and
> > the feature freeze came faster than I expected (like always!). We could get
> > this in fairly early in the CDT 9.0 cycle once we're confident enough in the
> > basic functionality and then we can make more improvements.
> 
> Hmm, that is unfortunate. As I mentioned earlier, my plan is to support
> CMake with the new build infrastructure in CDT 9.0. I'll first be doing
> qmake. Maybe once I have a good understanding of that we can move your work
> in the same direction.

That would be great. I'll try to keep up with the upcoming changes.
In the meantime, I'll continue to improve the current implementation. While doing so I will probably come across several points that are not so easy to implement on the current code base. I'll try to share them here and I would appreciate any hints on how to solve them better with the new code base to get a better chance to make it for the next deadline.
Comment 28 Marc-André Laperle CLA 2015-08-17 09:46:12 EDT
(In reply to Martin Runge from comment #26)
> In response to comment 24:
> 
> I got it working with MinGW yesterday, if cmake.exe, gcc.exe and
> mingw32-make.exe are in the Path. I want to add the possibility to select
> the cmake installation in the preference page (the cmake installer on
> windows lets the user choose, wether he wants to add cmake to the path so
> there may be installations around where it is not).
> How are the MinGW executables normally found? Is the installation path given
> in a CDT GUI or is it necessary to put them inside the Path environment
> variable when installing MinGW?

The algorithm for detecting MinGW is described here:
https://wiki.eclipse.org/CDT/User/FAQ#I_installed_MinGW_toolchain_on_my_PC_but_Eclipse_won.27t_find_it.

The code is in 
org.eclipse.cdt.internal.core.MinGW
 
> I don't have access to a Mac, so I can't test on OSX.

I can take care of that. I'll create a pull request if any changes are necessary.
Comment 29 Marc-André Laperle CLA 2015-08-20 23:04:37 EDT
(In reply to Marc-Andre Laperle from comment #28)
> > I don't have access to a Mac, so I can't test on OSX.
> 
> I can take care of that. I'll create a pull request if any changes are
> necessary.

Works OK on Mac, looks the same as Linux. Though I did find an issue when CMake is not on PATH: it tries to build in an infinite loop. I'll follow up about that on Github (issue + pull request).
Comment 30 Martin Runge CLA 2015-08-26 10:08:00 EDT
(In reply to Marc-Andre Laperle from comment #29)
> (In reply to Marc-Andre Laperle from comment #28)
> > > I don't have access to a Mac, so I can't test on OSX.
> > 
> > I can take care of that. I'll create a pull request if any changes are
> > necessary.
> 
> Works OK on Mac, looks the same as Linux. Though I did find an issue when
> CMake is not on PATH: it tries to build in an infinite loop. I'll follow up
> about that on Github (issue + pull request).

Thanks for the Mac test.
I found the reason for the loop in calling cmake: I should not call ManagedBuildManager.saveBuildInfo() inside build() ...   :-|

I dont't understand, why this doesn't happen when cmake is found in the path, auto build is off or just triggering a build manually.
Comment 31 Marc-André Laperle CLA 2015-08-26 23:54:34 EDT
(In reply to Martin Runge from comment #30)
> > Works OK on Mac, looks the same as Linux. Though I did find an issue when
> > CMake is not on PATH: it tries to build in an infinite loop. I'll follow up
> > about that on Github (issue + pull request).
> 
> Thanks for the Mac test.
> I found the reason for the loop in calling cmake: I should not call
> ManagedBuildManager.saveBuildInfo() inside build() ...   :-|
> 
> I dont't understand, why this doesn't happen when cmake is found in the
> path, auto build is off or just triggering a build manually.

That's odd. I thought maybe there was a problem with the exception handling but didn't get very far. I think ManagedBuildManager.saveBuildInfo must have triggered a resource change which triggered the auto build, and since the build cannot be successful, it loops forever.

On my end, I started to make a basic CMake error parser to help navigate and annotate problems. As I edit CMakeLists.txt files, I run into problems and would like to see the errors and jump to them quickly.
Comment 32 Martin Runge CLA 2015-08-27 08:51:15 EDT
(In reply to Marc-Andre Laperle from comment #31)
> On my end, I started to make a basic CMake error parser to help navigate and
> annotate problems. As I edit CMakeLists.txt files, I run into problems and
> would like to see the errors and jump to them quickly.

That's great. I wanted to start an error parser as one of the next steps, too. So I'll instead concentrate next on 
- making cmake executable selectable in preferences
- make CMake generator selectable in preferences / properties
Comment 33 Martin Runge CLA 2015-09-18 12:23:17 EDT
Language setting provider triggered in a loop

Does anybody know how I can avoid language settings provider to be triggered in a loop? As far as I understand, language setting provider's getSettingsEntries() method is triggered by the change of a project's resource, which happens during build if the build folder is a subfolder of the project. I Already switched off auto-build, but without success.
- I can see project explorer's tree view flickering, it looks like the "Binaries" node gets modified all the time?
- Any Idea where to dig into to understand this?
- Do I need to mark the output folders as no source folders?
I cannot see anything in the output folder gets modified during loop iterations.
Comment 34 Martin Runge CLA 2016-01-15 08:38:39 EST
I had some time again to work on the built-in settings scanner for use with cmake. I came along the following (new?) issue:

When the toolchain used for the build is specified by a cmake toolchain file, eclipse does not know anything about the compiler used and needs to parse that info out of the compile_command.json file. First I thought it would be enough to get the compiler command (and path), e.g. "/opt/cross/bin/arm-linux-gcc", but unfortunately, its not. Yocto uses a cross compiler with sysroot not compiled in, means it will be called with the sysroot as argument:

/opt/cross/bin/arm-linux-gcc  --sysroot=/opt/cross/target-sysroot  ....

without the sysroot switch, the builtin scanner will miss many std include paths like /opt/cross/target-sysroot/usr/include.

There are more switches that influence the builtin settings: -pthread (-DREENTRANT) -fopenmp (-D_OPENMP) ...


I must read thease infos out of per project and per build config files. I can (and need to) handle them per build config, but not per project. 

Is there a way to guarantee that build configs are the same across all projects in a workspace? Or at least across all projects in a workspace with the same project nature?
Comment 35 Doug Schaefer CLA 2016-01-19 14:27:31 EST
(In reply to Martin Runge from comment #34)
> I had some time again to work on the built-in settings scanner for use with
> cmake. I came along the following (new?) issue:
> 
> When the toolchain used for the build is specified by a cmake toolchain
> file, eclipse does not know anything about the compiler used and needs to
> parse that info out of the compile_command.json file. First I thought it
> would be enough to get the compiler command (and path), e.g.
> "/opt/cross/bin/arm-linux-gcc", but unfortunately, its not. Yocto uses a
> cross compiler with sysroot not compiled in, means it will be called with
> the sysroot as argument:
> 
> /opt/cross/bin/arm-linux-gcc  --sysroot=/opt/cross/target-sysroot  ....
> 
> without the sysroot switch, the builtin scanner will miss many std include
> paths like /opt/cross/target-sysroot/usr/include.
> 
> There are more switches that influence the builtin settings: -pthread
> (-DREENTRANT) -fopenmp (-D_OPENMP) ...
> 
> 
> I must read thease infos out of per project and per build config files. I
> can (and need to) handle them per build config, but not per project. 
> 
> Is there a way to guarantee that build configs are the same across all
> projects in a workspace? Or at least across all projects in a workspace with
> the same project nature?

Hi Martin, sorry about the delay.

IMHO, scanner discovery has to take into account all of the arguments to the compiler, except maybe -o. Any of them can have an affect on what the paths and symbols are.

I've used that strategy for qmake. I expect we'd do the same for the other build systems.

I think the new build system has the flexibility to create shared settings between projects and build config. The Arduino system is somewhat done that way since the build commands are defined by the metadata files in the SDK download.
Comment 36 Doug Schaefer CLA 2016-01-19 14:51:46 EST
BTW, if you haven't found it, the toolchains cmake file feeds into CMakeBuildConfiguration.getScanenrInfo.

I may do some refactoring in there, since the caching is done really weird (that's what the call to the superclass does). But that may take a few days to get to.
Comment 37 Martin Runge CLA 2016-01-20 09:59:15 EST
Hi Doug

I agree, that we must respct all compiler switches, but I still see two different sets of settings:

- built-in settings that need to be queried by calling the compiler 
- given by argument

so one scanner takes some switches, the other one the rest.
 
If those built-in settings vary between compilation units, because they use different compiler switches, it gets really nasty. Then we need to call the compiler for each cu, but do not need the two categories above any more.

I just try to get an internal prototype working just for us, still based on the old build model. Will start to use the new one soon (hope in two weeks).

BTW: in the old build model, I see the following problem:
When switching the configuration, the BuiltInSettingsScanner is triggered immediately. If that configuration was not yet configured (cmake run, lets call it "build step one"), the compiler and its built-in settings are unknown, I need the compile_commands.json file for that. 
The file gets available once I run cmake, but the BuiltInSettingsScanner is not triggered again by that build, because it thinks the compiler does not change due to a build, of cause. Which is correct for the actual build itself (calling make as "build step two")

Is there an easy way to control that in the new build model? I think of even letting the user confirm a switch of the build configuration or ask him, wether he wants to run cmake for the new configuration if the compile_command.json file is not there. Switching the configuration can be a lengthy operation when cdt hast to scan all the settings and rebuild the index for a large project.
Comment 38 Martin Runge CLA 2016-01-20 10:26:35 EST
Toolchain settings global or per project?

Just another detail: my BuiltInSettingsScanner (derived from the existing one, similar to CrossGccSettingsScanner) often gets called without a project scope when switching configurations. But as I need the project's compile_commands.json file to detect the used compiler, it does not make sense.

I think, for a clean solution, there is the need to somehow introduce workspace-wide configurations or an easy way to sync build configurations across all projects. 

Especially it should not be possible to have two projects in one workspace with different build configurations with the same name, e.g. two different kinds of "debug".
Comment 39 Doug Schaefer CLA 2016-01-20 10:29:41 EST
(In reply to Martin Runge from comment #37)
> Hi Doug
> 
> I agree, that we must respct all compiler switches, but I still see two
> different sets of settings:
> 
> - built-in settings that need to be queried by calling the compiler 
> - given by argument
> 
> so one scanner takes some switches, the other one the rest.
>  
> If those built-in settings vary between compilation units, because they use
> different compiler switches, it gets really nasty. Then we need to call the
> compiler for each cu, but do not need the two categories above any more.

The calls to the compiler are very quick. Though I haven't tried anything huge yet.

> I just try to get an internal prototype working just for us, still based on
> the old build model. Will start to use the new one soon (hope in two weeks).
> 
> BTW: in the old build model, I see the following problem:
> When switching the configuration, the BuiltInSettingsScanner is triggered
> immediately. If that configuration was not yet configured (cmake run, lets
> call it "build step one"), the compiler and its built-in settings are
> unknown, I need the compile_commands.json file for that. 
> The file gets available once I run cmake, but the BuiltInSettingsScanner is
> not triggered again by that build, because it thinks the compiler does not
> change due to a build, of cause. Which is correct for the actual build
> itself (calling make as "build step two")
> 
> Is there an easy way to control that in the new build model? I think of even
> letting the user confirm a switch of the build configuration or ask him,
> wether he wants to run cmake for the new configuration if the
> compile_command.json file is not there. Switching the configuration can be a
> lengthy operation when cdt hast to scan all the settings and rebuild the
> index for a large project.

Don't bug the user. If you look at the big picture, a huge majority of them won't know how to answer the question. They'll also expect the information in the editor to reflect the current build configuration. Just run cmake automatically. It'll need to be done sooner or later anyway.

At this point, we should just concentrate on making it work. We can fix issues once they show themselves.

Also, the old build system is dead to me now :). I'm trying hard to not even think about it.
Comment 40 Doug Schaefer CLA 2016-01-20 11:21:26 EST
(In reply to Martin Runge from comment #38)
> Toolchain settings global or per project?
> 
> Just another detail: my BuiltInSettingsScanner (derived from the existing
> one, similar to CrossGccSettingsScanner) often gets called without a project
> scope when switching configurations. But as I need the project's
> compile_commands.json file to detect the used compiler, it does not make
> sense.
> 
> I think, for a clean solution, there is the need to somehow introduce
> workspace-wide configurations or an easy way to sync build configurations
> across all projects. 
>
> Especially it should not be possible to have two projects in one workspace
> with different build configurations with the same name, e.g. two different
> kinds of "debug".

The new build system always gets called with IResource from which you can get the project.

I'm not sure you should waste time with the old system. It's really broken.

At this point, all I'm looking for is a mechanism to take the compile_commands.json file and see if we can generate scanner discovery info from it per file.
Comment 41 Martin Runge CLA 2016-01-21 11:44:16 EST
So you would suggest to have one LanguageSettingsProvider, that invokes the compiler executable (like the BuiltinSettingsScanner does now) but for every set of compiler switches used by the project, instead once per project/toolchain?
 
Including all the -I and -D switches and in an extreme case once for every compilation unit?
Comment 42 Doug Schaefer CLA 2016-01-22 09:56:36 EST
(In reply to Martin Runge from comment #41)
> So you would suggest to have one LanguageSettingsProvider, that invokes the
> compiler executable (like the BuiltinSettingsScanner does now) but for every
> set of compiler switches used by the project, instead once per
> project/toolchain?
>  
> Including all the -I and -D switches and in an extreme case once for every
> compilation unit?

The language settings providers aren't used in the new build system.

For Arduino, for example, I took the entire command line change -o to point to a tmp file and added the -E, -Md, etc. flags to it to generate the built-ins. You can see that in the ArduinoBuildConfiguration.calculateScannerInfo method.

Note though that the Arduino stuff doesn't use the real new build model yet. It was the prototype I used to figure out how to do it. But it's pretty close.
Comment 43 Marc-André Laperle CLA 2019-11-19 21:10:56 EST
I completely had forgotten about this bug. But I added a generic "Compilation database language settings provider" where you specify the path to the json file and choose an existing compiler output parser (GCCBuildCommandParser, etc). See bug 548730. It's a few manual steps to setup though and has no connection to the builder or project type (CMake or not) and it is only for MBS projects (where language settings provider can be used). It is still significantly quicker to setup indexing for a project using this new provider though. I think this bug can remain open in order to investigate configuring the LSP for Cmake projects automatically and address other concerns mentioned.