Drake: g++<=4.9 does not recognize clang's [abi:c++11] tags, can produce linker errors in drake_cmake_installed-like repos

Created on 14 Nov 2017  路  9Comments  路  Source: RobotLocomotion/drake

When @naveenoid was building a catkin-based downstream project for Drake, he had run into a linker error when trying to build his library in CMake:

undefined reference to `RigidBodyTree<double>::get_position_name(int) const'

However, get_position_name(...) was clearly defined, and other binaries (built in Bazel) were able to find this symbol.

Upon investigation, it was because Drake was being compiled with clang, while his project was compiled with g++ (the default compiler for his system). Digging slightly deeper revealed that this ABI compatibility incompatibility only seems to happen at or before g++-4.9.
As always, StackOverflow had an answer: https://stackoverflow.com/q/36159238/7829525

See repro and example output.

Possible courses of action:

  • In the generated drake-config.cmake, have it check the CXX compiler; if it detects gcc<=4.9 (and if it was generated with clang), stop and puke errors.
  • In some headers in //drake/common, add a version check to prevent any compilation for gcc<=4.9.
  • Add a check in install_prereqs.sh (something that may be similar to what we may do for the SIP /usr/bin/python on Mac?) to flag this as an issue.

At the time, the workaround we chose was to simply update-alternatives to switch cc / c++ from gcc / g++ to clang / clang++.

cc @stonier

Most helpful comment

FYI Never use update-alternatives to change the compiler your project it using. See for example https://askubuntu.com/questions/26498/choose-gcc-and-g-version/26500#26500 or tangentially #2830. People get away with doing it, but it is not correct and can sometimes fail disastrously. (It could be a different story within a docker build, but that doesn't sound like the case here.)

Typically, the solution is instead to set CC and/or CXX variables to point to the compiler you want.

All 9 comments

FYI Never use update-alternatives to change the compiler your project it using. See for example https://askubuntu.com/questions/26498/choose-gcc-and-g-version/26500#26500 or tangentially #2830. People get away with doing it, but it is not correct and can sometimes fail disastrously. (It could be a different story within a docker build, but that doesn't sound like the case here.)

Typically, the solution is instead to set CC and/or CXX variables to point to the compiler you want.

Neither g++-4.9 or Catkin are actually supported by Drake, of course. Catkin support will appear in the future, but g++-4.9 support is long gone.

Understood, but could we possibly throw an error in CMake if a user tries to consume Drake using g++-4.9, so that they have a (much much) more informative error?

I am inclined to say no since CMake supports so many compilers. The usual way to do these sorts of things is to specify compile features.

Looks like we currently only require cxx_decltype and cxx_decltype_auto from this list.

Gotcha. In that case, I will go ahead and update the FAQ with this failure mode.
Thanks!

An open question is whether packages should be generated with Clang 4.0, GCC 5.4, or both on Linux. CMake certainly tends to favor GCC as its default on most platforms for various (sometimes indirect) reasons.

FYI I would be OK with GCC 5.4 for Xenial binary releases; its the one used by build-essential. (I like Clang 4.0 as the default for from-source builds, as its error messages still seem to be better than GCC.)

Closing via #7491.

Was this page helpful?
0 / 5 - 0 ratings