Setting up an accurate Understand project is arguably the most important step in learning how to use Understand. Most languages aren't too difficult to setup, but C/C++ can be particularly difficult. Basically, anything the compiler needs to build an executable, Understand also needs. That means one of the best ways to build an Understand C/C++ project is to get the relevant information from the build system itself.
Both Clang and CMake have the option to generate a file called compile_commands.json during the build process. The compile_commands.json is a compilation database, which consists of an array of "command objects," where each command object specifies one way a translation unit is compiled in the project. Each command object contains the translation unit’s main file, the working directory of the compile run and the actual compile command.
Understand can use these compile_commands.json files to generate Understand projects quickly and without error. But what if you don't use Clang or CMake? Most Linux distributions just use GCC/G++, so how can I generate a compile_commands.json with GCC? The answer is an open source software called Bear.
Bear can be downloaded and installed from several different packages managers. Getting Bear working on Ubuntu, Fedora or SUSE (just to name a few) can easily be done through their respective package managers. But one of the more popular Linux distros is missing: CentOS/RHEL (And Rocky, too, starting from RHEL 8.6). We can build Bear from source, which wouldn't be an issue for CentOS/RHEL 9, but the problem is Bear is built using the filesystem library and according to this page, GCC 8 has only partial support of the filesystem library. In order to get the various Bear executables to link, we will need to add 'stdc++fs' to the target link libraries for several of Bear's compiled libraries. That means we need to edit some of our build files.
To start off, go ahead and get the dependencies installed. We should just need to run these commands:
sudo yum groupinstall "Development Tools" sudo yum install cmake sudo yum install pkg-config sudo yum install openssl-devel
If you are on CentOS/RHEL 7, you will need to install CMake 3.8 or later manually. The version of CMake that will be installed using yum install will be 2, which is not recent enough for Bear. You will also need a version of G++ that support C++ 17. The version of GCC that will be installed on CentOS/RHEL 7 using yum install will be 4 which only goes up to C++ 14. So you will need to manually install a more recent version of GCC as well. Double check the dependencies link above to make sure all your dependencies are installed. Bear's requirements may have changed since this document was written.
Before we run any build commands, we have to make some modifications to Bear's link libraries in several CMakeLists.txt files. These are the files we need to modify:
Bear-master/source/bear/CMakeLists.txt Bear-master/source/citnames/CMakeLists.txt Bear-master/source/intercept/CMakeLists.txt
In bear/CMakeLists.txt, we only need to modify one target. We have to add 'stdc++fs' to the target_link_libraries for bear_a. Here is what it looks like for me:
This is the pattern we are going to follow. Please note that the names of the libraries may vary slightly, but we are looking for the 'target_link_libraries' command below the 'add_library' command.
In citnames/CMakeLists.txt, we need to edit two libraries:
citnames_json_a citnames_a
And in intercept/CMakeLists.txt, we have three more edits. Here are the names of the libraries I added 'stdc++fs' to:
intercept_a wrapper_a exec_a
Afterwards, create a new directory for Bear to live and run these commands from the new directory:
cmake -DCMAKE_CXX_FLAGS=-std=c++17 -DENABLE_UNIT_TESTS=OFF -DENABLE_FUNC_TESTS=OFF $BEAR_SOURCE_DIR make all make install
That should be it. If you see any errors that look something like this:
undefined reference to `std::filesystem::__cxx11::path::*
It means one of the targets isn't finding the filesystems library. Double check each CMakeLists.txt and make sure 'stdc++fs' is added to the indicated libraries.
This guide was tested on CentOS 8 Stream and Rocky 8.6 using Bear 3.1.2; there may be additional steps required depending on your OS. It is probably only a matter of adding 'stdc++fs' to the 'target_link_libraries' command for the executable or library failing to compile or making sure the dependencies used by Bear are the correct version.