在源代码(您的Manifest.h
和.cpp
)中存储数据的问题之一是文字数据的大小限制,这取决于编译器。
我的建议是使用ld
. 它允许您在 ELF 文件中存储任意二进制数据(也是如此objcopy
)。如果您更喜欢编写自己的解决方案,请查看libbfd
.
假设我们有一个hello.cpp
包含常用 C++“Hello world”的示例。现在我们有以下make文件(GNUmakefile
):
hello: hello.o hello.om
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@
%.om: %.manifest
ld -b binary -o $@ $<
%.manifest:
echo "$@" > $@
我在这里所做的是将链接阶段分开,因为我希望清单(在转换为 ELF 对象格式之后)也链接到二进制文件中。由于我使用的是后缀规则,这是一种方法,其他方法当然是可能的,包括更好的清单命名方案,它们也最终作为.o
文件和 GNU make 可以弄清楚如何创建它们。在这里,我要明确说明食谱。所以我们有.om
文件,它们是从.manifest
文件创建的清单(任意二进制数据)。配方规定将二进制输入转换为 ELF 对象。创建.manifest
自身的方法只是将字符串通过管道传输到文件中。
显然,您的案例中棘手的部分不是存储清单数据,而是生成它。坦率地说,我对您的构建系统知之甚少,甚至无法尝试为这.manifest
一代人提出一个食谱。
无论您放入.manifest
文件中的任何内容都应该是一些结构化文本,可以由您提到的脚本解释,或者如果您实现命令行开关,甚至可以由二进制文件本身输出(并且忽略.so
文件和.so
文件被黑客入侵的行为就像普通可执行文件一样)从外壳运行时)。
上面的 make 文件没有考虑依赖项——或者更确切地说,它不会帮助您以任何方式创建依赖项列表。如果您清楚地为每个目标(即静态库等)表达您的依赖关系,您可能会强迫 GNU make 帮助您。但走那条路可能不值得……
还请看:
如果您想要从数据生成的符号的特定名称(在您的情况下为清单),您需要使用稍微不同的路线并使用 John Ripley在此处描述的方法。
如何访问符号?简单的。将它们声明为外部(C 链接!)数据,然后使用它们:
#include <cstdio>
extern "C" char _binary_hello_manifest_start;
extern "C" char _binary_hello_manifest_end;
int main(int argc, char** argv)
{
const ptrdiff_t len = &_binary_hello_manifest_end - &_binary_hello_manifest_start;
printf("Hello world: %*s\n", (int)len, &_binary_hello_manifest_start);
}
符号是确切的字符/字节。您也可以将它们声明为char[]
,但这会导致以后出现问题。例如printf
通话。
我自己计算大小的原因是因为 a.) 我不知道缓冲区是否保证为零终止,并且 b.) 我没有找到任何关于与*_size
变量接口的文档。
旁注:*
格式字符串中的 告诉printf
它应该从参数中读取字符串的长度,然后选择下一个参数作为要打印的字符串。