forked from hasu/notdeft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
notdeft-xapian-make.el
150 lines (136 loc) · 5.62 KB
/
notdeft-xapian-make.el
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;;; notdeft-xapian-make.el --- Xapian backend auto-installer -*- lexical-binding: t; -*-
;; Copyright (C) 2020 by the authors.
;; All rights reserved.
;; Author: MaxSt <max@stoerchle.at>
;; Author: Tero Hasu <tero@hasu.is>
;; See "notdeft.el" for licensing information.
;;; Commentary:
;; Functionality for compiling the C++ code for the NotDeft Xapian
;; backend, automatically or otherwise.
;;
;; Instead of setting the `notdeft-xapian-program' variable yourself,
;; you may instead load this `notdeft-xapian-make' feature to have the
;; program built and configured automatically. You may additionally
;; need to set the `notdeft-xapian-program-compile-command-format' to
;; something that produces a suitable compiler invocation for your
;; platform.
;;
;; Suggested use:
;; (add-hook 'notdeft-load-hook 'notdeft-xapian-make-program-when-uncurrent)
;;; Code:
(defcustom notdeft-xapian-program-compile-command-format
"c++ -o %s %s -std=c++11 -Wall `pkg-config --cflags --libs tclap` `xapian-config --cxxflags --libs`"
"Compilation shell command.
Can be a `format' string with two \"%s\" directives, or a
function of two arguments, with the first directive or argument
specifying the executable path for the program, and the second
specifying the C++ source file for the notdeft-xapian program. If
it is a function, it should do any necessary shell escaping of
the arguments."
:type '(choice
(string :tag "Format string")
(function :tag "Function"))
:group 'notdeft)
(defcustom notdeft-xapian-program-install-path
"notdeft-xapian"
"Path for the notdeft-xapian executable to build.
If the path is not absolute, it is considered relative to
`notdeft-xapian-home'."
:type 'string
:safe #'stringp
:group 'notdeft)
(defvar notdeft-xapian-home
(expand-file-name "xapian/"
(file-name-directory
(file-truename (locate-library "notdeft"))))
"Directory path for notdeft-xapian sources.
Must specify an absolute path.")
(defvar notdeft-xapian-compile-buffer-name "*Compile notdeft-xapian*"
"Name of the buffer used for compiling notdeft-xapian.")
(defun notdeft-xapian-program-current-p (&optional program)
"Whether the notdeft-xapian PROGRAM is current.
It is uncurrent if it does not exist as an executable, or if its
source file is newer. PROGRAM defaults to
`notdeft-xapian-program-install-path'."
(let ((exe-file (expand-file-name
(or program notdeft-xapian-program-install-path)
notdeft-xapian-home)))
(when (file-executable-p exe-file)
(let ((cxx-file (expand-file-name
"notdeft-xapian.cc"
notdeft-xapian-home)))
(when (file-exists-p cxx-file)
(not (time-less-p
(nth 5 (file-attributes exe-file))
(nth 5 (file-attributes cxx-file)))))))))
;;;###autoload
(defun notdeft-xapian-compile-program (&optional program)
"Compile the notdeft-xapian program.
Use notdeft-xapian sources in `notdeft-xapian-home', and build
the PROGRAM, which defaults to `notdeft-xapian-program-install-path'.
On success, return the path of the built executable."
(interactive)
(unless (file-directory-p notdeft-xapian-home)
(error "Cannot locate notdeft-xapian sources"))
(let* ((exe-file (expand-file-name
(or program notdeft-xapian-program-install-path)
notdeft-xapian-home))
(cxx-file (expand-file-name
"notdeft-xapian.cc"
notdeft-xapian-home))
(compile-command
(if (functionp notdeft-xapian-program-compile-command-format)
(funcall notdeft-xapian-program-compile-command-format
exe-file cxx-file)
(format notdeft-xapian-program-compile-command-format
(shell-quote-argument exe-file)
(shell-quote-argument cxx-file))))
(buffer (get-buffer-create notdeft-xapian-compile-buffer-name)))
(pop-to-buffer notdeft-xapian-compile-buffer-name)
(let ((exit-code
(call-process
"sh" nil buffer t "-c" compile-command)))
(unless (zerop exit-code)
(error "Compilation of notdeft-xapian failed: %s (%d)"
compile-command exit-code))
(unless (file-executable-p exe-file)
(error (concat "Compilation of notdeft-xapian failed: "
"Executable %S not created")
exe-file))
(message "Compilation of notdeft-xapian succeeded: %S" exe-file)
exe-file)))
(defun notdeft-xapian-make-program (&optional force)
"Compile notdeft-xapian program.
Only do that if the source directory `notdeft-xapian-home'
exists, and the target path `notdeft-xapian-program-install-path'
is non-nil. In that case generate the executable with the target
path, but only if any existing executable appears to be
uncurrent, or if the FORCE flag is non-nil. Return the absolute
target path if it is known, even if the program could not be
compiled."
(when notdeft-xapian-program-install-path
(when (and notdeft-xapian-home
(file-directory-p notdeft-xapian-home))
(let ((exe-file (expand-file-name
notdeft-xapian-program-install-path
notdeft-xapian-home)))
(when (or force (not (notdeft-xapian-program-current-p exe-file)))
(notdeft-xapian-compile-program exe-file))
exe-file))))
(eval-when-compile
(defvar notdeft-xapian-program))
;;;###autoload
(defun notdeft-xapian-make-program-when-uncurrent ()
"Compile notdeft-xapian program when it is uncurrent.
Do that as for `notdeft-xapian-make-program', but fail silently
if compilation fails. Set `notdeft-xapian-program' to the
program's absolute path, or to nil if the program does not exist
even after any compilation attempt."
(setq notdeft-xapian-program
(let ((exe-file
(ignore-errors
(notdeft-xapian-make-program nil))))
(when (and exe-file (file-executable-p exe-file))
exe-file))))
(provide 'notdeft-xapian-make)
;;; notdeft-xapian-make.el ends here