Dylibs get deps.m

Revision as of 14:18, 30 June 2012 by Bpabbott (talk | contribs) (Include Fink and /local when determining which libs need to be relocatable)

An m-file function used in support of creating a MacOS X App bundle.

## Copyright (C) 2012 Ben Abbott
## 
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
## 
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Function File} dylibs = dylibs_get_deps (@var{name})
## @deftypefnx {Function File}        = dylibs_get_deps (@var{name}, @var{root})
##
## Extracts the dependent libary names from the named binary, @var{name}.
## If @var{root} is specified, the only libraries returned will have paths
## which begin with one of the cell-strings contained by @var{root}.
##
## The defaults for @var{root} are @code{@{"/opt/local/", "/sw/", "/usr/local/",
## "@@executable_path"@}}.  These root paths are intended to match all the
## relocatable libraries which should be included in an App bundle.  The first
## and second entries correspond to the MacPorts and Fink installation
## directories, respectively.
##
## @seealso {dylibs_find, dylibs_fix}
## @end deftypefn

## Author: Ben Abbott <bpabbott@mac.com>
## Created: 2012-06-27

function [deps, full_deps] = dylibs_get_deps (names, root_dir = {"/opt/local/", "/sw/", "/usr/local", "@executable_path"})
  if (ischar (root_dir))
    root_dir = {root_dir};
  endif
  strip_back = @(str) str(1:find(str==" ", 1)-1);
  strip_path = @(str) str(find(str=="/", 1, "last")+1:end);
  if (ischar (names))
    names = {names};
  endif
  deps = cell (size (names));
  full_deps = cell (size (names));
  for n = 1:numel(names)
    [status, output] = system (sprintf ('otool -L "%s"', names{n}));
    if (status)
      error (output)
    endif
    output = strtrim (strsplit (output, char (10)) (1:end));
    is_dependent = @(str) ! isempty (str) && isempty (findstr (str, names{n}));
    full_output = output (cellfun (is_dependent, output, "UniformOutput", true));
    if (! isempty (root_dir))
      keep = false (size (full_output));
      for r = 1:numel(root_dir)
        if (numel (root_dir{r}) && ischar (root_dir{r}))
          keep = keep | strncmp (full_output, root_dir{r}, numel (root_dir{r}));
        endif
      endfor
      full_output = full_output (keep);
    endif
    full_output = cellfun(strip_back, full_output, "UniformOutput", false);
    output = cellfun(strip_path, full_output, "UniformOutput", false);
    deps(n) = {output};
    full_deps(n) = {full_output};
  endfor
  if (numel (names) == 1)
    deps = deps{1};
    full_deps = full_deps{1};
  endif
endfunction