2009-12-09 21 views
3

Je construis la bibliothèque .so et je me demandais - quelle est la différence b/w -h et -o cc complier option (en utilisant le Sun Studio C++) ?différence entre -h <name> et -o <outputfile> options en cc (C++)

Ne font-ils pas référence à la même chose - le nom du fichier de sortie?

+0

Bonne question - les docs disent, « en général, le nom après -h doit être exactement la même que celle d'après -o ». Il pourrait être plus intéressant s'ils ont dit quand vous pourriez vouloir qu'ils soient différents ou ce qui se passe si vous spécifiez l'un sans l'autre. Je pense qu'un peu d'expérimentation est en ordre. –

Répondre

5

-o est le nom du fichier qui sera écrit sur le disque par le compilateur

-h est le nom qui sera enregistré dans les exécutables ELF qui pointent contre ce fichier.

Une utilisation courante consiste à fournir des numéros de version de bibliothèque mineurs. Par exemple, si vous créez la libfoo de bibliothèque partagée, vous pourriez faire:

cc -o libfoo.so.1.0 -h libfoo.so.1 *.o 
ln -s libfoo.so.1.0 libfoo.so.1 
ln -s libfoo.so libfoo.so.1 

Ensuite, si vous compilez votre application Bonjour tout le monde et un lien contre avec

cc -o hello -lfoo 

le binaire elfe pour bonjour va enregistrer une entrée NEEDED pour libfoo.so.1 (que vous pouvez voir en exécutant elfdump -d hello).

Puis, quand vous avez besoin d'ajouter de nouvelles fonctions plus tard, vous pouvez changer la valeur -o à mais laisser le -h à libfoo.so.1 - tous les programmes que vous avez déjà construits avec 1.0 toujours essayer de charger libfoo.so.1 lors de l'exécution, afin de continuer pour travailler sans être reconstruit, mais vous verrez via ls que c'est 1.1. Ceci est également parfois utilisé lors de la construction de bibliothèques dans le même répertoire utilisé lors de l'exécution, si vous n'avez pas de répertoire d'installation séparé ou si vous installez via un système d'empaquetage. Pour éviter de s'écraser les programmes en cours d'exécution lorsque vous écrasez le binaire bibliothèque, et d'éviter les programmes ne pas être en mesure de commencer quand vous êtes au milieu de la construction, certains Makefile fera:

cc -o libfoo.so.1.new -h libfoo.so.1 *.o 
rm libfoo.so.1 ; mv libfoo.so.1.new libfoo.so.1 

(Makefile construit par l'ancien générateur de makefile d'Imake de X le font généralement.)

+0

Merci mon pote, super explication. – Steve

2

Ils font référence à des noms différents. Plus précisément, l'option -o est le nom réel du fichier - celui du système de fichiers. L'option -h définit le interneDT_SONAME dans le fichier objet final. C'est le nom par lequel l'objet partagé est référencé en interne par d'autres modules. Je crois que c'est le nom que vous voyez également lorsque vous exécutez ldd sur des objets qui y sont liés.

1

L'option -o nomme le fichier de sortie tandis que l'option -h définit un nom intrinsèque à l'intérieur de la bibliothèque. Ce nom intrinsèque a la priorité sur le nom de fichier lorsqu'il est utilisé par le chargeur dynamique et lui permet d'utiliser des règles prédéfinies pour afficher la bonne bibliothèque.

Vous pouvez voir quel nom intrinsèque a été enregistré dans une bibliothèque donnée avec cette commande:

elfdump -d xxx.donc | grep SONAME

Jetez un oeil ici pour plus de détails:

http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter4-97194.html