define starts a macro. Everything from the start of the macro to
endef is just text and is not evaluated.
So your inner "define" is not recognised - it's just treated as
text. That means that the dirst endef matches the first define and
all the other endefs seem to have no corresponding define
statement.
In other words, you cannot nest defines like that.
Sure you can, it is a documented feature. From the GNU make manual,
(make) Defining:
| You may nest `define' directives: `make' will keep track of
| nested directives and report an error if they are not all properly
| closed with `endef'. Note that lines beginning with tab characters
| are considered part of a command script, so any `define' or `endef'
| strings appearing on such a line will not be considered `make'
| operators.
This is more a bug than anything.