MacOS-14 ARM M1编译FFmpeg依赖程序时找不到libavcodec/avcodec.h
问题概述
我编写的链接FFmpeg开发库的程序在ubuntu-22-x86-64、ubuntu-24-x86-64、macos-13-x86-64环境下运行正常,但在macos-14-arm-m1环境下编译失败。通过brew install ffmpeg安装FFmpeg后,执行编译命令时出现头文件找不到的错误,但手动设置C_INCLUDE_PATH、LD_LIBRARY_PATH等环境变量后编译可成功。疑惑为何ARM环境下需要手动设置,而x86环境下无需操作。
编译命令:
cc -fPIC -I/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/erts-14.2.5/include -Ic_src/xav -shared -undefined dynamic_lookup c_src/xav/xav_nif.c c_src/xav/reader.c c_src/xav/decoder.c c_src/xav/utils.c -o /Users/runner/work/xav/xav/_build/test/lib/xav/priv/libxav.so -lavcodec -lswscale -lavutil -lavformat -lavdevice -lswresample
报错信息:
In file included from c_src/xav/xav_nif.c:1: c_src/xav/decoder.h:1:10: fatal error: 'libavcodec/avcodec.h' file not found #include <libavcodec/avcodec.h> ^~~~~~~~~~~~~~~~~~~~~~ 1 error generated. In file included from c_src/xav/reader.c:1: c_src/xav/reader.h:1:10: fatal error: 'libavcodec/avcodec.h' file not found #include <libavcodec/avcodec.h> ^~~~~~~~~~~~~~~~~~~~~~ 1 error generated. In file included from c_src/xav/decoder.c:1: c_src/xav/decoder.h:1:10: fatal error: 'libavcodec/avcodec.h' file not found #include <libavcodec/avcodec.h> ^~~~~~~~~~~~~~~~~~~~~~ 1 error generated. In file included from c_src/xav/utils.c:1: c_src/xav/utils.h:2:10: fatal error: 'libavcodec/avcodec.h' file not found #include <libavcodec/avcodec.h> ^~~~~~~~~~~~~~~~~~~~~~
原因解析
你的理解在x86架构的macOS上是成立的,但ARM架构(M1/M2)的Homebrew安装路径和x86有差异:
- x86 macOS上,Homebrew默认安装到
/usr/local,这个路径是Clang编译器默认的头文件(/usr/local/include)和库文件(/usr/local/lib)搜索路径,所以无需手动指定。 - ARM macOS上,Homebrew默认安装到
/opt/homebrew,而这个路径不在Clang的默认搜索范围内,因此编译器无法自动找到FFmpeg的头文件和库文件,必须手动添加路径或通过工具自动获取参数。
这并非Homebrew的bug,而是苹果ARM架构下的路径规范导致的差异。
解决方案
方案1:使用pkg-config自动获取编译参数
pkg-config能自动读取FFmpeg的安装路径,生成对应的编译和链接参数,是跨架构的通用解决方案。修改编译命令如下:
cc -fPIC -I/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/erts-14.2.5/include -Ic_src/xav -shared -undefined dynamic_lookup c_src/xav/xav_nif.c c_src/xav/reader.c c_src/xav/decoder.c c_src/xav/utils.c -o /Users/runner/work/xav/xav/_build/test/lib/xav/priv/libxav.so $(pkg-config --cflags --libs ffmpeg)
pkg-config --cflags --libs ffmpeg会自动输出FFmpeg的头文件路径(-I/opt/homebrew/include)和库链接参数(-L/opt/homebrew/lib -lavcodec ...),无需手动维护路径。
方案2:手动添加ARM架构的Homebrew路径
在编译命令中直接指定FFmpeg的头文件和库文件路径:
cc -fPIC -I/opt/homebrew/Cellar/erlang/26.2.5/lib/erlang/erts-14.2.5/include -Ic_src/xav -I/opt/homebrew/include -shared -undefined dynamic_lookup c_src/xav/xav_nif.c c_src/xav/reader.c c_src/xav/decoder.c c_src/xav/utils.c -o /Users/runner/work/xav/xav/_build/test/lib/xav/priv/libxav.so -L/opt/homebrew/lib -lavcodec -lswscale -lavutil -lavformat -lavdevice -lswresample
添加-I/opt/homebrew/include让编译器找到头文件,-L/opt/homebrew/lib让链接器找到库文件。
总结
ARM macOS的Homebrew路径不在系统默认搜索范围内,因此需要通过pkg-config或手动添加路径来让编译器找到FFmpeg的文件。这种架构差异是正常的,并非包管理器的问题。
内容的提问来源于stack exchange,提问作者mikeProgrammer

