Last active
December 20, 2018 19:11
-
-
Save nornagon/ec3b89c6df7c45e0e05aaa7beb396c9f to your computer and use it in GitHub Desktop.
List transitive dynamic library dependencies on macOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const child_process = require('child_process') | |
const printTree = require('print-tree') | |
const depsOf = (lib) => { | |
const res = child_process.spawnSync('otool', ['-L', lib]) | |
if (res.status !== 0) { | |
throw new Error(`Failed to run otool on ${lib}:\n${res.stderr}`) | |
} | |
return res.stdout.toString() | |
.split('\n') | |
.slice(2) // the first 2 lines of `otool` are the library itself | |
.map(x => x.substr(1).split(' ', 2)[0]) | |
.filter(l => l.startsWith('/')) // filter out @rpath, since we don't know how to resolve them | |
} | |
const root = process.argv[2] | |
printTree( | |
{lib: root, seen: new Set}, | |
node => node.lib, | |
node => { | |
const deps = depsOf(node.lib).filter(x => !node.seen.has(x)) | |
const seen = new Set([...deps, ...node.seen]) | |
return deps.map(lib => ({lib, seen})) | |
} | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./find-deps.js `which ls` | |
/bin/ls | |
├── /usr/lib/libncurses.5.4.dylib | |
└─┬ /usr/lib/libSystem.B.dylib | |
├── /usr/lib/system/libcache.dylib | |
├── /usr/lib/system/libcommonCrypto.dylib | |
├── /usr/lib/system/libcompiler_rt.dylib | |
├── /usr/lib/system/libcopyfile.dylib | |
├── /usr/lib/system/libcorecrypto.dylib | |
├─┬ /usr/lib/system/libdispatch.dylib | |
│ └─┬ /usr/lib/libobjc.A.dylib | |
│ ├── /usr/lib/libc++abi.dylib | |
│ └── /usr/lib/libc++.1.dylib | |
├─┬ /usr/lib/system/libdyld.dylib | |
│ └─┬ /usr/lib/closure/libclosured.dylib | |
│ └─┬ /usr/lib/libc++.1.dylib | |
│ └── /usr/lib/libc++abi.dylib | |
├── /usr/lib/system/libkeymgr.dylib | |
├── /usr/lib/system/liblaunch.dylib | |
├── /usr/lib/system/libmacho.dylib | |
├── /usr/lib/system/libquarantine.dylib | |
├── /usr/lib/system/libremovefile.dylib | |
├── /usr/lib/system/libsystem_asl.dylib | |
├── /usr/lib/system/libsystem_blocks.dylib | |
├── /usr/lib/system/libsystem_c.dylib | |
├── /usr/lib/system/libsystem_configuration.dylib | |
├── /usr/lib/system/libsystem_coreservices.dylib | |
├── /usr/lib/system/libsystem_darwin.dylib | |
├── /usr/lib/system/libsystem_dnssd.dylib | |
├── /usr/lib/system/libsystem_info.dylib | |
├── /usr/lib/system/libsystem_m.dylib | |
├── /usr/lib/system/libsystem_malloc.dylib | |
├─┬ /usr/lib/system/libsystem_network.dylib | |
│ └─┬ /usr/lib/libobjc.A.dylib | |
│ ├── /usr/lib/libc++abi.dylib | |
│ └── /usr/lib/libc++.1.dylib | |
├── /usr/lib/system/libsystem_networkextension.dylib | |
├── /usr/lib/system/libsystem_notify.dylib | |
├── /usr/lib/system/libsystem_sandbox.dylib | |
├── /usr/lib/system/libsystem_secinit.dylib | |
├── /usr/lib/system/libsystem_kernel.dylib | |
├── /usr/lib/system/libsystem_platform.dylib | |
├── /usr/lib/system/libsystem_pthread.dylib | |
├─┬ /usr/lib/system/libsystem_symptoms.dylib | |
│ └─┬ /usr/lib/libobjc.A.dylib | |
│ ├── /usr/lib/libc++abi.dylib | |
│ └── /usr/lib/libc++.1.dylib | |
├─┬ /usr/lib/system/libsystem_trace.dylib | |
│ └─┬ /usr/lib/libobjc.A.dylib | |
│ ├── /usr/lib/libc++abi.dylib | |
│ └── /usr/lib/libc++.1.dylib | |
├── /usr/lib/system/libunwind.dylib | |
└─┬ /usr/lib/system/libxpc.dylib | |
└─┬ /usr/lib/libobjc.A.dylib | |
├── /usr/lib/libc++abi.dylib | |
└── /usr/lib/libc++.1.dylib |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment