Comment faire en sorte que RPATH avec $ ORIGIN fonctionne sur Code :: Blocks GCC?
-
04-07-2019 - |
Question
J'essaie de lier un RPATH contenant la chaîne spéciale $ ORIGIN à un exécutable construit avec GCC avec l'IDE Code :: Blocks. J'ai spécifié
-Wl,-R$ORIGIN
dans les options de l'éditeur de liens pour le projet, mais la sortie de la ligne de commande vers GCC est incorrecte (pour plus de clarté):
g++ -Wl,-R
Quelle est la bonne façon de spécifier cet argument pour Code :: Blocks?
La solution
Celui qui a décidé de faire le jeton $ ORIGIN est un bâtard maléfique qui mérite une place spéciale dans l’enfer des programmeurs. Etant donné que '$' est un caractère spécial pour bash et d'autres langages de script tels que make, il écrase tout sauf s'il est soigneusement échappé. Pire encore, en fonction de l’environnement de construction que vous utilisez, la manière de s’échapper correctement changera probablement.
Sous Windows, vous devez coller une barre oblique inverse devant le $:
-Wl,-R\$ORIGIN
Code :: Blocks traite apparemment aussi le $ comme spécial. Ensuite, quel que soit le sous-processus, Code :: Blocks envoie la commande pour traiter la barre oblique inverse comme spéciale. Donc, la barre oblique inverse et le $ doivent être doublés pour être échappés correctement. Par conséquent, dans les paramètres de l'éditeur de code :: Blocks, vous devez spécifier:
-Wl,-R\\$ORIGIN
... quelles sorties:
-Wl,-R\\$ORIGIN
... dans le journal de construction, mais le shell est effectivement envoyé:
<*>... qui, comme mentionné ci-dessus, produit le résultat souhaité.
Quelle douleur.
Autres conseils
En plus de kblucks, la réponse à la question Code: Blocs .... Pour ceux qui, comme moi, sont tombés sur cette page en cherchant comment faire cela avec Make. L'astuce consiste à utiliser un signe $ supplémentaire comme caractère d'échappement et à le délimiter par des guillemets:
-Wl,-R,'$ORIGIN/../lib'
Une explication complète peut être obtenue ici: Utiliser ORIGIN pour une exécution dynamique chemin de recherche de la bibliothèque
Si votre exécutable est créé par un énorme environnement de script complexe que vous n'avez pas créé et que vous ne voulez pas approfondir avec cela, essayez de l'exécuter avec setenv LD_RUN_PATH = '$ ORIGIN /../ lib'
; si cela ne fonctionne pas, une approche pragmatique consiste à créer un wrapper pour ld:
#!/bin/sh
exec /usr/bin/ld -R '$ORIGIN/../lib' "$@"
... alors faites la construction avec ce bout sur le chemin. En pratique, il peut être appelé pour générer des fichiers .so ou d'autres exécutables. Vous devrez donc peut-être en faire un script plus complexe qui décidera d'insérer ou non le RPATH. OU, lancez la construction sans cela, et avec, et sélectionnez.
(ici, "/ usr / bin / ld" est le ld normalement exécuté, qui peut être ailleurs. gcc peut ne pas extraire ld du chemin, consultez les variables d'environnement gcc pour le remplacer. Le kilométrage peut usage unique seulement. N’est pas garanti d’être moins terrible que toute autre approche).