MantisBT - CMake
View Issue Details
0015417CMakeCMakepublic2015-02-24 10:052016-06-10 14:31
Christophe Dumeunier 
Brad King 
normalminoralways
closedmoved 
LinuxopenSUSE11.4
 
 
0015417: CMAKE_C_COMPILER_VERSION is wrong due to a bug in gcc
I suppose CMAKE_C_COMPILER_VERSION and CMAKE_CXX_COMPILER_VERSION are obtained from the maccros __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. It seems that gcc 4.5.1 has a bug : __GNUC_PATCHLEVEL__ is set to 0 instead of 1. It implies that CMake is wrong when loading the compiler information from gcc 4.5.1. Maybe the version should be checked with the maccro __VERSION__, or obtained directly from the command "gcc --version".
Simply create a project compiled with gcc 4.5.1 using C or CXX.

The bug of gcc can be observed with the following C++ code :
#include <iostream>
int main(int argc, char** argv)
{
  std::cout << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << std::endl;
  return 0;
}
Note that gcc 4.5.1 is the default compiler on openSUSE 11.4.
No tags attached.
patch v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch (4,384) 2015-02-24 11:07
https://public.kitware.com/Bug/file/5390/v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch
patch CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.9.patch (3,711) 2015-02-25 07:46
https://public.kitware.com/Bug/file/5391/CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.9.patch
patch CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.12.2.patch (3,489) 2015-02-25 07:46
https://public.kitware.com/Bug/file/5392/CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.12.2.patch
patch CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-3.1.0.patch (3,527) 2015-02-25 07:46
https://public.kitware.com/Bug/file/5393/CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-3.1.0.patch
Issue History
2015-02-24 10:05Christophe DumeunierNew Issue
2015-02-24 10:12Brad KingNote Added: 0038052
2015-02-24 10:12Brad KingStatusnew => resolved
2015-02-24 10:12Brad KingResolutionopen => won't fix
2015-02-24 10:20Christophe DumeunierNote Added: 0038053
2015-02-24 10:30Brad KingNote Added: 0038055
2015-02-24 10:38Christophe DumeunierNote Added: 0038056
2015-02-24 11:07Brad KingAssigned To => Brad King
2015-02-24 11:07Brad KingStatusresolved => assigned
2015-02-24 11:07Brad KingResolutionwon't fix => open
2015-02-24 11:07Brad KingFile Added: v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch
2015-02-24 11:08Brad KingNote Added: 0038057
2015-02-25 03:51Christophe DumeunierNote Added: 0038060
2015-02-25 04:22Christophe DumeunierNote Edited: 0038060bug_revision_view_page.php?bugnote_id=38060#r1713
2015-02-25 06:37Christophe DumeunierNote Added: 0038062
2015-02-25 07:26Christophe DumeunierNote Edited: 0038062bug_revision_view_page.php?bugnote_id=38062#r1715
2015-02-25 07:46Christophe DumeunierFile Added: CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.9.patch
2015-02-25 07:46Christophe DumeunierFile Added: CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-2.8.12.2.patch
2015-02-25 07:46Christophe DumeunierFile Added: CMakeDetermineCompilerId-Workaround-GNU-4.5.1-CMake-3.1.0.patch
2015-02-25 07:46Christophe DumeunierNote Edited: 0038062bug_revision_view_page.php?bugnote_id=38062#r1716
2015-02-25 09:17Brad KingNote Added: 0038063
2015-02-26 03:22Christophe DumeunierNote Added: 0038072
2015-02-26 10:49Brad KingNote Added: 0038077
2015-02-26 11:31Christophe DumeunierNote Added: 0038078
2016-06-10 14:29Kitware RobotNote Added: 0042719
2016-06-10 14:29Kitware RobotStatusassigned => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0038052)
Brad King   
2015-02-24 10:12   
We're using the officially documented preprocessor symbols to get the version. We can't help it if someone distributes a compiler that populates them incorrectly. Any other method could be equally prone to such compiler bugs.
(0038053)
Christophe Dumeunier   
2015-02-24 10:20   
Okay with that in a perfect world.
But it implies that CMAKE_C_COMPILER_VERSION is wrong on a quite popular Linux distribution, and then it's not safe to use this variable for portability...
(0038055)
Brad King   
2015-02-24 10:30   
Re 0015417:0038053: Do you actually perform a version comparison that depends on the patch level for this case? Any C source that uses the preprocessor for such a version check would hit this problem also.

Maybe openSUSE should update their compiler package to fix this.
(0038056)
Christophe Dumeunier   
2015-02-24 10:38   
Not for a fixed minor version. But it works perfectly with gcc 4.1.2, 4.4.7, and 4.7.2. However, the preprocessor variable __VERSION__ seems always correct (more popular, I think).
(0038057)
Brad King   
2015-02-24 11:08   
__VERSION__ is useless for performing version checks in the C preprocessor to make decisions because it is a string.

Anyway, we can perhaps work around this specific instance of the problem. Please try "v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch".
(0038060)
Christophe Dumeunier   
2015-02-25 03:51   
(edited on: 2015-02-25 04:22)
Thanks for this patch. But I never used git and I'm not confortable to install this patch correctly.
I have git 1.8.1.4. I tried to patch cmake 3.1.0.

I went to "pathtocmake/share/cmake-3.1", I copied the patch there and launch the command "git apply v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch". I obtained the following error :
> git apply v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch
error: patch failed: Modules/CMakeDetermineCompilerId.cmake:409
error: Modules/CMakeDetermineCompilerId.cmake: patch does not apply
error: patch failed: Modules/CMakeFortranCompilerId.F.in:198
error: Modules/CMakeFortranCompilerId.F.in: patch does not apply

I also tried with the "patch" command but I have some errors :
> patch -p1 < v1-0001-CMakeDetermineCompilerId-Workaround-GNU-4.5.1-report.patch
patching file Modules/CMakeCCompilerId.c.in
patching file Modules/CMakeCXXCompilerId.cpp.in
patching file Modules/CMakeDetermineCompilerId.cmake
Hunk #1 FAILED at 409.
Hunk 0000002 succeeded at 448 with fuzz 1 (offset -20 lines).
Hunk 0000003 succeeded at 453 with fuzz 2 (offset -34 lines).
1 out of 3 hunks FAILED -- saving rejects to file Modules/CMakeDetermineCompilerId.cmake.rej
patching file Modules/CMakeFortranCompilerId.F.in
Hunk #1 FAILED at 198.
1 out of 1 hunk FAILED -- saving rejects to file Modules/CMakeFortranCompilerId.F.in.rej

Have I to do it on CMake 3.1.3 to work ?

EDIT : Understanding the modification, I wrote my own patch file for my CMake installed versions. It works like a charm !

(0038062)
Christophe Dumeunier   
2015-02-25 06:37   
(edited on: 2015-02-25 07:46)
Testing with Fortran, there is a problem. The file CMakeFortranCompilerId.F can't be compiled. I don't know Fortran, but I suppose it's due to the length of the line containing __VERSION__ (it's too long).

EDIT 1 : I saw another problem. The following line in CMakeDetermineCompilerId.cmake has to be modified to manage one more argument :
file(STRINGS ${file} CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
Actually, I think it already should be 7 in the script without your modification for GNU_4.5.1.

EDIT 2 : Sorry for the noise...
Finally I wrote 3 patches for CMake 2.8.9, 2.8.12.2 and 3.1.0.
I uploaded them if you want to document/read/check them.

(0038063)
Brad King   
2015-02-25 09:17   
Re 0015417:0038062: Thanks for working on the changes.

Unfortunately the Fortran limitations present a problem. We do not actually run the compiler id programs because the approach is meant to work for cross-compiling too. Instead we extract the INFO strings directly from the binary. That means they need to appear as a whole. Both my separate arguments to PRINT and your CHARACTER array for __VERSION__ may cause the value to be stored in the binary as a separate string from the INFO text.

We will need another approach for Fortran, so we might as well try one for all the languages. Perhaps it can be simpler. Please try teaching CMakeDetermineCompilerId.cmake to recognize when COMPILER_ID is "GNU" and COMPILER_VERSION is exactly "4.5.0". If so, then use execute_process() to run the compiler with --version and check for "4.5.1" in the output.

FYI, this will not be backported to older releases upstream. At most such patches could be added by distro packagers.
(0038072)
Christophe Dumeunier   
2015-02-26 03:22   
Hum... Quite interesting problem !
Is it not possible to use preprocessor to obtain this information instead to extract the strings from the binary ?
Something like that ?
#pragma message "INFO:compiler_version_gnu=" __VERSION__
(0038077)
Brad King   
2015-02-26 10:49   
Re 0015417:0038072: There is no such pragma portably. The binary-extraction approach has worked well on all compilers for years. This issue is about a workaround for a bug in a specific version of a specific compiler. I'd rather not make more than a minimal change for that. The approach I describe in 0015417:0038063 with execute_process will suffice for fixing the GNU 4.5.1 version.
(0038078)
Christophe Dumeunier   
2015-02-26 11:31   
You're right. I was juste thinking about a better way in general.
For me, the bug is solved with your solution.
(0042719)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.