Встраивать двоичные данные в исполняемый файл с использованием CMake - PullRequest
0 голосов
/ 11 июня 2018

Я столкнулся с некоторой проблемой при внедрении двоичных данных в исполняемый файл при использовании 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, поэтому я удалил -Wl ... из COMPILE_FLAGS_MAIN и изменил вызов 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, тогда ничего не происходит.

Кто-нибудь может мне помочь с этим?Я не уверен, что я делаю неправильно.

1 Ответ

0 голосов
/ 11 июня 2018

Вместо добавления пользовательского ресурса в ваши флаги ссылок вы можете создать для него отдельное правило сборки: (идея взята из здесь )

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...