What Clever Solutions are There for Including Resources in a Static Lib?

二次信任 提交于 2019-12-06 15:49:47

You could try to create a framework, it seems to fit your needs. There's an example on how to create such a framework for iOS on this page:

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

The guy that wrote the guide actually uses this technique to distribute his own iOS 3D engine project.

Edit: linked to newer version of the guide.

For the benefit of posterity, I'll share the solution I ended up using. At a high level, the solution is to compile the resource in question into the application binary, thus obviating the need to also copy it to bundle resources.

I decided a generic and reliable way to compile any file data into the binary would be to store the file contents in a static byte array in a header file. Assuming there is already a header file created and added to the static lib target, I made the following bash script to read a file, and write its contents as a byte array of hex literals with C syntax. I then run the script in "Run Script" build phase before the Compile Sources and Copy Headers build phases:

#!/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)
fileHexString=$(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$fileHexString$nullTermination" >> $outfile
echo "};" >> $outfile
echo "#endif" >> $headerFile

So, for example, if I have a resource file example.txt:

Hello this
is a file

And I were to run ./Hexify.sh example.txt myHeader.h exampleArray, the header would look like this:

//
//  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

Now, at any point in time that I would have loaded said resource from the main bundle, I can instead refer to the byte array in that header file. Note that my version of the script adds a null terminated byte, which makes the data suitable for creating string objects. That may not apply in all cases.

As one final addendum, I apologize if that bash script makes any real bash programmers cringe; I have almost no idea what I'm doing with bash.

I feel your pain buddy, static libraries and resources don't go well together. I think the easiest way to do this is the one you already mentioned: Write a script that reads your shaders, escapes them properly and wraps them in C-compliant code.

I'm no expert, but maybe you could add the shader data to some section of your Mach-O executable upon linkage? But this eventually boils down to the same solution as mentioned above, with the only disadvantage that you're left with the ugly part of the job.

I'd go for the string constants using some shell script. PHP in my experience is pretty good at doing this kind of work. And of course bash scripts, but I'm not too good at that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!