2012-03-07 6 views
11

Il progetto che sto compilando utilizza CMake, che loves absolute pathnames.Crea gcc inserisce i relativi nomi di file nelle informazioni di debug

Quando compilo con le informazioni di debug abilitate, gcc inserisce questi nomi lunghi nelle sezioni .debug_str, il che è dannoso per il debug. Mi piacerebbe avere un breve percorso relativo a progetto relativo a root lì invece.

C'è qualche opzione per dire a gcc di rimuovere alcune parti del percorso prima di emettere i dati di debug? O forse c'è qualche strumento che potrebbe farlo sui binari compilati?

Ho provato a utilizzare l'opzione SET(CMAKE_USE_RELATIVE_PATHS ON) (che sembra essere frowned upon per dev), ma poiché sto utilizzando build non basate sull'origine, i nomi dei percorsi non sono ancora nella forma che vorrei che fossero. Cioè sono ./../src/mod_foo/foo.c anziché mod_foo/foo.c.

+1

'./../ src/mod_foo/foo.c' è un percorso ** relativo ** ... –

+0

Sì, ma non relativo * alla radice del progetto *, sebbene (che sia a' ../ src') – drdaeman

+0

Hai un problema con CMake, non con gcc. GCC inserisce in '.debug_str' esattamente come ottiene un argomento da linea di comando. – sirgeorge

risposta

5

È possibile impostare la proprietà RULE_LAUNCH_COMPILE di una destinazione CMake affinché CMake invochi uno script di shell che trasforma il percorso del file di origine in un percorso relativo del progetto prima di richiamare gcc. Utilizzare la funzione CMake configure_file per generare uno script della shell che conosca lo PROJECT_SOURCE_DIR e il PROJECT_BINARY_DIR del progetto.

Nel vostro più esterno CMakeLists.txt aggiungere il seguente codice:

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

Il seguente script di shell modello gcc_debug_fix.sh.in ha bisogno di andare alla directory principale del progetto 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}" 

Lo script di shell utilizza il informazioni dalle variabili PROJECT_BINARY_DIR e PROJECT_SOURCE_DIR per trasformare il percorso del file di origine in un percorso relativo alla radice del progetto e il percorso del file dell'oggetto su un percorso assoluto. Poiché gcc ha passato un percorso relativo al progetto ora, anche il percorso .debug_str deve essere utilizzato. si applicano

le seguenti avvertenze:

  • assicurarsi di impostare il bit di esecuzione di gcc_debug_fix.sh.in.
  • Per il corretto funzionamento dello script, CMAKE_USE_RELATIVE_PATHS deve essere impostato nuovamente su OFF.
  • Lo script fa presupposizioni sulla posizione dei percorsi di file sulla riga di comando. Questo potrebbe non funzionare se CMake utilizza una regola diversa per richiamare il compilatore. Una soluzione più robusta consisterebbe nell'esplorare gli argomenti dello script per i flag -o e -c.
+0

Grazie per la fantastica risposta! – drdaeman

1

Se davvero non potessi risolvere il file make/tool per farlo correttamente, scriverei uno script wrapper per gcc che riconosce percorsi assoluti e converte quindi in relativi.

Potrebbe sembrare qualcosa di simile in bash:

#!/bin/bash 

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

exec gcc "${out[@]}" 

Se la directory sorgente ha sottodirectory allora avrete bisogno di gestire quelli con attenzione, ma quanto sopra dovrebbe funzionare per una directory di origine piatta. Non l'ho ancora provato, e non sarei sorpreso se avessi sbagliato la quotazione, ma sarebbe solo un problema se hai dei percorsi con spazi. Inoltre non gestisce parametri come -I/whatever/include, ma puoi aggiustarlo.

10

È possibile utilizzare la -fdebug-prefix-map bandiera per rimappare i percorsi di informazioni di debug. Ad esempio, per utilizzare i percorsi relativi alla posizione di costruzione: -fdebug-prefix-map =/full/build/path =.