Migre automaticamente aplicativos iOS (ARM) para o macOS (x86) usando o Bitcode

Quando a Apple introduziu a tecnologia Bitcode e a tornou obrigatória para watchOS e tvOS, a empresa pareceu ignorar as perguntas sobre o motivo de sua necessidade. Ela disse apenas vagamente que ajuda a personalizar arquivos binários e usa as mais recentes melhorias do compilador.

Desde então, o Bitcode desempenhou um papel importante na transição suave do watchOS para 64 bits, onde os desenvolvedores nem precisaram recompilar seus aplicativos no diretório. A própria Apple fez isso automaticamente: todos os aplicativos começaram a funcionar no Apple Watch Series 4. Você provavelmente nem percebeu que a migração ocorreu.

O que é o Bitcode? Bem, o código de bits com b pequeno é a representação intermediária específica da arquitetura usada pelo LLVM, e o código de bit com B grande refere-se a um conjunto de funções que permitem incorporar essa visualização no seu binário Mach-O e os mecanismos pelos quais você pode renderizar esse arquivo na App Store.

O código de bits não é tão flexível quanto o código-fonte, mas é muito mais flexível que o binário incorporado, com metadados e anotações para o compilador. Na prática, você (ou Apple) pode facilmente tirar os blobs do Bitcode do aplicativo e recompilá-los em uma cópia totalmente funcional do seu aplicativo. Mudar de armv7 para armv7s ou de arm64 para arm64e é muito legal e economiza tempo para os desenvolvedores que tiveram que recompilar o binário toda vez que a Apple altera os chips ARM. O código de bits é usado há muito tempo pela Apple nos drivers OpenGL, para que o driver possa ser otimizado rapidamente para várias arquiteturas de GPU.

Vimos como a Microsoft aproveita efetivamente a recompilação estática no Xbox One, fornecendo acesso a toda uma biblioteca de jogos originalmente criados para o Xbox 360 (no PowerPC), completamente sem o envolvimento dos desenvolvedores ou o acesso ao código-fonte. E sem um intermediário como o Bitcode, que simplifica o processo.

Obviamente, o fantasma do macOS no ARM existe há muitos anos. Muitos se perguntaram se isso tornaria mais fácil portar aplicativos usando o Bitcode. Como resultado, eles chegaram a um consenso de que o Bitcode não é adequado para a transferência entre arquiteturas radicalmente diferentes, como Intel e ARM.

Isso não me convenceu, então decidi conferir!

Para começar, precisamos de um aplicativo de teste simples no Objective-C com Bitcode; ele geralmente é incluído apenas ao criar um arquivo morto para a App Store, portanto, você precisa forçá-lo a ser incluído na montagem regular. Você pode usar o -fembed-bitcode ou a opção de compilação personalizada:

 BITCODE_GENERATION_MODE = bitcode 

Crie um binário para o dispositivo iOS genérico ou dispositivo conectado, como de costume. Parece que o Bitcode não está embutido nos conjuntos arm64e (por exemplo, se você possui um dispositivo A12), portanto, você pode desativar a configuração do Xcode “compilar apenas para arquiteturas ativas” e compilar diretamente para o arm64.

Usando a ferramenta ebcutil, todos os objetos Bitcode são facilmente recuperados de um binário compilado.

 ebcutil -a arm64 -e path/to/MyApp.app/MyApp 

Em seguida, recompile cada objeto Bitcode para a Intel.

 for f in *; do clang -arch x86_64 -c -Xclang -disable-llvm-passes -emit-llvm -x ir -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk $f -o $fo; done 

Agora, vincularemos os blobs compilados novamente ao arquivo binário.

 clang -arch x86_64 -mios-version-min=12.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk *.o -o path/to/MyApp.app/MyApp 

Se funcionar, agora temos a versão x86 do aplicativo arm64 original! Em teoria, ele pode ser colocado diretamente na janela do simulador do iOS, instalado e lançado.

Esse é um fato muito importante: você pode transferir estaticamente arquivos binários entre as plataformas Intel e ARM se elas incluírem Bitcode . Isso realmente funciona!


Armadilhas para projetos mais complexos


Parece que o ARC usa o montador embutido, portanto, para a transferência de arm64 para x86 no momento, você precisa desativar o ARC.

Alguns tipos de blocos, como manipuladores de conclusão, iniciam o compilador com instruções inaceitáveis. Se você receber um erro do X87, este é provavelmente o problema.

Por que o Objective-C? Bem, o Swift foi projetado com o ARC em mente. Não acho que exista uma maneira de evitar o montador inline mencionado, portanto a recompilação falhará agora.
Vamos dar mais um passo: usaremos o marzipanify para converter esse aplicativo Intel iOS em um programa para Mac que funcione com o maçapão.



Foi fácil!

Teoricamente, isso significa que a Apple tem uma maneira de executar qualquer aplicativo iOS da App Store em um Mac sem exigir que os desenvolvedores atualizem ou recompilem seus aplicativos.


E se o Mac mudar dos chips Intel para ARM? Bem, como você pode ver, com o Bitcode, ele pode transferir todos os aplicativos habilitados para Bitcode para a Mac App Store sem a ajuda dos desenvolvedores, para que esteja pronto para trocar o processador desde o primeiro dia. Isso dá à Apple mais liberdade. Agora você não precisa anunciar antecipadamente a transição para novos processadores um ano antes do tempo, e tecnologias como a Rosetta não são mais necessárias.

Obviamente, não chegamos a esse ponto: hoje a Apple não inclui o Bitcode para aplicativos na Mac App Store e hoje o Bitcode pode não ser o ideal para uma transferência dessa arquitetura. No lugar da Apple, eu focaria nesses dois fatores e, é claro, habilitaria o Bitcode sem falhas para todos os aplicativos de maçapão no macOS 10.15.

Source: https://habr.com/ru/post/pt452734/


All Articles