[Dicas-L] uClibc - Uma biblioteca alternativa para sistemas embarcados
uClibc - Uma biblioteca alternativa para sistemas embarcados
Colaboração: André Murbach Maidl
Data de Publicação: 03 de Janeiro de 2005
A uClibc[2] é uma biblioteca muito interessante, pois pode-se dizer que se trata de uma alternativa a glibc, podendo gerar binários menores, porque ela é um tanto mais crua e mais leve que a glibc. Por isso, é muito boa para a criação de aplicações para sistemas embarcados.
Segue abaixo a descrição da uClibc, traduzida do site oficial:
uClibc (aka µClibc/pronuncia micro-c-lib-c) é uma biblioteca C para
o desenvolvimento de sistemas embarcados no Linux. Ela é relativamente
menor que a GNU C Library. Quase todas as aplicações suportadas pela
glibc também trabalham, perfeitamente, com a uClibc. Normalmente, portar
aplicações da glibc para a uClibc, implica apenas recompilar o código
fonte. uClibc também suporta bibliotecas compartilhadas e threads.
Atualmente, ela pode ser executada no Linux padrão e em sistema sem
unidade de processamento de ponto flutuante (também conhecidos como
µClinux), com suporte a alpha, ARM, cris, e1, h8300, i386, i960, m68k,
microblaze, mips/mipsel, PowerPC, SH, SPARC e processadores v850.
Atualmente ela é mantida pelo mantenedor do busybox[1], com isso ele garante que o busybox[3] esteja sempre compatível com a uClibc. O busybox é um ótimo caso de uso da uClibc, pois ele contém vários comandos utéis do Linux em apenas um binário, que normalmente é gerado estático.
Após instalada, é interessante que seja criado um script, o qual configura o PATH, apontando para onde se encontra o compilador da uClibc.
Segue abaixo o script (uclibc) criado. Vale lembrar que é interessante adicioná-lo em um diretório como o /usr/bin ou /usr/local/bin, para facilitar o uso da biblioteca em questão.
export PATH=/usr/i386-linux-uclibc/usr/bin:$PATH
Agora veremos como a uClibc consegue reduzir significativamente o tamanho de um binário estático.
Segue abaixo o código fonte C, de exemplo, que calcula o quadrado de um número n passado como parâmetro.
/* inicio do exemplo */
p = atof(argv[1]);
r = pow(p,2.0);
printf("pow(%.2lf,2.00) = %.2lf\n", p, r);
/* fim do exemplo */
Após instalada a uClibc e criado o script de conveniência (uclibc), usamos as seguintes linhas de comando para compilar o código e gerar os binários correspondentes a cada metodologia.
criando um binário dinâmico com a glibc
$ gcc quad.c -o quad-gcc -lm -Wall
criando um binário estático com a glibc
$ gcc quad.c -o quad-gcc-static -lm -static -Wall
criando um binário dinâmico com a uClibc
$ uclibc gcc quad.c -o quad-uc-gcc -lm -Wall
criando um binário estático com a uClibc
$ uclibc gcc quad.c -o quad-uc-gcc-static -lm -static -Wall
Agora observe o tamanho dos binários:
-rwxrwxr-x  1 murbach murbach 4,9K 2004-12-16 14:27 quad-gcc*
-rwxrwxr-x  1 murbach murbach 495K 2004-12-16 14:27 quad-gcc-static*
-rwxrwxr-x  1 murbach murbach 3,8K 2004-12-16 14:28 quad-uc-gcc*
-rwxrwxr-x  1 murbach murbach  22K 2004-12-16 14:28 quad-uc-gcc-static*
Isto, antes deles serem stripados. Após serem stripados, ficaram como segue abaixo:
-rwxrwxr-x  1 murbach murbach 3,0K 2004-12-16 14:28 quad-gcc*
-rwxrwxr-x  1 murbach murbach 453K 2004-12-16 14:28 quad-gcc-static*
-rwxrwxr-x  1 murbach murbach 2,4K 2004-12-16 14:28 quad-uc-gcc*
-rwxrwxr-x  1 murbach murbach  18K 2004-12-16 14:28 quad-uc-gcc-static*
Se observarmos os binários dinâmicos, não notamos muita diferença, mas se verificarmos os estáticos, notamos uma grande diferença. Repare que um simples programa em C, para calcular o quadrado de um número n, se ligado estaticamente com a glibc, fica com 453K, mas se ligado estaticamente com a uClibc cai para apenas 18K.
Existem outros projetos semelhantes, como a dietlibc[4], mas a uClibc parece ser a mais compatível com a glibc.