过去,我首先.o
使用 GNU 链接器将资源文件(图像)转换为文件,从而将资源文件(图像)嵌入到程序中。例如:
ld -r -b binary -o file.o file.svg
从 FreeBSD 12 开始,默认链接器已从 GNU 更改为 LLVM。尽管链接器似乎理解命令行选项,但它会导致错误。例如:
ld -r -b binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required
还尝试使用ld.lld(1)手册页中的命令行选项:
ld --relocatable --format=binary -o file.o file.svg
ld: error: target emulation unknown: -m or at least one .o file required
我使用了正确的工具吗?我需要为-m
选项指定一个值吗?
看来您需要添加
-z noexecstack
(这也是在LLD 7.0.0中为 ELF 二进制文件添加的)。默认设置是有一个可执行的堆栈区域,该区域易受堆栈内存的利用。您的二进制映像没有可执行堆栈,我相信这就是它失败的原因。该错误会让你失望,因为它要求你告诉你的堆栈使用什么目标仿真(你没有)。David Herrmann做了所有艰苦的工作,并找到了一个跨平台的解决方案,其中包括:
魔术调用是:
大多数情况下,您希望该二进制段是只读的:
更新:
我无法测试,因为我的系统是:
我用 FreeBSD 12.0 启动了一个虚拟机来测试它并发现了这个:
仅在 7.0.0中
-z noexecstack
添加,并且未在6.0.1的手册页中列出。更烦人的指定不支持的值-z
不会触发错误!我还没有升级到 LLVM 7 来测试这是否有效。@Richard Smith 通过
-m
在另一个答案中指定仿真自己找到了一个合适的解决方案。如果 LLD 列出了支持的仿真,那么这条路线会容易得多-V
。如果您使用该
file
命令,file.o
您将看到它标识为 SYSV ELF。这对你来说可能已经足够好了。但是,如果您想要与系统完全相同,请使用whichelf_amd64_fbsd
是. Annoyingly不像 GNU ld 那样输出受支持的 LLD 仿真。elf_x86_64_fbsd
ld -V
elf_amd64_fbsd
是elf_x86_64_fbsd
(参见D7837和D24356)的别名。希望 LLD 将仿真添加到-V
输出中。查看源代码后,我的平台的正确目标仿真是elf_amd64。因此,从二进制文件到目标文件的转换使用:
真的值得麻烦吗?那一开始就不是便携的。
您最好将 .svg 转换为 C char 数组;例子:
当然,您可以将数组的名称设置为不同/更健壮的名称(例如,
char $(subst /,_,$*)[] = ...
而不是char $*[] = ...
使用 GNU make)。此外,您可以构建一个用 C 编写的临时bin2c
转换器,而不是那种可怕的 od+sed 组合。