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

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

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

есть ли возможность сказать gcc, чтобы очистить некоторую часть пути перед излучением отладочных данных? Или, может быть, есть какой-то инструмент, который может сделать это на compiled бинарники?

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

3 ответов


вы можете установить RULE_LAUNCH_COMPILE свойство цели CMake, чтобы CMake вызывал сценарий оболочки, который преобразует путь исходного файла в относительный путь проекта перед вызовом gcc. Используйте функцию х configure_file для создания сценария оболочки, который знает о 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")

следующий шаблон скрипт gcc_debug_fix.sh.in необходимо перейти в корневой каталог проекта CMake:

#!/bin/sh

PROJECT_BINARY_DIR="@PROJECT_BINARY_DIR@"
PROJECT_SOURCE_DIR="@PROJECT_SOURCE_DIR@"

# 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}"

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

следующие факторы:

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

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


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

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

#!/bin/bash

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

exec gcc "${out[@]}"

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