_glfw_set_search_path.py 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # Part of ImGui Bundle - MIT License - Copyright (c) 2022-2026 Pascal Thomet - https://github.com/pthom/imgui_bundle
  2. def _glfw_set_search_path() -> None:
  3. """Sets os.environ["PYGLFW_LIBRARY"] so that glfw provided by pip uses our dynamic glfw library
  4. (provided in imgui_bundle package).
  5. This is necessary if a user want to "import glfw" after having started an imgui_bundle application:
  6. 1. imgui_bundle ships its own glfw dynamic library (libglfw.so / glfw3.dll / libglfw.dylib)
  7. 2. in that case the glfw python package (pyglfw) must be told to use that library
  8. This function searches for the GLFW dynamic library in multiple locations to support
  9. different packaging tools (pip, PyInstaller, Nuitka, etc.).
  10. Search priority:
  11. 1. PYGLFW_LIBRARY preexisting environment variable (user override)
  12. 2. imgui_bundle package directory (standard pip install)
  13. 3. Directory containing sys.executable (for Nuitka and frozen apps)
  14. 4. Current working directory (fallback)
  15. If GLFW library is not found in any location, a warning is issued and the function
  16. returns without setting PYGLFW_LIBRARY, allowing the system to attempt loading GLFW
  17. through default mechanisms.
  18. Background:
  19. venv/lib/python3.9/site-packages/glfw/library.py checks:
  20. if os.environ.get('PYGLFW_LIBRARY', ''):
  21. try:
  22. glfw = ctypes.CDLL(os.environ['PYGLFW_LIBRARY'])
  23. except OSError:
  24. glfw = None
  25. """
  26. import os
  27. import sys
  28. import platform
  29. import warnings
  30. # Determine the expected library filename for the current platform
  31. if platform.system() == "Darwin":
  32. lib_filenames = ["libglfw.3.dylib"]
  33. elif platform.system() == "Windows":
  34. lib_filenames = ["glfw3.dll"]
  35. elif platform.system() == "Linux":
  36. # Try multiple common naming conventions
  37. lib_filenames = ["libglfw.so.3", "libglfw.3.so", "libglfw. so.3.4", "libglfw.so.3.3"]
  38. elif platform.system() == "Emscripten":
  39. return
  40. else:
  41. warnings.warn(
  42. f"GLFW library search not implemented for platform: {platform.system()}. "
  43. f"GLFW functionality may not work correctly.",
  44. RuntimeWarning,
  45. stacklevel=2
  46. )
  47. return
  48. # Priority 1: Check if user has explicitly set PYGLFW_LIBRARY
  49. if os.environ.get("PYGLFW_LIBRARY"):
  50. glfw_path = os.environ["PYGLFW_LIBRARY"]
  51. if os.path.exists(glfw_path):
  52. return
  53. else:
  54. warnings.warn(
  55. f"env var PYGLFW_LIBRARY is set to '{glfw_path}' but file does not exist. ",
  56. RuntimeWarning,
  57. stacklevel=2
  58. )
  59. return
  60. # Define search directories in priority order
  61. search_dirs = [
  62. os.path.dirname(__file__), # imgui_bundle package directory (pip install)
  63. os.path.dirname(os.path.abspath(sys. executable)), # Nuitka/PyInstaller executable directory
  64. os.getcwd(), # Current working directory (fallback)
  65. ]
  66. # Search for the library in all directories
  67. for search_dir in search_dirs:
  68. for lib_filename in lib_filenames:
  69. lib_path = os.path.join(search_dir, lib_filename)
  70. if os.path. exists(lib_path):
  71. # Found it! Set the environment variable and return
  72. os. environ["PYGLFW_LIBRARY"] = lib_path
  73. return
  74. # If we get here, we couldn't find the GLFW library anywhere
  75. search_locations = "\n - ".join(search_dirs)
  76. warnings.warn(
  77. f"Could not find GLFW library ({', '.join(lib_filenames)}) in any of the following locations:\n"
  78. f" - {search_locations}\n\n"
  79. f"GLFW functionality may not work correctly."
  80. f"You may set the PYGLFW_LIBRARY environment variable to the full path of your GLFW library.\n\n"
  81. f"Falling back to system GLFW library loading (if available).",
  82. RuntimeWarning,
  83. stacklevel=2
  84. )