Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A asdf
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 62
    • Issues 62
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 20
    • Merge requests 20
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • asdf
  • asdf
  • Issues
  • #90
Closed
Open
Issue created Sep 02, 2021 by Symbolics@Symbolics

uiop:call-with-current-directory broken on Linux

I think I've discovered a bug in call-with-current-directory on Linux, demonstrated below.

First, a quick background:

The intention is to have ASDF automatically compile custom C code on system load for CFFI wrappers. The C code is conditionalised by platform, so all we need to do is invoke make. This is going to be a common pattern and I'm trying to develop a good examplar to use as 'best practice' going forward.

Here's what I've tried:

(run-program (format nil "cd ~S && make" (namestring lib-dir)) :output t) ; works with slime, Linux

But that doesn't work from PowerShell nor MSYS2 bash.

(call-with-current-directory (native-namestring lib-dir)
			     (lambda ()
			       (run-program "make" :output t)))

works with MS Windows CLI and slime, but not Linux, and the problem appears to be that on Linux the current directory isn't being changed. By changing the run-program command from make to pwd, we can see this (output of debugging statements included):

CL-USER(1): (asdf:load-system :cephes)
namestring: "/home/symbolics/common-lisp/cephes/scipy-cephes"
native namestring: "/home/symbolics/common-lisp/cephes/scipy-cephes"
Building #P"/home/symbolics/common-lisp/cephes/scipy-cephes/libmd.so"
/home/symbolics/common-lisp/cephes <-- this is the output of 'pwd'

The only way I can make this reliably work is:

(uiop:chdir (native-namestring lib-dir))
(run-program "make" :output t)

which fine, but call-with-current-directory does seem broken. Tested on Ubuntu 18.

System definition:

;; Define a makefile as a kind of source file in ASDF
(defclass makefile (source-file) ((type :initform "m")))
(defmethod perform ((o load-op) (c makefile)) t)
(defmethod perform ((o compile-op) (c makefile))
  (let* ((lib-dir (system-relative-pathname "cephes" "scipy-cephes"))
         (lib (make-pathname :directory `(:relative ,(namestring lib-dir))
                             :name "libmd"
                             :type #+unix "so" #+(or windows win32) "dll"))
	 (built (probe-file (namestring lib))))
    (format t "namestring: ~S~%" (namestring lib-dir))
    (format t "native namestring: ~S~%" (native-namestring lib-dir))
    (if built
	(format *error-output* "Library ~S exists, skipping build" lib)
	(format *error-output* "Building ~S~%" lib))
    (unless built
      ;; (run-program (format nil "cd ~S && make" (namestring lib-dir)) :output t)))) ;works with slime and Linux
      ;; (call-with-current-directory (native-namestring lib-dir) (lambda () (run-program "make" :output t))) ;works with Windows CLI & slime

      ;; Works on MS Windows CLI, slime and Linux
      (uiop:chdir (native-namestring lib-dir))
      (run-program "make" :output t))))

(defsystem "cephes"
  :description "Wrapper for the Cephes Mathematical Library"
  :version     "1.0.0"
  :license     :MS-PL
  :depends-on ("cffi")
  :serial t
  :components ((:module "libmd"
	         :components ((:makefile "makefile")))
	       (:file "package")
	       (:file "init")
               (:file "cephes")))
Assignee
Assign to
Time tracking