-
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_PATH
andLD_LIBRARY_PATH
variables as well as symlinking to the correct binary in alibsodium
library 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.dmg
I build after makingflet build macos
.Here's sample code of what I had to do to get
pysodium
to load mylibsodium
dynamic library from thelibsodium/
directory in my repository.