-
Package DetailsThis is a very simple wrapper around libsodium (written in C) masquerading as nacl. Github: stef/pysodium Important consideration:Pysodium uses the system library installed to In order to pass MacOS Gatekeeper checks the The request here is to include Pysodium as a statically linked binary, or if that is not possible, some standard way to tell Pysodium in a Flet app where the signed Relevant issues and discussionsSee this Flutter issue and this Flet issue discussing packaging that includes links to native libraries like this. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
|
I was able to get a workaround functional for pysodium by modifying the This works because the entire app repo is copied to the app cache directory of Here's sample code of what I had to do to get ################################# Custom Libsodium Loader ############################################
# This code has to be in the main module to avoid a partially initialized module error
# for the main app module.
def load_custom_libsodium(appdir):
"""
Instruct the pysodium library to load a custom libsodium dylib from the appdir/libsodium
"""
set_load_path_or_link(appdir)
set_load_env_vars(appdir)
custom_path = os.path.expanduser(f'{os.path.dirname(os.path.abspath(__file__))}/libsodium/libsodium.dylib')
logger.info(f'Loading custom libsodium from {custom_path}')
if os.path.exists(custom_path):
logger.info(f'Found custom libsodium at {custom_path}')
sodium = ctypes.cdll.LoadLibrary(custom_path)
else:
logger.info('Custom libsodium not found, loading from system')
libsodium_path = find_library('sodium')
if libsodium_path is not None:
logger.info(f'Found libsodium at {libsodium_path}')
sodium = ctypes.cdll.LoadLibrary(libsodium_path)
logger.info(f'Loaded libsodium from {libsodium_path}')
else:
raise OSError('libsodium not found')
def set_load_path_or_link(appdir):
"""
Symlinks the correct libsodium dylib based on the architecture of the system.
"""
lib_home = f'{appdir}/libsodium'
arch = platform.processor()
if platform.system() == 'Windows':
match arch:
case 'x86' | 'i386' | 'i486' | 'i586' | 'i686':
sodium_lib = 'libsodium.26.x32.dll'
case 'AMD64' | 'x86_64':
sodium_lib = 'libsodium.26.x64.dll'
case _:
raise OSError(f'Unsupported Windows architecture: {arch}')
elif platform.system() == 'Darwin':
match platform.processor():
case 'x86_64':
sodium_lib = 'libsodium.26.x86_64.dylib'
case 'arm' | 'arm64' | 'aarch64':
sodium_lib = 'libsodium.23.arm.dylib'
# doesn't work
case 'i386':
sodium_lib = 'libsodium.23.i386.dylib'
case _:
raise OSError(f'Unsupported architecture: {platform.processor()}')
else:
# Linux and other Unix-like systems
sodium_lib = 'libsodium.so.23' # not yet supported
raise OSError(f'Unsupported architecture: {platform.processor()}')
lib_path = Path(os.path.join(lib_home, sodium_lib))
logger.info(f'Arch: {platform.processor()} Linking libsodium lib: {sodium_lib} at path: {lib_path}')
if platform.system() == 'Windows': # if windows just set the PATH
logger.info(f'Setting PATH to include {lib_path}')
os.environ['PATH'] = f'{lib_path};{os.environ["PATH"]}'
elif platform.system() == 'Darwin': # if macOS, symlink the dylib
if not lib_path.exists():
logger.error(f'libsodium for architecture {platform.processor()} missing at {lib_path}, cannot link')
raise FileNotFoundError(f'libsodium for architecture {platform.processor()} missing at {lib_path}')
link_path = Path(os.path.join(lib_home, 'libsodium.dylib'))
logger.info(f'Symlinking {lib_path} to {link_path}')
try:
os.symlink(f'{lib_path}', f'{link_path}')
except FileExistsError:
os.remove(f'{link_path}')
os.symlink(f'{lib_path}', f'{link_path}')
logger.info(f'Linked libsodium dylib: {link_path}')
def set_load_env_vars(appdir):
"""
Sets the DYLD_LIBRARY_PATH and LD_LIBRARY_PATH that pysodium uses to find libsodium to the custom libsodium dylib.
"""
if platform.system() == 'Windows':
return # Windows doesn't need this
local_path = appdir
logger.info(f'Setting DYLD_LIBRARY_PATH to {local_path}/libsodium')
os.environ['DYLD_LIBRARY_PATH'] = f'{local_path}/libsodium'
logger.info(f'Setting LD_LIBRARY_PATH to {local_path}/libsodium')
os.environ['LD_LIBRARY_PATH'] = f'{local_path}/libsodium'
################################### End Custom Libsodium Loader ######################################This is just for MacOS machines. I haven't tested the Windows support yet. Static linking would completely remove the need to do this dynamic module loading. |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for sharing the solution! (I will add more comments in the similar issue). |
Beta Was this translation helpful? Give feedback.
I was able to get a workaround functional for pysodium by modifying the
DYLD_LIBRARY_PATHandLD_LIBRARY_PATHvariables as well as symlinking to the correct binary in alibsodiumlibrary directory in my repository.This works because the entire app repo is copied to the app cache directory of
~/Library/Caches/myapp/app/when running the app from the.dmgI build after makingflet build macos.Here's sample code of what I had to do to get
pysodiumto load mylibsodiumdynamic library from thelibsodium/directory in my repository.