@@ -270,24 +270,25 @@ function stageFfmpegBinary(outDir, ffmpegDir) {
270270 throw new Error ( `${ to } links no ffmpeg dylib — nothing to rewrite, which is wrong.` ) ;
271271 }
272272 // The CLI links more of the SDK than the addon does (libavdevice, libpostproc, …).
273- // `vendorFfmpegDylibs` staged only what the addon needs, so copy anything still
274- // missing — with the same `@rpath/<name>` id and inter-library rewrites, so the
275- // chain resolves the same way the addon's set does.
276- const copied = [ ] ;
277- for ( const dep of deps ) {
273+ // Refresh every direct dependency, including files vendorFfmpegDylibs already staged.
274+ // The output directory persists between local builds, so keeping an existing file could
275+ // mix a new CLI with an old SDK dylib or preserve a half-rewritten file from an interrupted
276+ // run. Replacing the complete set also gives every file the same atomic-install guarantee
277+ // as the addon and CLI.
278+ const stagedLibraries = [ ] ;
279+ for ( const dep of new Set ( deps ) ) {
278280 const name = path . basename ( dep ) ;
279281 const staged = path . join ( outDir , name ) ;
280- if ( fs . existsSync ( staged ) ) continue ;
281282 const sdkLib = path . join ( ffmpegDir , "lib" , name ) ;
282283 if ( ! fs . existsSync ( sdkLib ) ) {
283284 throw new Error ( `Missing ${ sdkLib } ; the binary links it but the SDK does not ship it.` ) ;
284285 }
285- fs . copyFileSync ( sdkLib , staged ) ;
286+ installAtomically ( sdkLib , staged ) ;
286287 fs . chmodSync ( staged , 0o755 ) ;
287288 execFileSync ( "install_name_tool" , [ "-id" , `@rpath/${ name } ` , staged ] ) ;
288- copied . push ( staged ) ;
289+ stagedLibraries . push ( staged ) ;
289290 }
290- for ( const file of [ ...copied , to ] ) {
291+ for ( const file of [ ...stagedLibraries , to ] ) {
291292 const fileDeps = execFileSync ( "otool" , [ "-L" , file ] , { encoding : "utf8" } )
292293 . split ( "\n" )
293294 . map ( ( line ) => line . trim ( ) . split ( " " ) [ 0 ] )
@@ -300,12 +301,14 @@ function stageFfmpegBinary(outDir, ffmpegDir) {
300301 execFileSync ( "codesign" , [ "--force" , "--sign" , "-" , file ] ) ;
301302 }
302303
303- const remaining = absolutePaths ( to ) ;
304- if ( remaining . length > 0 ) {
305- throw new Error (
306- `${ path . basename ( to ) } still references build-machine paths after rewriting: ` +
307- remaining . join ( ", " ) ,
308- ) ;
304+ for ( const file of [ ...stagedLibraries , to ] ) {
305+ const remaining = absolutePaths ( file ) ;
306+ if ( remaining . length > 0 ) {
307+ throw new Error (
308+ `${ path . basename ( file ) } still references build-machine paths after rewriting: ` +
309+ remaining . join ( ", " ) ,
310+ ) ;
311+ }
309312 }
310313 console . log ( `Staged ffmpeg binary at ${ to } (rewritten to @rpath beside the vendored dylibs)` ) ;
311314}
0 commit comments