MATLAB:mex-compile 上缺少框架 – 架构 x86_64 的未定义符号
Posted
技术标签:
【中文标题】MATLAB:mex-compile 上缺少框架 – 架构 x86_64 的未定义符号【英文标题】:MATLAB: Missing Frameworks on mex-compile – Undefined symbols for architecture x86_64 【发布时间】:2012-03-30 20:38:05 【问题描述】:我一直在努力解决在编译用 C(在 Mac OS X 上)编写的 MATLAB 函数时遇到的一些错误。 msound 函数是我的大学为 Windows 和 Linux 预编译的,它是有关音频录制和播放的一些进一步功能的基础。因为我是 Mac 用户,所以我认为将它编译成 Mac 版本也很不错。
从源代码及其适用于 Linux 的编译器函数中,我尝试对编译器指令的 Mac 版本进行逆向工程,但我不断收到错误,导致编译失败。到目前为止,这是我作为编译器函数汇总的内容:
function compile_msound_unix
disp('Building msound ...')
szOptions = '';
szDefines = '';
szPaths = '';
szFiles = '';
szLibs = '';
szOptions = sprintf( '%s %s', szOptions, '-output msound' );
szOptions = sprintf( '%s %s', szOptions, '-largeArrayDims' );
% Add main file.
szFiles = addFile( szFiles, 'msound.c' );
% Add basic PortAudio include paths and files.
szPaths = addPath( szPaths, 'portaudio/include' );
szPaths = addPath( szPaths, 'portaudio/src/common' );
szPaths = addPath( szPaths, 'portaudio/src/os/unix' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_allocation.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_converters.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_cpuload.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_debugprint.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_dither.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_front.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_process.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_ringbuffer.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_skeleton.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_stream.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_trace.c' );
% Host
szFiles = addFile( szFiles, 'portaudio/src/os/unix/pa_unix_hostapis.c' );
szFiles = addFile( szFiles, 'portaudio/src/os/unix/pa_unix_util.c' );
% Add PortAudio path for: Apple Core Audio API
disp(' Using ''Apple Core Audio API'' ...')
% Defines
szDefines = addDefine( szDefines, 'PA_USE_COREAUDIO' );
szDefines = addDefine( szDefines, '__MACOSX_CORE__');
% PortAudio
szPaths = addPath( szPaths, 'portaudio/src/hostapi/coreaudio' );
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c' );
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c' );
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core.c' );
% Libs
% szLibs = addLib ( szLibs , '/full/path/to/library?' );
% Build msound MEX-file using default compiler.
eval( [ 'mex', szOptions, szDefines, szPaths, szFiles, szLibs ] );
function szCmd = addFile ( szCmd, szFile )
szCmd = sprintf( '%s "%s"' , szCmd, szFile );
function szCmd = addPath ( szCmd, szPath )
szCmd = sprintf( '%s "-I%s"', szCmd, szPath );
function szCmd = addDefine( szCmd, szName )
szCmd = sprintf( '%s "-D%s"', szCmd, szName );
function szCmd = addLib ( szCmd, szLib )
szCmd = sprintf( '%s "-l%s"', szCmd, szLib );
function szCmd = addLibPath( szCmd, szPath )
szCmd = sprintf( '%s "-L%s"', szCmd, szPath )
我已经消除了一些其他错误,但现在我遇到了以下 MATLAB 控制台输出:
Building msound ...
Using 'Apple Core Audio API' ...
msound.c: In function 'msoundDeviceInfo':
msound.c:3042: warning: initialization makes pointer from integer without a cast
msound.c:3044: warning: initialization makes pointer from integer without a cast
msound.c:3046: warning: initialization makes pointer from integer without a cast
msound.c:3048: warning: initialization makes pointer from integer without a cast
portaudio/src/hostapi/coreaudio/pa_mac_core.c: In function 'AudioIOProc':
portaudio/src/hostapi/coreaudio/pa_mac_core.c:1911: warning: 'AudioConverterFillBuffer' is deprecated (declared at /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AudioToolbox.framework/Headers/AudioConverter.h:641)
portaudio/src/hostapi/coreaudio/pa_mac_core.c:2080: warning: 'AudioConverterFillBuffer' is deprecated (declared at /Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/AudioToolbox.framework/Headers/AudioConverter.h:641)
Undefined symbols for architecture x86_64:
"_mxCreateScalarDouble", referenced from:
_msoundDeviceInfo in msound.o
"_AudioDeviceSetProperty", referenced from:
_setBestFramesPerBuffer in pa_mac_core_utilities.o
_AudioDeviceSetPropertyNowAndWaitForChange in pa_mac_core_utilities.o
(maybe you meant: _AudioDeviceSetPropertyNowAndWaitForChange)
"_AudioDeviceGetProperty", referenced from:
_setBestFramesPerBuffer in pa_mac_core_utilities.o
_AudioDeviceSetPropertyNowAndWaitForChange in pa_mac_core_utilities.o
_setBestSampleRateForDevice in pa_mac_core_utilities.o
_GetChannelInfo in pa_mac_core.o
_PaMacCore_Initialize in pa_mac_core.o
_OpenStream in pa_mac_core.o
_PaMacCore_GetChannelName in pa_mac_core.o
...
"_AudioDeviceGetPropertyInfo", referenced from:
_setBestFramesPerBuffer in pa_mac_core_utilities.o
_setBestSampleRateForDevice in pa_mac_core_utilities.o
_GetChannelInfo in pa_mac_core.o
_PaMacCore_Initialize in pa_mac_core.o
_PaMacCore_GetChannelName in pa_mac_core.o
"_AudioDeviceAddPropertyListener", referenced from:
_AudioDeviceSetPropertyNowAndWaitForChange in pa_mac_core_utilities.o
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioDeviceRemovePropertyListener", referenced from:
_AudioDeviceSetPropertyNowAndWaitForChange in pa_mac_core_utilities.o
_CloseStream in pa_mac_core.o
"_AudioHardwareGetPropertyInfo", referenced from:
_PaMacCore_Initialize in pa_mac_core.o
"_AudioHardwareGetProperty", referenced from:
_PaMacCore_Initialize in pa_mac_core.o
"_AudioUnitUninitialize", referenced from:
_CloseStream in pa_mac_core.o
"_CloseComponent", referenced from:
_CloseStream in pa_mac_core.o
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioConverterDispose", referenced from:
_CloseStream in pa_mac_core.o
"_AudioConverterReset", referenced from:
_StartStream in pa_mac_core.o
"_AudioOutputUnitStart", referenced from:
_StartStream in pa_mac_core.o
"_AudioOutputUnitStop", referenced from:
_StopStream in pa_mac_core.o
_AudioIOProc in pa_mac_core.o
"_AudioUnitGetProperty", referenced from:
_StopStream in pa_mac_core.o
_startStopCallback in pa_mac_core.o
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioUnitReset", referenced from:
_StopStream in pa_mac_core.o
"_AudioDeviceGetCurrentTime", referenced from:
_GetStreamTime in pa_mac_core.o
_AudioIOProc in pa_mac_core.o
"_FindNextComponent", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_OpenAComponent", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioUnitSetProperty", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioUnitAddPropertyListener", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioConverterNew", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioConverterSetProperty", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioUnitInitialize", referenced from:
_OpenAndSetupOneAudioUnit in pa_mac_core.o
"_AudioUnitRender", referenced from:
_AudioIOProc in pa_mac_core.o
"_AudioConverterFillBuffer", referenced from:
_AudioIOProc in pa_mac_core.o
"_CFStringCreateWithFormat", referenced from:
_PaMacCore_GetChannelName in pa_mac_core.o
"_CFStringGetLength", referenced from:
_PaMacCore_GetChannelName in pa_mac_core.o
"_CFStringGetCString", referenced from:
_PaMacCore_GetChannelName in pa_mac_core.o
"_CFRelease", referenced from:
_PaMacCore_GetChannelName in pa_mac_core.o
"___CFConstantStringClassReference", referenced from:
CFString in pa_mac_core.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
mex: link of ' "msound.mexmaci64"' failed.
??? Error using ==> mex at 208
Unable to complete successfully.
Error in ==> compile_msound_unix at 51
eval( [ 'mex', szOptions, szDefines, szPaths, szFiles, szLibs ] );
主要问题似乎是 Undefined symbols for architecture x86_64
。我对此做了一些研究,我现在知道可能缺少一些框架。但我对这种编程(以及在 Mac 上编译)非常陌生,我需要一些帮助。
我尝试编译的函数是基于Mac上支持CoreAudio的PortAudioAudio-I/O。正如您在我的编译器函数中看到的那样,我已经包含了必要的 PortAudio 文件,但我仍然缺少相应的库/框架。我已经尝试为他们提供如下行:
szLibs = addLib ( szLibs , '/System/Library/Frameworks/CoreAudio.framework' );
但没有任何成功。我真的希望你们有想法如何让这个运行。我正在使用 Mac OS X 10.7.3 Lion,并且安装了 Xcode 并且 gcc-4.2 正在运行。 MATLAB 版本为 2011a (v7.12)
提前致谢,Jan。
【问题讨论】:
所以我继续解决问题并修复了第 3042、3044、3046 和 3048 行的警告:它们是由mxCreateScalarDouble
创建的,在 MATLAB 6.5 中被 mxCreateDoubleScalar
函数替换,并且已经在我的版本中删除。所以它和第一个丢失的符号一起消失了,这是由于前面提到的 mxCreateDoubleScalar
的替换引起的。
【参考方案1】:
赫里卡!我终于自己发现了:由于我只是从 msound 的 Linux mex-compiling-function 中提取了很多代码,因此问题在于如何链接必要的框架。事实证明路径和文件中的" ... "
(双引号)无法正常工作,只有框架真正需要它们,因为它们会传递给gcc。我从addFile
、addPath
等中删除了它们,最后所有文件都被识别并链接了框架,因此所有丢失的符号都消失了。我的顿悟主要是由this *** question 发起的,特别是它的正确答案。
如果有兴趣,这里是完整的编译器函数:
function compile_msound_mac
bOldMexApi = false;
disp('Building msound ...')
szOptions = '';
szDefines = '';
szPaths = '';
szFiles = '';
szFrameworks = 'LDFLAGS="\$LDFLAGS';
szOptions = sprintf( '%s %s', szOptions, '-output msound' );
% Use the old MATLAB C API on newer MATLAB versions.
if( ~verLessThan('matlab','7.3') )
if( bOldMexApi )
% Use backward compatible old MATLAB C API
szOptions = sprintf( '%s %s', szOptions, '-compatibleArrayDims' );
else
szOptions = sprintf( '%s %s', szOptions, '-largeArrayDims' );
end
end
% Add main file.
szFiles = addFile( szFiles, 'msound.c' );
% Add basic PortAudio include paths and files.
szPaths = addPath( szPaths, 'portaudio/include' );
szPaths = addPath( szPaths, 'portaudio/src/common' );
szPaths = addPath( szPaths, 'portaudio/src/os/unix' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_allocation.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_converters.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_cpuload.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_debugprint.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_dither.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_front.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_process.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_ringbuffer.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_skeleton.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_stream.c' );
szFiles = addFile( szFiles, 'portaudio/src/common/pa_trace.c' );
% Host
szFiles = addFile( szFiles, 'portaudio/src/os/unix/pa_unix_hostapis.c' );
szFiles = addFile( szFiles, 'portaudio/src/os/unix/pa_unix_util.c' );
% Add PortAudio path for: Apple Core Audio API
disp(' Using ''Apple Core Audio API'' ...')
% Defines
szDefines = addDefine( szDefines, 'PA_USE_COREAUDIO' );
szDefines = addDefine( szDefines, '__MACOSX_CORE__');
% PortAudio
szPaths = addPath( szPaths, 'portaudio/src/hostapi/coreaudio' );
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c' );
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c');
szFiles = addFile( szFiles, 'portaudio/src/hostapi/coreaudio/pa_mac_core.c ' );
% Frameworks
szFrameworks = addFramework ( szFrameworks , 'CoreAudio' );
szFrameworks = addFramework ( szFrameworks , 'AudioToolbox' );
szFrameworks = addFramework ( szFrameworks , 'AudioUnit' );
szFrameworks = addFramework ( szFrameworks , 'CoreServices' );
%
%
% % Closing Tag for Frameworks
szFrameworks = sprintf('%s"', szFrameworks);
% Build msound MEX-file using default compiler.
eval( [ 'mex', szOptions, szDefines, szPaths, szFiles , szFrameworks ] )
disp('Done.')
function szCmd = addFile ( szCmd, szFile )
szCmd = sprintf( '%s %s' , szCmd, szFile );
function szCmd = addPath ( szCmd, szPath )
szCmd = sprintf( '%s -I%s', szCmd, szPath );
function szCmd = addDefine( szCmd, szName )
szCmd = sprintf( '%s -D%s', szCmd, szName );
function szCmd = addFramework( szCmd, szFramework)
szCmd = sprintf( '%s -framework %s', szCmd, szFramework);
【讨论】:
以上是关于MATLAB:mex-compile 上缺少框架 – 架构 x86_64 的未定义符号的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB 无效的 MEX 文件错误:缺少符号 invalid_argument