File: osxsetoctaverpath.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (86 lines) | stat: -rw-r--r-- 3,455 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
function osxsetoctaverpath(mexfname, mexpath)
% osxsetoctaverpath(mexfname [, mexpath])
%
% Change the @rpath library search path for the octave
% runtime libraries inside the given mex file.
%
% We change from absolute path to @rpath.
%
% E.g.,
%
% osxsetoctaverpath('Screen'); would rewrite Screen.mex
% to use the @rpath settings stored in this function.
% We define one rpath as @loader_path, so the runtime dylibs
% are expected in loader_path, e.g., a system library path,
% or the Psychtoolbox folder where the mex files are stored.
% 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.

    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!');
    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)
            if IsARM
                mexpath = [PsychtoolboxRoot 'PsychBasic/Octave8OSXFilesARM64/'];
            else
                mexpath = [PsychtoolboxRoot 'PsychBasic/Octave8OSXFiles64/'];
            end
        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>
                    osxsetoctaverpath(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];

    % This is how the libdir should be defined automatically:
    libdir = GetOctlibDir;

    % This is sadly how we have to do it with Octave on macOS 13-14 due to
    % the latest macOS linker crap - Hardcoding the path for a Octave install
    % from HomeBrew. Yes, this is sad...
    if IsARM
        libdir = '/opt/homebrew/opt/octave/lib/octave/9.2.0';
    else
        libdir = '/usr/local/opt/octave/lib/octave/9.2.0';
    end

    % Replace absolute path to liboctinterp.12.dylib with @rpath:
    system(['install_name_tool -change ' libdir '/liboctinterp.12.dylib @rpath/liboctinterp.dylib ' mexfname]);

    % 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
    % 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' };

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

return;