View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010868CMakeModulespublic2010-06-22 17:272010-09-10 00:05
Reporterdnewmarch 
Assigned ToAlex Neundorf 
PrioritynormalSeverityminorReproducibilitysometimes
StatusclosedResolutionfixed 
PlatformOSOS Version
Product VersionCMake-2-8 
Target VersionCMake 2.8.3Fixed in VersionCMake 2.8.3 
Summary0010868: Eclipse CDT 4 Generator incorrectly generates builtin macro definitions in .cproject file
DescriptionI'm having a problem using MinGW 3.4.5 with Eclipse 3.5, the CMake generated .cproject files load without any include directories or macro definitions. I looked in the .cproject file that was generated and saw that all the include directories and built in macros were in the .cproject file so I dug a little deeper. I noticed that some of the built in macros that were included were incorrect (eg. macro names were sometimes in the value attribute and macro values were sometimes in the name attribute). The one that actually causes Eclipse to fail to parse the file correctly is that some of the name attributes have an unescaped string in them. It seems as though Eclipse just silently fails to parse that part of the file with that invalid xml, but it wont' show any includes directories or macros.

So I dug deeper to see where CMake gets that builtin macro information, it turns out there is a CMake macro in Modules/CMakeFindEclipseCDT4.cmake called _DETERMINE_GCC_SYSTEM_INCLUDE_DIRS. This macro calls gcc to get the builtin macros, but I believe the way it parses gcc's output is incorrect. Basically gcc outputs a #define statement per line, but the way that's handled is to remove the #define and the \n and then split the text into a list at the spaces. Obviously this doesn't work for #defines whose value has a space in it. This is part of the problem, but it won't fix the problem completely unless strings are escaped before they are written into .cproject attributes as well.

I am still looking into fixing the problem, but I'm relatively new at CMake so I'm not sure what a better strategy is to parse the text that gcc outputs into an appropriate list.
TagsNo tags attached.
Attached Filespatch file icon CMakeFindEclipseCDT4.cmake.patch [^] (1,901 bytes) 2010-06-23 01:13 [Show Content]
? file icon CMakeFindEclipseCDT4.cmake [^] (4,890 bytes) 2010-08-19 16:11
? file icon CMakeFindEclipseCDT4.cmake.patch2 [^] (433 bytes) 2010-08-19 19:43
? file icon CMakeFindEclipseCDT4.cmake.2 [^] (5,150 bytes) 2010-08-22 18:35

 Relationships

  Notes
(0021141)
dnewmarch (reporter)
2010-06-22 21:50

I've just uploaded a fix for CMakeFindEclipseCDT4.cmake which resolves the issue for me (although I haven't tested it extensively). It splits up the #define lines in a more robust way. The comment I made in the original bug description about the need to escape strings written into the .cproject isn't actually necessary, as I've checked the source code and the value attributes are already escaped, and as long as the names and values don't get confused, the names should not need to be escaped.
(0021143)
dnewmarch (reporter)
2010-06-23 01:17

In CMakeFindEclipseCDT4.cmake the standard include paths are also determined by parsing the output of gcc, this also doesn't work correctly for me because (on windows) my standard include paths have spaces in them, and the criteria for splitting up the paths that was being used was spaces. I've uploaded a new patch that includes both the fix for built in macros the a new fix for standard include paths. In both cases each line is parsed so it should be more robust than making assumptions about spaces.
(0021757)
Alex Neundorf (developer)
2010-08-15 09:19

Thanks for the patch, I applied it (with only minor changes).

What I didn't understand is why did you use the following regexp for getting the name of a macro:

"[A-Za-z_][A-Za-z0-9_]*|[A-Za-z_][A-Za-z0-9_]*\\([A-Za-z0-9_, ]*\\)"

instead of just

"[A-Za-z_][A-Za-z0-9_]*"

? The shorter one seems to work too.

Alex
(0021765)
dnewmarch (reporter)
2010-08-15 20:37

Hi Alex,

I'm not sure if that regex was the best expression of what I was trying to do. But what I was trying to capture is the possibility of macro definitions optionally having parameters in brackets. I'm not sure the shorter one will do that.

Thanks for merging the patch though.

Dan
(0021777)
Alex Neundorf (developer)
2010-08-16 16:48

Like
#define FOO(a) ...something
?

Is something like that possible in the list of predefined macros ?

Alex
(0021778)
dnewmarch (reporter)
2010-08-16 20:58
edited on: 2010-08-16 20:59

Yeah, exactly. I just went back to check whether any of the predefined macros used by my compiler were functions. There are a few such as:
#define UINT64_C(c) c ## ULL

However, I also noted the regex above doesn't actually work. The following one does though:
[A-Za-z_][A-Za-z0-9_]*\\([A-Za-z0-9_, ]*\\)|[A-Za-z_][A-Za-z0-9_]*
It's essentially the same as above, but the expression which matches the macro functions is first otherwise the shorter expression will catch everything.

(0021782)
Alex Neundorf (developer)
2010-08-17 16:21

Can you please check that the following loop works ?
It seems this matches both cases (I tried with
"#define foo(a,b) ((a) > (b) ? (b) : (a))"

  FOREACH(nextLine ${_defineLines})
    STRING(REGEX REPLACE "#define " "" _defineRemoved "${nextLine}")
    STRING(REGEX MATCH "([A-Za-z_][A-Za-z0-9_]*)( *\\([^\\)]+\\))?"
           _name "${_defineRemoved}")
    LIST(APPEND ${_resultDefines} "${CMAKE_MATCH_1}")

    STRING(REPLACE ${_name} "" _nameRemoved "${_defineRemoved}")
    STRING(STRIP "${_nameRemoved}" _value)
    IF(_value)
      LIST(APPEND ${_resultDefines} "${_value}")
    ELSE()
      LIST(APPEND ${_resultDefines} " ")
    ENDIF()
  ENDFOREACH(nextLine)
(0021785)
dnewmarch (reporter)
2010-08-17 20:24

Hi Alex,

That expression does work, much more compact that mine too. However, I think there is one problem, it allows a space between the name and the opening bracket of the arguments. I don't think this should be allowed, because it means that macro definitions that are enclosed in brackets are parsed as part of the name, eg:
'#define __FLT_MIN_10_EXP__ (-37)'

I've included the change for that below. I discovered one other thing that was broken with the previous loop though. Because it was doing a replace of the macro name with an empty string, if the macro name was found with the macro definition it would also be replaced, which caused problems for definitions such as:
'#define __fastcall __attribute__((__fastcall__))'

So I've also made a change to take a substring instead instead of doing a replacement. Both of the above changes are reflected in the revised loop below:

  FOREACH(nextline ${_defineLines})
    STRING(REGEX REPLACE "#define " "" _defineRemoved "${nextline}")
    STRING(REGEX MATCH "([A-Za-z_][A-Za-z0-9_]*)(\\([^\\)]+\\))?" _name "${_defineRemoved}")
    LIST(APPEND ${_resultDefines} "${_name}")
    
    STRING(LENGTH ${_name} _start)
    STRING(LENGTH "${_defineRemoved}" _defineRemovedLen)
    MATH(EXPR _len "${_defineRemovedLen} - ${_start}")
    STRING(SUBSTRING "${_defineRemoved}" ${_start} ${_len} _nameRemoved)
    STRING(STRIP "${_nameRemoved}" _value)
    
    IF(_value)
      STRING(STRIP ${_nameRemoved} _value)
      LIST(APPEND ${_resultDefines} "${_value}")
    ELSE()
      LIST(APPEND ${_resultDefines} " ")
    ENDIF()
  ENDFOREACH(nextline)
(0021851)
Alex Neundorf (developer)
2010-08-19 16:12

I attached a new CMakeFindEclipseCDT4.cmake file.
How about this one ?

Alex
(0021854)
dnewmarch (reporter)
2010-08-19 19:51

Hi Alex,

I would like to suggest two changes to the file you uploaded.

The first is to use append the _name variable rather than the CMAKE_MATCH_1 variable to the _resultDefines list as the name. The reason for this is that ${_name} is the whole name including the argument, whereas ${CMAKE_MATCH_1} is only the name (as I think it matches what is in the first set of brackets in the regex). I'm not sure if this was intended or not, but if the argument is included in the name eclipse will evaluate the macro function properly, whereas if without the macro variables are not resolved, so I would prefer to use _name.

The second suggestion is to remove the name from the definition by taking a substring of the _defineRemoved variable. As I mentioned in my previous note, this avoids the problem where the macro name is mentioned with the macro definition, eg:
'#define __fastcall __attribute__((__fastcall__))'
would be parsed as
name: __fastcall
value: __attribute__((__))

I've created a patch with those suggestions against the file you uploaded and attached it as CMakeFindEclipseCDT4.cmake.patch2

Thanks

Dan
(0021885)
Alex Neundorf (developer)
2010-08-22 18:36

I attached a new CMakeFindEclipseCDT4.cmake.2.
I tuned the regexp a bit more.

Can you still find problematic cases ?

Alex
(0021888)
dnewmarch (reporter)
2010-08-22 20:22

Hi Alex,

I can't find any more problematic cases with that file, it looks like a much better approach, and works for all the cases that I was concerned about.

Thanks

Dan
(0021902)
Alex Neundorf (developer)
2010-08-23 14:58

Ok, pushed to next.
(with one more tiny change, the first regexp replace was not necessary)

Alex
(0022066)
Alex Neundorf (developer)
2010-09-01 12:11

Assigning target version...

 Issue History
Date Modified Username Field Change
2010-06-22 17:27 dnewmarch New Issue
2010-06-22 21:46 dnewmarch File Added: CMakeFindEclipseCDT4.cmake
2010-06-22 21:50 dnewmarch Note Added: 0021141
2010-06-23 01:13 dnewmarch File Added: CMakeFindEclipseCDT4.cmake.patch
2010-06-23 01:17 dnewmarch Note Added: 0021143
2010-06-23 08:43 Bill Hoffman Status new => assigned
2010-06-23 08:43 Bill Hoffman Assigned To => Alex Neundorf
2010-08-15 09:19 Alex Neundorf Note Added: 0021757
2010-08-15 09:20 Alex Neundorf Status assigned => resolved
2010-08-15 09:20 Alex Neundorf Resolution open => fixed
2010-08-15 09:20 Alex Neundorf Category CMake => Modules
2010-08-15 09:20 Alex Neundorf Status resolved => feedback
2010-08-15 09:20 Alex Neundorf Resolution fixed => reopened
2010-08-15 20:37 dnewmarch Note Added: 0021765
2010-08-16 16:48 Alex Neundorf Note Added: 0021777
2010-08-16 20:58 dnewmarch Note Added: 0021778
2010-08-16 20:59 dnewmarch Note Edited: 0021778
2010-08-17 16:21 Alex Neundorf Note Added: 0021782
2010-08-17 20:24 dnewmarch Note Added: 0021785
2010-08-19 16:10 Alex Neundorf File Deleted: CMakeFindEclipseCDT4.cmake
2010-08-19 16:11 Alex Neundorf File Added: CMakeFindEclipseCDT4.cmake
2010-08-19 16:12 Alex Neundorf Note Added: 0021851
2010-08-19 19:43 dnewmarch File Added: CMakeFindEclipseCDT4.cmake.patch2
2010-08-19 19:51 dnewmarch Note Added: 0021854
2010-08-22 18:35 Alex Neundorf File Added: CMakeFindEclipseCDT4.cmake.2
2010-08-22 18:36 Alex Neundorf Note Added: 0021885
2010-08-22 20:22 dnewmarch Note Added: 0021888
2010-08-23 14:58 Alex Neundorf Note Added: 0021902
2010-08-23 14:58 Alex Neundorf Status feedback => closed
2010-08-23 14:58 Alex Neundorf Resolution reopened => fixed
2010-09-01 12:11 Alex Neundorf Note Added: 0022066
2010-09-01 12:11 Alex Neundorf Status closed => feedback
2010-09-01 12:11 Alex Neundorf Resolution fixed => reopened
2010-09-01 12:11 Alex Neundorf Status feedback => closed
2010-09-01 12:11 Alex Neundorf Resolution reopened => fixed
2010-09-01 12:11 Alex Neundorf Target Version => CMake 2.8.3
2010-09-10 00:05 David Cole Fixed in Version => CMake 2.8.3


Copyright © 2000 - 2018 MantisBT Team