Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions scripts/build_local_artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import os
import sys
import runpy
import shutil
import argparse
import platform
Expand All @@ -43,12 +44,11 @@
# Where the package loads the library from at runtime for an editable install.
PACKAGE_LIBS_DIR = Path("src/c2pa/libs")

# Library file name per OS (matches what setup.py/lib.py load at runtime).
LIB_NAMES = {
"darwin": "libc2pa_c.dylib",
"linux": "libc2pa_c.so",
"windows": "c2pa_c.dll",
}
# Library file name per sys.platform, loaded by path: importing the c2pa
# package would load the native library.
LIB_NAMES = runpy.run_path(
str(Path(__file__).resolve().parents[1] / "src/c2pa/_library_names.py")
)["LIBRARY_NAMES"]


def get_platform_identifier():
Expand Down Expand Up @@ -180,7 +180,7 @@ def build_native(c2pa_rs_path, debug=False):
"""Build the FFI crate for the host arch. Returns the built library path."""
profile = "debug" if debug else "release"
run_cargo(c2pa_rs_path, debug=debug)
lib_name = LIB_NAMES[platform.system().lower()]
lib_name = LIB_NAMES[sys.platform]
lib = c2pa_rs_path / "target" / profile / lib_name
if not lib.is_file():
print(f"Error: expected built library not found: {lib}")
Expand Down
18 changes: 11 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from setuptools import setup, find_namespace_packages
import sys
import platform
import runpy
import shutil
from pathlib import Path
import toml
Expand All @@ -26,16 +27,19 @@ def get_version():
VERSION = get_version()
PACKAGE_NAME = "c2pa-python" # Define package name as a constant

# Loaded by path: importing the c2pa package would load the native library
LIBRARY_NAMES = runpy.run_path("src/c2pa/_library_names.py")["LIBRARY_NAMES"]

# Based on what c2pa-rs repo publishes: each platform folder and the
# native library in it that src/c2pa/lib.py loads
PLATFORM_FOLDERS = {
'universal-apple-darwin': 'libc2pa_c.dylib',
'aarch64-apple-darwin': 'libc2pa_c.dylib',
'x86_64-apple-darwin': 'libc2pa_c.dylib',
'x86_64-pc-windows-msvc': 'c2pa_c.dll',
'aarch64-pc-windows-msvc': 'c2pa_c.dll',
'x86_64-unknown-linux-gnu': 'libc2pa_c.so',
'aarch64-unknown-linux-gnu': 'libc2pa_c.so',
'universal-apple-darwin': LIBRARY_NAMES['darwin'],
'aarch64-apple-darwin': LIBRARY_NAMES['darwin'],
'x86_64-apple-darwin': LIBRARY_NAMES['darwin'],
'x86_64-pc-windows-msvc': LIBRARY_NAMES['win32'],
'aarch64-pc-windows-msvc': LIBRARY_NAMES['win32'],
'x86_64-unknown-linux-gnu': LIBRARY_NAMES['linux'],
'aarch64-unknown-linux-gnu': LIBRARY_NAMES['linux'],
}

# Directory structure
Expand Down
21 changes: 21 additions & 0 deletions src/c2pa/_library_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""File names of the native c2pa library, keyed by sys.platform.

Standard library only: setup.py and scripts/build_local_artifacts.py load
this file by path, because importing the c2pa package loads the library.
"""

import sys

LIBRARY_NAMES = {
"darwin": "libc2pa_c.dylib",
"linux": "libc2pa_c.so",
"win32": "c2pa_c.dll",
}


def get_library_name() -> str:
"""Return the native library file name for the running platform."""
library_name = LIBRARY_NAMES.get(sys.platform)
if library_name is None:
raise RuntimeError(f"Unsupported platform: {sys.platform}")
return library_name
8 changes: 2 additions & 6 deletions src/c2pa/c2pa.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from typing import Optional, Union, Callable, Any, overload
import io
from .lib import dynamically_load_library, record_owner_pid, is_foreign_process
from ._library_names import get_library_name
import mimetypes
from itertools import count

Expand Down Expand Up @@ -144,12 +145,7 @@ def _validate_library_exports(lib):


# Determine the library name based on the platform
if sys.platform == "win32": # pragma: no cover
_lib_name_default = "c2pa_c.dll"
elif sys.platform == "darwin": # pragma: no cover
_lib_name_default = "libc2pa_c.dylib"
else: # pragma: no cover
_lib_name_default = "libc2pa_c.so"
_lib_name_default = get_library_name()

# Check for C2PA_LIBRARY_NAME environment variable
env_lib_name = os.environ.get("C2PA_LIBRARY_NAME")
Expand Down
11 changes: 3 additions & 8 deletions src/c2pa/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from typing import Optional
from enum import Enum

from ._library_names import get_library_name

# Debug flag for library loading
DEBUG_LIBRARY_LOADING = False

Expand Down Expand Up @@ -219,14 +221,7 @@ def dynamically_load_library(
Returns:
The loaded library or None if loading failed
"""
if sys.platform == "darwin":
c2pa_lib_name = "libc2pa_c.dylib"
elif sys.platform == "linux":
c2pa_lib_name = "libc2pa_c.so"
elif sys.platform == "win32":
c2pa_lib_name = "c2pa_c.dll"
else:
raise RuntimeError(f"Unsupported platform: {sys.platform}")
c2pa_lib_name = get_library_name()

if DEBUG_LIBRARY_LOADING: # pragma: no cover
logger.info(f"Current working directory: {Path.cwd()}")
Expand Down
Loading