O aviso é que se você programa em Swift ou utiliza Xcode, muito provavelmente não precisa dos itens relacionados abaixo, já que o próprio Xcode faz todo o processo, porém caso necessite, é possível adicionar um build target com comandos ou script shell que faça isso.

É mais comum projetos que utilizem processos de complicação e empacotamento fora do Xcode, precisem de fato do conteúdo deste post. Algo como CMake e/ou qmake, caso saiba de algum outro, te espero no @droposhado.

Comando otool

Este comando otool faz parte do llvm (compilador), sendo seu nome llvm-otool. Ele é parser para as saídas do comando llvm-objdump, sua saída contém informações muito úteis para desenvolvimento, apresentando ID e bibliotecas de dependência.

É interesante saber que o LLVM do Xcode é chamado de Apple LLVM.

Todo executável ou biblioteca (.dylib) no macOS tem um ID, até mesmo .frameworks mencionados no post anterior, possuem binários que utilizam ID, para obter esse ID use a flag -D (desconsiderando um : que sempre aparece):

$ otool -D <binario>
/Applications/<app-name>.app/Content/Frameworks/<lib-name>.dynlib:

De fato é um ID e toda vez que incluir ele como dependência de outro binário, seu caminho físico no disco tem de ser igual ao ID. Considerando o ID que vimos anteriormente, seu valor como dependência é:

/Applications/<app-name>.app/Content/Frameworks/<lib-name>.dynlib

Perceba que é hardcode onde encontrar dependência e o bundle em si (.app) abre em qualquer pasta, apenas exibindo a recomendação de ser movido para a pasta /Application, porém se o bundle (.app) que tem a dependência estiver em outro local, ele não encontra a dependência e ocorre um erro de execução. Sendo assim, através deste post vamos entender como fazer que o ID seja relativo ao bundle (.app).

A próxima flag -L, lista o ID e todas as dependências com link dinânico a esse binário:

$ otool -L <binario>
    <path>/CoreFoundation (compatibility version 150.0.0, current version 1452.23.0)
    <path>/Cocoa (compatibility version 1.0.0, current version 22.0.0)
    @rpath/libvlc.dylib (compatibility version 12.0.0, current version 12.0.0)

Onde <path> é o caminho no disco, só utilizei disso pra nao ficar imenso horizontalmente e a saída a partir da segunda linha é sempre tabulação dupla (\t\t).

RPATH

É uma lista de paths inserida no binário, onde ele procura as bibliotecas, frameworks e dependências de link dinâmico em tempo de execução. Essa lista pode ser obtida através do comando:

otool -l <binario>

Os RPATHs são representados por LC_RPATH, como é uma lista, pode existir mais de uma entrada, esse é um dos paths de busca:

   Load command 55
    cmd LC_RPATH
cmdsize 48
   path @executable_path/../Frameworks (offset 12)

A representação de LC_LOAD_DYLIB é a mesma de quando se usa a flag -L, com algumas informações relativas a dependência:

         Load command 52
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name @rpath/libswiftObjectiveC.dylib (offset 24)
   time stamp 2 Wed Dec 31 21:00:02 1969
      current version 0.0.0
compatibility version 1.0.0

Como bundles tem dependências auto suficientes, utilizar elas com caminho absoluto pode não ser viável, considerando dependências que não são do sistema. Para essas existem modos relativos do executável principal encontrar as dependências.

@executable_path

Representa o executável do bundle (.app) que se encontra dentro da pasta apresentada abaixo:

<name>.app/Contents/MacOS

Isso quer dizer que para chegar na pasta Frameworks o caminho seria:

@executable_path/../Frameworks/

@rpath

Os binários são procurados na lista de paths inseridos na LC_RPATH onde o @rpath é substitído por cada path até que se finalize a lista encontrando ou não o binário.

Como no exemplo a cima utilizando o binário @rpath/libswiftObjectiveC.dylib, o caminho final dele seria:

@executable_path/../Frameworks/libswiftObjectiveC.dylib

@loader_path

É mais direcionado ao uso em frameworks e plugins (com esse em especifíco não tenho tanta experiência), porém o @loader_path ao que entendi assume o valor do path de onde ele foi carregado, o valor de onde o binário que o invocou está.

Esta parte pode receber atualização.

Comando install_tool_name

Tudo visto até aqui, foi somente para visualizar e possívelmente encontrar um erro relacionado a ID e paths, porém é preciso corrigir e nesse momento entram as funcionalidades do comando install_name_tool.

ID

Como já foi dito, todo binário tem um ID e é possível fazer a troca. É comum quando ele vem com caminho absoluto da máquina em que foi feito o processo de compilação e se quer criar o bundle (.app) com algo relativo. Então é utilizado o comando:

$ install_name_tool -id <novo-id> <binario>

Alterar um RPATH

Caso já tenha registrado um path no RPATH e queira alterar, utilize o comando:

$ install_name_tool -rpath <antigo> <novo> <binário>

Adicionar RPATH

Para adicionar um novo path a lista de RPATH do binário, utilize o comando:

$ install_name_tool -add_rpath <novo> <binário>

Remover RPATH

Para remover um path da lista de RPATH do binário, utilize o comando:

$ install_name_tool -delete_rpath <path> <binário>

Referências

Oficiais da Apple

Gerais