7

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

在 Linux 上,似乎可以使用objcopy从二进制文件生成目标文件:

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

但是,OS X 开发者工具链不包含 objcopy 命令。没有安装binutils,有什么可能?

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

4

2 回答 2

8

在链接阶段,将参数传递-sectcreate <segname> <sectname> <file>给链接器。如果您通过调用编译器来驱动链接器,这很常见,您可以将其传递为-Wl,-sectcreate,<segname>,<sectname>,<file>.

你会组成段和部分的名称。

您将使用该getsectdata()函数以及_dyld_get_image_vmaddr_slide()在运行时获取指向数据的指针。

于 2016-01-06T20:23:12.357 回答
3

正如另一个关于objcopy的问题所证明的那样,将二进制文件包含到可执行文件中的另一种方法是使用.incbin汇编程序指令。这个解决方案有两个主要优点objcopy:开发人员可以控制符号名称(objcopy似乎有一个固定的命名方案),而且,它不需要objcopy.

与基于链接器的解决方案相比,该解决方案还具有优势-sectcreate。它是跨平台的,访问数据要简单得多。

我正在使用这个 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_somefiledata_end_somefile符号在 C 中访问数据(macOS 链接器在 C 名称前加上一个 spurious _,这就是程序集文件有它们的原因):

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符号)。

于 2016-01-06T22:43:45.790 回答