forked from emacs-taskrunner/emacs-taskrunner
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtaskrunner-clang.el
164 lines (141 loc) · 6.01 KB
/
taskrunner-clang.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
;;; taskrunner-clang.el --- Provide functions to retrieve c/c++ build system targets -*- lexical-binding: t; -*-
;; Copyright (C) 2019 Yavor Konstantinov
;;;; Commentary:
;; Provide function for extracting makefile targets.
;; Support included for:
;; - Makefiles(Makefile, makefile, GNUmakefile)
;; - CMake
;; - Meson/Ninja
;;;; Requirements
(require 'projectile)
(require 'cl-lib)
;;;; Code:
(defcustom taskrunner-build-dir-list '("build" "Build" "buildDir" "builddir" "builds")
"A list containing the name of build folders to be looked for."
:group 'taskrunner
:type 'list)
(defcustom taskrunner-source-dir-list '("src" "Src" "source" "Source")
"A list containing the name of source code folders to be looked for."
:group 'taskrunner
:type 'list)
(defcustom taskrunner-retrieve-all-make-targets t
"Variable indicates whether or not to always retrieve targets starting with `_'."
:type 'symbol
:options '(t nil)
:group 'taskrunner)
;;;; Constants
(defconst taskrunner--make-target-regexp-no-hidden
"^[1-9a-zA-Z/\\-][1-9a-zA-Z-_/\\]*[[:space:]]*:"
"Regular expression used to locate all Makefile targets which are not PHONY.")
(defconst taskrunner--make-target-regexp-hidden
"^[1-9a-zA-Z-_/\\]+[[:space:]]*:"
"Regular expression used to locate all Makefile targets which are not PHONY.")
(defconst taskrunner--make-nqp-command
"make -nqp __BASH_MAKE_COMPLETION__=1 .DEFAULT 2>/dev/null"
"Command used to build up the database of targets.")
(defconst taskrunner--cmake-warning
"Taskrunner: Detected CMake build system but no build folder or Makefile were found! Please setup
CMake for either insource or outsource build and then call emacs-taskrunner again!"
"Warning used to indicate that not build folder was found for CMake.")
;;;; Functions
;; These are here just to silence the bytecompiler. They are defined in
;; `taskrunner.el' and will be loaded later on but due to these files being
;; required before the function being loaded, a warning is emitted.
(declare-function taskrunner--narrow-to-line "ext:taskrunner")
(declare-function taskrunner--make-task-buff-name "ext:taskrunner")
(declare-function taskrunner-add-to-build-cache "ext:taskrunner")
(defun taskrunner-get-make-targets (DIR MAKEFILE-NAME HIDDEN)
"Find all makefile targets from file called MAKEFILE-NAME located in DIR.
If HIDDEN is non-nil then include targets which start with _."
(let* ((makefile-path (expand-file-name MAKEFILE-NAME DIR))
(buff (get-file-buffer makefile-path))
(curr-line)
(targets '())
(target-regexp (if HIDDEN
taskrunner--make-target-regexp-hidden
taskrunner--make-target-regexp-no-hidden)))
(with-temp-buffer
;; Check if the current makefile is already opened
(if buff
(set-buffer buff)
(insert-file-contents makefile-path))
;; Locate all targets
(while (search-forward-regexp
target-regexp nil t)
(taskrunner--narrow-to-line)
(setq curr-line (buffer-string))
(if (and
;; Do not match anything of the form NAME := MORE_NAMES
(not (string-match-p ".:=.*" curr-line))
;; Do not match anything of the form PHONY NAME : MORE_NAMES
(not (string-match-p "^PHONY" curr-line))
;; Do not match anything of the form .PHONY NAME : MORE_NAMES
(not (string-match-p "^\.PHONY" curr-line))
;; Do not match anything of the form FORCE NAME : MORE_NAMES
(not (string-match-p "^FORCE" curr-line)))
(push (car (split-string curr-line ":")) targets))
(widen)
)
)
(taskrunner-add-to-build-cache (projectile-project-root) DIR)
(cl-map 'list (lambda (elem)
(concat "MAKE" " " elem)) targets)
)
)
(defun taskrunner-get-cmake-tasks (ROOT)
"Retrieve all cmake tasks for the project in directory ROOT."
(let ((dir-contents (directory-files ROOT))
(build-dir-name)
(build-path)
(targets)
(found-flag nil)
(i 0))
(while (and
(not found-flag)
(<= i (length taskrunner-build-dir-list)))
(when (member (elt taskrunner-build-dir-list i) dir-contents)
(setq build-dir-name (elt taskrunner-build-dir-list i))
(setq found-flag t))
(setq i (1+ i)))
(when found-flag
(setq build-path (expand-file-name build-dir-name ROOT))
(setq dir-contents (directory-files build-path))
(when (member "Makefile" dir-contents)
(setq targets (taskrunner-get-make-targets build-path "Makefile" nil))))
targets))
(defun taskrunner-get-ninja-tasks (DIR)
"Retrieve all ninja tasks from directory DIR."
(let ((default-directory DIR)
(targets '()))
(call-process "ninja" nil (taskrunner--make-task-buff-name "ninja") nil "-t" "targets")
(with-temp-buffer
(set-buffer (taskrunner--make-task-buff-name "ninja"))
(goto-char (point-min))
(dolist (elem (split-string (buffer-string) "\n"))
(push (concat "NINJA" " " (car (split-string elem ":"))) targets))
(kill-current-buffer))
(when targets
(pop targets)
(taskrunner-add-to-build-cache (projectile-project-root) DIR))
targets))
(defun taskrunner-get-meson-tasks (ROOT)
"Retrieve all Ninja tasks from a Meson project in directory ROOT."
(let ((dir-contents (directory-files ROOT))
(build-dir-name) ;; Build folder name
(build-path) ;; Absolute path to build folder
(targets '())
(found-flag nil)
(i 0))
(while (and
(not found-flag)
(<= i (length taskrunner-build-dir-list)))
(when (member (elt taskrunner-build-dir-list i) dir-contents)
(setq build-dir-name (elt taskrunner-build-dir-list i))
(setq found-flag t))
(setq i (1+ i)))
(when found-flag
(setq build-path (expand-file-name build-dir-name ROOT))
(setq targets (taskrunner-get-ninja-tasks build-path)))
targets))
(provide 'taskrunner-clang)
;;; taskrunner-clang.el ends here