使用 CMake 在可执行文件中嵌入二进制数据
Embedd binary data in executable using CMake
当我使用 CMake 时,我在将二进制数据嵌入可执行文件时遇到了一些问题。这两个选项的代码相同,如下所示:
#include <iostream>
extern char _binary_res_txt_start;
extern char _binary_res_txt_end;
int main (int, char**) {
for (char* c = &_binary_res_txt_start; c != &_binary_res_txt_end; ++c) {
std::cout << *c;
}
return 0;
}
当我使用 GCC 编译它时:
g++ -std=c++17 -Wall -Wextra -Wpedantic -Werror=return-type -Wl,--format=binary -Wl,res.txt -Wl,--format=default main.cpp -o main
我的res.txt文件存储简单的"HELLO WORLD"文本,我得到了适当的输出,所以一切都符合预期。
现在我想使用 CMake 编译这段代码,所以我的尝试是:
cmake_minimum_required(VERSION 3.10)
set(app_name main)
project(${app_name} CXX)
set(BIN_DIR "${PROJECT_SOURCE_DIR}/bin")
set(OPTIMIZATION_LEVEL " -O0")
set(COMPILE_FLAGS_MAIN "-Wall -Wextra -Wpedantic -Wno-deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wl,--format=binary -Wl,res.txt -Wl,--format=default")
set(COMPILE_FLAGS_RELEASE "${COMPILE_FLAGS_MAIN} ${OPTIMIZATION_LEVEL}")
set(CPP_STD "17")
set(CPP_STD_REQUIRED "ON")
set(CPP_EXTENSION_REQUIRED "OFF")
file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/cpp/*.cpp")
add_executable(${app_name} ${SOURCES})
set_target_properties(${app_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_DIR}
COMPILE_FLAGS ${COMPILE_FLAGS_RELEASE}
CXX_STANDARD ${CPP_STD}
CXX_STANDARD_REQUIRED ${CPP_STD_REQUIRED}
CXX_EXTENSIONS ${CPP_EXTENSION_REQUIRED})
不幸的是,在链接过程中,我得到了:
main.cpp:(.text+0x13): undefined reference to `_binary_res_txt_start'
main.cpp:(.text+0x1b): undefined reference to `_binary_res_txt_end'
我做到了:cmake -Bbuild -H. && cmake --build build
,我的"项目"结构如下所示:
├── CMakeLists.txt
├── res.txt
└── src
└── cpp
└── main.cpp
到目前为止,我的观察和我所做的事情:
当我使用命令行编译时,nm main显示对象已初始化
0000000000601050 D _binary_res_txt_end 000000000000000c A _binary_res_txt_size 0000000000601044 D _binary_res_txt_start
当我使用 CMake 编译它时,这些对象不会初始化:
U _binary_res_txt_end U _binary_res_txt_start
看起来 CMake 忽略了我已通过的链接器选项,所以我也尝试使用 LINK_FLAGS,所以我从COMPILE_FLAGS_MAIN中删除了
-Wl ...
,并修改set_target_properties调用:set_target_properties(${app_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${BIN_DIR} COMPILE_FLAGS ${COMPILE_FLAGS_RELEASE} CXX_STANDARD ${CPP_STD} CXX_STANDARD_REQUIRED ${CPP_STD_REQUIRED} CXX_EXTENSIONS ${CPP_EXTENSION_REQUIRED} LINK_FLAGS "-Wl,--format=binary -Wl,${PROJECT_SOURCE_DIR}/res.txt -Wl,--format=default")
所以当我在这里传递不存在的文件时,链接器哭了,这就是我使用 PROJECT_SOURCE_DIR 但仍然不起作用的原因。
- 当我将错误的路径传递给COMPILE_FLAGS_MAIN文件中时,什么也没发生。
有人可以帮我解决这个问题吗?我不确定我做错了什么。
与其将自定义资源硬塞到链接标志中,不如为其创建单独的构建规则: (想法取自此处(
add_custom_command(
OUTPUT res.o
COMMAND ld -r -b binary -o res.o res.txt
DEPENDS res.txt)
add_executable(${app_name} ${sources} res.o)
相关文章:
- 如何从dicom文件中读取二进制数据
- 如何在Qt中从数据库中检索二进制数据?
- readsome() 适合在 Windows 上读取二进制数据吗?
- 如何使用 redis-plus-plus 存储二进制数据,就像我想存储结构一样?@for_stack?
- 将包含二进制数据的 QByteArray 传递到按值运行
- 如何在 c++ 中生成十六进制二进制数据的 sha256 哈希?
- 在处理网络、二进制数据和序列化时应使用流或容器
- 我能确定从文件中读取的 32 字节二进制数据等于 256 位吗?
- C++:如何通过 curl 调用使用 HTTP post 请求发送二进制数据(protobuf 数据)
- 使用二进制数据更新 PostgreSQL 表
- 使用二进制数据和无符号字符
- sd_journal_send发送二进制数据.如何使用日志检索数据?
- 从带有 std::ifstream::read() 的文件中读取 int 遍历 char * 二进制数据
- 将文本和二进制数据连接到一个文件中
- 二进制模式 + 格式化文本操作或文本模式 + 二进制数据操作 - 有意义吗?
- 将整数的二进制数据转换为浮点数
- 使用 CMake 在可执行文件中嵌入二进制数据
- 二进制数据作为命令行参数
- 如何访问文件的二进制数据?
- 返回二进制数据的通用方式,而无需原始指针