labstreaminglayer / liblsl-Matlab

Matlab bindings for liblsl
MIT License
36 stars 13 forks source link

Issue with building mex Mac M1 #40

Open gkumar2021 opened 1 month ago

gkumar2021 commented 1 month ago

Hi,

I am getting the following error while running the build mex file on Mac M1. I will appreciate if you could help with this.

build_mex Building mex files. This may take a few minutes. lsl_append_child.mexmaca64 up to date lsl_append_child_value.mexmaca64 up to date lsl_append_copy.mexmaca64 up to date lsl_child.mexmaca64 up to date lsl_child_value.mexmaca64 up to date lsl_child_value_n.mexmaca64 up to date Building with 'Xcode with Clang'. Error using mex /Users/gautamkumar/Downloads/liblsl-Matlab/bin/../mex/lsl_close_stream.c:29:10: warning: incompatible pointer types assigning to 'lsl_close_stream_t' (aka 'void ()(void )') from 'lsl_close_stream_t *' (aka 'void (*)(void )'); dereference with [-Wincompatible-pointer-types] func = (lsl_close_stream_t)pTmp; ^ ~~~~~~ /Users/gautamkumar/Downloads/liblsl-Matlab/bin/../mex/lsl_close_stream.c:35:10: error: incompatible integer to pointer conversion passing 'uint64_T' (aka 'unsigned long long') to parameter of type 'inlet' (aka 'void *') [-Wint-conversion] func(out); ^~~ 1 warning and 1 error generated.

Error in build_mex (line 35) mex(['-I', lsl_include_dir], '-L.', libs{:}, ['../mex/', f.name]);

roberttoth02 commented 4 weeks ago

Seconding the issue, but it does not seem related to the architecture. I managed to reproduce this on an M1 and an Intel Macbook as well (with identical OS and software versions).

My versions are Mac OS 14.4.1, XCode 15.4, Matlab 2024a. The error is present with both liblsl 1.16.2 when building it myself from source (no errors there) and when using the automatically downloaded 1.16.0 library version.

The issue is related to previous open issue #8 in that it is a portion of the warning noted there that are now showing as errors (incompatible integer to pointer conversions).

This pointed to a recent change implemented in Clang 15.0 that ships with newer Mac OS / XCode releases, where they promoted the default behaviour of integer conversions from a warning to an error as documented here.

A flag is available to override the error: -Wno-error=int-conversion, which we can pass to the MEX build step by patching the build_mex.m script as follows. The patch should be non-breaking and only applies to Macs that produce the error.

% Build mex bindings
% For Octave on Linux, you need the package liboctave-dev installed
% You also need the liblsl64 binary in the bin folder and a configured
% C compiler (mex -setup)

orig_path = pwd();  % Will change back to this when done.
ext = ['.' mexext];
script_dir = fileparts(mfilename('fullpath'));
files = dir('mex/*.c');

% Find liblsl, possibly downloading it if it can't be found locally.
[lsl_fname, lsl_include_dir] = lsl_get_dll();

% Build cell array of libray dependencies (liblsl and maybe others)
libs = {};
if contains(lsl_fname, '32')
  libs{end+1} = '-llsl32';
elseif contains(lsl_fname, '64')
  libs{end+1} = '-llsl64';
else
  libs{end+1} = '-llsl';
end
if isunix
  libs{end+1} = '-ldl';
end

disp('Building mex files. This may take a few minutes.');
binarypath = fullfile(script_dir, 'bin');
cd(binarypath);
for i = 1:length(files)
  f = files(i);
  [~, base, ~] = fileparts(f.name);
  targetstats = dir([base, ext]);
  if isempty(targetstats) || f.datenum > targetstats.datenum
    try
      mex(['-I', lsl_include_dir], '-L.', ['-L', fileparts(lsl_fname)], ...
        libs{:}, ['../mex/', f.name]);
    catch err
      if ismac
        flags = 'CFLAGS="$CFLAGS -Wno-error=int-conversion"';
        mex(flags, ['-I', lsl_include_dir], '-L.', ['-L', fileparts(lsl_fname)], ...
          libs{:}, ['../mex/', f.name], '-v');
      else
        rethrow(err);
      end
    end
  else
    disp([base, ext, ' up to date']);
  end
end
if ismac
  targ_lib = dir('lsl_loadlib_.mexmac*');
  system(['install_name_tool -add_rpath "@loader_path/" ', targ_lib.name]);
end

cd(orig_path);

With this change the .mex files are built successfully, however they crash when I try using them. I am stumped at this point as the underlying behaviour of the compiler is not supposed to have changed. @gkumar2021 could you test that you get the same behaviour?

At this point I tried having a look at fixing the pointer conversions, but did not have success in that so far. I am hoping someone more experienced with the library may be kind enough to have a look.


Note: As a temporary solution for others encountering the issue, I found that Release 1.14.0 of liblsl-Matlab works fine on an M1 Mac so long as you use the x86-64 version of Matlab through Rosetta. Similarly, Release 1.14.0 still works on Intel Macs under the latest OS / XCode version, despite not being able to directly compile anymore. Of course that is if 1.14.0 is compatible with your application.