Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential Shared Library Extract #14

Open
jmercouris opened this issue May 11, 2020 · 0 comments
Open

Potential Shared Library Extract #14

jmercouris opened this issue May 11, 2020 · 0 comments

Comments

@jmercouris
Copy link

Draft source code, it should lend an idea as to how I believe it can work. Feel free to copy/modify and integrate into deploy:

(in-package :cl-user)

(uiop:define-package shared-library-extract
    (:use :common-lisp))

(in-package :shared-library-extract)

(defvar *object-tool* "otool")
(defvar *cp* "cp")
(defvar *copyable-library-paths* (list "/opt/local/lib"))
(defvar *install-name-tool* "install_name_tool")

(defun object-tool (path)
  (flet ((process-line (line) (first (str:split " " (str:trim line)))))
    (with-input-from-string (output (uiop:run-program (list *object-tool* "-L" path)
                                                      :output '(:string :stripped t)))
      (loop for line = (read-line output nil)
            while (not (null line))
            collect (process-line line)))))

(defun copy-library-p (library-path)
  (find-if (lambda (i) (str:containsp i library-path)) *copyable-library-paths*))

(defun copy-file (from to)
  (format t "Copy file ~a to ~a~%" from to)
  (uiop:run-program (list *cp* from to)))

(defun file-name (path)
  (car (last (str:split "/" path))))

(defun install-name (from to path)
  (uiop:run-program (list *install-name-tool* "-change"
                          from to path)))

(defun install-names (library)
  (format t "Install names for library ~a~%" library)
  (loop for object in (object-tool library)
        if (copy-library-p object)
          do (install-name object (format nil "@executable_path/../Resources/~a" (file-name object)) library)))

(defun library-dependency-tree (library-path)
  (let ((queue (object-tool library-path))
        (seen-libraries))
    (remove-duplicates
     (loop for library = (pop queue)
           while (not (null library))
           if (copy-library-p library)
             do (unless (find library seen-libraries :test #'equal)
                  (push library seen-libraries)
                  (setf queue (append queue (rest (object-tool library))))
                  (format t "Process Library: ~a ~%Depends on:~a~%" library (rest (object-tool library))))
           if (copy-library-p library)
             collect library)
     :test #'equal)))

(defun process-library (library-path destination)
  (loop for library in (library-dependency-tree library-path)
        do (let ((destination-path (format nil "~a/~a" destination (file-name library))))
             (copy-file library destination-path)
             (install-names destination-path))))

(defun process-libraries (libraries destination)
  (mapcar (lambda (i) (process-library i destination)) libraries))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant