通过无法优化的标头嵌入字符串 [英] embed string via header that cannot be optimized away

查看:85
本文介绍了通过无法优化的标头嵌入字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发仅标头的库时,我想确保将给定的字符串嵌入使用标头的所有二进制文件中,即使编译器配置为优化未使用的常量,并且二进制文件也被剥离。

While developing a header-only library, I'd like to make sure that a given string is embedded in all binaries that use my header, even if the compiler is configured to optimize away unused constants, and the binary gets stripped.

嵌入不应有任何副作用(除了使生成的二进制文件更大一点)。

The embedding shouldn't have any side-effects (apart from making the resulting binary a little bit bigger).

我不知道人们将如何使用标题,但是

I don't know how people are going to use the headers, but


  • 标题可能会包含在多个编译单元中,所有链接在一起的单个二进制文件

  • 目标平台是Linux / macOS / Windows

  • 编译器很可能是gcc / clang / MSVC

我的琐碎尝试为:

static char frobnozzel_version_string[] = "Frobnozzel v0.1; © 2019 ACME; GPLv3";

...,但是在构建过程中很容易删除该字符串(因为该字符串实际上并未在任何地方使用,

..., but that get's easily removed during the build (since the string is nowhere actually used, it's easy prey for an optimizing compilere).

所以问题是:是否可以将字符串嵌入任何包含给定标头的二进制文件中,而不会

So the question is: is it possible to embed a string in any binary that includes a given header, that won't get optimized/stripped away by usual strategies to build "Release" binaries?

我知道,任何使用该库的人都可以(手动)删除我放的任何东西

I'm aware, that anybody who is using the library can just (manually) remove whatever I put in, but let's assume, people just use the header "as is".

上下文:问题标题被释放了在 GPL 下,我希望能够进行检查,

Context: the headers in question are released under the GPL, and I'd like to be able to check, if the users actually comply with the license.

推荐答案

您可以将程序集伪操作嵌入标题中,并且应该保留(

You can embed assembly pseudo-ops in your header, and it should stay (although it's never used):

asm(".ascii \"Frobnozzel v0.1; © 2019 ACME; GPLv3\"\n\t");

请注意,这是特定于GCC /-语的。

Note that this is GCC/Clang-specific.

MSVC的替代方法是使用 #pragma注释 __ asm db

An alternative for MSVC would be using #pragma comment or __asm db:

__asm db "Frobnozzel v0.1; © 2019 ACME; GPLv3"
#pragma comment(user, "Frobnozzel v0.1; © 2019 ACME; GPLv3")

以下是示例:

chronos@localhost ~/Downloads $ cat file.c 
#include <stdio.h>

#include "file.h"

int main(void)
{
        puts("The string is never used.");
}
chronos@localhost ~/Downloads $ cat file.h
#ifndef FILE_H
#define FILE_H 1

#if defined(__GNUC__)
    asm(".ascii \"Frobnozzel v0.1; © 2019 ACME; GPLv3\"\n\t");
#elif defined(_MSC_VER)
# if defined(_WIN32)
    __asm db "Frobnozzel v0.1; © 2019 ACME; GPLv3"
# elif defined(_WIN64)
#  pragma comment(user, "Frobnozzel v0.1; © 2019 ACME; GPLv3")
# endif
#endif
chronos@localhost ~/Downloads $ gcc file.c
chronos@localhost ~/Downloads $ grep "Frobnozzel v0.1; © 2019 ACME; GPLv3" a.out
Binary file a.out matches
chronos@localhost ~/Downloads $ 

clang替换 gcc 命令,结果是相同的。

Replace the gcc command with clang and the result is the same.

对于64位Windows,这需要替换 user 和已弃用的 exestr 或创建一个将字符串嵌入可执行文件中的资源文件。这样,链接时该字符串将被删除。

For 64-bit Windows, this requires either replacing user with the deprecated exestr or creating a resource file that embeds the string in the executable file. As this is, the string will be removed when linking.

这篇关于通过无法优化的标头嵌入字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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