Support native macOS speech relocation and safe indexing
This commit is contained in:
1 parent
9a93ee6375
commit
5b93dd67a7
8 files changed
+287
-14
No files matched your search
@@ -33,6 +33,11 @@ else()
|
||||
set(GGML_METAL OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
if(APPLE AND NOT SEARCHI_INTERNAL_CPU)
|
||||
# Every dylib/backend must resolve beside the installed worker, without the build tree.
|
||||
set(CMAKE_INSTALL_RPATH "@loader_path")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE AND NOT SEARCHI_INTERNAL_CPU)
|
||||
# The staged worker and every dynamic backend live together. RUNPATH is
|
||||
# non-transitive, so each shared target needs its own relocatable lookup.
|
||||
@@ -51,7 +56,7 @@ if(MSVC)
|
||||
target_compile_options(searchi-speech-worker PRIVATE /utf-8)
|
||||
endif()
|
||||
if(APPLE)
|
||||
set_target_properties(searchi-speech-worker PROPERTIES BUILD_RPATH "$ORIGIN;@loader_path" INSTALL_RPATH "$ORIGIN;@loader_path")
|
||||
set_target_properties(searchi-speech-worker PROPERTIES BUILD_RPATH "@loader_path" INSTALL_RPATH "@loader_path")
|
||||
elseif(UNIX)
|
||||
set_target_properties(searchi-speech-worker PROPERTIES BUILD_RPATH "$ORIGIN" INSTALL_RPATH "$ORIGIN")
|
||||
endif()
|
||||
@@ -0,0 +1,30 @@
|
||||
"""Check installed Mac speech linkage and real recognition of an owned PCM fixture."""
|
||||
import argparse,json,struct,subprocess
|
||||
from pathlib import Path
|
||||
|
||||
def check_runtime(runtime):
|
||||
names={p.name for p in runtime.iterdir() if p.is_file()}
|
||||
for p in runtime.iterdir():
|
||||
if not p.is_file() or not (p.name=='searchi-speech-worker' or p.suffix in {'.dylib','.so'}):continue
|
||||
loads=subprocess.check_output(['otool','-L',str(p)],text=True).splitlines()[1:]
|
||||
for line in loads:
|
||||
dep=line.strip().split(' (',1)[0]
|
||||
assert dep.startswith(('/System/Library/','/usr/lib/')) or dep.startswith('@rpath/') and Path(dep).name in names,(p.name,dep)
|
||||
meta=subprocess.check_output(['otool','-l',str(p)],text=True).splitlines()
|
||||
paths=[meta[i+2].strip().split(' (',1)[0].removeprefix('path ')for i,l in enumerate(meta)if l.strip()=='cmd LC_RPATH']
|
||||
assert paths and all(x=='@loader_path' for x in paths),(p.name,paths)
|
||||
|
||||
def frames(raw):
|
||||
out=[]
|
||||
while raw:
|
||||
assert len(raw)>=4
|
||||
n=struct.unpack('<I',raw[:4])[0];assert 0<n<=4*1024*1024 and len(raw)>=4+n
|
||||
out.append(json.loads(raw[4:4+n]));raw=raw[4+n:]
|
||||
return out
|
||||
|
||||
if __name__=='__main__':
|
||||
a=argparse.ArgumentParser();a.add_argument('--runtime',type=Path,required=True);a.add_argument('--models',type=Path,required=True);a.add_argument('--pcm',type=Path,required=True);a.add_argument('--output',type=Path,required=True);args=a.parse_args();check_runtime(args.runtime)
|
||||
pcm=args.pcm.read_bytes();assert len(pcm)%4==0 and 0<len(pcm)//4<=480000
|
||||
command=[str(args.runtime/'searchi-speech-worker'),str(args.models/'ggml-base.bin'),str(args.models/'ggml-silero-v6.2.0.bin'),'auto']
|
||||
result=subprocess.run(command,input=b'\x02'+struct.pack('<I',len(pcm)//4)+pcm,capture_output=True,timeout=180,check=True)
|
||||
messages=frames(result.stdout);assert len(messages)==2 and messages[0]['ready'] and messages[0]['distribution_auto'];assert messages[1]['ok'];text=' '.join(x.get('text','')for x in messages[1].get('sentences',[])).lower();assert 'free' in text and 'equal' in text,text;args.output.write_text(json.dumps(messages,indent=2));print('PASS: installed @loader_path closure and actual recognition; backend',messages[1].get('backend_observed'))
|
||||
Reference in new issue
Block a user