Day 53 — A tool to list PE file dependencies

Today I read up on some numpy docs to try and find how they bundle the OpenBLAS DLL with the numpy wheel. I've updated the day 51 post with the things that I found.

I also packaged the find_dll_dependencies function from wheel_repair.py into a convenient CLI tool which can be used to list dependencies for a PE file.


  $ pedep pdftopng.cp38-win_amd64.pyd
  Imports for pdftopng.cp38-win_amd64.pyd:
    - MSVCP140.dll
    - python38.dll
    - KERNEL32.dll
    - VCRUNTIME140_1.dll
    - VCRUNTIME140.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-string-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-convert-l1-1-0.dll
    - api-ms-win-crt-time-l1-1-0.dll
    - api-ms-win-crt-math-l1-1-0.dll
    - api-ms-win-crt-multibyte-l1-1-0.dll
    - api-ms-win-crt-locale-l1-1-0.dll
    - api-ms-win-crt-filesystem-l1-1-0.dll
    - freetype.dll
    - libpng16.dll
    - jpeg62.dll
    - ADVAPI32.dll

There's also a --json option which will print all the imports as a JSON string.

And if you pass in a --dll-dir which might contain some of the DLL dependencies, pedep will recursively list down dependencies for every file it finds in the --dll-dir:


  $ pedep --dll-dir C:\path\to\dll\directory pdftopng.cp38-win_amd64.pyd
  Imports for pdftopng.cp38-win_amd64.pyd:
    - MSVCP140.dll
    - python38.dll
    - KERNEL32.dll
    - VCRUNTIME140_1.dll
    - VCRUNTIME140.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-string-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-convert-l1-1-0.dll
    - api-ms-win-crt-time-l1-1-0.dll
    - api-ms-win-crt-math-l1-1-0.dll
    - api-ms-win-crt-multibyte-l1-1-0.dll
    - api-ms-win-crt-locale-l1-1-0.dll
    - api-ms-win-crt-filesystem-l1-1-0.dll
    - freetype.dll
    - libpng16.dll
    - jpeg62.dll
    - ADVAPI32.dll

  Imports for freetype.dll:
    - zlib1.dll
    - bz2.dll
    - libpng16.dll
    - brotlidec.dll
    - VCRUNTIME140.dll
    - api-ms-win-crt-convert-l1-1-0.dll
    - api-ms-win-crt-string-l1-1-0.dll
    - api-ms-win-crt-utility-l1-1-0.dll
    - api-ms-win-crt-environment-l1-1-0.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - KERNEL32.dll

  Imports for zlib1.dll:
    - VCRUNTIME140.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-convert-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - KERNEL32.dll

  Imports for bz2.dll:
    - VCRUNTIME140.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - api-ms-win-crt-string-l1-1-0.dll
    - api-ms-win-crt-math-l1-1-0.dll
    - KERNEL32.dll

  Imports for libpng16.dll:
    - zlib1.dll
    - VCRUNTIME140.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-math-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - api-ms-win-crt-convert-l1-1-0.dll
    - api-ms-win-crt-filesystem-l1-1-0.dll
    - api-ms-win-crt-time-l1-1-0.dll
    - KERNEL32.dll

  Imports for brotlidec.dll:
    - brotlicommon.dll
    - VCRUNTIME140.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - KERNEL32.dll

  Imports for brotlicommon.dll:
    - VCRUNTIME140.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - KERNEL32.dll

  Imports for jpeg62.dll:
    - VCRUNTIME140.dll
    - api-ms-win-crt-environment-l1-1-0.dll
    - api-ms-win-crt-heap-l1-1-0.dll
    - api-ms-win-crt-stdio-l1-1-0.dll
    - api-ms-win-crt-runtime-l1-1-0.dll
    - KERNEL32.dll

If I can somehow get the dependency file paths from the PE file itself (I'm not sure if that's possible), or emulate the behavior of the Windows dynamic library loader to look for DLLs in every possible Windows directory where they might occur (C:\Windows, C:\Windows\System32, etc. or maybe every directory on the PATH variable?!), I could remove the need for a --dll-dir option!


I also watched this talk by Steve Dower where he shows some statistics on how more than 50% VS Code and PyCharm users are on Windows, and talks about how we should make the code we release more inclusive by supporting Windows as a platform. He mentions the following things that can help us do that: