cmake

CMAKE_EXPORT_COMPILE_COMMANDS doesn't work since many cpp files is built into 1 big file somehow


I want to use CMAKE_EXPORT_COMPILE_COMMANDS to generate compile_commands.json, however I find many files are missed. Here is what I found:

  1. I modified a file named ob_join_order.cpp, and then build the project again, then I see
Building CXX objectsrc/sql/CMakeFiles/ob_sql.dir/Unity/unity_ob_sql_optimizer/0_cxx.cxx.o

You can see that it is not ob_join_order.cpp, but it is 0_cxx.cxx.o. By checking the files src/sql/CMakeFiles/ob_sql.dir/Unity/unity_ob_sql_optimizer/0_cxx.cxx, I see something like this.

#include "/u01/yizhi/github/oceanbase/src/sql/optimizer/ob_join_order.cpp"
#ifdef USING_LOG_PREFIX
#undef USING_LOG_PREFIX
#endif

#include "/u01/yizhi/github/oceanbase/src/sql/optimizer/ob_log_monitoring_dump.cpp"
#ifdef USING_LOG_PREFIX
#undef USING_LOG_PREFIX
#endif

So I think before the compiler compile the source file, the source files are merged into a big one. that's why CMAKE_EXPORT_COMPILE_COMMANDS failed.

Is it some tech in CMake or not? how can I disable it?

All the stuff can be reproduced by

git clone https://github.com/oceanbase/oceanbase.git

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 540863a..d12c4e4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,8 @@ project("OceanBase CE"
   HOMEPAGE_URL "https://www.oceanbase.com/"
   LANGUAGES CXX C ASM)
 
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
+
 ob_define(WITH_OSS OFF)
 
 if(ENABLE_DEBUG_LOG)
diff --git a/build.sh b/build.sh
index 98f91e4..0d17d42 100755
--- a/build.sh
+++ b/build.sh
@@ -94,7 +94,7 @@ function do_build
 {
     TYPE=$1; shift
     prepare_build_dir $TYPE || return
-    ${CMAKE_COMMAND} ${TOPDIR} "$@"
+    ${CMAKE_COMMAND}  -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ${TOPDIR} "$@"
 }

sh build.sh debug --init --make

Solution

  • You're correct all the files are being collected into a single file, and that CMake is partially responsible. However this isn't default CMake behavior.

    OceanBase is specifically configured as a unity build, meaning all of the translation units are collected into a single "unity" translation unit. You can see where they set this up in their cmake utilities. The relevant target property is UNITY_BUILD ON.