[tools] gcc compiler version detection

The attached patch file fixes a problem that I have been having attempting to build a recent version from cvs with gcc 4.1.1 on sparc solaris 2.8. Just to make sure I wasn't seeing things I also tried a build on Linux (FC5, gcc 4.0.1) and got the same results. running configure then make was produceing output that included the following lines: ...updating 695 targets... MkDir1 bin.v2 MkDir1 bin.v2/libs MkDir1 bin.v2/libs/program_options MkDir1 bin.v2/libs/program_options/build MkDir1 bin.v2/libs/program_options/build/gcc-4.1.1 Copyright MkDir1 bin.v2/libs/program_options/build/gcc-4.1.1 Copyright/release ETC... Note the additional newlines and the word 'Copyright'. This should have been: ...updating 695 targets... MkDir1 bin.v2 MkDir1 bin.v2/libs MkDir1 bin.v2/libs/program_options MkDir1 bin.v2/libs/program_options/build MkDir1 bin.v2/libs/program_options/build/gcc-4.1.1 MkDir1 bin.v2/libs/program_options/build/gcc-4.1.1/release ETC... The fragment of the paths after build/ is determined by bjam based on parsing the output of 'gcc --version'. My compiler produces: $> gcc --version gcc (GCC) 4.1.1 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $> Jam appears to build a single string out of this output, newlines and all. The real problem is in tools/build/v2/tools/gcc.jam. The line that parses the gcc output is: local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)" The regex snippet that should match the version number is '([^ ]+)'. The problem is that since '\n' != ' ' everything from 4.1.1 through Copyright is being matched and being interpreted as part of the compiler version. This agrees with the bad output above. I also checked for 'bin.v2/libs/program_options/build/gcc*' and ls indeed shows a filename with an embedded newline (this makes the ls output look pretty strange). The attached patch modifies tools/jam/src/regexp.c to add support for using newlines in character ranges and changes the above line in gcc.jam to: local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ \\n]+)[^(]*[(]?([^)]*)" Has anybody else seen this? -glenn diff -ru boost-20070103/tools/build/v2/tools/gcc.jam boost-20070103-new/tools/build/v2/tools/gcc.jam --- boost-20070103/tools/build/v2/tools/gcc.jam 2006-12-24 16:27:14.000000000 -0500 +++ boost-20070103-new/tools/build/v2/tools/gcc.jam 2007-01-08 11:27:09.591881456 -0500 @@ -78,7 +78,7 @@ # The 'command' variable can have multiple-element. When calling # the SHELL builtin we need a single string. local command-string = $(command:J=" ") ; - local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)" + local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ \\n]+)[^(]*[(]?([^)]*)" : [ SHELL "$(command-string) --version" ] ] ; version ?= $(command-info[1]) ; switch $(command-info[2]:L) diff -ru boost-20070103/tools/jam/src/regexp.c boost-20070103-new/tools/jam/src/regexp.c --- boost-20070103/tools/jam/src/regexp.c 2006-09-06 22:57:02.000000000 -0400 +++ boost-20070103-new/tools/jam/src/regexp.c 2007-01-08 11:26:31.469584407 -0500 @@ -518,6 +518,14 @@ regc(classr); regparse++; } + } else if (*regparse == '\\' ) { + regparse++; + if (*regparse) { + char ch=*regparse++; + if (ch == 'n') { regc('\n'); } + else { regc('\\'); regc(ch); } + } else + regc('\\'); } else regc(*regparse++); }

Glenn Schrader wrote:
The attached patch file fixes a problem that I have been having attempting to build a recent version from cvs with gcc 4.1.1
Sorry for not trying to fix this earlier...
Jam appears to build a single string out of this output, newlines and all. The real problem is in tools/build/v2/tools/gcc.jam. The line that parses the gcc output is:
local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)"
The regex snippet that should match the version number is '([^ ]+)'. The problem is that since '\n' != ' '
As it should be.
The attached patch modifies tools/jam/src/regexp.c to add support for using newlines in character ranges and changes the above line in gcc.jam to:
local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ \\n]+)[^(]*[(]?([^)]*)"
This would not be the way I would fix it. It will have the likely effect of breaking a bunch of other stuff that uses the regex function in bjam. The easier fix is to change the regex itself to include the newline as: local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)" Yes that's a literal newline at the end of the first line. If you could test with that change the would be wonderful :-)
Has anybody else seen this?
Nope, yours is the first GCC that I've seen that doesn't put something after the version number. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - grafikrobot/yahoo

Rene Rivera wrote:
Yes that's a literal newline at the end of the first line. If you could test with that change the would be wonderful :-)
Has anybody else seen this?
Nope, yours is the first GCC that I've seen that doesn't put something after the version number.
I suppose that the first case somebody tried with a vanilla FSF gdb, not the one prebuilt and shipped with some distro ;-) - Volodya

Rene Rivera wrote:
This would not be the way I would fix it. It will have the likely effect of breaking a bunch of other stuff that uses the regex function in bjam. The easier fix is to change the regex itself to include the newline as:
local command-info = [ MATCH "^[^ ]+[ ]+[^ ]+[ ]+([^ ]+)[^(]*[(]?([^)]*)"
Yes that's a literal newline at the end of the first line. If you could test with that change the would be wonderful :-)
Yep, that works. Even so, that invisible trailing space character strikes me as an editing mistake waiting to happen. Would it be worthwhile to add explicit syntax to the parser for handling these cases so that they're at least visible? -glenn
participants (3)
-
Glenn Schrader
-
Rene Rivera
-
Vladimir Prus