-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuild-cmake.el
90 lines (77 loc) · 3.53 KB
/
build-cmake.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
;;; cmake.el --- Build CMake projects in Emacs -*- lexical-binding: t; -*-
;; Copyright (C) 2024 Justin Andreas Lacoste
;; Author: Justin Andreas Lacoste <[email protected]>
;; URL: https://github.com/27justin/build.el
;; Package-Requires: ((seq))
;; Version: 0.1
;; Keywords: compile, build-system, cmake
;;; Commentary:
;;; Requirements:
(require 'build-api)
(require 'seq)
;;; Code
(defvar build--cmake-generators '(
"Unix Makefiles"
"NMake Makefiles"
"MinGW Makefiles"
"Ninja"
"Visual Studio 16 2019"
"Visual Studio 17 2022"
)
"A list of default options for the generator option of the
CMake transient")
(defun build-cmake-project-p ()
(build--project-file-exists-p "CMakeLists.txt"))
(defun build--cmake-strip-arguments (list args)
"Strip elements in `args' from `list` using fuzzy matching.
If an element in `list` starts with any string in `args`, it will be stripped."
(let ((results '()))
(seq-do (lambda (item)
(unless (seq-some (lambda (arg)
(string-prefix-p arg item))
args)
(push item results)))
list)
(reverse results)))
(defun build-cmake-build (&optional args)
"Run CMake build with the provided OPTIONS or default to '--build build'."
(interactive
(list (transient-args 'build-cmake-transient)))
(let* ((default-directory (project-root (project-current)))
(build-command (format "cmake --build %s %s" (transient-arg-value "-B=" args) (string-join (build--cmake-strip-arguments args '("-B=" "-S=" "-G=" " -D")) " "))))
(funcall build--compile build-command)))
(defun build-cmake-generate (&optional args)
"Run CMake generate with the provided ARGS."
(interactive
(list (transient-args 'build-cmake-transient)))
(let ((default-directory (project-root (project-current))))
;; Process arguments
(let ((processed-args (mapcar (lambda (arg)
(if (string-prefix-p "-G=" arg)
;; Wrap the value after '-G=' in quotes if it's a generator
(concat "-G=\"" (substring arg 3) "\"")
arg))
(build--cmake-strip-arguments args '("--clean-first" "--target")))))
;; Join the processed args into a single string and run cmake
(let ((generate-command (format "cmake %s" (string-join processed-args " "))))
(funcall build--compile generate-command)))))
(transient-define-prefix build-cmake-transient ()
"CMake Build Commands"
:value '("-S=." "-B=build" "--defines=-DCMAKE_BUILD_TYPE=Release" "-G=Unix Makefiles")
["CMake Options\n"
["Generating"
("-S" "Set source directory" "-S=" :prompt "Path to source: ")
("-B" "Set build directory" "-B=" :prompt "Path to build: ")
("-D" "Defines" " " :prompt "Set defines: " :class transient-option :always-read t)
("-G" "Generator" "-G=" :prompt "Build generator: " :choices (lambda() build--cmake-generators) :always-read t)
]
["Building"
("-C" "Clean first" "--clean-first") ;; Only for building, stripped from generate.
]
]
["Build"
("g" "Generate" build-cmake-generate)
("b" "Build" build-cmake-build)
])
(add-to-list 'build--systems '(build-cmake-project-p . build-cmake-transient))
(provide 'build-cmake)