[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/emacsql a6155464c7 274/427: Try to build the package local
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/emacsql a6155464c7 274/427: Try to build the package locally if possible. |
Date: |
Tue, 13 Dec 2022 02:59:51 -0500 (EST) |
branch: elpa/emacsql
commit a6155464c764822380848260935c0a6f9de285d8
Author: Christopher Wellons <wellons@nullprogram.com>
Commit: Christopher Wellons <wellons@nullprogram.com>
Try to build the package locally if possible.
---
Makefile | 8 ++---
emacsql-sqlite.el | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
emacsql.el | 5 +++
3 files changed, 101 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index 983f0d0033..138b90ac2e 100644
--- a/Makefile
+++ b/Makefile
@@ -25,21 +25,21 @@ all : test
binary :
$(MAKE) -C sqlite
-compile: .cask $(ELC) binary
+compile: .cask $(ELC)
-package : compile $(PACKAGE)-$(VERSION).tar
+package : $(PACKAGE)-$(VERSION).tar
$(PACKAGE)-pkg.el : Cask
$(CASK) package
-$(PACKAGE)-$(VERSION).tar : $(PACKAGE)-pkg.el $(EL) bin/ $(EXTRA_DIST)
+$(PACKAGE)-$(VERSION).tar : $(PACKAGE)-pkg.el $(EL) sqlite/ $(EXTRA_DIST)
tar -cf $@ --transform "s,^,$(PACKAGE)-$(VERSION)/," $^
test: compile $(TEST_ELC)
$(BATCH) -l tests/$(PACKAGE)-tests.elc -f ert-run-tests-batch
clean :
- $(RM) *.tar *.elc tests/*.elc $(PACKAGE)-pkg.el
+ $(RM) *.tar *.elc tests/*.elc $(PACKAGE)-pkg.el bin/*
distclean : clean
$(MAKE) -C sqlite clean
diff --git a/emacsql-sqlite.el b/emacsql-sqlite.el
index abf0b4c322..d9b062ac00 100644
--- a/emacsql-sqlite.el
+++ b/emacsql-sqlite.el
@@ -4,12 +4,17 @@
(require 'cl-lib)
(require 'eieio)
+(require 'url)
+(require 'url-http)
(require 'emacsql)
(require 'emacsql-system)
(defvar emacsql-sqlite-executable
- (expand-file-name (concat "bin/emacsql-sqlite-" (emacsql-system-tuple))
- (file-name-directory load-file-name))
+ (expand-file-name (format "bin/emacsql-sqlite-%s%s" (emacsql-system-tuple)
+ (if (memq system-type '(windows-nt cygwin ms-dos))
+ ".exe"
+ ""))
+ emacsql-data-root)
"Path to the EmacSQL backend (this is not the sqlite3 shell).")
(defclass emacsql-sqlite-connection (emacsql-connection emacsql-protocol-mixin)
@@ -30,6 +35,7 @@ If FILE is nil use an in-memory database.
:debug LOG -- When non-nil, log all SQLite commands to a log
buffer. This is for debugging purposes."
+ (emacsql-sqlite-ensure-binary)
(let* ((process-connection-type nil) ; use a pipe
(coding-system-for-write 'utf-8-auto)
(coding-system-for-read 'utf-8-auto)
@@ -78,6 +84,90 @@ buffer. This is for debugging purposes."
'emacsql-error)
(list message)))
+;; SQLite compilation
+
+(defun emacsql-sqlite-compile-switches ()
+ (let ((makefile (expand-file-name "sqlite/Makefile" emacsql-data-root))
+ (case-fold-search nil))
+ (with-temp-buffer
+ (insert-file-contents makefile)
+ (setf (point) (point-min))
+ (cl-loop while (re-search-forward "-D[A-Z0-9_=]+" nil :no-error)
+ collect (match-string 0)))))
+
+(defun emacsql-sqlite-compile (&optional o-level async)
+ "Compile the SQLite back-end for EmacSQL, returning non-nil on success."
+ (let* ((cc (executable-find "cc"))
+ (src (expand-file-name "sqlite" emacsql-data-root))
+ (files (mapcar (lambda (f) (expand-file-name f src))
+ '("sqlite3.c" "emacsql.c")))
+ (cflags (list (format "-I%s" (shell-quote-argument src))
+ (format "-O%d" (or o-level 2))))
+ (ldlibs (if (eq system-type 'windows-nt) () (list "-ldl")))
+ (options (emacsql-sqlite-compile-switches))
+ (output (list "-o" emacsql-sqlite-executable))
+ (arguments (nconc ldlibs cflags options files output)))
+ (if (not cc)
+ (prog1 nil
+ (message "Could not find C compiler, skipping SQLite compilation"))
+ (mkdir (expand-file-name "bin" emacsql-data-root) t)
+ (message "Compiling EmacSQL SQLite binary ...")
+ (let ((log (get-buffer-create byte-compile-log-buffer)))
+ (with-current-buffer log
+ (let ((inhibit-read-only t))
+ (insert (mapconcat #'identity (cons cc arguments) " ") "\n")
+ (apply #'call-process cc nil (if async 0 t) t arguments))))
+ :success)))
+
+(defvar emacsql-sqlite-user-prompted nil
+ "To avoid prompting for fetch multiple times.")
+
+(defvar emacsql-sqlite-host "http://nullprogram.s3.amazonaws.com/emacsql/"
+ "Location where EmacSQL binaries can be found.")
+
+(defun emacsql-sqlite-download (url filename)
+ "Downlod URL to FILENAME, clobbering returning nil on failure.
+This works like `url-copy-file' but actually checks for errors."
+ (cl-declare (special url-http-end-of-headers))
+ (let ((buffer (url-retrieve-synchronously url)))
+ (when buffer
+ (with-current-buffer buffer
+ (let ((response (url-http-parse-response)))
+ (when (and (>= 200 response) (< response 300))
+ (mkdir (file-name-directory filename) t)
+ (let ((buffer-file-coding-system 'no-conversion))
+ (write-region (1+ url-http-end-of-headers) (point-max) filename)
+ :success)))))))
+
+(defun emacsql-sqlite-mark-exec (file)
+ "Set executable bits on FILE's mode."
+ (set-file-modes file (logior (file-modes file) #o111)))
+
+(defun emacsql-sqlite-fetch-binary ()
+ (let ((query "EmacSQL binary could not be built. Fetch from the Internet?"))
+ (unless emacsql-sqlite-user-prompted
+ (let ((prompt (y-or-n-p query)))
+ (setf emacsql-sqlite-user-prompted t)
+ (when prompt
+ (let* ((file (file-name-nondirectory emacsql-sqlite-executable))
+ (url (format "%s%s/%s"
+ emacsql-sqlite-host emacsql-version file)))
+ (when (emacsql-sqlite-download url emacsql-sqlite-executable)
+ (emacsql-sqlite-mark-exec emacsql-sqlite-executable)
+ :success)))))))
+
+(defun emacsql-sqlite-ensure-binary ()
+ "Ensure the EmacSQL SQLite binary is available, signaling an error if not."
+ (unless (file-exists-p emacsql-sqlite-executable)
+ ;; try compiling again at the last minute
+ (unless (ignore-errors (emacsql-sqlite-compile 0))
+ (unless (emacsql-sqlite-fetch-binary)
+ (error "No EmacSQL SQLite binary available, aborting")))))
+
+(cl-eval-when (compile)
+ (unless (file-exists-p emacsql-sqlite-executable)
+ (ignore-errors (emacsql-sqlite-compile 2))))
+
(provide 'emacsql-sqlite)
;;; emacsql-sqlite.el ends here
diff --git a/emacsql.el b/emacsql.el
index a35ee3c02a..c3c4183bd3 100644
--- a/emacsql.el
+++ b/emacsql.el
@@ -73,10 +73,15 @@
(require 'finalize)
(require 'emacsql-compiler)
+(defvar emacsql-version "1.0.0")
+
(defvar emacsql-global-timeout 30
"Maximum number of seconds to wait before bailing out on a SQL command.
If nil, wait forever.")
+(defvar emacsql-data-root (file-name-directory load-file-name)
+ "Directory where EmacSQL is installed.")
+
(defclass emacsql-connection ()
((process :type process
:initarg :process
- [nongnu] elpa/emacsql fcba876d0e 251/427: Solve the tty (pty) issue in MySQL., (continued)
- [nongnu] elpa/emacsql fcba876d0e 251/427: Solve the tty (pty) issue in MySQL., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql fb0e2d5423 256/427: Fix typecase typo., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a6e859f1b5 260/427: Normalize darwin OS., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4332bd67ec 271/427: Flesh out the main header a bit more., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 4e9297233d 273/427: Don't rely on C99 mode., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 7963261ef3 270/427: Bump to version 1.0.0., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 6f6533ab70 272/427: Add Cygwin note., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 45f43323ad 275/427: Check the compiler error code., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 2f606fdd2d 300/427: Fix with-transaction macro to return results., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 76acd4f8a1 304/427: Add a test for reserved word escaping., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a6155464c7 274/427: Try to build the package locally if possible.,
ELPA Syncer <=
- [nongnu] elpa/emacsql 4a58806d64 299/427: Improve new indentation a little bit., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql c512f4287c 315/427: Add back-end note to README., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a0587f1b5f 311/427: Fix docstring on emacsql-enable-debugging., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 9cf4e267cc 310/427: Bump up to version 1.0.2., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql fd73d37df8 319/427: Ignore the generated executable, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 048e81b759 320/427: Add file tests/.nosearch, ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 017cd8460d 329/427: Use own data root in emacsql-sqlite., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 03d4788708 332/427: Bump to version 2.0.0 (fix #15)., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql 0a2b3f6496 337/427: Follow rename of emacsql-with-vars in doc-strings., ELPA Syncer, 2022/12/13
- [nongnu] elpa/emacsql a60deae960 335/427: Add NOTNULL and ISNULL special operators (#16)., ELPA Syncer, 2022/12/13