如何将二进制文件的内容嵌入到 Mac OS X 上的可执行文件中?
How do I embed the contents of a binary file in an executable on Mac OS X?
我的命令行程序的构建过程生成了一个二进制文件(超过 500KB),当前必须通过 argv 的路径引用该文件。我想将此文件嵌入到可执行文件中。
在 Linux 上,appears possible 使用 objcopy
从二进制文件生成目标文件:
objcopy --input binary --output elf32-i386 --binary-architecture i386 myfile.dat myfile.o
但是,OS X 开发人员工具链不包含 objcopy 命令。没有安装binutils,有什么可能?
我从 Xcode 构建我的项目,文件是使用自定义构建规则生成的。
在 link 阶段,将参数 -sectcreate <segname> <sectname> <file>
传递给 linker。如果您通过调用编译器来驱动 linker,这很常见,您可以将其作为 -Wl,-sectcreate,<segname>,<sectname>,<file>
.
传递
您可以编写段和部分名称。
您将使用 getsectdata()
function along with _dyld_get_image_vmaddr_slide()
在运行时获取指向数据的指针。
如 this other question about objcopy
所示,另一种将二进制文件包含到可执行文件中的方法是使用 .incbin
汇编指令。与 objcopy
相比,此解决方案有两个主要优势:开发人员可以控制符号名称(objcopy
似乎有固定的方案来命名它们),而且,它不需要 objcopy
.
该解决方案也优于 linker-based -sectcreate
解决方案。 cross-platform 并且访问数据要简单得多。
我正在使用此 Xcode 构建规则脚本来生成要包含的文件和带有 .incbin
指令的程序集文件:
my_generation_tool -o $DERIVED_FILE_DIR/$INPUT_FILE_NAME.out $INPUT_FILE_PATH
export AS_PATH=$DERIVED_FILE_DIR/$INPUT_FILE_NAME.out.s
echo "\t.global _data_start_$INPUT_FILE_BASE" > $AS_PATH
echo "\t.global _data_end_$INPUT_FILE_BASE" >> $AS_PATH
echo "_data_start_ $INPUT_FILE_BASE:" >> $AS_PATH
echo "\t.incbin \"$INPUT_FILE_NAME.out\"" >> $AS_PATH
echo "_data_end_$INPUT_FILE_BASE:" >> $AS_PATH
然后,给定一个使用此规则处理的文件 "somefile.gen",程序集将如下所示:
.global _data_start_somefile
.global _data_end_somefile
_data_start_somefile:
.incbin "somefile.gen.out"
_data_end_somefile:
可以使用 data_start_somefile
和 data_end_somefile
符号在 C 中访问数据(macOS 链接器在 C 名称前加上虚假的 _
前缀,这就是汇编文件包含它们的原因) :
extern char data_start_somefile, data_end_somefile;
for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
// do something with character
}
另一个线程上的答案有更多的花里胡哨的东西,有些人可能会觉得有用(例如,length
符号)。
我的命令行程序的构建过程生成了一个二进制文件(超过 500KB),当前必须通过 argv 的路径引用该文件。我想将此文件嵌入到可执行文件中。
在 Linux 上,appears possible 使用 objcopy
从二进制文件生成目标文件:
objcopy --input binary --output elf32-i386 --binary-architecture i386 myfile.dat myfile.o
但是,OS X 开发人员工具链不包含 objcopy 命令。没有安装binutils,有什么可能?
我从 Xcode 构建我的项目,文件是使用自定义构建规则生成的。
在 link 阶段,将参数 -sectcreate <segname> <sectname> <file>
传递给 linker。如果您通过调用编译器来驱动 linker,这很常见,您可以将其作为 -Wl,-sectcreate,<segname>,<sectname>,<file>
.
您可以编写段和部分名称。
您将使用 getsectdata()
function along with _dyld_get_image_vmaddr_slide()
在运行时获取指向数据的指针。
如 this other question about objcopy
所示,另一种将二进制文件包含到可执行文件中的方法是使用 .incbin
汇编指令。与 objcopy
相比,此解决方案有两个主要优势:开发人员可以控制符号名称(objcopy
似乎有固定的方案来命名它们),而且,它不需要 objcopy
.
该解决方案也优于 linker-based -sectcreate
解决方案。 cross-platform 并且访问数据要简单得多。
我正在使用此 Xcode 构建规则脚本来生成要包含的文件和带有 .incbin
指令的程序集文件:
my_generation_tool -o $DERIVED_FILE_DIR/$INPUT_FILE_NAME.out $INPUT_FILE_PATH
export AS_PATH=$DERIVED_FILE_DIR/$INPUT_FILE_NAME.out.s
echo "\t.global _data_start_$INPUT_FILE_BASE" > $AS_PATH
echo "\t.global _data_end_$INPUT_FILE_BASE" >> $AS_PATH
echo "_data_start_ $INPUT_FILE_BASE:" >> $AS_PATH
echo "\t.incbin \"$INPUT_FILE_NAME.out\"" >> $AS_PATH
echo "_data_end_$INPUT_FILE_BASE:" >> $AS_PATH
然后,给定一个使用此规则处理的文件 "somefile.gen",程序集将如下所示:
.global _data_start_somefile
.global _data_end_somefile
_data_start_somefile:
.incbin "somefile.gen.out"
_data_end_somefile:
可以使用 data_start_somefile
和 data_end_somefile
符号在 C 中访问数据(macOS 链接器在 C 名称前加上虚假的 _
前缀,这就是汇编文件包含它们的原因) :
extern char data_start_somefile, data_end_somefile;
for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
// do something with character
}
另一个线程上的答案有更多的花里胡哨的东西,有些人可能会觉得有用(例如,length
符号)。