如何在Mac OS X的可执行文件中嵌入二进制文件的内容? [英] How do I embed the contents of a binary file in an executable on Mac OS X?

查看:659
本文介绍了如何在Mac OS X的可执行文件中嵌入二进制文件的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的命令行程序的生成过程会生成一个二进制文件(超过500KB),当前必须由argv的路径引用该文件.我想将此文件嵌入可执行文件中.

在Linux上,它可能出现使用objcopy从二进制文件制作目标文件:

objcopy --input binary --output elf32-i386 --binary-architecture i386 myfile.dat myfile.o

但是,OS X开发人员工具链不包含objcopy命令.如果没有安装binutils,有什么可能?

我从Xcode构建我的项目,并使用自定义构建规则生成文件.

解决方案

然后,给定使用此规则处理的文件"somefile.gen",程序集将如下所示:

    .global _data_start_somefile
    .global _data_end_somefile
_data_start_somefile:
    .incbin "somefile.gen.out"
_data_end_somefile:

可以使用data_start_somefiledata_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符号).

My command-line program's build process generates a binary file (over 500KB) that currently has to be referenced by path from argv. I would like to embed this file in the executable instead.

On Linux, it appears possible to use objcopy to make an object file from a binary file:

objcopy --input binary --output elf32-i386 --binary-architecture i386 myfile.dat myfile.o

However, the OS X developer toolchain doesn't include an objcopy command. Short of installing binutils, what are the possibilities?

I build my project from Xcode and the file is generated with a custom build rule.

解决方案

As evidenced in this other question about objcopy, another way to include a binary file into an executable is to use the .incbin assembler directive. This solution has two main advantages over objcopy: the developer is in control of the symbol names (objcopy appears to have a fixed scheme to name them), and, well, it doesn't require objcopy.

The solution also has advantages over the linker-based -sectcreate solution. It's cross-platform and accessing the data is much, much more straightforward.

I'm using this Xcode build rule script to generate the file to be included and an assembly file with the .incbin directive:

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

Then, given a file "somefile.gen" that is processed with this rule, the assembly will look like:

    .global _data_start_somefile
    .global _data_end_somefile
_data_start_somefile:
    .incbin "somefile.gen.out"
_data_end_somefile:

The data can be accessed in C using the data_start_somefile and data_end_somefile symbols (the macOS linker prefixes C names with a spurious _, that's why the assembly file has them):

extern char data_start_somefile, data_end_somefile;

for (const char* c = &data_start_somefile; c != &data_end_somefile; ++c)
{
    // do something with character
}

The answer on the other thread has more bells and whistles that some people may find useful (for instance, a length symbol).

这篇关于如何在Mac OS X的可执行文件中嵌入二进制文件的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆