C / C ++. Como usar recursos de aplicativos incorporados ao trabalhar no GCC no Linux

Além disso, eu queria usar os recursos incorporados do Linux automaticamente. Em geral, a tarefa é esta:


  1. Existe um programa de projeto Eclipse em C ++.
  2. SO: Linux Ubuntu. Compilador: G ++
  3. O projeto usa dados de arquivos externos: cadeias de localização, consultas SQL, imagens, sons etc.
  4. Todos os recursos devem ser incorporados no arquivo executável, porque o programa está planejado para ser distribuído como portátil.
  5. Além disso, quero que o processo seja o mais automatizado possível, devido à preguiça.

Para começar, uma pesquisa nos fóruns forneceu várias maneiras possíveis de resolver o problema. Entre os que foram considerados os mais universais, a idéia me pareceu usar o --format=binary " --format=binary " do vinculador " ld ". As postagens do fórum prometeram uma equipe do formulário:

 g++ -Wl,--format=binary -Wl,my.res -Wl,--format=default 

vinculará o arquivo “my.res” ao aplicativo e criará dois caracteres - _binary_my_res_start e _binary_my_res_end , indicando, respectivamente, o início e o final dos mesmos dados que estavam no arquivo vinculado. Portanto, acessar dados do C ++ pode ser feito da seguinte maneira:
 extern const uint8_t my_res_start[] asm("_binary_my_res_start"); extern const uint8_t my_res_end[] asm("_binary_my_res_end"); 

Mas lá estava. Nós escrevemos tudo como deveria, e o compilador não está feliz. O símbolo «_binary_my_res_start» , você vê, não pode ser encontrado. Bem, nada, nm para nos ajudar. Escrevemos o seguinte comando:

 nm MyProgramm |grep -w -o -P -e '_binary_[\w\d_]+' 

E temos:

 _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_end _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_start 

Acontece que o nome do símbolo inclui todo o caminho para ele, o que, no futuro, pode levar à necessidade de reescrita constante do arquivo de cabeçalho que contém links para recursos. O problema será resolvido se o seguinte script for incluído no evento PostBuild nas configurações do projeto Eclipse:

 #!/bin/bash OUTPUT=$1/resources.h printf '#ifndef __RESOURCES_H__\n' > "$OUTPUT" printf '#define __RESOURCES_H__\n\n' >> "$OUTPUT" printf '#include <inttypes.h>\n\n' >> "$OUTPUT" SYMBOLS=$(nm NewsParser |grep -w -o -P -e '_binary_[\w\d_]+') >> "$OUTPUT" VAR_SIZES_LIST='' for SYMBOL in $SYMBOLS do VAR_NAME=$(echo $SYMBOL | grep -o -P -e 'res_[\w\d_]+'|cut -c 5-) if [[ -z $(echo $SYMBOL|grep _size) ]] then printf '\textern const uint8_t '$VAR_NAME'[]\tasm("'$SYMBOL'");\n\n' >> "$OUTPUT" else START_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'start' END_VAR=$(echo $VAR_NAME|rev|cut -c 5-|rev)'end' VAR_SIZES_LIST=$VAR_SIZES_LIST$(printf '\\tconst uint64_t '$VAR_NAME'\\t=\\t'$END_VAR' - '$START_VAR';\\n\\n') fi done printf "$VAR_SIZES_LIST" >> "$OUTPUT" printf '#endif\n' >> "$OUTPUT" printf 'File '$OUTPUT' is generated.\n' 

Como adicionar o script “update_resource.sh”, que está na raiz do projeto, ao evento PostBuild nas configurações do projeto Eclipse.


Bom Agora, o arquivo de cabeçalho será sempre novo, e você poderá acessar os dados pelos nomes de variáveis ​​que não serão alteradas, a menos que você renomeie o arquivo de recurso. Além disso, este script calcula o tamanho de cada recurso. Não foi apenas um grande problema levar o ponteiro do começo ao fim, mas, no entanto, é mais conveniente.

Mas isso, por enquanto, não é tudo. Afinal, adicionar cada novo recurso a um projeto se transformará em um AD em forma. E esse problema também pode ser resolvido com a ajuda de um script, apenas no estágio de vinculação:

 FLAGS=$1 OUTPUT_FLAG=$2 OUTPUT_PREFIX=$3 OUTPUT=$4 INPUTS=$5 RESOURCE_PATH=$6 RESOURCES='' for res_file in $(ls $RESOURCE_PATH/*) do RESOURCES=$RESOURCES' '-Wl,$res_file echo ' '$res_file'   ' done g++ $FLAGS $OUTPUT_FLAG $OUTPUT_PREFIX$OUTPUT $INPUTS -Wl,--format=binary $RESOURCES -Wl,--format=default 

Como substituir a chamada do vinculador padrão por um script customizado nas configurações do projeto Eclipse.


  • O local em vermelho é marcado na figura, onde, em vez do comando padrão para chamar o vinculador, o caminho para o script "link.sh" está localizado na raiz do projeto.
  • Verde na imagem é um local em que outro vinculador é adicionado aos parâmetros usuais do vinculador, que informa ao script a localização do diretório com recursos.
  • Além disso , é importante não esquecer de colocar os parâmetros restantes entre aspas duplas, para que eles não quebrem acidentalmente com espaços na ordem errada na qual o script os espera.


Ótimo. Agora, todos os arquivos que estão no subdiretório "res" caem nos recursos durante cada montagem.

Source: https://habr.com/ru/post/pt468399/


All Articles