Existem duas maneiras de criar um pacote de aplicativos no MacOSX, o Easy e o Ugly.
A maneira mais fácil é usar o XCode. Feito.
O problema é que às vezes você não consegue.
No meu caso, estou construindo um aplicativo que cria outros aplicativos. Não posso presumir que o usuário tenha o XCode instalado. Também estou usando MacPorts para construir as bibliotecas das quais meu aplicativo depende. Preciso ter certeza de que esses dylibs sejam incluídos no aplicativo antes de distribuí-lo.
Isenção de responsabilidade: eu não estou totalmente qualificado para escrever este post, tudo nele foi mostrado nos documentos da Apple, separando aplicativos existentes e tentativa e erro. Funciona para mim, mas provavelmente está errado. Por favor, me envie um email se você tiver alguma correção.
A primeira coisa que você deve saber é que um pacote de aplicativos é apenas um diretório.
Vamos examinar a estrutura de um foo.app hipotético.
foo.app/
Conteúdo/
Info.plist
Mac OS/
foo
Recursos/
foo.icns
Info.plist é um arquivo XML simples. Você pode editá-lo com um editor de texto ou o aplicativo Property List Editor que vem com o XCode. (Está no diretório / Desenvolvedor / Aplicativos / Utilitários /).
Os principais itens que você precisa incluir são:
CFBundleName - O nome do aplicativo.
CFBundleIcon - Um arquivo de ícone que se presume estar no diretório Conteúdo / Recursos. Use o aplicativo Icon Composer para criar o ícone. (Também está no diretório / Developer / Applications / Utilities /). Você pode simplesmente arrastar e soltar um png em sua janela e deve gerar automaticamente os níveis de mip para você.
CFBundleExecutable - Nome do arquivo executável que se presume estar em Contents / MacOS / subpasta.
Existem muito mais opções, as listadas acima são apenas o mínimo. Aqui estão algumas documentações da Apple sobre o
arquivo Info.plist e a
estrutura do pacote de aplicativos .
Além disso, aqui está um exemplo de Info.plist.
<? xml version = "1.0" encoding = "UTF-8"?>
<! DOCTYPE plist PUBLIC "- // Apple Computer // DTD PLIST 1.0 // EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version = "1.0">
<dict>
<key> CFBundleGetInfoString </key>
<string> Foo </string>
<key> CFBundleExecutable </key>
<string> foo </string>
<key> CFBundleIdentifier </key>
<string> com.nome-da-sua-empresa.www </string>
<key> CFBundleName </key>
<string> foo </string>
<key> CFBundleIconFile </key>
<string> foo.icns </string>
<key> CFBundleShortVersionString </key>
<string> 0,01 </string>
<key> CFBundleInfoDictionaryVersion </key>
<string> 6.0 </string>
<key> CFBundlePackageType </key>
<string> APPL </string>
<key> IFMajorVersion </key>
<integer> 0 </integer>
<key> IFMinorVersion </key>
<integer> 1 </integer>
</dict>
</plist>
Em um mundo perfeito, você poderia simplesmente soltar seu executável no diretório Contents / MacOS / e pronto. No entanto, se seu aplicativo tiver dependências dylib fora do padrão, ele não funcionará. Como o Windows, o MacOS vem com seu próprio tipo especial de DLL Hell .
Se você estiver usando MacPorts para construir bibliotecas às quais vincular, os locais dos dylibs serão embutidos em código em seu executável. Se você executar o aplicativo em uma máquina que tenha os dylibs exatamente no mesmo local, ele funcionará bem. No entanto, a maioria dos usuários não os instalará; quando eles clicarem duas vezes em seu aplicativo, ele simplesmente travará.
Antes de distribuir seu executável, você precisará coletar todos os dylibs que carrega e copiá-los para o pacote de aplicativos. Você também precisará editar o executável para que procure os dylibs no local correto. ou seja, para onde você os copiou.
Editar manualmente um executável parece perigoso, certo? Felizmente, existem ferramentas de linha de comando para ajudar.
otool -L executable_name
Este comando listará todos os dylibs dos quais seu aplicativo depende. Se você vir algum que NÃO esteja na pasta System / Library ou usr / lib, esses são os que você precisa copiar para o pacote de aplicativos. Copie-os para a pasta / Contents / MacOS /. Em seguida, você precisará editar o executável para usar os novos dylibs.
Primeiro, você precisa ter certeza de vincular usando o sinalizador -headerpad_max_install_names. Isso apenas garante que, se o novo caminho dylib for mais longo que o anterior, haverá espaço para ele.
Em segundo lugar, use o install_name_tool para alterar cada caminho dylib.
install_name_tool -change existing_path_to_dylib @ executable_path / blah.dylib executable_name
Como um exemplo prático, digamos que seu aplicativo usa libSDL e otool lista sua localização como "/opt/local/lib/libSDL-1.2.0.dylib".
Primeiro, copie-o para o pacote de aplicativos.
cp /opt/local/lib/libSDL-1.2.0.dylib foo.app/Contents/MacOS/
Em seguida, edite o executável para usar o novo local (NOTA: certifique-se de criá-lo com o sinalizador -headerpad_max_install_names)
install_name_tool -change /opt/local/lib/libSDL-1.2.0.dylib @ executable_path / libSDL-1.2.0.dylib foo.app/Contents/MacOS/foo
Ufa, estamos quase terminando. Agora há um pequeno problema com o diretório de trabalho atual.
Ao iniciar seu aplicativo, o diretório atual será o diretório acima de onde o aplicativo está localizado. Por exemplo: Se você colocar o foo.app na pasta / Applcations, o diretório atual ao iniciar o aplicativo será a pasta / Applications. Não o /Applications/foo.app/Contents/MacOS/ como você poderia esperar.
Você pode alterar seu aplicativo para dar conta disso, ou pode usar este pequeno script de iniciador mágico que mudará o diretório atual e iniciará seu aplicativo.
#! / bin / bash
cd "$ {0% / *}"
./foo
Certifique-se de ajustar o arquivo Info.plist de forma que CFBundleExecutable aponte para o script de inicialização e não para o executável anterior.
Ok, tudo feito agora. Felizmente, depois de saber todas essas coisas, você as enterra em um script de construção.