Search code examples
python-3.xwindowspyinstallerportaudio

PyInstaller executable on Windows not working because of PortAudio library issues (OSError)


I'm trying to build a .exe on Windows from my Python 3.7 application using PyInstaller. The build appears to run smoothly and shows no errors; however, executing the file on the Windows command prompt results in this awful error:

OSError: PortAudio library not found

I've done some research about this problem and found some info, but still couldn't overcome it. My app uses the sounddevice library, which depends on PortAudio library. PortAudio is installed, since the app works perfectly when I run it directly using Python; the problem is, clearly, that PyInstaller tracks the dependencies in some different way and is not able to find it and link it to the build.

This 'different way' is, actually, calling the 'find_library' function from 'ctypes.util' Python library to find the PortAudio library on the system. So, I ran the following on Python and confirmed it is not able to find the libary.

Python 3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)] :: > Anaconda, Inc. on win32 Type "help", "copyright", "credits" or "license" for more information.

from ctypes.util import find_library

a = find_library('portaudio')

print(a)

None

So far, I've tried several solutions. First, I downloaded and compiled the last PortAudio version manually. Didn't work. Then, I tried using Anaconda instead of the official Python distribution; as you may know, Anaconda's package manager 'conda' can deal with C libraries like PortAudio. So I installed it on my Anaconda's virtual environment and tried to build my app in there. Didn't work either. I also tried adding PortAudio directory to Windows PATH variable, but it also failed. I'm kinda lost. The only idea I have yet to try is building it on Linux using Wine, but I suspect there might be a way to get it working on Windows.

Any ideas?


Solution

  • I managed to solve it myself. I'll post the answer, it may be useful to somebody.

    What I thought was right. ctypes checks the folders defined in Windows PATH environment variable and searches them for libraries. Thing is, on Linux the system uses some kind of alias, so when

    from ctypes.util import find_library
    find_library('portaudio')
    

    it returns the correct portaudio library. But on Windows, only the file names are checked. So, you have to make sure this two conditions are met:

    • The directory containing the PortAudio DLLs is in your PATH environment variable.
    • The DLL filename (without the extension) must be exactly 'portaudio'.

    About the DLLs, if you were using sounddevice in your Python app, you should be able to find them here:

    \your\path\to\python\Lib\site-packages_sounddevice_data\portaudio-binaries

    The file is named 'libportaudio64bit.dll', so simply adding that directory to PATH won't do the trick. To overcome this, I just copied the dll into another directory, renamed it as 'portaudio.dll' and added that directory to PATH. Worked like magic.

    If you're not using sounddevice, you can also download those same precompiled DLLs from here:

    https://github.com/spatialaudio/portaudio-binaries

    That's all. Hope it helps!