Tutorial Autopackage GNOME Launch Box
Relocabilidade do binário
Autopackages podem ser instalados no diretório home (ou em qualquer outro), e esta funcionalidade é popular para os usuários finais. Logo, para construir um autopackage, você deve primeiro garantir que seu programa pode localizar todos os seus arquivos em tempo de execução sem utilizar caminhos fixos no código fonte. Isto não é difícil.
Primeiro, decida como você vai implementar esta funcionalidade. Para programas em C como Launch Box, há duas abordagens: utilizando o kit pré-fabricado BinReloc, ou simplesmente fazê-lo manualmente. A ferramenta BinReloc gera um arquivo C que você pode compilar e ligar (linkar) em sua aplicação: ele lê /proc/self/exe (entre outros) se disponível, e deixa você determinar os prefixos de sua aplicação através disto. Ele irá utilizar os valores padrões em tempo de compilação se falhar. A outra abordagem é fazer a mesma coisa, mas manualmente. Se seu código já suporta relocabilidade (por exemplo, porque é portável para Windows) então isto pode ser mais fácil.
Vamos utilizar o kit binreloc. Antes de tudo, nós precisamos localizar aonde caminhos fixos no fonte estão sendo utilizados. Olhando para o Makefile.am no diretóro src, nós vemos o seguinte código:
AM_CPPFLAGS = \
-DIMAGEDIR=\"$(datadir)/lb/images\" \
......
Ah, a macro IMAGEDIR está sendo utilizada em outro lugar. Utilizando grep para procurar, descobrimos que é utilizado no arquivo lb-window.c:
switch (corner) {
case LB_WINDOW_CORNER_TOP_LEFT:
filename = IMAGEDIR "/lb-top-left.png";
break;
case LB_WINDOW_CORNER_TOP_RIGHT:
filename = IMAGEDIR "/lb-top-right.png";
break;
.... (e continua)
O primeiro passo é fazer este código utilizar string dinâmicas (alocadas no heap)
em vez de strings estaticamente alocadas produzidas pelo pre-processador C. Isto não
é muito difícil, porque o Launch Box é uma aplicação glib nós podemos utilizar a chamada
g_build_file_name (lembrando de adicionar um g_free depois que a variável de
nome de arquivo é utilizada):
switch (corner) {
case LB_WINDOW_CORNER_TOP_LEFT:
filename = g_build_filename (IMAGEDIR, "lb-top-left.png", NULL);
break;
case LB_WINDOW_CORNER_TOP_RIGHT:
filename = g_build_filename (IMAGEDIR, "lb-top-right.png", NULL);
break;
.... (e continua)
Agora nós precisamos tornar a constante macro IMAGEDIR uma variável. A maneira mais fácil de fazer isso é gerar um par binreloc.[ch] para seu programa então utilizar uma função construtora, mas você poderia também colocar isso em algum lugar na sua função principal (main).
Pegue o binreloc do CVS autopackage, então execute o script generate.pl. Neste exemplo, nós queremos a versão glib não a crua versão C então passe "glib" como parâmetro. Ele vai gerar dois arquivos de saída: binreloc.c e binreloc.h. Adicione-os ao Makefile.am e re-execute autogen, e agora está integrado com nosso projeto.
static gchar *imagedir;
/* will be called automatically before main() */
static void __attribute__((constructor))
locate_image_dir ()
{
if (gbr_init (NULL))
imagedir = g_build_filename (gbr_find_data_dir (DATADIR), "lb", "images", NULL);
else
imagedir = DATADIR "/lb/images";
}
Nós apenas modificamos "IMAGEDIR" para "imagedir" na função window_pixbuf_fill_corner e estamos prontos. Vamos testar!
Há uma forma muito simples de garantir que seu binário possui relocabilidade correta: instale seu programa no seu próprio prefixo, e execute-o. Então renomeie o prefixo e execute novamente. Ele funciona corretamente?
$ make install DESTDIR=/tmp/glb $ /tmp/glb/usr/local/bin/gnome-launch-box (sem erros) $ mv /tmp/glb /tmp/glb2 $ /tmp/glb2/usr/local/bin/gnome-launch-box (sem erros)

