MATLAB: Отсутствие фреймворков в mex-compile - неопределенные символы для архитектуры x86_64 - PullRequest
1 голос
/ 31 марта 2012

Я пытался разобраться в некоторых ошибках, которые я получаю при компиляции функции MATLAB, написанной на C (в Mac OS X).Функция 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), и я мог бы использовать некоторую помощь.

Функция, которую я пытаюсь компилировать, основана на PortAudio Audio-I / O, который поддерживает CoreAudio на Mac.Как вы видите в моей функции компилятора, я уже включил необходимые файлы PortAudio, но мне все еще не хватает соответствующих библиотек / фреймворков.Я уже пытался предоставить им такие строки, как:

szLibs  = addLib ( szLibs , '/System/Library/Frameworks/CoreAudio.framework' ); 

, но безуспешно.Я очень надеюсь, что у вас, ребята, есть идеи, как сделать это.Я использую Mac OS X 10.7.3 Lion, у меня установлен Xcode и запущен gcc-4.2.Версия MATLAB 2011a (v7.12)

Заранее спасибо, январь.

1 Ответ

3 голосов
/ 01 апреля 2012

Эврика! Наконец-то я сам это выяснил: поскольку я просто взял большую часть кода из функции mex-compiling в Linux msound , проблема заключалась в том, как были связаны необходимые фреймворки. Как оказалось, " ... " (двойные кавычки) в путях и файлах не подходили для его работы, и они нужны только для фреймворков, потому что они были переданы gcc . Я удалил их из addFile, addPath и так далее, и, наконец, все файлы были распознаны и каркасы были связаны, так что все недостающие символы исчезли. Мое прозрение было в основном инициировано этим вопросом Stackoverflow и, в частности, его правильным ответом.

В случае интереса, вот полностью работающая функция компилятора:

    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);
...