Quería usar de alguna manera los recursos integrados de Linux, además, automáticamente. En general, la tarea es esta:
- Hay un programa de proyecto Eclipse en C ++.
- SO: Linux Ubuntu. Compilador: G ++
- El proyecto utiliza datos de archivos externos: cadenas de localización, consultas SQL, imágenes, sonidos, etc.
- Todos los recursos deben estar integrados en el archivo ejecutable, ya que el programa está planificado para distribuirse como portátil.
- Además, quiero que el proceso sea lo más automatizado posible, debido a la pereza.
Para empezar, una búsqueda en los foros proporcionó varias formas posibles de resolver el problema. Entre los que resultaron ser los más universales, la idea me pareció utilizar el --format=binary
" --format=binary
" del enlazador " ld
". Las publicaciones del foro prometieron un equipo de la forma:
g++ -Wl,--format=binary -Wl,my.res -Wl,--format=default
vinculará el archivo "my.res" a la aplicación y creará dos caracteres:
_binary_my_res_start
y
_binary_my_res_end
, indicando, respectivamente, el principio y el final de los mismos datos que estaban en el archivo vinculado. Por lo tanto, acceder a datos de C ++ podría hacerse de la siguiente manera:
extern const uint8_t my_res_start[] asm("_binary_my_res_start"); extern const uint8_t my_res_end[] asm("_binary_my_res_end");
Pero ahí estaba. Escribimos todo como debería, y el compilador no está contento. El símbolo «_binary_my_res_start»
, como ve, no se puede encontrar. Bueno, nada, nm
para ayudarnos. Escribimos el siguiente comando:
nm MyProgramm |grep -w -o -P -e '_binary_[\w\d_]+'
Y obtenemos:
_binary__home_unknown_workspace_MyProgramm_res_my_res_sql_end _binary__home_unknown_workspace_MyProgramm_res_my_res_sql_start
Resulta que el nombre del símbolo incluye la ruta completa, lo que, en el futuro, puede llevar a la necesidad de reescribir constantemente el archivo de encabezado que contiene enlaces a recursos. El problema se resuelve si se agrega el siguiente script al evento PostBuild en la configuración del proyecto Eclipse:
Cómo agregar el script "update_resource.sh", que está en la raíz del proyecto, al evento PostBuild en la configuración del proyecto Eclipse Bueno Ahora el archivo de encabezado será como nuevo cada vez, y puede acceder a los datos por los nombres de las variables que no cambiarán a menos que cambie el nombre del archivo de recursos. Además, este script calcula el tamaño de cada recurso. No solo llevar el puntero al principio desde el puntero hasta el final fue un gran problema, sino que, sin embargo, es más conveniente.
Pero esto, por ahora, no es todo. Después de todo, agregar cada nuevo recurso a un proyecto se convertirá en un AD con forma. Y este problema también se puede resolver con la ayuda de un script, solo en la etapa de vinculación:
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
Cómo reemplazar la llamada del enlazador estándar con un script personalizado en la configuración del proyecto Eclipse.
- El lugar en rojo está marcado en la imagen, donde en lugar del comando estándar para llamar al vinculador, la ruta al script "link.sh" se encuentra en la raíz del proyecto.
- El verde en la imagen es un lugar en el que se agrega otro vinculador a los parámetros habituales del vinculador, que le indica al script la ubicación del directorio con recursos.
- Además , es importante no olvidar envolver los parámetros restantes con comillas dobles para que no se rompan accidentalmente con espacios en el orden incorrecto en el que el script los está esperando.
Genial Ahora todos los archivos que están en el subdirectorio "res" caerán en los recursos durante cada ensamblaje.