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:
- Como o sistema de compilação OpenWrt determina as dependências de bibliotecas para os arquivos binários e de biblioteca recém-criados?
- 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*.kono diretório de compilação do pacote (linha 186 depackage-ipkg.mk). - O conteúdo do arquivo
libc.provides(linha 187). - A diretiva
extra_providesdefinida noMakefiledo 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.