@@ -83,6 +83,75 @@ fn stage_macos(manifest_dir: &Path, skip_existing: bool) -> Result<(), String> {
8383 let _ = fs:: set_permissions ( & dest, perms) ;
8484 }
8585 }
86+
87+ rewrite_macos_install_names ( & frameworks, & names, & prefix) ?;
88+ Ok ( ( ) )
89+ }
90+
91+ fn rewrite_macos_install_names (
92+ frameworks : & Path ,
93+ names : & [ & str ] ,
94+ brew_prefix : & Path ,
95+ ) -> Result < ( ) , String > {
96+ for name in names {
97+ let dest = frameworks. join ( name) ;
98+ let new_id = format ! ( "@executable_path/../Frameworks/{name}" ) ;
99+ run_install_name_tool ( & [ "-id" , & new_id, dest. to_str ( ) . unwrap ( ) ] ) ?;
100+
101+ let output = Command :: new ( "otool" )
102+ . args ( [ "-L" , dest. to_str ( ) . unwrap ( ) ] )
103+ . output ( )
104+ . map_err ( |e| format ! ( "otool -L {}: {e}" , dest. display( ) ) ) ?;
105+ if !output. status . success ( ) {
106+ return Err ( format ! (
107+ "otool -L {} failed: {}" ,
108+ dest. display( ) ,
109+ String :: from_utf8_lossy( & output. stderr)
110+ ) ) ;
111+ }
112+ let listing = String :: from_utf8_lossy ( & output. stdout ) . into_owned ( ) ;
113+ for dep in names {
114+ if dep == name {
115+ continue ;
116+ }
117+ for line in listing. lines ( ) {
118+ let trimmed = line. trim ( ) ;
119+ let path = trimmed. split_whitespace ( ) . next ( ) . unwrap_or ( "" ) ;
120+ if path. is_empty ( ) || path == dest. to_str ( ) . unwrap ( ) {
121+ continue ;
122+ }
123+ if path. ends_with ( & format ! ( "/{dep}" ) )
124+ && ( path. starts_with ( brew_prefix. to_str ( ) . unwrap_or ( "" ) )
125+ || path. starts_with ( "/usr/local/" )
126+ || path. starts_with ( "/opt/homebrew/" )
127+ || path. starts_with ( "@loader_path" )
128+ || path. starts_with ( "@rpath" ) )
129+ {
130+ let new_dep = format ! ( "@executable_path/../Frameworks/{dep}" ) ;
131+ run_install_name_tool ( & [ "-change" , path, & new_dep, dest. to_str ( ) . unwrap ( ) ] ) ?;
132+ }
133+ }
134+ }
135+
136+ let _ = Command :: new ( "codesign" )
137+ . args ( [ "--force" , "--sign" , "-" , dest. to_str ( ) . unwrap ( ) ] )
138+ . status ( ) ;
139+ }
140+ Ok ( ( ) )
141+ }
142+
143+ fn run_install_name_tool ( args : & [ & str ] ) -> Result < ( ) , String > {
144+ let output = Command :: new ( "install_name_tool" )
145+ . args ( args)
146+ . output ( )
147+ . map_err ( |e| format ! ( "install_name_tool {:?}: {e}" , args) ) ?;
148+ if !output. status . success ( ) {
149+ return Err ( format ! (
150+ "install_name_tool {:?} failed: {}" ,
151+ args,
152+ String :: from_utf8_lossy( & output. stderr)
153+ ) ) ;
154+ }
86155 Ok ( ( ) )
87156}
88157
0 commit comments