Сделать gcc поместить относительные имена файлов в отладочную информацию

В проекте, который я компилирую, используется CMake, который любит абсолютные пути.

Когда я компилирую с включенной информацией об отладке, gcc помещает эти длинные имена в разделы .debug_str, что плохо для отладки. Вместо этого я хотел бы иметь короткие пути к корневому каталогу.

Есть ли какая-то опция, чтобы сообщить gcc о том, чтобы удалить часть пути до того, как исправить данные отладки? Или, может быть, есть какой-то инструмент, который мог бы сделать это в скомпилированных двоичных файлах?

Я пробовал использовать SET(CMAKE_USE_RELATIVE_PATHS ON) (который, как представляется, нахмурился разработчиками), но поскольку я использую -f-source-сборки, имена путей все еще не в той форме, в которой я бы хотел. То есть они ./../src/mod_foo/foo.c вместо mod_foo/foo.c.

Ответ 1

Вы можете установить свойство RULE_LAUNCH_COMPILE цели CMake, чтобы CMake вызывал оболочку script, которая преобразует путь исходного файла к относительный путь проекта до вызова gcc. Используйте функцию CMake configure_file для создания оболочки script, которая знает о PROJECT_SOURCE_DIR и PROJECT_BINARY_DIR вашего проекта.

В своем внешнем CMakeLists.txt добавьте следующий код:

configure_file(
    "${PROJECT_SOURCE_DIR}/gcc_debug_fix.sh.in"
    "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh"
    @ONLY)

add_executable (MyExecutable ...)

set_target_properties(MyExecutable PROPERTIES 
    RULE_LAUNCH_COMPILE "${PROJECT_BINARY_DIR}/gcc_debug_fix.sh")

Следующая оболочка шаблона script gcc_debug_fix.sh.in должна перейти в корневую директорию проекта CMake:

#!/bin/sh

PROJECT_BINARY_DIR="@[email protected]"
PROJECT_SOURCE_DIR="@[email protected]"

# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE

# extract parameters
SOURCE_FILE="${@: -1:1}"
OBJECT_FILE="${@: -3:1}"
COMPILER_AND_FLAGS=${@:1:$#-4}

# make source file path relative to project source dir
SOURCE_FILE_RELATIVE="${SOURCE_FILE:${#PROJECT_SOURCE_DIR} + 1}"

# make object file path absolute
OBJECT_FILE_ABSOLUTE="$PROJECT_BINARY_DIR/$OBJECT_FILE"

cd "$PROJECT_SOURCE_DIR"

# invoke compiler
exec $COMPILER_AND_FLAGS -c "${SOURCE_FILE_RELATIVE}" -o "${OBJECT_FILE_ABSOLUTE}"

В оболочке script используется информация из переменных PROJECT_BINARY_DIR и PROJECT_SOURCE_DIR, чтобы преобразовать путь исходного файла к пути относительно корня проекта и пути к файлу объекта к абсолютному пути. Поскольку gcc получает относительный путь проекта, .debug_str также должен использовать этот путь.

Применяются следующие оговорки:

  • Обязательно установите исполняемый бит gcc_debug_fix.sh.in.
  • Для работы script CMAKE_USE_RELATIVE_PATHS необходимо снова установить на OFF.
  • script делает предположения о расположении путей файла в командной строке. Это может не работать, если CMake использует другое правило для вызова компилятора. Более надежным решением было бы сканирование аргументов script для флагов -o и -c.

Ответ 2

Вы можете использовать флаг -fdebug-prefix-map для переназначения путей информации для отладки. Например, чтобы сделать пути относительно местоположения сборки, используйте: -fdebug-prefix-map =/full/build/path =.

Ответ 3

Если бы я действительно не смог исправить make файл/инструмент, чтобы сделать это правильно, я бы написал оболочку script для gcc, которая распознает абсолютные пути и преобразует их в относительные.

Он может выглядеть примерно так: bash:

#!/bin/bash

out=()
for arg; do
  out=("${out[@]}" $(echo "$arg" | sed 's:/my/absolute/directory/:../:'))
done

exec gcc "${out[@]}"

Если в вашем исходном каталоге есть подкаталоги, вам необходимо тщательно их обрабатывать, но вышеприведенное должно работать для плоского исходного каталога. Я не тестировал это, хотя, и я не удивлюсь, если у меня получится неверный код, но это будет проблемой только в том случае, если у вас есть пути с пробелами. Он также не обрабатывает такие параметры, как -I/whatever/include, но вы можете это исправить.