2012-03-07 7 views
11

El proyecto que estoy compilando utiliza CMake, que loves absolute pathnames.Hacer gcc poner nombres de archivo relativos en la información de depuración

Cuando compilo con la información de depuración habilitada, gcc pone esos largos nombres en las secciones .debug_str, lo cual es malo para la depuración. En su lugar, me gustaría tener nombres de rutas cortas relativas a raíz del proyecto.

¿Hay alguna opción para decirle a gcc que quite parte de la ruta antes de emitir datos de depuración? O, tal vez, hay alguna herramienta que podría hacer eso en los binarios compilados?

He intentado usar la opción SET(CMAKE_USE_RELATIVE_PATHS ON) (que parece ser frowned upon por los desarrolladores), pero como uso compilaciones fuera de la fuente, los nombres de las rutas aún no están en la forma en que yo quisiera que estuvieran. Es decir. son ./../src/mod_foo/foo.c en lugar de mod_foo/foo.c.

+1

'./../ src/mod_foo/foo.c' es una ruta ** relativa ** ... –

+0

Sí, pero no relativa * a la raíz del proyecto *, aunque (que está en' ./ ../ src') – drdaeman

+0

Tiene un problema con CMake, no con gcc. GCC pone en '.debug_str' exactamente que se obtiene como un argumento de línea de comando. – sirgeorge

Respuesta

5

Puede establecer la propiedad RULE_LAUNCH_COMPILE de un objetivo CMake para que CMake invoque un script de shell que transforma la ruta del archivo de origen en una ruta relativa al proyecto antes de invocar gcc. Use la función CMake configure_file para generar un script de shell que conozca el PROJECT_SOURCE_DIR y el PROJECT_BINARY_DIR de su proyecto.

En su exterior CMakeLists.txt añadir el siguiente código:

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") 

El siguiente script de plantilla gcc_debug_fix.sh.in tiene que ir al directorio raíz del proyecto 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}" 

utiliza la secuencia de comandos shell del información de las variables PROJECT_BINARY_DIR y PROJECT_SOURCE_DIR para transformar la ruta del archivo fuente en una ruta relativa a la raíz del proyecto y la ruta del archivo del objeto a una ruta absoluta. Debido a que gcc pasa una ruta relativa al proyecto ahora, .debug_str también debe usar esa ruta.

Las siguientes advertencias se aplican:

  • Asegúrese de ajustar el bit de ejecución de gcc_debug_fix.sh.in.
  • Para que la secuencia de comandos funcione, CMAKE_USE_RELATIVE_PATHS tiene que volver a establecerse en OFF.
  • El script realiza suposiciones sobre la ubicación de las rutas de archivos en la línea de comandos. Esto puede no funcionar si CMake usa una regla diferente para invocar al compilador. Una solución más robusta sería escanear los argumentos del script para los flags -o y -c.
+0

¡Gracias por la increíble respuesta! – drdaeman

1

Si realmente no pudiera arreglar el archivo/herramienta make para hacer esto correctamente, escribiría un script envoltorio para gcc que reconozca las rutas absolutas y luego las convierta en relativas.

Podría ser algo como esto en bash:

#!/bin/bash 

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

exec gcc "${out[@]}" 

Si su directorio de origen tiene subdirectorios entonces usted necesita para manejar los cuidadosamente, pero lo anterior debe trabajar para un directorio de origen plana. Sin embargo, no lo he probado, y no me sorprendería si las citas fueran incorrectas, pero eso solo será un problema si tienes nombres de ruta con espacios. Tampoco maneja parámetros como -I/whatever/include, pero puedes arreglar eso.

10

Puede utilizar el -fdebug-prefix-mapa bandera para volver a asignar los canales de información de depuración. Por ejemplo, para hacer que las rutas relativas a la ubicación de compilación utilicen: -fdebug-prefix-map =/full/build/path =.

Cuestiones relacionadas