From 256da01046da8f4fbe81d629cf54ae32dc04a1fb Mon Sep 17 00:00:00 2001
From: Georgiy Lebedev <g.lebedev@tarantool.org>
Date: Sat, 15 Oct 2022 16:55:04 +0300
Subject: [PATCH] build: use relative paths in diagnostics and debugging
 information

Since our diagnostics use the `__FILE__` macro, they provide absolute
paths, which is kind of redundant and inconsistent: replace them with
relative ones.

As for debugging information, replacing absolute paths with relative ones
also requires an extra command to tell the debugger where to find the
source files, which is not convenient for developers: provide a new
`DEV_BUILD` option (turned off by default), which replaces absolute paths
with relative ones in debugging information if turned off.

Strip the prefix map flags from compiler flags exported to tarantool via
`src/trvia/config.h`.

Closes #7808

NO_DOC=<verbosity>
NO_TEST=<verbosity>
---
 CMakeLists.txt                                |  7 +++++
 ...x-abs-file-paths-in-diag-and-debug-info.md |  6 ++++
 cmake/prefix.cmake                            | 30 +++++++++++++++++++
 src/CMakeLists.txt                            |  6 ++--
 static-build/CMakeLists.txt                   |  6 ++++
 5 files changed, 53 insertions(+), 2 deletions(-)
 create mode 100644 changelogs/unreleased/gh-7808-fix-abs-file-paths-in-diag-and-debug-info.md
 create mode 100644 cmake/prefix.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 54c69b7953..11fdfac938 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,6 +53,8 @@ if(NOT EXISTS ${PROJECT_SOURCE_DIR}/src/lib/small/CMakeLists.txt)
     endif()
 endif()
 
+option(DEV_BUILD "Enable build options that make debugging more convenient" OFF)
+
 # Define GNU standard installation directories
 include(GNUInstallDirs)
 
@@ -71,12 +73,17 @@ include(cmake/profile.cmake)
 include(cmake/module.cmake)
 include(cmake/thread.cmake)
 include(cmake/hardening.cmake)
+include(cmake/prefix.cmake)
 
 add_compile_flags("C;CXX" ${HARDENING_FLAGS})
 set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${HARDENING_FLAGS}")
 set(DEPENDENCY_CXXFLAGS "${DEPENDENCY_CXXFLAGS} ${HARDENING_FLAGS}")
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${HARDENING_LDFLAGS}")
 
+add_compile_flags("C;CXX" ${PREFIX_MAP_FLAGS})
+set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${PREFIX_MAP_FLAGS}")
+set(DEPENDENCY_CXXFLAGS "${DEPENDENCY_CXXFLAGS} ${PREFIX_MAP_FLAGS}")
+
 set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
 
 check_symbol_exists(MAP_ANON sys/mman.h HAVE_MAP_ANON)
diff --git a/changelogs/unreleased/gh-7808-fix-abs-file-paths-in-diag-and-debug-info.md b/changelogs/unreleased/gh-7808-fix-abs-file-paths-in-diag-and-debug-info.md
new file mode 100644
index 0000000000..9ab923cf5c
--- /dev/null
+++ b/changelogs/unreleased/gh-7808-fix-abs-file-paths-in-diag-and-debug-info.md
@@ -0,0 +1,6 @@
+## feature/build
+
+* Made diagnostics and debugging information provide absolute file paths
+  instead of relative ones when building by default (absolute file paths in
+  debugging information can be retained by turning on `DEV_BUILD` CMake
+  option) (gh-7808).
diff --git a/cmake/prefix.cmake b/cmake/prefix.cmake
new file mode 100644
index 0000000000..231844a595
--- /dev/null
+++ b/cmake/prefix.cmake
@@ -0,0 +1,30 @@
+# Uses the `DEV_BUILD` option.
+
+# Assuming the C and C++ compiler IDs are equal.
+# For clang `MATCHES` is used to match both Clang and AppleClang.
+# `VERSION_GREATER` instead of `VERSION_GREATER_EQUAL` for compatibility
+# with cmake 3.5 on ubuntu 16.04.
+if ((CMAKE_C_COMPILER_ID MATCHES "Clang" AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER "9" OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL "9")) OR
+    (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER "8" OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL "8")))
+    set(PREFIX_MAP_FLAGS "-fmacro-prefix-map=${CMAKE_SOURCE_DIR}=.")
+endif()
+
+# Assuming the C and C++ compiler IDs are equal.
+# For clang `MATCHES` is used to match both Clang and AppleClang.
+# Since this flag requires an extra command to tell the debugger where to find
+# the source files, which is not convenient for developers, it is disabled when
+# `DEV_BUILD` option is turned on.
+if (NOT DEV_BUILD AND
+    # `VERSION_GREATER` instead of `VERSION_GREATER_EQUAL` for compatibility
+    # with cmake 3.5 on ubuntu 16.04.
+    ((CMAKE_C_COMPILER_ID MATCHES "Clang" AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER "3.8" OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL "3.8")) OR
+    (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND (CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.4.7" OR CMAKE_C_COMPILER_VERSION VERSION_EQUAL "4.4.7"))))
+    # Clang integrated assembler does not support this option.
+    set(CMAKE_REQUIRED_FLAGS "-Wa,--debug-prefix-map")
+    check_c_source_compiles("int main(void) {}" HAVE_AS_DEBUG_PREFIX_MAP)
+    unset(CMAKE_REQUIRED_FLAGS)
+    if (HAVE_WA_DEBUG_PREFIX_MAP)
+        set(AS_DEBUG_PREFIX_MAP_FLAG "-Wa,--debug-prefix-map=${CMAKE_SOURCE_DIR}=.")
+    endif()
+    set(PREFIX_MAP_FLAGS "${PREFIX_MAP_FLAGS} -fdebug-prefix-map=${CMAKE_SOURCE_DIR}=. ${AS_DEBUG_PREFIX_MAP_FLAG}")
+endif()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4db5e1926d..6429a244dd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -280,8 +280,10 @@ add_subdirectory(box)
 include_directories(${EXTRA_BOX_INCLUDE_DIRS})
 
 # Save CMAKE_XXX_FLAGS from this directory for config.h (used in --version)
-set(TARANTOOL_C_FLAGS ${CMAKE_C_FLAGS} PARENT_SCOPE)
-set(TARANTOOL_CXX_FLAGS ${CMAKE_CXX_FLAGS} PARENT_SCOPE)
+string(REPLACE  ${PREFIX_MAP_FLAGS} "" STRIPPED_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+set(TARANTOOL_C_FLAGS ${STRIPPED_CMAKE_C_FLAGS} PARENT_SCOPE)
+string(REGEX REPLACE ${PREFIX_MAP_FLAGS} "" STRIPPED_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+set(TARANTOOL_CXX_FLAGS ${STRIPPED_CMAKE_CXX_FLAGS} PARENT_SCOPE)
 
 set(EXPORT_LIST)
 if(BUILD_STATIC)
diff --git a/static-build/CMakeLists.txt b/static-build/CMakeLists.txt
index 05dcce921a..4711538576 100644
--- a/static-build/CMakeLists.txt
+++ b/static-build/CMakeLists.txt
@@ -25,9 +25,12 @@ set(READLINE_VERSION 8.0)
 set(READLINE_HASH 7e6c1f16aee3244a69aba6e438295ca3)
 set(BACKUP_STORAGE https://distrib.hb.bizmrg.com)
 
+option(DEV_BUILD "Enable build options that make debugging more convenient" OFF)
+
 include(../cmake/os.cmake)
 include(../cmake/profile.cmake)
 include(../cmake/hardening.cmake)
+include(../cmake/prefix.cmake)
 
 # Pass -isysroot=<SDK_PATH> option on Mac OS to a preprocessor and a C
 # compiler to find header files installed with an SDK.
@@ -54,6 +57,9 @@ set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${HARDENING_FLAGS}")
 set(DEPENDENCY_CXXFLAGS "${DEPENDENCY_CXXFLAGS} ${HARDENING_FLAGS}")
 set(DEPENDENCY_LDFLAGS "${DEPENDENCY_LDFLAGS} ${HARDENING_LDFLAGS}")
 
+set(DEPENDENCY_CFLAGS "${DEPENDENCY_CFLAGS} ${PREFIX_MAP_FLAGS}")
+set(DEPENDENCY_CXXFLAGS "${DEPENDENCY_CXXFLAGS} ${PREFIX_MAP_FLAGS}")
+
 # Install all libraries required by tarantool at current build dir
 
 #
-- 
GitLab