Skip to content

Commit

Permalink
macOS: Prepare adding PsychPlugins folder to linker path.
Browse files Browse the repository at this point in the history
So libraries in the Psychtoolbox/PsychBasic/PsychPlugins/ folder can
always be found and linked by the linker on macOS.

We add the folder to the -rpath. Extend osxsetoctaverpath.m for this.
Add new helper script macossetmatlabrpath.m for the same purpose
wrt. Matlab.
  • Loading branch information
kleinerm committed Sep 1, 2024
1 parent e41087d commit 241d638
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
59 changes: 59 additions & 0 deletions PsychSourceGL/Source/macossetmatlabrpath.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
function macossetmatlabrpath(mexfname, mexpath)
% macossetmatlabrpath(mexfname [, mexpath])
%
% Change the @rpath library search path for some helper libraries inside the
% given Matlab mex file, so they can be found by the dynamic linker inside the
% Psychtoolbox/PsychBasic/PsychPlugins. We change from absolute path to @rpath.
%
% E.g.,
%
% macossetmatlabrpath('Screen'); would rewrite Screen.mexmaci64 on Intel Matlab
% to use the @rpath settings stored in this function. We define one candidate
% rpath as @loader_path/PsychPlugins, so the helper dylibs are expected there,
% e.g., a system library path, or the PsychPlugins folder.

if ~IsOSX(1) || IsOctave
error('macossetmatlabrpath only works with 64-Bit Matlab for macOS!');
end

% If no mex filename given, iterate over 'mexpath' - or the default install
% location of mex files - and apply the rpath editing to each mex file there:
if nargin < 1 || isempty(mexfname)
if nargin < 2 || isempty(mexpath)
mexpath = [PsychtoolboxRoot 'PsychBasic/'];
end

d = dir (mexpath);
for j = 1:length(d)
if ~d(j).isdir
[~, mexfname, extension] = fileparts(d(j).name);
if ~isempty(strfind(extension, mexext)) %#ok<STREMP>
macossetmatlabrpath(mexfname, mexpath);
end
end
end

return;
end

% Set default path for finding the mex file to process, if omitted:
if nargin < 2 || isempty(mexpath)
mexpath = '../Projects/MacOSX/build/';
end

% Build full path to file:
mexfname = [mexpath mexfname '.' mexext];

% We add the @loader_path/PsychPlugins path to our PsychBasic/PsychPlugins
% folder, so our mex files can find additional helper dylibs there, which
% are needed by some of them:
lpaths = { '@loader_path/PsychPlugins' };

% Add all paths in lpaths as potential search paths for @rpath:
for i = 1:length(lpaths)
system(['install_name_tool -add_rpath ' lpaths{i} ' ' mexfname]);
fprintf('Added Matlab @rpath %s to mex file %s ...\n', lpaths{i}, mexfname);
end

return;

13 changes: 8 additions & 5 deletions PsychSourceGL/Source/osxsetoctaverpath.m
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
function osxsetoctaverpath(mexfname, mexpath)
% osxsetoctaverpath(mexfname [, mexpath])
%
% Change the @rpath library search path for the octave
% runtime libraries inside the given mex file.
% Change the @rpath library search path for the octave runtime libraries
% and other helper libraries inside the given mex file.
%
% We change from absolute path to @rpath.
%
Expand All @@ -16,6 +16,7 @@ function osxsetoctaverpath(mexfname, mexpath)
% PsychtoolboxPostInstallRoutine copies or symlinks the Octave
% runtime libraries into the mex file folder of PTB, so the mex
% files should always find a dylib for the currently running Octave.
% We also add Psychtoolbox/PsychBasic/PsychPlugins to the dylib search path.

if ~IsOSX(1) || ~IsOctave || ~compare_versions(version, '9.2.0', '==')
error('osxsetoctaverpath only works with a 64-Bit version of HomeBrew Octave-9.2.0 for macOS!');
Expand Down Expand Up @@ -70,11 +71,13 @@ function osxsetoctaverpath(mexfname, mexpath)
% Replace absolute path to liboctave.11.dylib with @rpath:
system(['install_name_tool -change ' libdir '/liboctave.11.dylib @rpath/liboctave.dylib ' mexfname]);

% Add one single rpath: @loader_path. This is the path to our folder where our
% Add @loader_path to the @rpath. This is the path to our folder where our
% mex file is stored. If we place symlinks to liboctave.dylib and liboctinterp.dylib
% there, then the linker will find them. In absence, the linker will also search the
% users $HOME/lib/ directory as a possible fallback:
lpaths = { '@loader_path' };
% users $HOME/lib/ directory as a possible fallback. Additionally we add the path to
% our Psychtoolbox/PsychBasic/PsychPlugins folder, so our mex files can find additional
% helper dylibs there which are needed by some of them:
lpaths = { '@loader_path', '@loader_path/../PsychPlugins' };

% Add all paths in lpaths as potential search paths for the octave
% library directories, ie., as settings for @rpath:
Expand Down

0 comments on commit 241d638

Please sign in to comment.