在使用 g++ 编译器链接 FFmpeg 的静态库时经常出现 Undefined symbols
错误。
编译命令示例如下:
g++ -o main main.cc -lavutil -lavcodec -lavformat -lavfilter -lavdevice;
错误示例如下:
Undefined symbols for architecture x86_64:
"_AudioObjectGetPropertyData", referenced from:
_at_write_header in libavdevice.a(audiotoolbox.o)
"_AudioObjectGetPropertyDataSize", referenced from:
_at_write_header in libavdevice.a(audiotoolbox.o)
这一般是因未指定对应的 framework
所致。
我们向上述编译命令中添加 -v
参数
g++ -v -o main main.cc -lavutil -lavcodec -lavformat -lavfilter -lavdevice;
执行后,会输出头文件的搜索路径,示例如下:
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
.
/usr/local/include
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1
/Library/Developer/CommandLineTools/usr/lib/clang/12.0.0/include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include
/Library/Developer/CommandLineTools/usr/include
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks (framework directory)
找出其中带有 framework directory
标记的目录,并进入。然后在其中搜索错误中的符号名称,如 _AudioObjectGetPropertyData
。示例命令如下:
cd /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks;
grep _AudioObjectGetPropertyData -Irsn *
grep
的输出示例如下:
CoreAudio.framework/CoreAudio.tbd:34: _AudioObjectExists, _AudioObjectGetPropertyData, _AudioObjectGetPropertyDataSize,
CoreAudio.framework/Versions/A/CoreAudio.tbd:34: _AudioObjectExists, _AudioObjectGetPropertyData, _AudioObjectGetPropertyDataSize,
CoreAudio.framework/Versions/Current/CoreAudio.tbd:34: _AudioObjectExists, _AudioObjectGetPropertyData, _AudioObjectGetPropertyDataSize,
将下图中 framework 的名称作为参数 -framework CoreAudio
添加至编译命令中即可解决找不到 _AudioObjectGetPropertyData
引发的错误。
编译命令示例如下:
g++ -o main main.cc -lavutil -lavcodec -lavformat -lavfilter -lavdevice -framework CoreAudio;