Domanda

Sto cercando di collegare un RPATH contenente la stringa speciale $ ORIGIN in un eseguibile creato utilizzando GCC con l'IDE Code :: Blocks. Ho specificato

-Wl,-R$ORIGIN

nelle opzioni del linker per il progetto, ma l'output della riga di comando su GCC è errato (eliminato per chiarezza):

g++ -Wl,-R

Qual è il modo corretto di specificare questo argomento per Code :: Blocks?

È stato utile?

Soluzione

Chiunque abbia deciso di creare il token $ ORIGIN è un bastardo malvagio che merita un posto speciale nell'inferno del programmatore. Poiché "$" è un carattere speciale per bash e altri linguaggi di scripting come make, rovina tutto a meno che non sia evaso con cura. Ancora peggio, a seconda dell'ambiente di costruzione che stai usando, le specifiche di come fuggire correttamente probabilmente cambieranno.

In bash, devi mettere una barra rovesciata davanti a $:

-Wl,-R\$ORIGIN

Code :: Blocks apparentemente considera anche $ come speciale. Quindi, qualunque controller di sottoprocesso Code :: Blocks invia il comando per considerare la barra rovesciata come speciale. Quindi, sia la barra rovesciata che il $ devono essere raddoppiati per sfuggire correttamente. Pertanto, nelle impostazioni del linker Code :: Blocks, è necessario specificare:

-Wl,-R\\$ORIGIN

... che genera:

-Wl,-R\\$ORIGIN

... al registro di compilazione, ma la shell viene effettivamente inviata:

<*>

... che come detto sopra produce il risultato desiderato.

Che dolore.

Altri suggerimenti

Oltre alla risposta di kblucks che risponde alla domanda per Code: Blocks .... Per quelli come me che sono incappati in questa pagina alla ricerca di come farlo con Make. Il trucco è usare un segno $ in più come carattere di escape e racchiuderlo tra virgolette:

-Wl,-R,'$ORIGIN/../lib'

La spiegazione completa è disponibile qui: Uso di ORIGIN per un runtime dinamico percorso di ricerca della biblioteca

Se il tuo eseguibile è stato creato da un enorme ambiente di script complesso non creato da te e non vuoi approfondire, provando a eseguire con setenv LD_RUN_PATH = '$ ORIGIN /../ lib' ; se non funziona, un approccio pragmatico è quello di creare un wrapper per ld:

#!/bin/sh
exec /usr/bin/ld -R '$ORIGIN/../lib' "$@"

... quindi esegui la compilazione con quello stub sul percorso. In pratica, potrebbe essere chiamato per creare file .so o altri eseguibili, quindi potrebbe essere necessario renderlo uno script più complesso che decide se inserire l'RPATH. OPPURE, esegui build senza questo, e con, e cherry pick.

(qui " / usr / bin / ld " è l'ld che normalmente sarebbe stato eseguito, che potrebbe essere da qualche altra parte. gcc potrebbe non raccogliere ld dal percorso, vedere le variabili di ambiente gcc per sovrascriverlo. Il chilometraggio potrebbe variano. Solo per uso singolo. Non è garantito che sia meno terribile di qualsiasi altro approccio).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top