2014-12-09 17 views
8

Ho un programma Qt Linux. Mi piacerebbe utilizzare preferenzialmente le librerie Qt (dinamiche) nella directory dell'eseguibile, se esistono, altrimenti usare le librerie Qt del sistema. RPATH in soccorso.Impostazione dell'ordine RPATH in QMake

aggiungo questa linea al qmake s' del file .pro:

QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN\'' 

e guardando l'eseguibile risultante con readelf vedo:

0x000000000000000f (RPATH)    Library rpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib] 
0x000000000000001d (RUNPATH)   Library runpath: [$ORIGIN:/usr/local/Trolltech/Qt-5.2.0/lib] 

sembra giusto, ma ldd indica che sta utilizzando la versione di sistema:

libQt5Core.so.5 => /usr/local/Trolltech/Qt-5.2.0/lib/libQt5Core.so.5 (0x00007f2d2fe09000) 

Se modifico manualmente qmake sta risultante Makefile per scambiare l'ordine delle due rpaths, quindi $ ORIGIN viene dopo// ..., ottengo il comportamento usr/local destra:

0x000000000000000f (RPATH)    Library rpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN] 
0x000000000000001d (RUNPATH)   Library runpath: [/usr/local/Trolltech/Qt-5.2.0/lib:$ORIGIN] 

libQt5Core.so.5 => ./libQt5Core.so.5 (0x00007fb92aba9000) 

Il mio problema è con come qmake costruisce la variabile finale LFLAGS. Non riesco a capire come farlo mettere la mia aggiunta ($ ORIGIN) dopo la libreria di sistema. Qualche idea?

+0

Perché preferisci preferire le librerie locali alle librerie di sistema? In un normale scenario di distribuzione in cui vengono spedite le librerie con il binario, si ha solo locale o sistema su locale. –

+0

Non lo farei per un prodotto di produzione, ma è utile per il debug, dove la libreria locale ha un output diagnostico extra (per esempio). Mi rendo conto che posso semplicemente usare qualcosa sulla linea di LD_LIBRARY_PATH in uno script di wrapper, ma mi sono precipitato giù nella tana del coniglio QMAke/RPATH, e ora sono curioso di sapere come fare QMake a fare quello che voglio ... –

risposta

0

Sto prendendo un po 'di ipotesi su quello che sta succedendo, ma si basa sulla conoscenza di alcuni dei comportamenti strani di LD.

controllare la presenza di una variabile LD_LIBRARY_PATH che entrerà in vigore prima dell'elaborazione di una variabile RUNPATH. A causa della presenza sia di RPATH sia di RUNPATH, la regola LD_LIBRARY_PATH diventa effettiva, quindi se è impostata, disattivarla.

In secondo luogo, non avevo mai aspetto di vedere:

libQt5Core.so.5 => ./libQt5Core.so.5 (0x00007fb92aba9000) 

nella produzione di ldd, vorrei sempre vedere l'espansione della $ORIGIN nella directory del binario (? Forse si accorciato), così mi sarei aspettato:

libQt5Core.so.5 => /path/to/bin/./libQt5Core.so.5 (0x00007fb92aba9000) 

il che significa che suona come l'espansione LD_LIBRARY_PATH è .:/usr/local/Trolltech/Qt-5.2.0/lib, che a me sembra che tu hai le sostituzioni ambientali accadendo.

+0

Questo è il output testuale da ldd, nessun accorciamento coinvolto. LD_LIBRARY_PATH non è impostato in nessuno di questi esempi. –

+0

Avete impostato * qualsiasi * variabile di ambiente 'LD_'? hai lo stesso comportamento con 'env -i ldd '? Quale distro linux stai usando (cercando di verificare la presenza di bug)? – Petesh

1

Per quanto riguarda la mia ricerca, è possibile aggiungere RPATH solo all'inizio della lista con QMake.

Ma se si utilizza Linux e si può installare chrpath, è possibile modificarlo.

Aggiungi questo blocco alla fine del file .pro

# Add spacing since chrpath cannot expand RPATH length 
QMAKE_RPATHDIR = \ 
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY1\ 
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY2\ 
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY3\ 
    /XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY4 
QMAKE_POST_LINK += 'chrpath -r \'/my/qt/installation:\$$ORIGIN\' $$OUT_PWD/mybinaryname;' 
+0

Non proprio la soluzione che stavo anticipando, ma un grande hack nondimeno! –

+0

Si potrebbe usare 'patchelf --set-rpath' invece di' chrpath -r'. Sembra che non abbia alcun problema nell'espansione del rpath, quindi non è necessario cancellare QMAKE_RPATHDIR. – user362515

8

È possibile aggiungere il seguente al vostro.file di pro per forzare il linker dinamico di guardare nella stessa directory come l'applicazione Qt in fase di esecuzione in Linux:

unix:{ 
    # suppress the default RPATH if you wish 
    QMAKE_LFLAGS_RPATH= 
    # add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded 
    QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\'" 
} 

Se si desidera guardare in una sottodirectory del percorso dell'eseguibile, è possibile utilizzare:

QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/libs\'" 

Si noti che i file .so devono avere lo stesso nome nella directory dell'applicazione. Ad esempio, è necessario copiare libQt5Core.so.5.2.0 nella directory dell'applicazione con il nome libQt5Core.so.5. Ora il ldd mostra la directory dell'applicazione.

È inoltre possibile avere libQt5Core.so.5.2.0 e un collegamento ad esso con il nome libQt5Core.so.5 nella directory dell'applicazione.

+0

Questo è vicino. L'impostazione 'QMAKE_FLAGS_RPATH =' per sopprimere l'impostazione predefinita era la chiave. Quindi posso fare: 'QMAKE_FLAGS + =" -Wl, -rpath, \ '/ usr/local/Trolltech/Qt-5.2.0/libs \' -Wl, -rpath, \ '\ $$ ORIGIN \' "' per ottenere gli elementi giusti in RPATH nel giusto ordine. Probabilmente c'è qualche variabile che contiene il percorso del sistema che potrei usare, ma non riuscivo a trovarlo ... –

0

qmake sarebbe sempre aggiungere il QMAKE_RPATHDIR con l'QT_INSTALL_LIBS definito internamente $(QT_DIR)/mkspecs/features/qt.prf di file:

170: relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\ 
173:  QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase()) 
175:  QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev] 
179:!isEmpty(QMAKE_LFLAGS_RPATHLINK):!contains(QT_CONFIG, static) { 
189: QMAKE_RPATHLINKDIR *= $$unique(rpaths) 

Quindi, per evitare l'applicazione utilizzando la libreria QTdal percorso di sistema, commentare le righe di sopra del quale aggiungere il QMAKE_RPATHDIR e aggiungi QMAKE_RPATHDIR=$ORIGIN nel tuo file .pro.

Problemi correlati