cmbruns / pyopenvr

Unofficial python bindings for Valve's OpenVR virtual reality SDK
BSD 3-Clause "New" or "Revised" License
245 stars 39 forks source link

FileNotFoundError: Could not find module 'libopenvr_api_64' on Windows with Anaconda #89

Open Florian-Cormee opened 2 years ago

Florian-Cormee commented 2 years ago

Hi, I'm trying to setup a conda environment to code in Spyder. However, when I try to import openvr, I get a FileNotFoundError on the dll. I found that adding CONDA_DLL_SEARCH_MODIFICATION_ENABLE=1 is not enough (related issue). I get a WinError deeper in the callstack.

To recreate

conda create -n openvr-env python -y conda activate openvr-env pip install openvr python import openvr

Traceback

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\<User>\miniconda3\envs\openvr-env\lib\site-packages\openvr\__init__.py", line 64, in <module>
    _openvr = cdll.LoadLibrary(_openvr_lib_name)
  File "C:\Users\<User>\miniconda3\envs\openvr-env\lib\ctypes\__init__.py", line 460, in LoadLibrary
    return self._dlltype(name)
  File "C:\Users\<User>\miniconda3\envs\openvr-env\lib\ctypes\__init__.py", line 382, in __init__
    self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'libopenvr_api_64' (or one of its dependencies). Try using the full path with constructor syntax.

OS: Windows 64bit

Possible fix

Always import the full path has it is done for Linux (line 62 in openvr__init__.py). This works fine in conda and in standard python install.

cmbruns commented 2 years ago

@Florian-Cormee Thank you for reporting this. Would you be able to create a patch or pull request implementing the fix you suggest?

I wonder if it would be possible to use pkg_resources.resource_filename(...) or similar instead of os.path.whatever and __file__. But we'd need folks who can test on linux and Windows and maybe Mac before inserting a comprehensive change using these.

cmbruns commented 2 years ago

@Florian-Cormee please try the latest branch PyOpenVR-1.16 which has a simplified shared library loader based on your suggestion.

Florian-Cormee commented 2 years ago

@cmbruns Thank you for your replies. I was away for a few days, hence the delay.

It seems that pkg_resources is deprecated now [source]. Is there something wrong with __file__ and os.path? To me it's the simplest solution and it's cross platform.

I'll try the new branch asap then I'll edit this post. Thank you.

cmbruns commented 2 years ago

pkg_resources.resource_filename() will still work even if your whole app and python environment are packed into a single executable or zip file. In that case it will magically pluck the shared library into a temp folder in the file system and load it from there. I don't think __file__ etc. can do that.

You raise a good point that pkg_resources injects a dependency on setuptools. Switching to importlib instead would raise the python version requirement to 3.7. But maybe that's OK by now.

I'm unsure why you mention "cross platform". I don't see anything that's not cross-platform in any of the possible implementations here.

Please let me know whether the latest works for you. I'd like this sort of thing to work correctly.

Florian-Cormee commented 2 years ago

You are totally right. pkg_resources is a serious improvement.

I agree with you, python 3.7 as a requirement seems reasonnable.

I miss use the term "cross platform". I meant it would add a dependency. Cross install would make more sense. It doesn't really matter anyway.

I tested both pkg_resources and you're latest switch to importlib both work like a charm on windows in my conda environment.

cmbruns commented 2 years ago

@Florian-Cormee that's great news! Thanks for testing and reporting. By the way, I will probably go back to pkg_resources, because I found a problem with importlib on python 3.8, and python 3.8 will likely be the system python on Ubuntu LTS at least until April 2022. Eventually when python 3.8 is no longer important, it will be time to move to importlib.