Comment créer une bibliothèque statique pour iOS sans rendre tous les symboles publics

Cette question a déjà été posée, mais en cherchant dans la documentation des différents outils de développement, il semble que cela soit possible, mais pas évident.

Motivation: Faire une bibliothèque statique pour une utilisation par d'autres développeurs iOS. Certains symboles de la librairie causeront des problèmes s'ils sont exportés. Je souhaite donc en faire des symboles internes uniquement. Avec une bibliothèque dynamic c'est facile, il suffit d'utiliser l' -exported_symbols_list libtool ( ld ) et de listr ceux que vous voulez public. libtool documentation libtool n'autorise pas cet argument pour les bibliothèques statiques.

Library a plusieurs files ObjectiveC .m qui utilisent le code les uns des autres. Une seule class du groupe doit être rendue publique aux users du file de bibliothèque statique final.

Essayé libtool -exported_symbols_list publicsymbols.exp mais cet argument à libtool n'est pas supporté par -static pour les bibliothèques statiques.

Impossible de rendre les symboles privés avec des attributes (si cela fonctionne même) car ils sont nécessaires aux autres files .m du groupe.

ressemble à ld peut prendre plusieurs files .o et les lier set dans un nouveau file .o (via l'argument -r ) et il n'a pas la clause de non-responsabilité "dynamic only" pour l'argument -exported_symbols_list (qui pourrait être une documentation peu claire) …).

juste comme un test, je construis mon projet avec Xcode, donc j'ai tous les files .o, et puis j'essaye d'appeler ld sur la command line, comme ceci:

 ld -r -x -all_load -static -arch armv6 -syslibroot {path} -filelist /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Dissortingbution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCsdk.LinkFileList -exported_symbols_list {exp file path} -o outputfile.o 

où les choses de type {path} ont de longs paths vers les endroits appropriés.

mais j'ai des erreurs comme celles-ci:

/ usr / bin / ld_classic: /Users/Dad/ABCsdk/iphone-ABClib/build/ABCLib.build/Dissortingbution-iphoneos/ABCLib-device.build/Objects-normal/armv6/ABCmain.o incompatible, le file contient un type de support non pris en charge section 3 (_ TEXT, _picsymbolstub4) dans la command load 0 (doit spécifier "-dynamic" à utiliser)

donc quelque chose semble mal là …

Quelqu'un sait-il une manière intelligente de faire ce travail? Merci.

Ce n'est vraiment pas possible, je suis désolé de le dire. Cela a à voir avec le fonctionnement des bibliothèques statiques. Une bibliothèque statique est un peu plus qu'un tas de files object *.o regroupés, mais une bibliothèque dynamic est une image binary chargeable, tout comme un exécutable.

Supposons que vous avez quatre files,

  • common.c définit common , qui est "privé"
  • fn1.c définit fn1 , qui appelle common .
  • fn2.c définit fn2 , qui appelle common .
  • other.c définit l' other .

Dans une bibliothèque dynamic, l'éditeur de liens regroupe tout dans un gros morceau de code. La bibliothèque exporte les other , fn1 et fn2 . Vous devez charger la bibliothèque entière ou pas, mais deux programmes peuvent la charger sans mettre plusieurs copys en memory. Le point d'input à common est simplement absent de la table des symboles – vous ne pouvez pas l'appeler depuis l'extérieur de la bibliothèque car l'éditeur de liens ne peut pas le find.

Notez qu'une application et une bibliothèque partagée ont essentiellement le même format: une application est essentiellement une bibliothèque partagée qui n'exporte qu'un seul symbole, main . (Ce n'est pas exactement vrai, mais proche.)

Dans une bibliothèque statique, l'éditeur de liens ne s'exécute jamais. Les files sont tous compilés en files * .o et placés dans une archive de bibliothèque * .a. Les references internes ne seront pas résolues.

Supposons que votre application appelle fn1 . L'éditeur de liens voit un appel non résolu à fn1 , puis examine les bibliothèques. Il trouve une définition de fn1 dans fn1.o. Alors l'éditeur de liens remarque un appel non résolu à common , donc il le regarde en commun. Ce programme n'obtiendra pas le code de fn2.c ou other.c, car il n'utilise pas les définitions de ces files.

Les bibliothèques statiques sont très anciennes et ne possèdent aucune des fonctionnalités des bibliothèques dynamics. Vous pouvez penser à une bibliothèque statique comme un file zip plein de code source compilé, contrairement à une bibliothèque dynamic qui est liée set. Personne n'a jamais pris la peine d'étendre le format d'archive pour append la visibilité des symboles. Lorsque vous liez avec une bibliothèque statique, vous obtenez le même résultat que si vous aviez ajouté le code source de la bibliothèque à votre programme.

La version courte: Une bibliothèque dynamic possède une table de symboles de tous les symboles exportés, mais aucun des symboles privés. De la même manière, un file object possède une list de tous ses symboles extern mais aucun de ceux static . Mais une bibliothèque statique n'a pas de table de symboles, c'est juste une archive. Il n'y a donc pas de mécanisme pour rendre le code privé à une bibliothèque statique (autre que la définition d'objects static , mais cela ne fonctionne pas pour les classs Objective-C).

Si nous savions pourquoi vous essayiez de faire cela, nous pourrions peut-être vous faire une suggestion. (Est-ce pour la security? Les conflits de noms? Toutes ces questions ont des solutions.)

XCode BuildSetting peut le faire! 1. Définissez Perform Single-Object Prelink sur YES 2. Définissez le Exported Symbols File sur path_for_symbols_file

peut-être que vous devriez supprimer -static , -exported_symbols_list ne peut pas fonctionner en statique, mais peut prendre effet sur le file object.