web-dev-qa-db-fra.com

Imprimer le chemin d'un exécutable sur macOS

Je veux changer le rpath d'un exécutable en utilisant install_name_tool, mais je ne peux pas comprendre ce que le rpath est en ce moment. install_name_tool requiert que l'ancien et le nouveau rpath soient donnés sur la ligne de commande. Quelle commande puis-je utiliser pour imprimer le rpath d'un exécutable sous macOS?

66
staticfloat

Tout d'abord, sachez qu'un exécutable ne contient pas une seule entrée rpath, mais un tableau d'une ou plusieurs entrées.

Deuxièmement, vous pouvez utiliser otool pour répertorier les entrées rpath d'une image. En utilisant otool -l, vous obtiendrez une sortie comme celle-ci, à la toute fin des entrées rpath:

Load command 34
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1038.32.0
compatibility version 45.0.0

Load command 35
          cmd LC_RPATH
      cmdsize 40
         path @loader_path/../Frameworks (offset 12)

Cherchez le LC_RPATH commandes et notez le chemin sous l'entrée path.

86
NSGod

J'ai constaté que je peux imprimer le nom d'installation d'une bibliothèque partagée sur macOS à l'aide

otool -D mylib

De plus, je peux définir le nom d'installation directement sans référence à l'ancien nom d'installation en passant le -id drapeau à install_name_tool:

install_name_tool -id @rpath/my/path mylib
3
Amos Joshua

J'écris actuellement plusieurs scripts Bash-3 pour le traitement de DYLD et celui-ci répond à la question, donc je le poste pour référence:

#! /bin/bash

# ######################################################################### #

if [ ${#} -eq 0 ]
then
    echo "
Usage: ${0##*/} FILE...

List rpaths in FILEs
"    
    exit 0
fi

# ######################################################################### #

shopt -s extglob

# ######################################################################### #

for file in "${@}"
do
    if [ ! -r "${file}" ]
    then
        echo "${file}: no such file" 1>&2
        continue
    fi

    if ! [[ "$(/usr/bin/file "${file}")" =~ ^${file}:\ *Mach-O\ .*$ ]]
    then
        echo "${file}: is not an object file" 1>&2
        continue
    fi

    if [ ${#} -gt 1 ]
     then
         echo "${file}:"
    fi

    IFS_save="${IFS}"
    IFS=$'\n'

    _next_path_is_rpath=

    while read line
    do
        case "${line}" in
            *(\ )cmd\ LC_RPATH)
                _next_path_is_rpath=yes
                ;;
            *(\ )path\ *\ \(offset\ +([0-9])\))
                if [ -z "${_next_path_is_rpath}" ]
                then
                    continue
                fi
                line="${line#* path }"
                line="${line% (offset *}"
                if [ ${#} -gt 1 ]
                then
                    line=$'\t'"${line}"
                fi
                echo "${line}"
                _next_path_is_rpath=
                ;;
        esac
    done < <(/usr/bin/otool -l "${file}")

    IFS="${IFS_save}"
done

# ######################################################################### #

'J'espère que ça aide ;-)

NB: Quelqu'un connaît-il des astuces Bash-3 qui peuvent être utiles pour ce script?

2
Fravadona

Vous pouvez utiliser otool -l myexecutable, mais cela imprime beaucoup d'informations inutiles si vous n'êtes intéressé que par la liste des rpath s.

Vous pouvez filtrer la sortie de otool -l aux entrées pertinentes rpath par

otool -l myexecutable | grep RPATH -A2
2
plasmacel