eclipse-embed-cdt / eclipse-plugins

The Eclipse Embedded CDT plug-ins for Arm & RISC-V C/C++ developers (formerly known as the GNU MCU Eclipse plug-ins). Includes the archive of previous plug-ins versions, as Releases.
http://eclipse-embed-cdt.github.io/
Eclipse Public License 2.0
558 stars 130 forks source link

Makefile projects do not inherit "global" ${cross_make) setting #493

Closed TommyMurphyTM1234 closed 3 years ago

TommyMurphyTM1234 commented 3 years ago

I installed Eclipse 2021-06 IDE for Embedded C/C++ Developers from here on Windows 10:

https://www.eclipse.org/downloads/packages/

I dropped the Windows Build Tools and RISC-V GCC toolchain into this to allow me to work with RISC-V projects.

Image 204

Image 205

I created a Makefile (not a Managed Make) RISC-V project

Image 198

and added a Makefile containing the following:

all:
    $(info This is my Makefile)

I built the project and got this:

11:05:56 **** Incremental Build of configuration Default for project test ****
make all 
This is my Makefile
make: 'all' is up to date.

11:05:56 Build Finished. 0 errors, 0 warnings. (took 349ms)

All good so far.

I then went to Main Menu > Window > Preferences > C/C++ > Build > Build Variables and defined ${cross_make} there:

Image 201

I saved this and then tried to build the project again expecting it to fail because it should attempt to call foobar instead of make but it actually still calls make and works fine.

My understanding is that the Makefile project should inherit the ${cross_make} vairable defined at the "global" level but it does not.

Note that ${cross_make} is not defined at the project level which would override any "global" setting.

Image 202

Image 203

I hope that that describes the issue adequately but if not please let me know what additional info is needed.

Regards Tommy

ilg-ul commented 3 years ago

My understanding is that the Makefile project should inherit the ${cross_make} variable defined at the "global" level but it does not.

I would say it should, but I don't know how the Embedded CDT plug-ins could help, the code to start the build command is part of CDT.

Could you try a similar scenario on a plain Eclipse CDT, without the Embedded CDT plug-ins, to see if it makes any difference?

TommyMurphyTM1234 commented 3 years ago

Thanks @ilg-ul

I should have said that the reason that I logged it against Embedded CDT and not CDT itself is that I cannot see any mention of ${cross_make} in the latter. For example, using Eclipse for C/C++ Developers 2021-06:

Image 228 Image 229 Image 230 Image 231

Maybe I'm missing something here and ${cross_make} is not specific to Embedded CDT and can be found somewhere in CDT?

Regards Tommy

TommyMurphyTM1234 commented 3 years ago

Ah - when I use the Makefile Project with Existing Code option

Image 236

then I get this:

Image 234

And if I configure it to use ${cross_tool} instead of make then this only works if ${cross_make} is defined in the project properties but does not work if it is defined "globally".

Image 235

So perhaps this is a CDT rather than an Embedded CDT issue after all? I wonder if @jonahgraham might be able to comment?

Thanks Regards Tommy

jonahgraham commented 3 years ago

@TommyMurphyTM1234 your conclusion sounds right, it should be handled in CDT. Please move the bug to CDT (you can just reference the step-by-steps here rather than try to recreate all that in CDT's bugzilla). Can you CC Jantje (or I can) on the bugzilla, AFAIK he is the most experienced in this area of the code.

TommyMurphyTM1234 commented 3 years ago

@TommyMurphyTM1234 your conclusion sounds right, it should be handled in CDT. Please move the bug to CDT (you can just reference the step-by-steps here rather than try to recreate all that in CDT's bugzilla). Can you CC Jantje (or I can) on the bugzilla, AFAIK he is the most experienced in this area of the code.

Thanks @jonahgraham I've logged a new CDT issue here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=574514 But I cannot find any "Jantje" in the CC list.

TommyMurphyTM1234 commented 3 years ago

Ah - I found, and CC'd, Jan Baeyens who seems to be Jantje?

https://www.eclipse.org/forums/index.php/t/452632/

jonahgraham commented 3 years ago

Thanks @TommyMurphyTM1234

ilg-ul commented 3 years ago

Maybe I'm missing something here and ${cross_make} is not specific to Embedded CDT and can be found somewhere in CDT?

It is somehow usual that CDT remembers the last contents of some fields and offers them as defaults when creating new instances, so this might explain why the ${cross_make} string was present in that use case not specific to Embedded CDT.

TommyMurphyTM1234 commented 3 years ago

FWIW if I do a clean install of Eclipse for Embedded C/C++ Developers 2021-06:

Image 244 Image 245

And then launch it from the installer and point it at a new/empty workspace folder:

Image 246 Image 247

And then create a Makefile project and look at the project properties it has a reference to ${cross_make}.

Image 250

As mentioned previously I do not see any reference to ${cross_make} in a Makefile project created using Eclipse for C/C++ Developers (i.e. without Embedded CDT).

ilg-ul commented 3 years ago

In this case it looks like the Embedded CDT plug-ins redefine several defaults for the GUI content, including that for the make executable. :-(

jantje commented 3 years ago

The default build command is defined in the plugin.xml. Here you see how Sloeber defines it. afbeelding As you see Sloeber uses a variable but this variable has always been defined at the project level and not at the workspace level. The cdt managed build one does not specify the command so it defaults to make afbeelding I have never seen ${cross_make} before so I assume it is defined in a plugin.xml of one of the plugins of Embedded CDT The way I think it works is that IBuilder.getCommand returns the string representation in the plugin.xml (if not overwritten in the gui) and is then run in the os. I don't know whether CDT dumps the environment variables in the os or tries to expand them before executing the command. As Sloeber heavily relies on environment variables including global variables and I never had global variables excluded. I would expect one of the 2 following to be the problem 1) cdt tries to expand the command before executing ignoring the global variables 2) Something else is wrong causing an exception resulting in a not properly expanded environment variable

I tried to locate if/where cdt expands the command but IBuilder.getCommand is used at so many places it is "confusing to me"

jantje commented 3 years ago

I did some more tests and I think this is a Embedded CDT problem. afbeelding afbeelding afbeelding I suspect a name provider provides a empty cross_make. Try again with a variable with a different name.

ilg-ul commented 3 years ago

I have never seen ${cross_make} before so I assume it is defined in a plugin.xml of one of the plugins of Embedded CDT

Indeed, it is defined by the Arm & RISC-V managed build plug-ins, and is implemented as a class ConfigurationBuildMacroSupplier that implements IConfigurationBuildMacroSupplier.

It gets the value from the toolchain definition. For non-managed projects it probably returns a null value.

If I understand Tommy's issue correctly, it should also check the C/C++ -> Build -> Build Variables.

I currently don't have a quick fix at hand, if someone can provide some hits, preferably as a pull request, it would make things faster.

jantje commented 3 years ago

I think; first of all OP should check the environment variables as well as the build variables. Secondly OP should verify the workaround "use a different variable name like my_cross_make and do not use the default make command but F.I. ${my_cross_make}"

@ilg-ul I'm not using IConfigurationBuildMacroSupplier so I can't comment on that. I'm using IConfigurationEnvironmentVariableSupplier and IProjectEnvironmentVariableSupplier and both have their variables appear in the environment variables not the build. They are made known to CDT in the plugin.xml afbeelding afbeelding I see the build macro supplier is just underneath on the picture above. I do not know why there is a build and environment variable concept and I do not know how they relate. I think it is very confusing because when I turn on "show system variables" in preferences->C/C++->Build->build variables CDT shows me all system environment variables and others. I project properties->C/C++ build->Environment the os environment variables are also shown.

TommyMurphyTM1234 commented 3 years ago

I think; first of all OP should check the environment variables as well as the build variables.

What exactly do you mean here? Check the environment variables for what exactly?

Secondly OP should verify the workaround "use a different variable name like my_cross_make and do not use the default make command but F.I. ${my_cross_make}"

I don't understand this either. What does "F.I." mean?

TommyMurphyTM1234 commented 3 years ago

I suspect a name provider provides a empty cross_make. Try again with a variable with a different name.

Again I don't understand. What is a "name provider"?

jantje commented 3 years ago

Location to check afbeelding

Workaround to try afbeelding afbeelding

What is a "name provider"?

That was a comment for @ilg-ul I do not expect you to understand that

jantje commented 3 years ago

F.I. stands for "for instance"

TommyMurphyTM1234 commented 3 years ago

Thanks @jantje

Using Eclipse for Embedded C/C++ Developers 2021-06 I defined ${my_cross_make} at the "global" level and gave it a value of badmake:

Image 256

I then configured the Makefile project to use ${my_cross_make} instead of ${cross_make}:

Image 258

And when I build it tries to use badmake and fails.

Image 259

So the Makefile project is "inheriting" ${my_cross_make} from the global configuration but not ${cross_make}for some reason.

TommyMurphyTM1234 commented 3 years ago

FWIW I also did another test with a Managed Make project to which I added a pre-build step that invokes ${cross_make} and if I define ${cross_make} at the "global" scope (Windows > Preferences > C/C++ Build > Build > Build Variables) and set it to badmake this does NOT cause the pre-build step to fail so, like with the Makefile project, the global variable setting is not being "inherited" for the Managed Make project.

TommyMurphyTM1234 commented 3 years ago

I think; first of all OP should check the environment variables as well as the build variables.

I'm not sure what environment variables I should be looking at/for here but I can't see anything in my environment that would impact the use of ${cross_make} (or any other Eclipse variable) in the project settings.

Also - in case PATH is a concern here I am running with a minimal PATH to avoid picking up other tools inadvertently:

M31570@IRD-LT-M31570 d:\tools\eclipse\embedcpp-2021-06
$ path %SystemRoot%;%SystemRoot%\System32

M31570@IRD-LT-M31570 d:\tools\eclipse\embedcpp-2021-06
$ eclipse\eclipse.exe

If you need me to check anything else please let me know.

Regards Tommy

ilg-ul commented 3 years ago

I can't see anything in my environment that would impact the use of ${cross_make} (or any other Eclipse variable) in the project settings

cross_make is a special variable, its value is provided by a class, dynamically at run time, using a custom logic, which, at this moment, does not include looking in the manually defined build variables or environment variables.

This implementation obviously can be improved; if someone is willing to contribute a better logic, we'll consider it.

TommyMurphyTM1234 commented 3 years ago

cross_make is a special variable, its value is provided by a class, dynamically at run time, using a custom logic, which, at this moment, does not include looking in the manually defined build variables or environment variables.

But it does look at the manually defined variables in the project properties - just not those defined at the "global scope"?

ilg-ul commented 3 years ago

This is the current implementation:

In the same folder there is also an EnvironmentVariableSupplier.java which processes the PATH.

jantje commented 3 years ago

IMHO the only problem I see is that the build variables "cross_prefix", "cross_suffix", "cross_c", "cross_cpp", "cross_ar", "cross_objcopy","cross_objdump", "cross_size", "cross_make", "cross_rm" , "cross_toolchain_flags" are not visible in the project properties->C/C++ build->build variables. I think all other "problems" are due to confusion/misunderstanding. I have no clue whether the visibility is "by design" "a bug " in CDT or a bug somewhere else. @ilg-ul code seems fine to me. I also do not understand why there are "Build" and "environment" variables and how they relate.

cross_make is a special variable, its value is provided by a class, dynamically at run time, using a custom logic, which, at this moment, does not include looking in the manually defined build variables or environment variables.

IMHO it should not. The current code is as I would expect it and works as I would expect it.

But it does look at the manually defined variables in the project properties - just not those defined at the "global scope"?

IMHO I guess iit works as follows ->resolve at workspace scope (= global scope) ->resolve at project scope ->resolve at toolchain scope ->resolve at configuration scope

later resolving overwrites previous resolving. Basically embedded CDT uses and controls "cross_make". My advice: use it the way embedded CDT has planned to use it or use a different variable name.

TommyMurphyTM1234 commented 3 years ago

I think all other "problems" are due to confusion/misunderstanding.

I don't see how it's merely confusion/misunderstanding to expect ${cross_make} (and others) to behave like any other variable and take its value from the global scope if not defined at the project scope? This "problem" of where the variable gets its value seems real to me and my understanding was that @ilg-ul agreed?

Also - not being able to define it at global scope so that it is used at the project level means that the default value cannot be overridden externally using, for example. an INI file passed from the eclipse.ini file using -pluginCustomization.

I also do not understand why there are "Build" and "environment" variables and how they relate.

Eclipse for C/C++ Developers also has these (under both Windows > Preferences > C/C++ > Build and Project Properties > C/C++ Build) so they are not specific to Embedded CDT. Maybe this helps explain them?

https://stackoverflow.com/questions/31147348/what-are-eclipses-build-variables-and-how-do-they-differ-from-the-environment-v

IMHO it should not. The current code is as I would expect it and works as I would expect it.

Why do you think that it should not work like any other variable?

IMHO I guess iit works as follows ->resolve at workspace scope (= global scope) ->resolve at project scope ->resolve at toolchain scope ->resolve at configuration scope

This seems to contradict what you said previously?

ilg-ul commented 3 years ago

The cross_* build variables are visible in the project properties:

Screenshot 2021-06-29 at 21 26 06

By definition they are specific to a toolchain, and do not have global visibility.

As for the multiple scopes mentioned before, IMHO they are different things and are not related to build variables or environment variables.

The scopes are used to store configuration variables and/or internal status; they apply to global preferences (stored per Eclipse instance or per workspace) and to project properties (stored in the project .settings folder).

jantje commented 3 years ago

As the cross variables are visible in the UI I say this works as designed,; the issue is user error

ilg-ul commented 3 years ago

BTW, Tommy, did you manage to define global build variables in the eclipse.ini file? And where are these variables actually stored?

TommyMurphyTM1234 commented 3 years ago

BTW, Tommy, did you manage to define global build variables in the eclipse.ini file? And where are these variables actually stored?

Good point. I had assumed that the following in an ini file referenced by -pluginCustomization in the eclipse.ini file would do it but so far I have not managed to do so - maybe this is another case of settings that cannot be overridden in this way after all? In my experience some settings can be overridden this way and others cannot.

org.eclipse.cdt.core/macros/workspace=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<macros>\r\n <stringMacro name\="test_variable" type\="VALUE_TEXT" value\="This is a test"/>\r\n</macros>\r\n

or

/instance/org.eclipse.cdt.core/macros/workspace=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?>\r\n<macros>\r\n <stringMacro name\="test_variable" type\="VALUE_TEXT" value\="This is a test"/>\r\n</macros>\r\n

TommyMurphyTM1234 commented 3 years ago

OK - I think that the view is that this is not a bug after all so I am closing it.