Problem 1351

Summary: -ansi flags prevents building c++11 version
Product: Geant4 Reporter: Philippe Canal <pcanal>
Component: cmakeAssignee: Ben Morgan <Ben.Morgan>
Status: CLOSED FIXED    
Severity: major CC: Ben.Morgan, Gabriele.Cosmo, pcanal
Priority: P2    
Version: 9.5   
Hardware: PC   
OS: Linux   

Description Philippe Canal 2012-09-14 09:59:15 CEST
Hi,

When attempting to compile Geant4 in c++11 mode with gcc v4.7.1 and using CMAKE:

CXXFLAGS="-std=c++11 -Wno-deprecated-declarations" cmake
   -DCMAKE_INSTALL_PREFIX=${GEANT4_FQ_DIR} -DGEANT4_USE_SYSTEM_CLHEP=ON
   -DCLHEP_ROOT_DIR:STRING="${CLHEP_BASE_DIR}" -DBUILD_STATIC_LIBS=ON
   -DGEANT4_USE_OPENGL_X11=ON -DGEANT4_USE_GDML=ON
   -DXERCESC_ROOT_DIR:STRING="${XERCESCROOT}" -DCMAKE_BUILD_TYPE=Debug
   ${GEANT4_SOURCE}

It turns out that the resulting build is actually in c++98 mode.

This was discovered when an executable build with ROOT was crashing as soon as the Geant4 library were also linked in.

Tracking the issues down,it turns out that the build flags were:
   -std=c++11 ... -ansi
with -ansi overriding -std=c++11 based simply on the order of the flags (I think)

We can see the effect because the _Rb_tree<int>::_M_insert_unique
function has two versions, one for c++11 and one for c++03.

For now we can work around the problem by making a local fix (to the CMAKE files).

The real problem here seems to be that CXXFLAGS="..." cmake ...  results in the additional flags being added to the front of the list of flags.  I think that this should be reversed.  The additional flags should go at the end so that they take precedence if there are any conflicts.

In addition, it would be best if there was an official (platform independent) mean to turn on the c++11 build.

Thanks,
Philippe.
Comment 1 Ben Morgan 2012-09-14 11:07:48 CEST
Koichi, could you reassign this to me please?
Comment 2 Ben Morgan 2012-09-19 16:46:19 CEST
Gabriele, just to check on flags and policies...

As the issue is with the "-ansi" flag, could we make the selection of this flag dependent on a user supplied option for the C++ standard required (98, 03, 0x, 11), plus a compiler check that the requested standard is supported? 
If the standard is supplied, and the compiler supports it, the needed flag would be appended, otherwise CMake would exit with an error. Should the default still be for c++98 if the user does not supply the option (that seems reasonable, safe and clear)?

I think I've got all the info on required flags and checks for standards for gcc/icpc/clang - not sure about MSVC yet.
Comment 3 Ben Morgan 2012-09-19 17:07:16 CEST
Just to comment of the prepending of CXXFLAGS to the default flags - that's actually handled in the core CMakeCXXInformation module. It does seem wrong though, so will check with Kitware.
Comment 4 Gabriele Cosmo 2012-09-21 10:45:10 CEST
Hi Ben,

> As the issue is with the "-ansi" flag, could we make the selection of this flag
> dependent on a user supplied option for the C++ standard required (98, 03, 0x,
> 11), plus a compiler check that the requested standard is supported? 
> If the standard is supplied, and the compiler supports it, the needed flag
> would be appended, otherwise CMake would exit with an error. Should the default
> still be for c++98 if the user does not supply the option (that seems
> reasonable, safe and clear)?

yes, I would leave c++98 as the default, and do as you suggest for the selection of
the C++ standard by the user. I would expect though that CMake would properly
set the flags in such case !

Cheers, Gabriele
Comment 5 Ben Morgan 2012-11-13 15:20:34 CET
Fixed as of tag cmake-V09-05-67. There will be a new option "GEANT4_BUILD_CXXSTD" which can be set to the required standard - c++98, c++0x, c++11 for the GNU, Clang and Intel compilers. The value passed is validated, and checked against which standards the compiler supports. If it meets these criteria, the appropriate flags is appended to CMAKE_CXX_FLAGS. If no value is set, the c++98 (plus addenda) standard will be used.

This will be in release 9.6