Quelles solutions astucieuses sont là pour inclure les ressources dans une bibliothèque statique?

J'ai un projet de bibliothèque statique Xcode 4 qui inclut un moteur de rendu fait maison, et je réutilise ce moteur dans plusieurs applications. Ce moteur utilise OpenGL ES 2.0, et par extension, les shaders. Au fur et à mesure que les shaders se compliquaient, je ne les stockais plus sous NSSsortingngs dans un file source et les stockais maintenant sous forme de files text autonomes avec les extensions .vert et .frag.

Cela fonctionne correctement pour les applications qui incluent le moteur de rendu dans leur propre source. les shaders sont simplement ajoutés à la phase de construction "Copy Bundle Resources" de l'application, et chargés à l'exécution dans NSSsortingngs et compilés, liés, etc.

Cette stratégie ne fonctionne pas du tout si le moteur de rendu qui charge ces shaders est dans un projet de bibliothèque statique; il n'y a aucun package dans lequel copyr des ressources. Actuellement, je suis obligé de faire en sorte que chaque projet client du moteur de rendu statique libère ses propres copys des shaders dans sa propre phase de construction "Copier les ressources de l'set". Ceci est une douleur géante, et détruit une grande partie de la commodité de faire du moteur de rendu une librairie statique en premier lieu.

Je suppose que c'est une instance spécifique du problème plus général de "Ressources dans une bibliothèque statique". La meilleure solution à laquelle je pense est de copyr le contenu des files shader dans des strings dans un file d'en-tête, qui sont ensuite inclus dans la source du moteur de rendu. Je peux même être capable d'automatiser la conversion de .frag en .h avec un peu de magie de phase de construction "Run Scripts", mais cela semble malheureusement compliqué.

Y a-t-il quelque chose qui me manque?

Vous pourriez essayer de créer un cadre, il semble correspondre à vos besoins. Il y a un exemple sur la façon de créer un tel framework pour iOS sur cette page:

http://db-in.com/blog/2011/07/universal-framework-iphone-ios-2-0/

Le gars qui a écrit le guide utilise réellement cette technique pour dissortingbuer son propre projet de moteur 3D iOS .

Edit: lié à une version plus récente du guide.

Pour le bénéfice de la postérité, je vais partager la solution que j'ai fini par utiliser. À un niveau élevé, la solution consiste à comstackr la ressource en question dans le binary de l'application, évitant ainsi de devoir également le copyr pour regrouper les ressources.

J'ai décidé qu'une façon générique et fiable de comstackr n'importe quelle donnée de file dans le binary serait de stocker le contenu du file dans un tableau d'octets statique dans un file d'en-tête. En supposant qu'il existe déjà un file d'en-tête créé et ajouté à la cible statique lib, j'ai créé le script bash suivant pour lire un file et écrire son contenu sous la forme d'un tableau d'octets de littéraux hexadécimaux avec la syntaxe C. Je lance ensuite le script dans la phase de construction "Exécuter le script" avant les phases de compilation Comstackr les sources et Copier les en-têtes:

#!/bin/bash # Hexify.sh reads an input file, and hexdumps its contents to an output # file in C-compliant syntax. The final argument is the name of the array. infile=$1 outfile=$2 arrayName=$3 fileSize=$(stat -f "%z" $infile) fileHexSsortingng=$(hexdump -ve '1/1 "0x%.2x, "' $infile) prefix=$arrayName suffix="Size" variableName=$arrayName$suffix nullTermination="0x00" echo "//" > $headerFile echo "// This file was automatically generated by a build script." >> $headerFile echo "// Do not modify; the contents of this file will be overwritten on each build." >> $headerFile echo "//" >> $headerFile echo "" >> $headerFile; echo "#ifndef some_arbitrary_include_guard" >> $headerFile echo "#define some_arbitrary_include_guard" >> $headerFile echo "" >> $headerFile echo "static const int $variableName = $((fileSize+1));" >> $outfile echo "static const char $arrayName[$variableName] = {" >> $outfile echo -e "\t$fileHexSsortingng$nullTermination" >> $outfile echo "};" >> $outfile echo "#endif" >> $headerFile 

Ainsi, par exemple, si j'ai un file de ressources example.txt:

 Hello this is a file 

Et je ./Hexify.sh example.txt myHeader.h exampleArray exécuter ./Hexify.sh example.txt myHeader.h exampleArray , l'en-tête ressemblerait à ceci:

 // // This file was automatically generated by a build script. // Do not modify; the contents of this file will be overwritten on each build. // #ifndef some_arbitrary_include_guard #define some_arbitrary_include_guard static const int exampleArraySize = 21; static const char exampleArray[exampleArraySize] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x0a, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x00 }; #endif 

Maintenant, à tout moment où j'aurais chargé cette ressource du package principal, je peux me référer au tableau d'octets dans ce file d'en-tête. Notez que ma version du script ajoute un octet terminé nul, ce qui rend datatables appropriées pour créer des objects string. Cela peut ne pas s'appliquer dans tous les cas.

En tant qu'additif final, je m'excuse si ce script bash fait grincer des vrais programmeurs bash; Je n'ai presque aucune idée de ce que je fais avec bash.

Je sens que votre compagnon de douleur, vos bibliothèques statiques et vos ressources ne vont pas bien set. Je pense que la façon la plus simple de le faire est celle que vous avez déjà mentionnée: écrire un script qui lit vos shaders, les échappe correctement et les enveloppe dans du code compatible C.

Je ne suis pas un expert, mais peut-être pourriez-vous append datatables de shader à une section de votre exécutable Mach-O lors de la binding? Mais cela se résume finalement à la même solution que celle mentionnée ci-dessus, avec le seul inconvénient que vous vous retrouvez avec la partie la plus laide du travail.

J'irais pour les constantes de string en utilisant un script shell. PHP dans mon expérience est assez bon pour faire ce genre de travail. Et bien sûr, bash scripts, mais je ne suis pas très bon à cela.