From 6599115a688109fa79ec57401b7c55b671b64e64 Mon Sep 17 00:00:00 2001
From: Siarhei Siniak <siarheisiniak@gmail.com>
Date: Mon, 30 Dec 2024 15:03:45 +0300
Subject: [PATCH] [+] 0.1.4.7, improve os module

  1. add runtime initialization;
    works for .so files;
    linux platform only at the moment;
---
 deps/com.github.aiortc.aiortc                 |  2 +-
 .../pr34/commands_typed/cli_bootstrap.py      | 18 ++++-
 .../online/fxreader/pr34/commands_typed/os.py | 69 ++++++++++++++++++-
 python/pyproject.toml                         |  6 +-
 4 files changed, 89 insertions(+), 6 deletions(-)

diff --git a/deps/com.github.aiortc.aiortc b/deps/com.github.aiortc.aiortc
index e6422d3..f94ded8 160000
--- a/deps/com.github.aiortc.aiortc
+++ b/deps/com.github.aiortc.aiortc
@@ -1 +1 @@
-Subproject commit e6422d353cda8ff688ceff7036b91d2a0de0d277
+Subproject commit f94ded8fbfe62bea6e96827312eb25853990ecd3
diff --git a/python/online/fxreader/pr34/commands_typed/cli_bootstrap.py b/python/online/fxreader/pr34/commands_typed/cli_bootstrap.py
index 10d0381..51692c6 100644
--- a/python/online/fxreader/pr34/commands_typed/cli_bootstrap.py
+++ b/python/online/fxreader/pr34/commands_typed/cli_bootstrap.py
@@ -18,6 +18,8 @@ class PyProject:
     dependencies: dict[str, list[str]]
     early_features: Optional[list[str]] = None
     pip_find_links: Optional[list[pathlib.Path]] = None
+    runtime_libdirs: Optional[list[pathlib.Path]] = None
+    runtime_preload: Optional[list[pathlib.Path]] = None
     
 def pyproject_load(
     d: pathlib.Path,
@@ -68,10 +70,24 @@ def pyproject_load(
 
         if 'pip_find_links' in content['tool'][tool_name]:
             res.pip_find_links = [
-                pathlib.Path(o)
+                d.parent / pathlib.Path(o)
                 for o in content['tool'][tool_name]['pip_find_links']
             ]
 
+        if 'runtime_libdirs' in content['tool'][tool_name]:
+            res.runtime_libdirs = [
+                d.parent / pathlib.Path(o)
+                # pathlib.Path(o)
+                for o in content['tool'][tool_name]['runtime_libdirs']
+            ]
+
+        if 'runtime_preload' in content['tool'][tool_name]:
+            res.runtime_preload = [
+                d.parent / pathlib.Path(o)
+                # pathlib.Path(o)
+                for o in content['tool'][tool_name]['runtime_preload']
+            ]
+
     return res
 
 @dataclasses.dataclass
diff --git a/python/online/fxreader/pr34/commands_typed/os.py b/python/online/fxreader/pr34/commands_typed/os.py
index a4b3563..dc04d62 100644
--- a/python/online/fxreader/pr34/commands_typed/os.py
+++ b/python/online/fxreader/pr34/commands_typed/os.py
@@ -1,7 +1,17 @@
 import shutil
+import glob
+import pathlib
+import ctypes
+import os
+import sys
+import logging
+
+logger = logging.getLogger(__name__)
 
 from typing import (overload, Optional, Literal,)
 
+from .cli_bootstrap import PyProject
+
 @overload
 def shutil_which(
     name: str,
@@ -22,4 +32,61 @@ def shutil_which(
     if res is None and raise_on_failure:
         raise NotImplementedError
     else:
-        return res
\ No newline at end of file
+        return res
+
+def runtime_libdirs_init(
+    project: PyProject,
+) -> None:
+    if sys.platform == 'linux':
+        ld_library_path : list[pathlib.Path] = [
+            o
+            for o in [
+                *[
+                    o.absolute()
+                    for o in (
+                        project.runtime_libdirs
+                        if project.runtime_libdirs
+                        else []
+                    )
+                ],
+                *[
+                    pathlib.Path(o)
+                    for o in os.environ.get(
+                        'LD_LIBRARY_PATH',
+                        ''
+                    ).split(os.path.pathsep)
+                    if o != ''
+                ]
+            ]
+        ]
+
+        ld_library_path_present : list[pathlib.Path] = []
+
+        for o in ld_library_path:
+            if not o.exists():
+                logger.warning(dict(
+                    ld_library_path=o,
+                    msg='not found',
+                ))
+
+            ld_library_path_present.append(o)
+
+        os.environ.update(
+            LD_LIBRARY_PATH=os.path.pathsep.join([
+                str(o) for o in ld_library_path_present
+            ])
+        )
+
+        for preload_path in (project.runtime_preload or []):
+            for preload_found in glob.glob(str(
+                preload_path.parent / ('lib%s.so' % preload_path.name)
+            )):
+                logger.info(dict(
+                    preload_path=preload_path, preload_found=preload_found,
+                    # lib_path=o,
+                    msg='load_library',
+                ))
+
+                ctypes.cdll.LoadLibrary(preload_found)
+    else:
+        raise NotImplementedError
\ No newline at end of file
diff --git a/python/pyproject.toml b/python/pyproject.toml
index 532a118..e76fccb 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -1,6 +1,6 @@
 [project]
 name = 'online.fxreader.pr34'
-version = '0.1.4.1'
+version = '0.1.4.7'
 
 dependencies = [
     #"-r requirements.txt",
@@ -38,8 +38,8 @@ include-package-data = false
 #exclude = ['*']
 #include = ['*.py']
 
-[tool.setuptools.exclude-package-data]
-'online.fxreader.pr34' = ['online/fxreader/pr34/py.typed']
+# [tool.setuptools.exclude-package-data]
+# 'online.fxreader.pr34' = ['online/fxreader/pr34/py.typed']
 
 #[tool.setuptools.package-data]
 #'online_fxreader.vpn' = ['requirements.txt']