cpp-pd-code-simplify-interface 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cpp_pd_code_simplify_interface/main.py +362 -5
- {cpp_pd_code_simplify_interface-0.1.7.dist-info → cpp_pd_code_simplify_interface-0.1.8.dist-info}/METADATA +8 -1
- {cpp_pd_code_simplify_interface-0.1.7.dist-info → cpp_pd_code_simplify_interface-0.1.8.dist-info}/RECORD +5 -5
- {cpp_pd_code_simplify_interface-0.1.7.dist-info → cpp_pd_code_simplify_interface-0.1.8.dist-info}/WHEEL +0 -0
- {cpp_pd_code_simplify_interface-0.1.7.dist-info → cpp_pd_code_simplify_interface-0.1.8.dist-info}/entry_points.txt +0 -0
|
@@ -11,7 +11,9 @@ import pathlib
|
|
|
11
11
|
import platform
|
|
12
12
|
import re
|
|
13
13
|
import shlex
|
|
14
|
+
import shutil
|
|
14
15
|
import struct
|
|
16
|
+
import subprocess
|
|
15
17
|
import sys
|
|
16
18
|
from importlib import resources
|
|
17
19
|
from typing import Any, Optional, Sequence, Union
|
|
@@ -229,12 +231,20 @@ def _library_suffix() -> str:
|
|
|
229
231
|
|
|
230
232
|
def _default_compile_flags(include_dir: pathlib.Path, library_path: pathlib.Path) -> list[str]:
|
|
231
233
|
flags = ["-std=c++14", "-O3", "-DNDEBUG", "-I" + str(include_dir)]
|
|
232
|
-
|
|
234
|
+
system = platform.system()
|
|
235
|
+
if system != "Windows":
|
|
233
236
|
flags.append("-fPIC")
|
|
234
|
-
if
|
|
235
|
-
flags.extend([
|
|
237
|
+
if system == "Darwin":
|
|
238
|
+
flags.extend([
|
|
239
|
+
"-dynamiclib",
|
|
240
|
+
"-install_name",
|
|
241
|
+
"@rpath/" + library_path.name,
|
|
242
|
+
"-Wl,-rpath,@loader_path",
|
|
243
|
+
])
|
|
236
244
|
else:
|
|
237
245
|
flags.append("-shared")
|
|
246
|
+
if system == "Linux":
|
|
247
|
+
flags.append("-Wl,-rpath,$ORIGIN")
|
|
238
248
|
native = os.environ.get("CPP_PD_CODE_SIMPLIFY_INTERFACE_NATIVE", "1").strip().lower()
|
|
239
249
|
if native not in ("0", "false", "no", "off"):
|
|
240
250
|
flags.append("-march=native")
|
|
@@ -249,6 +259,7 @@ def _cache_key(source_bytes: bytes, flags: Sequence[str]) -> str:
|
|
|
249
259
|
digest.update(source_bytes)
|
|
250
260
|
digest.update("\0".join(flags).encode("utf-8"))
|
|
251
261
|
digest.update(cpp_simple_interface.get_gpp_filepath().encode("utf-8"))
|
|
262
|
+
digest.update(_runtime_fingerprint())
|
|
252
263
|
digest.update(platform.platform().encode("utf-8"))
|
|
253
264
|
return digest.hexdigest()[:20]
|
|
254
265
|
|
|
@@ -274,9 +285,337 @@ def _compiler_runtime_path_entries() -> list[pathlib.Path]:
|
|
|
274
285
|
path = pathlib.Path(candidate)
|
|
275
286
|
if path.exists() and path.is_file() and path.parent not in paths:
|
|
276
287
|
paths.append(path.parent)
|
|
288
|
+
continue
|
|
289
|
+
resolved = shutil.which(candidate)
|
|
290
|
+
if resolved:
|
|
291
|
+
resolved_path = pathlib.Path(resolved)
|
|
292
|
+
if resolved_path.exists() and resolved_path.parent not in paths:
|
|
293
|
+
paths.append(resolved_path.parent)
|
|
277
294
|
return paths
|
|
278
295
|
|
|
279
296
|
|
|
297
|
+
def _path_entries() -> list[pathlib.Path]:
|
|
298
|
+
paths: list[pathlib.Path] = []
|
|
299
|
+
for entry in os.environ.get("PATH", "").split(os.pathsep):
|
|
300
|
+
if not entry:
|
|
301
|
+
continue
|
|
302
|
+
path = pathlib.Path(entry)
|
|
303
|
+
if path.exists() and path.is_dir() and path not in paths:
|
|
304
|
+
paths.append(path)
|
|
305
|
+
return paths
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def _tool_path(names: Sequence[str], extra_dirs: Sequence[pathlib.Path] = ()) -> Optional[str]:
|
|
309
|
+
for directory in extra_dirs:
|
|
310
|
+
for name in names:
|
|
311
|
+
candidate = directory / name
|
|
312
|
+
if candidate.exists() and candidate.is_file():
|
|
313
|
+
return str(candidate)
|
|
314
|
+
for name in names:
|
|
315
|
+
resolved = shutil.which(name)
|
|
316
|
+
if resolved:
|
|
317
|
+
return resolved
|
|
318
|
+
return None
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def _run_dependency_tool(command: Sequence[str]) -> str:
|
|
322
|
+
try:
|
|
323
|
+
result = subprocess.run(
|
|
324
|
+
list(command),
|
|
325
|
+
check=False,
|
|
326
|
+
text=True,
|
|
327
|
+
stdout=subprocess.PIPE,
|
|
328
|
+
stderr=subprocess.STDOUT,
|
|
329
|
+
encoding="utf-8",
|
|
330
|
+
errors="replace",
|
|
331
|
+
)
|
|
332
|
+
except OSError:
|
|
333
|
+
return ""
|
|
334
|
+
if result.returncode != 0 and not result.stdout:
|
|
335
|
+
return ""
|
|
336
|
+
return result.stdout
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def _objdump_dependency_names(path: pathlib.Path) -> list[str]:
|
|
340
|
+
tool = _tool_path(["objdump.exe", "objdump"], _compiler_runtime_path_entries())
|
|
341
|
+
if not tool:
|
|
342
|
+
return []
|
|
343
|
+
output = _run_dependency_tool([tool, "-p", str(path)])
|
|
344
|
+
names: list[str] = []
|
|
345
|
+
for line in output.splitlines():
|
|
346
|
+
stripped = line.strip()
|
|
347
|
+
if stripped.startswith("DLL Name:"):
|
|
348
|
+
names.append(stripped.split(":", 1)[1].strip())
|
|
349
|
+
elif stripped.startswith("NEEDED"):
|
|
350
|
+
parts = stripped.split()
|
|
351
|
+
if len(parts) >= 2:
|
|
352
|
+
names.append(parts[-1])
|
|
353
|
+
return names
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _dumpbin_dependency_names(path: pathlib.Path) -> list[str]:
|
|
357
|
+
tool = _tool_path(["dumpbin.exe", "dumpbin"])
|
|
358
|
+
if not tool:
|
|
359
|
+
return []
|
|
360
|
+
output = _run_dependency_tool([tool, "/DEPENDENTS", str(path)])
|
|
361
|
+
names: list[str] = []
|
|
362
|
+
for line in output.splitlines():
|
|
363
|
+
stripped = line.strip()
|
|
364
|
+
if stripped.lower().endswith(".dll"):
|
|
365
|
+
names.append(stripped)
|
|
366
|
+
return names
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def _ldd_dependency_paths(path: pathlib.Path) -> tuple[list[pathlib.Path], list[str]]:
|
|
370
|
+
tool = _tool_path(["ldd"])
|
|
371
|
+
if not tool:
|
|
372
|
+
return [], []
|
|
373
|
+
output = _run_dependency_tool([tool, str(path)])
|
|
374
|
+
paths: list[pathlib.Path] = []
|
|
375
|
+
missing: list[str] = []
|
|
376
|
+
for line in output.splitlines():
|
|
377
|
+
stripped = line.strip()
|
|
378
|
+
if "not found" in stripped:
|
|
379
|
+
missing.append(stripped.split()[0])
|
|
380
|
+
continue
|
|
381
|
+
candidate = ""
|
|
382
|
+
if "=>" in stripped:
|
|
383
|
+
right = stripped.split("=>", 1)[1].strip()
|
|
384
|
+
candidate = right.split("(", 1)[0].strip()
|
|
385
|
+
elif stripped.startswith("/"):
|
|
386
|
+
candidate = stripped.split("(", 1)[0].strip()
|
|
387
|
+
if candidate:
|
|
388
|
+
dependency = pathlib.Path(candidate)
|
|
389
|
+
if dependency.exists() and dependency not in paths:
|
|
390
|
+
paths.append(dependency)
|
|
391
|
+
return paths, missing
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def _otool_dependency_paths(path: pathlib.Path) -> list[pathlib.Path]:
|
|
395
|
+
tool = _tool_path(["otool"])
|
|
396
|
+
if not tool:
|
|
397
|
+
return []
|
|
398
|
+
output = _run_dependency_tool([tool, "-L", str(path)])
|
|
399
|
+
paths: list[pathlib.Path] = []
|
|
400
|
+
for line in output.splitlines()[1:]:
|
|
401
|
+
stripped = line.strip()
|
|
402
|
+
if not stripped:
|
|
403
|
+
continue
|
|
404
|
+
name = stripped.split(" ", 1)[0]
|
|
405
|
+
dependency: Optional[pathlib.Path] = None
|
|
406
|
+
if name.startswith("/"):
|
|
407
|
+
dependency = pathlib.Path(name)
|
|
408
|
+
elif name.startswith("@loader_path/"):
|
|
409
|
+
dependency = path.parent / name.removeprefix("@loader_path/")
|
|
410
|
+
elif name.startswith("@rpath/"):
|
|
411
|
+
dependency = _find_dependency_file(
|
|
412
|
+
pathlib.Path(name).name,
|
|
413
|
+
_runtime_search_dirs(path.parent),
|
|
414
|
+
)
|
|
415
|
+
if dependency is not None and dependency.exists() and dependency not in paths:
|
|
416
|
+
paths.append(dependency)
|
|
417
|
+
return paths
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _is_platform_library(path: pathlib.Path) -> bool:
|
|
421
|
+
if platform.system() == "Darwin":
|
|
422
|
+
text = str(path)
|
|
423
|
+
return text.startswith("/usr/lib/") or text.startswith("/System/Library/")
|
|
424
|
+
return False
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def _runtime_basename_is_cacheable(name: str) -> bool:
|
|
428
|
+
lowered = name.lower()
|
|
429
|
+
return (
|
|
430
|
+
lowered.startswith("libstdc++")
|
|
431
|
+
or lowered.startswith("libgcc_s")
|
|
432
|
+
or lowered.startswith("libwinpthread")
|
|
433
|
+
or lowered.startswith("libgomp")
|
|
434
|
+
or lowered.startswith("libquadmath")
|
|
435
|
+
or lowered.startswith("libatomic")
|
|
436
|
+
or lowered.startswith("libc++")
|
|
437
|
+
or lowered.startswith("libc++abi")
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _runtime_search_dirs(cache_dir: pathlib.Path) -> list[pathlib.Path]:
|
|
442
|
+
directories = [cache_dir, *_compiler_runtime_path_entries(), *_path_entries()]
|
|
443
|
+
result: list[pathlib.Path] = []
|
|
444
|
+
for directory in directories:
|
|
445
|
+
if directory.exists() and directory.is_dir() and directory not in result:
|
|
446
|
+
result.append(directory)
|
|
447
|
+
return result
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def _find_dependency_file(name: str, directories: Sequence[pathlib.Path]) -> Optional[pathlib.Path]:
|
|
451
|
+
wanted = name.lower()
|
|
452
|
+
for directory in directories:
|
|
453
|
+
candidate = directory / name
|
|
454
|
+
if candidate.exists() and candidate.is_file():
|
|
455
|
+
return candidate
|
|
456
|
+
try:
|
|
457
|
+
for item in directory.iterdir():
|
|
458
|
+
if item.is_file() and item.name.lower() == wanted:
|
|
459
|
+
return item
|
|
460
|
+
except OSError:
|
|
461
|
+
continue
|
|
462
|
+
return None
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def _copy_file_if_needed(source: pathlib.Path, destination: pathlib.Path) -> None:
|
|
466
|
+
try:
|
|
467
|
+
if destination.exists() and source.resolve() == destination.resolve():
|
|
468
|
+
return
|
|
469
|
+
except OSError:
|
|
470
|
+
pass
|
|
471
|
+
copy_needed = True
|
|
472
|
+
if destination.exists():
|
|
473
|
+
try:
|
|
474
|
+
source_stat = source.stat()
|
|
475
|
+
destination_stat = destination.stat()
|
|
476
|
+
copy_needed = (
|
|
477
|
+
source_stat.st_size != destination_stat.st_size
|
|
478
|
+
or source_stat.st_mtime_ns != destination_stat.st_mtime_ns
|
|
479
|
+
)
|
|
480
|
+
except OSError:
|
|
481
|
+
copy_needed = True
|
|
482
|
+
if copy_needed:
|
|
483
|
+
shutil.copy2(source, destination)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def _windows_dependency_names(path: pathlib.Path) -> list[str]:
|
|
487
|
+
names = _objdump_dependency_names(path) or _dumpbin_dependency_names(path)
|
|
488
|
+
if names:
|
|
489
|
+
return names
|
|
490
|
+
return [
|
|
491
|
+
"libstdc++-6.dll",
|
|
492
|
+
"libgcc_s_seh-1.dll",
|
|
493
|
+
"libgcc_s_sjlj-1.dll",
|
|
494
|
+
"libgcc_s_dw2-1.dll",
|
|
495
|
+
"libwinpthread-1.dll",
|
|
496
|
+
]
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def _runtime_fingerprint() -> bytes:
|
|
500
|
+
digest = hashlib.sha256()
|
|
501
|
+
if platform.system() == "Windows":
|
|
502
|
+
names = _windows_dependency_names(pathlib.Path("pdcode-simplify-placeholder.dll"))
|
|
503
|
+
else:
|
|
504
|
+
names = [
|
|
505
|
+
"libstdc++.so",
|
|
506
|
+
"libstdc++.so.6",
|
|
507
|
+
"libgcc_s.so",
|
|
508
|
+
"libgcc_s.so.1",
|
|
509
|
+
"libc++.dylib",
|
|
510
|
+
"libc++abi.dylib",
|
|
511
|
+
]
|
|
512
|
+
for directory in _compiler_runtime_path_entries():
|
|
513
|
+
for name in names:
|
|
514
|
+
candidate = directory / name
|
|
515
|
+
if not candidate.exists():
|
|
516
|
+
continue
|
|
517
|
+
try:
|
|
518
|
+
stat = candidate.stat()
|
|
519
|
+
except OSError:
|
|
520
|
+
continue
|
|
521
|
+
digest.update(str(candidate).encode("utf-8", errors="replace"))
|
|
522
|
+
digest.update(str(stat.st_size).encode("ascii"))
|
|
523
|
+
digest.update(str(stat.st_mtime_ns).encode("ascii"))
|
|
524
|
+
return digest.digest()
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def _cache_runtime_dependencies(library: pathlib.Path) -> None:
|
|
528
|
+
system = platform.system()
|
|
529
|
+
if system == "Windows":
|
|
530
|
+
search_dirs = _runtime_search_dirs(library.parent)
|
|
531
|
+
pending = list(_windows_dependency_names(library))
|
|
532
|
+
visited: set[str] = set()
|
|
533
|
+
while pending:
|
|
534
|
+
name = pending.pop(0)
|
|
535
|
+
key = name.lower()
|
|
536
|
+
if key in visited:
|
|
537
|
+
continue
|
|
538
|
+
visited.add(key)
|
|
539
|
+
if not _runtime_basename_is_cacheable(name):
|
|
540
|
+
continue
|
|
541
|
+
source = _find_dependency_file(name, search_dirs)
|
|
542
|
+
if source is None:
|
|
543
|
+
continue
|
|
544
|
+
destination = library.parent / source.name
|
|
545
|
+
_copy_file_if_needed(source, destination)
|
|
546
|
+
for imported in _windows_dependency_names(destination):
|
|
547
|
+
if imported.lower() not in visited:
|
|
548
|
+
pending.append(imported)
|
|
549
|
+
return
|
|
550
|
+
|
|
551
|
+
if system == "Linux":
|
|
552
|
+
paths, _ = _ldd_dependency_paths(library)
|
|
553
|
+
elif system == "Darwin":
|
|
554
|
+
paths = _otool_dependency_paths(library)
|
|
555
|
+
else:
|
|
556
|
+
paths = []
|
|
557
|
+
|
|
558
|
+
for dependency in paths:
|
|
559
|
+
if _is_platform_library(dependency):
|
|
560
|
+
continue
|
|
561
|
+
if _runtime_basename_is_cacheable(dependency.name):
|
|
562
|
+
_copy_file_if_needed(dependency, library.parent / dependency.name)
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
def _cached_runtime_dependencies(library: pathlib.Path) -> list[pathlib.Path]:
|
|
566
|
+
result: list[pathlib.Path] = []
|
|
567
|
+
try:
|
|
568
|
+
items = list(library.parent.iterdir())
|
|
569
|
+
except OSError:
|
|
570
|
+
return result
|
|
571
|
+
for item in items:
|
|
572
|
+
if item == library or not item.is_file():
|
|
573
|
+
continue
|
|
574
|
+
if _runtime_basename_is_cacheable(item.name):
|
|
575
|
+
result.append(item)
|
|
576
|
+
return result
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def _missing_runtime_dependency_names(library: pathlib.Path) -> list[str]:
|
|
580
|
+
system = platform.system()
|
|
581
|
+
if system == "Windows":
|
|
582
|
+
search_dirs = _runtime_search_dirs(library.parent)
|
|
583
|
+
missing = []
|
|
584
|
+
for name in _windows_dependency_names(library):
|
|
585
|
+
if _runtime_basename_is_cacheable(name) and _find_dependency_file(name, search_dirs) is None:
|
|
586
|
+
missing.append(name)
|
|
587
|
+
return missing
|
|
588
|
+
if system == "Linux":
|
|
589
|
+
_, missing = _ldd_dependency_paths(library)
|
|
590
|
+
return missing
|
|
591
|
+
return []
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
def _load_failure_message(path: pathlib.Path, error: OSError) -> str:
|
|
595
|
+
system = platform.system()
|
|
596
|
+
missing = _missing_runtime_dependency_names(path)
|
|
597
|
+
details = f"failed to load cached dynamic library {path}: {error}"
|
|
598
|
+
if missing:
|
|
599
|
+
details += "; missing dependencies: " + ", ".join(sorted(set(missing)))
|
|
600
|
+
if system == "Windows":
|
|
601
|
+
details += (
|
|
602
|
+
". The interface caches MinGW runtime DLLs next to the generated DLL; "
|
|
603
|
+
"if this cache was created by an older package version, delete the cache directory "
|
|
604
|
+
f"{path.parent} or call compile_simplifier(force=True)."
|
|
605
|
+
)
|
|
606
|
+
elif system == "Linux":
|
|
607
|
+
details += (
|
|
608
|
+
". Ensure the compiler runtime is installed, or set LD_LIBRARY_PATH before "
|
|
609
|
+
"starting Python when using a custom compiler runtime."
|
|
610
|
+
)
|
|
611
|
+
elif system == "Darwin":
|
|
612
|
+
details += (
|
|
613
|
+
". Ensure the compiler runtime is installed, or set DYLD_LIBRARY_PATH before "
|
|
614
|
+
"starting Python when using a custom compiler runtime."
|
|
615
|
+
)
|
|
616
|
+
return details
|
|
617
|
+
|
|
618
|
+
|
|
280
619
|
def _pe_machine_bits(path: pathlib.Path) -> Optional[int]:
|
|
281
620
|
if platform.system() != "Windows":
|
|
282
621
|
return None
|
|
@@ -334,6 +673,7 @@ def compile_simplifier(
|
|
|
334
673
|
flags.extend(str(flag) for flag in extra_flags)
|
|
335
674
|
|
|
336
675
|
if library.exists() and not force:
|
|
676
|
+
_cache_runtime_dependencies(library)
|
|
337
677
|
return library
|
|
338
678
|
|
|
339
679
|
tmp_library = cache / f"{library.name}.tmp-{os.getpid()}{_library_suffix()}"
|
|
@@ -358,6 +698,7 @@ def compile_simplifier(
|
|
|
358
698
|
if not tmp_library.exists():
|
|
359
699
|
raise PdCodeSimplifyInterfaceError(f"compiled dynamic library was not created: {tmp_library}")
|
|
360
700
|
os.replace(tmp_library, library)
|
|
701
|
+
_cache_runtime_dependencies(library)
|
|
361
702
|
return library
|
|
362
703
|
|
|
363
704
|
|
|
@@ -381,7 +722,7 @@ _DLL_DIRECTORY_HANDLES: list[Any] = []
|
|
|
381
722
|
def _prepare_dll_search_path(path: pathlib.Path) -> None:
|
|
382
723
|
if platform.system() != "Windows" or not hasattr(os, "add_dll_directory"):
|
|
383
724
|
return
|
|
384
|
-
for directory in
|
|
725
|
+
for directory in _runtime_search_dirs(path.parent):
|
|
385
726
|
try:
|
|
386
727
|
handle = os.add_dll_directory(str(directory))
|
|
387
728
|
except OSError:
|
|
@@ -389,6 +730,17 @@ def _prepare_dll_search_path(path: pathlib.Path) -> None:
|
|
|
389
730
|
_DLL_DIRECTORY_HANDLES.append(handle)
|
|
390
731
|
|
|
391
732
|
|
|
733
|
+
def _preload_runtime_dependencies(path: pathlib.Path) -> None:
|
|
734
|
+
if platform.system() == "Windows":
|
|
735
|
+
return
|
|
736
|
+
mode = getattr(ctypes, "RTLD_GLOBAL", 0)
|
|
737
|
+
for dependency in _cached_runtime_dependencies(path):
|
|
738
|
+
try:
|
|
739
|
+
ctypes.CDLL(str(dependency), mode=mode)
|
|
740
|
+
except OSError:
|
|
741
|
+
continue
|
|
742
|
+
|
|
743
|
+
|
|
392
744
|
def _load_library() -> ctypes.CDLL:
|
|
393
745
|
global _LOADED_LIBRARY_PATH, _LOADED_LIBRARY
|
|
394
746
|
path = compile_simplifier()
|
|
@@ -396,8 +748,13 @@ def _load_library() -> ctypes.CDLL:
|
|
|
396
748
|
return _LOADED_LIBRARY
|
|
397
749
|
|
|
398
750
|
_validate_library_architecture(path)
|
|
751
|
+
_cache_runtime_dependencies(path)
|
|
399
752
|
_prepare_dll_search_path(path)
|
|
400
|
-
|
|
753
|
+
_preload_runtime_dependencies(path)
|
|
754
|
+
try:
|
|
755
|
+
library = ctypes.CDLL(str(path))
|
|
756
|
+
except OSError as exc:
|
|
757
|
+
raise PdCodeSimplifyInterfaceError(_load_failure_message(path, exc)) from exc
|
|
401
758
|
library.pdcode_simplify_run_json.argtypes = [
|
|
402
759
|
ctypes.c_char_p,
|
|
403
760
|
ctypes.c_int,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cpp-pd-code-simplify-interface
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Python interface for cpp-pd-code-simplify with runtime C++ compilation.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Author: GGN_2015
|
|
@@ -34,6 +34,13 @@ use, the package compiles a cached local dynamic library through
|
|
|
34
34
|
`cpp-simple-interface`; later calls reuse that library through `ctypes`. A C++14
|
|
35
35
|
compiler compatible with `g++` must be available at runtime.
|
|
36
36
|
|
|
37
|
+
Runtime dependencies are handled per platform. On Windows, the interface uses
|
|
38
|
+
`objdump -p` or `dumpbin /DEPENDENTS` when available, then caches MinGW runtime
|
|
39
|
+
DLLs such as `libstdc++-6.dll`, `libgcc_s_*.dll`, and `libwinpthread-1.dll`
|
|
40
|
+
next to the generated DLL. On Linux it adds `$ORIGIN` rpath and can inspect
|
|
41
|
+
`ldd`; on macOS it adds `@loader_path` rpath and can inspect `otool -L`. Load
|
|
42
|
+
failures are wrapped with platform-specific dependency hints.
|
|
43
|
+
|
|
37
44
|
The core C++ source and header are not stored as permanent generated copies in
|
|
38
45
|
this subproject. The custom Poetry build backend syncs them from the repository
|
|
39
46
|
root during `poetry build`, embeds them in the wheel and sdist, then removes the
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
cpp_pd_code_simplify_interface/__init__.py,sha256=aaNwD--zgQX13xiU1hpuvgXy8vVTFGRk-r5zLm8zIRY,447
|
|
2
2
|
cpp_pd_code_simplify_interface/__main__.py,sha256=fdA1QWBe5LNX0fbtaJXa1-dwEhrg_4sS_5UnjaajcMo,80
|
|
3
|
-
cpp_pd_code_simplify_interface/main.py,sha256=
|
|
3
|
+
cpp_pd_code_simplify_interface/main.py,sha256=4t-6xvjQjsuEWP_oiwedGtgrLYu3316uATrl9t4Q8zs,32778
|
|
4
4
|
cpp_pd_code_simplify_interface/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
5
|
-
cpp_pd_code_simplify_interface-0.1.
|
|
6
|
-
cpp_pd_code_simplify_interface-0.1.
|
|
7
|
-
cpp_pd_code_simplify_interface-0.1.
|
|
5
|
+
cpp_pd_code_simplify_interface-0.1.8.dist-info/entry_points.txt,sha256=ThorC4Enxp317TKITsXm9pE0gUp7pt-pP6Dl5mEPUR8,91
|
|
6
|
+
cpp_pd_code_simplify_interface-0.1.8.dist-info/METADATA,sha256=BApOUJ3sW3u7ULBD8YuI-YMPtkABDLbB-ayxVZonDKE,3726
|
|
7
|
+
cpp_pd_code_simplify_interface-0.1.8.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
|
|
8
8
|
cpp_pd_code_simplify_interface/data/include/pdcode_simplify/pdcode_simplify.hpp,sha256=h5aob9gqRq8Gz2Hs4ePzyoRAXFCIGRBShlRw3TxQ7wQ,4843
|
|
9
9
|
cpp_pd_code_simplify_interface/data/src/native_interface.cpp,sha256=yXUJ0LHZDqz7WgFTwsq0U9pddH0KFTiOPr5sNyj7o1Y,6549
|
|
10
10
|
cpp_pd_code_simplify_interface/data/src/pdcode_simplify.cpp,sha256=hXBEDQQC3C2KlHlKTbmuKqC3l48XF5p76iODfMqolWQ,88691
|
|
11
|
-
cpp_pd_code_simplify_interface-0.1.
|
|
11
|
+
cpp_pd_code_simplify_interface-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|