Заставьте gcc поместить относительные имена файлов в отладочную информацию - PullRequest
13 голосов
/ 07 марта 2012

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

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

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

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

Ответы [ 3 ]

14 голосов
/ 10 октября 2013

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

6 голосов
/ 09 марта 2012

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

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

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

#!/bin/bash

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

exec gcc "${out[@]}"

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

...