ros / rosconsole

17 stars 61 forks source link

export `CMAKE_CXX_STANDARD` if `log4cxx` requires `C++17` #56

Open dreuter opened 2 years ago

dreuter commented 2 years ago

On Ubuntu 22.04 log4cxx is configured to use the std library for shared_mutex and shared_lock. Unfortunately this requires C++17, because otherwise the reverse dependencies of rosconsole fail with an error like this:

[ 50%] Building CXX object CMakeFiles/resource_retriever.dir/src/retriever.cpp.o
In file included from /usr/include/log4cxx/log4cxx.h:45,
                 from /usr/include/log4cxx/logstring.h:28,
                 from /usr/include/log4cxx/level.h:22,
                 from /root/ws/src/rosconsole/include/ros/console.h:46,
                 from /root/ws/src/resource_retriever/src/retriever.cpp:33:
/usr/include/log4cxx/boost-std-configuration.h:10:18: error: ‘shared_mutex’ in namespace ‘std’ does not name a type
   10 |     typedef std::shared_mutex shared_mutex;
      |                  ^~~~~~~~~~~~
/usr/include/log4cxx/boost-std-configuration.h:10:13: note: ‘std::shared_mutex’ is only available from C++17 onwards
   10 |     typedef std::shared_mutex shared_mutex;
      |             ^~~
/usr/include/log4cxx/boost-std-configuration.h:12:30: error: ‘shared_lock’ in namespace ‘std’ does not name a template type
   12 |     using shared_lock = std::shared_lock<T>;
      |                              ^~~~~~~~~~~
/usr/include/log4cxx/boost-std-configuration.h:12:25: note: ‘std::shared_lock’ is only available from C++14 onwards
   12 |     using shared_lock = std::shared_lock<T>;
      |                         ^~~

This means that if log4cxx requires C++17 everything that links rosconsole_log4xx also needs to compile with C++17 enabled, which is why I am setting the CMAKE_CXX_STANDARD and CMAKE_CXX_STANDARD_REQUIRED in cfg extras. I am checking whether the standard is already set to a higher standard, to not overwrite the user settings, if they need a newer standard.

Unfortunately we cannot set the CXX_STANDARD property on rosconsole_log4cxx directly, since it is not exported with catkin.

We cannot make log4cxx use boost, since this is an upstream package and the decision is made during configure time. Since this is an option that can be toggled by the provider of the log4cxx library and since it is not version dependent the best way I found to figure out whether the option was set or not is by "inspecting" the log4cxx/boost-std-configuration.h file.

Unfortunately try_compile has no option to set the include_directories when using the overload for a single source file and since we did not include_directories LOG4CXX_INCLUDE_DIRS at this point I created a small cmake project which includes the log4cxx headers. (We cannot execute the try_compile later, since it needs to run before catkin_package)

sloretz commented 2 years ago

Noetic targets Ubuntu 20.04. Is this in support of building Noetic from source on 22.04?

dreuter commented 2 years ago

Noetic targets Ubuntu 20.04. Is this in support of building Noetic from source on 22.04?

Yes this is for a source build of noetic on Ubuntu 22.04 (or any rolling distro like Gentoo and Arch)