Análise Aprofundada de Erros de Dependência em Pacotes OpenWrt

Ao compilar pacotes personalizados para o OpenWrt e tentar incluí-los no sistema de imagem, é comum encontrar o erro: "Package XXX is missing dependencies for the following libraries". Este erro levanta duas questões principais:

  1. Como o sistema de compilação OpenWrt determina as dependências de bibliotecas para os arquivos binários e de biblioteca recém-criados?
  2. Como resolver este erro, especialmente quando se tem certeza de que as bibliotecas necessárias já existem no sistema de destino?

Exemplo Prático

Para ilustrar, vamos criar um pacote de teste simples chamado pkg_test.


$ tree package/pkg_test
package/pkg_test
├── Makefile
└── test_bin
 

Conteúdo do Makefile:


include $(TOPDIR)/rules.mk
include $(BUILD_DIR)/kernel.mk

PKG_NAME:=pkg_test
PKG_VERSION:=0.0.1
PKG_RELEASE:=1
PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME)

include $(BUILD_DIR)/package.mk

define Package/$(PKG_NAME)
 SECTION:=utils
 CATEGORY:=Utilities
 TITLE:=pkg_test
endef

define Package/$(PKG_NAME)/description
endef

define Build/Prepare
   $(INSTALL_DIR) $(PKG_BUILD_DIR)/
   $(CP) test_bin $(PKG_BUILD_DIR)/
endef

define Build/Configure
endef

define Build/Compile
endef

define Package/$(PKG_NAME)/install
   $(INSTALL_DIR) $(1)/usr/bin
   $(INSTALL_BIN) $(PKG_BUILD_DIR)/test_bin $(1)/usr/bin
endef

$(eval $(call BuildPackage,$(PKG_NAME)))
 

Executando a compilação:


$ make package/pkg_test/install V=99
 

Após a compilação, podemos verificar a localização dos arquivos gerados:


$ find ./out/ -name test_bin
./out/astar-parrot/compile_dir/target/pkg_test/ipkg-sunxi/pkg_test/usr/bin/test_bin
./out/astar-parrot/compile_dir/target/pkg_test/test_bin
 

Observa-se que o executável test_bin foi criado com sucesso, mas o processo de verificação de dependências falhou. Isso indica que o problema não está na etapa de compilação em si, mas sim na análise das dependências de bibliotecas.

Análise do Processo de Verificação de Dependências

O erro "Package XXX is missing dependencies for the following libraries" origina-se no script $(TOPDIR)/build/package-ipkg.mk. Especificamente, nas linhas 73-77, o sistema verifcia a existência do arquivo pkg_test.missing no diretório $(PKG_INFO_DIR). Se este arquivo existir, as dependências ausentes são listadas.

Vamos inspecionar o conteúdo desse arquivo:


$ cat out/astar-parrot/staging_dir/target/pkginfo/pkg_test.missing
libstdc++.so.6
 

A questão agora é entender como o arquivo pkg_test.missing é gerado. A origem está no script $(TOPDIR)/scripts/gen-dependencies.sh.

Este script utiliza ferramentas como file e readelf para analisar os binários e bibliotecas no diretório de compilação ($TARGETS). A saída do comando readelf -d $TARGETS/test_bin revela as bibliotceas dinamicamante vinculadas necessárias para o executável:


$ readelf -d $TARGETS/test_bin
Dynamic section at offset 0x4008 contains 23 entries:
 Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED)                     Shared library: [libc.so]
... (outras entradas) ...
 

Após o processamento por awk e sort -u, o script gen-dependencies.sh gera uma lista das dependências, como:


libc.so
libgcc_s.so.1
libstdc++.so.6
 

Este processo resolve a primeira questão: como o sistema identifica as dependências.

Resolvendo o Erro de Dependência

O script $(TOPDIR)/build/package-ipkg.mk, especificamente a partir da linha 70, compara as dependências identificadas por gen-dependencies.sh com as bibliotecas que o pacote declara fornecer (listadas em pkg_test.provides). Se uma dependência listada em pkg_test.missing não for encontrada em pkg_test.provides, o erro é reportado.

O arquivo pkg_test.provides é gerado a partir de:

  • Arquivos lib*.so* e *.ko no diretório de compilação do pacote (linha 186 de package-ipkg.mk).
  • O conteúdo do arquivo libc.provides (linha 187).
  • A diretiva extra_provides definida no Makefile do pacote (linha 192).

Para corrigir o erro, podemos modificar uma dessas fontes para incluir a biblioteca ausente (libstdc++.so.6, no nosso exemplo).

Opção 1: Adicionar a biblioteca ao diretório de compilação e instalação

Esta abordagem envolve copiar a biblioteca para o diretório de build e, em seguida, para o destino de instalação. Embora funcione, é considerada menos "oficial".

Opção 2: Modificar o arquivo .provides da biblioteca dependente

Adicionar libstdc++.so.6 ao arquivo libc.provides pode resolver o problema. No entanto, como libc.provides é gerado dinamicamente, essa alteração pode ser perdida em limpezas subsequentes de compilação.

Opção 3: Utilizar a diretiva extra_provides no Makefile

Esta é frequentemente a abordagem mais recomendada e limpa. Adicionamos a seguinte definição ao Makefile do pacote:


define Package/$(PKG_NAME)/extra_provides
   echo "libstdc++.so.6";
endef
 

Esta solução é explícita e mantida dentro do contexto do Makefile do pacote.

Processamento Pós-Compilação (Strip)

Um detalhe adicional a ser observado é que, após a compilação e instalação dos arquivos binários, o sistema OpenWrt aplica uma ferramenta chamada strip (ou sstrip) para remover informações de depuração e símbolos, reduzindo o tamanho dos arquivos. Isso é feito na linha 197 de package-ipkg.mk usando $(RSTRIP).

Se for necessário desativar essa funcionalidade de strip, consulte a documentação específica do OpenWrt sobre como modificar ou desabilitar os parâmetros de strip.

Tags: OpenWrt compilacao Dependências Makefile gen-dependencies.sh

Publicado em 7-26 16:48