zmwangx / rust-ffmpeg

Safe FFmpeg wrapper.
Do What The F*ck You Want To Public License
1.2k stars 195 forks source link

Can't build on macos 13.4: ld: symbol(s) not found for architecture x86_64 #158

Open sujaymansingh opened 11 months ago

sujaymansingh commented 11 months ago

I'm on MacOS 13.4 (22F66)

I'm trying to use ffmpeg-next to build a video from a series of image files.

I can get ffmpeg-next = { version = "6.0.0", features = ["build"] } to build, but then I don't have any h264 capabilities. (Most examples, and the libraries that sit on top of this, e.g. video-rs, use h264)

If I add ffmpeg-next = { version = "6.0.0", features = ["build", "codec", "build-license-gpl", "build-lib-x264"] } I get the following when I build:

...
  = note: ld: warning: could not create compact unwind for _ff_rl_init_vlc: stack subq instruction is too different from dwarf stack size
          Undefined symbols for architecture x86_64:
            "_x264_param_cleanup", referenced from:
                _X264_close in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_close", referenced from:
                _X264_close in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_picture_init", referenced from:
                _X264_frame in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_reconfig", referenced from:
                _X264_frame in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_encode", referenced from:
                _X264_frame in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_param_default", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_param_apply_fastfirstpass", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_levels", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_open_164", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_param_default_preset", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_param_apply_profile", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_param_parse", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
                _parse_opts in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_delayed_frames", referenced from:
                _X264_frame in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_headers", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
            "_x264_encoder_maximum_delayed_frames", referenced from:
                _X264_init in libffmpeg_sys_next-1911200132984294.rlib(libx264.o)
          ld: symbol(s) not found for architecture x86_64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

This looks like I have something pretty fundamental missing, but I am not sure where to look. (I have ffmpeg 6 installed via homebrew)

Anyone have any ideas or pointers?

dashuai009 commented 4 months ago

I have encountered the same problem, have you solved it?

dashuai009 commented 1 month ago

I have found two solutions.

  1. Add extern crate ffmpeg_next; at the top of your binary.

    https://github.com/huggingface/candle?tab=readme-ov-file#missing-symbols-when-compiling-with-the-mkl-feature

Or add such .cargo/config.toml

[target.x86_64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]

[target.aarch64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]
  1. Add pkg-config to your build.rs

    extern crate pkg_config;
    fn main() {
    let mut config = pkg_config::Config::new();
    config.statik(true).probe("x264").unwrap();
    
    config.statik(true).probe("dav1d").unwrap();
    // config.statik(true).probe("aom").unwrap();
    // config.statik(true).probe("opencore-amrwb").unwrap();
    //
    // config.statik(true).probe("snappy").unwrap(); 
    config.statik(true).probe("x265").unwrap();
    config.statik(true).probe("vpx").unwrap();
    }

This will work on macos.

darmie commented 1 month ago

@dashuai009 I could not get this to work on MacOS Sonoma M1 Pro.

I have found two solutions.

  1. Add extern crate ffmpeg_next; at the top of your binary. https://github.com/huggingface/candle?tab=readme-ov-file#missing-symbols-when-compiling-with-the-mkl-feature

Or add such .cargo/config.toml

[target.x86_64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]

[target.aarch64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]
  1. Add pkg-config to your build.rs
extern crate pkg_config;
fn main() {
    let mut config = pkg_config::Config::new();
    config.statik(true).probe("x264").unwrap();

    config.statik(true).probe("dav1d").unwrap();
    // config.statik(true).probe("aom").unwrap();
    // config.statik(true).probe("opencore-amrwb").unwrap();
    //
    // config.statik(true).probe("snappy").unwrap(); 
    config.statik(true).probe("x265").unwrap();
    config.statik(true).probe("vpx").unwrap();
}

This will work on macos.

I have found two solutions.

  1. Add extern crate ffmpeg_next; at the top of your binary. https://github.com/huggingface/candle?tab=readme-ov-file#missing-symbols-when-compiling-with-the-mkl-feature

Or add such .cargo/config.toml

[target.x86_64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]

[target.aarch64-apple-darwin]
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]
  1. Add pkg-config to your build.rs
extern crate pkg_config;
fn main() {
    let mut config = pkg_config::Config::new();
    config.statik(true).probe("x264").unwrap();

    config.statik(true).probe("dav1d").unwrap();
    // config.statik(true).probe("aom").unwrap();
    // config.statik(true).probe("opencore-amrwb").unwrap();
    //
    // config.statik(true).probe("snappy").unwrap(); 
    config.statik(true).probe("x265").unwrap();
    config.statik(true).probe("vpx").unwrap();
}

This will work on macos.

dashuai009 commented 1 month ago

First, brew install ffmpeg pkg-config.

here is cargo.toml

[target.'cfg(windows)'.dependencies]
ffmpeg-next = { version = "7.0.1" }

[target.'cfg(not(windows))'.dependencies]
ffmpeg-next = { version = "7.0.1", default-features = false, features = [
    "format", "software-resampling",
    "build",
    "build-license-gpl", "build-license-nonfree", "build-license-version3"
], optional = true }

I used the feature build, it will pull ffmpeg source code from github and compile on your local.

Then, recommend to add extern crate ffmpeg_next on the top of binary/lib file.

This will be worked if you just use the default features of ffmpeg_next, including format, device, swr and so on.

If you want to use the avcodec, for example, x265. First

brew install x265

Then, add feature build-lib-x265 of ffmpeg_next in cargo.toml. Then, add pkg-config in buid.rs of your project like this,

extern crate pkg_config;
fn main() {
    let mut config = pkg_config::Config::new();
    config.statik(true).probe("x265").unwrap();
}
darmie commented 1 month ago

Thanks I'll try these.