Patching packages (Português)
Esse artigo cobre como criar e como aplicar patches (correções, remendos) em pacotes no Sistema de compilação do Arch.
Um patch descreve um conjunto de alterações a linha para um ou mais arquivos. Patches são geralmente usados para automatizar as alterações ao código-fonte.
Criando patches
A ferramenta diff compara arquivos linha por linha. Se você salvar sua saída, você terá um patch, por exemplo diff --unified --recursive --text foo bar > patch
. Se você informar diretórios, diff vai comparar os arquivos que eles contêm.
- Exclua o diretório
src
se você já tiver construído o pacote. - Execute
makepkg --nobuild
, o qual baixará e extrairá os arquivos fonte, especificados emPKGBUILD
, mas não os compilará. Se o sistema no qual você está fazendo o patch não tiver as dependências necessárias, você pode ter que executarmakepkg --nobuild --nodeps
em vez disso. - Crie duas cópias do diretório extraído no diretório
src
, uma como uma cópia original e outra para sua versão alterada. Nós os chamaremos depacote.orig
epacote.new
. - Faça suas alterações no diretório
pacote.new
. - Execute
diff --unified --recursive --text pacote.orig pacote.new --color
e verifique se o patch está correto. - Execute
diff --unified --recursive --text pacote.orig pacote.new > pacote.patch
para criar o patch. - Entre no diretório
src/package
inicial, a partir do qual você fez cópias, e aplique o patch usandopatch --strip=1 < ../pacote.patch
. Verifique se o patch está funcionando na compilação e instalação do pacote modificado commakepkg --noextract --install
.
Veja diff(1) e git-diff(1) para mais informações.
Aplicando patches
Esta seção descreve como aplicar patches criados ou baixados da Internet a partir da função PKGBUILD
prepare()
. Siga esses passos:
- Adicione uma entrada ao array
source
doPKGBUILD
para o arquivo de patch, separado do URL fonte original por um espaço. Se o arquivo estiver disponível online, você pode fornecer a URL completa e ela será automaticamente baixada e colocada no diretóriosrc
. Se for um patch criado por você mesmo ou não estiver disponível, você deverá colocar o arquivo de patch no mesmo diretório que o arquivoPKGBUILD
e apenas adicionar o nome do arquivo ao array de fontes para que ele é copiado para o diretóriosrc
. Se você redistribuir oPKGBUILD
, você deve, claro, incluir o patch com oPKGBUILD
. - Então, use
makepkg -g >> PKGBUILD
ouupdpkgsums
(do pacman-contrib) para atualizar o arraysha512sums
. Ou adicione manualmente uma entrada à matrizsha512sums
; você pode gerar a soma do seu patch usando a ferramenta sha512sum. - Crie a função
prepare()
noPKGBUILD
se ainda não houver uma. - O primeiro passo é mudar para o diretório que precisa ser corrigido (na função
prepare()
, não no seu terminal! Você quer automatizar o processo de aplicação do patch). Você pode fazer isso com algo comocd "$srcdir/$pkgname-$pkgver"
. O$pkgname-$pkgver
é geralmente o nome de um diretório criado pela descompactação de um arquivo de origem baixado, mas não em todos os casos. - Agora você só precisa aplicar o patch dentro desse diretório. Isto é feito simplesmente adicionando
patch --strip=1 --input=pkgname.patch
à sua funçãoprepare()
, alterandopkgname.patch
para o nome do arquivo que contém o diff (o arquivo que foi copiado automaticamente em seu diretóriosrc
porque estava no arraysource
do arquivoPKGBUILD
).
Um exemplo de função "prepare":
prepare() { cd "$pkgname-$pkgver" patch --forward --strip=1 --input="${srcdir}/eject.patch" }
Alternativamente, você pode usar a opção --directory
de patch
sem ter que usar cd. O exemplo, então, se tornaria:
prepare() { patch --directory="$pkgname-$pkgver" --forward --strip=1 --input="${srcdir}/eject.patch" }
Execute makepkg
(a partir do terminal agora). Se tudo correr bem, o patch será aplicado automaticamente e o novo pacote conterá as alterações incluídas no patch. Se não, você pode ter que tentar com a opção --strip
do patch. Enquanto estiver tentado, você pode achar as opções --dry-run
, --reverse
ou --verbose
utilizáveis. Leia patch(1) para mais informações.
Basicamente, funciona da seguinte forma. Se o arquivo diff foi criado para aplicar patches a arquivos em minhaversão/
, os arquivos diff serão aplicados a minhaversão/arquivo
. Você está executando-o de dentro do diretório suaversão/
(porque você mudar o diretório para dentro daquele diretório no PKGBUILD
), então quando o patch é aplicado ao arquivo, você vai querer aplicá-lo ao arquivo arquivo
, retirando a parte minhaversão/
. --strip=1
faz isso, removendo um diretório do caminho. Porém, se o desenvolvedor aplicou patch em meusarquivos/minhaversão
, você precisa remover dois diretórios, usando --strip=2
.
Se você não aplicar uma opção --strip
, ela tirará toda a estrutura do diretório. Tudo bem se todos os arquivos estiverem no diretório base, mas se o patch foi criado em minhaversão/
e um dos arquivos editados for minhaversão/src/arquivo
, e você executar o patch sem uma opção --strip
de suaversão
, ele tentará corrigir um arquivo chamado suaversão/arquivo
.
A maioria dos desenvolvedores cria patches a partir do diretório pai do diretório que está sendo corrigido, então --strip=1
geralmente estará correto.
Usando quilt
Uma maneira mais simples de criar patches é usar o quilt, que tem um trabalho melhor para gerenciar vários patches, como aplicar patches, atualizar patches e reverter arquivos com patches para o estado original. O quilt é usado no Debian para gerenciar seus patches. Consulte Using Quilt para obter informações básicas sobre o uso de quilt básico para gerar, aplicar patches e reverter arquivos corrigidos.
Veja também
- http://www.kegel.com/academy/opensource.html — Informações úteis sobre fazer patching de arquivos