Subject: Optimizations for emacs-clang-format and emacs-clang-rename

From: Tim Gesthuizen <[email-masked]>
Date: Mon, 3 Dec 2018 14:47:48 +0100

Hi,
the attached patches add optimizations to emacs-clang-format and
emacs-clang-rename:

- Only package the required elisp file in the source
- Add a function for generating package definitions of packages
  containing a single elisp file from the clang source.

The patches make clear that the elisp file is the only thing required
for building the package and should save some disk space as the packages
do not need the full clang source tree.

Tim.
From 5d85956a30ff1bed8f7c529d4b760bb609ac4ab7 Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <[email-masked]>
Date: Fri, 30 Nov 2018 14:49:51 +0100
Subject: [PATCH 1/3] gnu: Shrink source for emacs-clang-format.

To build emacs-clang-format only the `clang-format.el` file is needed. In
order to save disk space and make clear that this is the only file needed
modify the downloaded source to only contain `clang-format.el`.

* gnu/packages/emacs.scm (emacs-clang-format): Add source snippet.
* gnu/packages/emacs.scm (emacs-clang-format): Modify phases.
---
 gnu/packages/llvm.scm | 58 ++++++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 20 deletions(-)

diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index dace546a4..e7dd6477a 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -461,28 +461,46 @@ code analysis tools.")
     (license license:bsd-3)))
 
 (define-public emacs-clang-format
-  (package
-    (inherit clang)
-    (name "emacs-clang-format")
-    (build-system emacs-build-system)
-    (inputs
-     `(("clang" ,clang)))
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'configure
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((clang (assoc-ref inputs "clang")))
-               (copy-file "tools/clang-format/clang-format.el" "clang-format.el")
-               (emacs-substitute-variables "clang-format.el"
-                 ("clang-format-executable"
-                  (string-append clang "/bin/clang-format"))))
-             #t)))))
-    (synopsis "Format code using clang-format")
-    (description "This package allows to filter code through @code{clang-format}
+  (let ((target-file "clang-format.el"))
+    (package
+      (inherit clang)
+      (name "emacs-clang-format")
+      (source (let ((orig (package-source clang)))
+                (origin
+                  (method (origin-method orig))
+                  (uri (origin-uri orig))
+                  (sha256 (origin-sha256 orig))
+                  (modules '((guix build utils)
+                             (srfi srfi-1)
+                             (ice-9 ftw)))
+                  (snippet
+                   `(begin
+                      ;; Copy target file to source root and delete all other files
+                      (copy-file (string-append "tools/clang-format/" ,target-file)
+                                 ,target-file)
+                      (map delete-file-recursively
+                           (fold delete
+                                 (scandir ".")
+                                 '("." ".." ,target-file)))
+                      #t)))))
+      (build-system emacs-build-system)
+      (inputs
+       `(("clang" ,clang)))
+      (arguments
+       `(#:phases
+         (modify-phases %standard-phases
+           (add-after 'unpack 'configure
+             (lambda* (#:key inputs #:allow-other-keys)
+               (let ((clang (assoc-ref inputs "clang")))
+                 (emacs-substitute-variables ,target-file
+                   ("clang-format-executable"
+                    (string-append clang "/bin/clang-format"))))
+               #t)))))
+      (synopsis "Format code using clang-format")
+      (description "This package allows to filter code through @code{clang-format}
 to fix its formatting.  @code{clang-format} is a tool that formats
 C/C++/Obj-C code according to a set of style options, see
-@url{http://clang.llvm.org/docs/ClangFormatStyleOptions.html}.")))
+@url{http://clang.llvm.org/docs/ClangFormatStyleOptions.html}."))))
 
 (define-public emacs-clang-rename
   (package
-- 
2.19.2

From 29a1992253908ea191ef0227462972f78ce20da3 Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <[email-masked]>
Date: Fri, 30 Nov 2018 15:01:10 +0100
Subject: [PATCH 2/3] gnu: Shrink source for emacs-clang-rename.

To build emacs-clang-rename only the `clang-rename.el` file is needed. In
order to save disk space and make clear that this is the only file needed
modify the downloaded source to only contain `clang-rename.el`.

* gnu/packages/emacs.scm (emacs-clang-rename): Add source snippet.
* gnu/packages/emacs.scm (emacs-clang-rename): Modify phases.
---
 gnu/packages/llvm.scm | 59 ++++++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index e7dd6477a..3eb0fb29f 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -503,23 +503,42 @@ C/C++/Obj-C code according to a set of style options, see
 @url{http://clang.llvm.org/docs/ClangFormatStyleOptions.html}."))))
 
 (define-public emacs-clang-rename
-  (package
-    (inherit clang)
-    (name "emacs-clang-rename")
-    (build-system emacs-build-system)
-    (inputs
-     `(("clang" ,clang)))
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'configure
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((clang (assoc-ref inputs "clang")))
-               (copy-file "tools/clang-rename/clang-rename.el" "clang-rename.el")
-               (emacs-substitute-variables "clang-rename.el"
-                 ("clang-rename-binary"
-                  (string-append clang "/bin/clang-rename"))))
-             #t)))))
-    (synopsis "Rename every occurrence of a symbol using clang-rename")
-    (description "This package renames every occurrence of a symbol at point
-using @code{clang-rename}.")))
+  (let ((target-file "clang-rename.el"))
+   (package
+     (inherit clang)
+     (name "emacs-clang-rename")
+     (source (let ((orig (package-source clang)))
+               (origin
+                 (method (origin-method orig))
+                 (uri (origin-uri orig))
+                 (sha256 (origin-sha256 orig))
+                 (file-name (string-append name
+                                           (package-version clang)))
+                 (modules '((guix build utils)
+                            (srfi srfi-1)
+                            (ice-9 ftw)))
+                 (snippet
+                  `(begin
+                     (copy-file (string-append "tools/clang-rename/" ,target-file)
+                                ,target-file)
+                     (map delete-file-recursively
+                          (fold delete
+                                (scandir ".")
+                                '("." ".." ,target-file)))
+                     #t)))))
+     (build-system emacs-build-system)
+     (inputs
+      `(("clang" ,clang)))
+     (arguments
+      `(#:phases
+        (modify-phases %standard-phases
+          (add-after 'unpack 'configure
+            (lambda* (#:key inputs #:allow-other-keys)
+              (let ((clang (assoc-ref inputs "clang")))
+                (emacs-substitute-variables ,target-file
+                  ("clang-rename-binary"
+                   (string-append clang "/bin/clang-rename"))))
+              #t)))))
+     (synopsis "Rename every occurrence of a symbol using clang-rename")
+     (description "This package renames every occurrence of a symbol at point
+using @code{clang-rename}."))))
-- 
2.19.2

From e4fdd028c0e71118073aee34c5976a4948b46511 Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <[email-masked]>
Date: Fri, 30 Nov 2018 15:13:51 +0100
Subject: [PATCH 3/3] gnu: Add package-from-clang-elisp-file

emacs-clang-format and emacs-clang-rename both are packages that are build by
extracting a single elisp file and building it as an emacs package.
This concept is encapsulated in the package-from-clang-elisp-file
function. This reduces repeating of concepts in the two package definitions.

* gnu/packages/llvm.scm (package-from-clang-elisp-file): New function
* gnu/packages/llvm.scm (emacs-clang-format): Use new function
* gnu/packages/llvm.scm (emacs-clang-rename): Use new function
---
 gnu/packages/llvm.scm | 138 +++++++++++++++++++-----------------------
 1 file changed, 61 insertions(+), 77 deletions(-)

diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 3eb0fb29f..ad71c967a 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -460,85 +460,69 @@ code analysis tools.")
      "This package provides a Python binding to LLVM for use in Numba.")
     (license license:bsd-3)))
 
+;;; Returns a package definition that packages an emacs-lisp file from the
+;;; clang source. The package has the name PKGNAME and packages the file
+;;; SRC-FILE from the clang source in its root directory with the name
+;;; TARGET-FILE where SUBST substitutions will be performed on the elisp file
+;;; and SYN and DESC as the package synopsis an description.
+(define (package-from-clang-elisp-file pkgname src-file target-file subst syn desc)
+  (package
+    (inherit clang)
+    (name pkgname)
+    (source (let ((orig (package-source clang)))
+              (origin
+                (method (origin-method orig))
+                (uri (origin-uri orig))
+                (sha256 (origin-sha256 orig))
+                (file-name (string-append pkgname "-" (package-version clang)))
+                (modules '((guix build utils)
+                           (srfi srfi-1)
+                           (ice-9 ftw)))
+                (snippet
+                 `(begin
+                    ;; Copy target file to source root and delete all other files
+                    (copy-file (string-append ,src-file)
+                               ,target-file)
+                    (map delete-file-recursively
+                         (fold delete
+                               (scandir ".")
+                               '("." ".." ,target-file)))
+                    #t)))))
+    (build-system emacs-build-system)
+    (inputs
+     `(("clang" ,clang)))
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'configure
+           (lambda* (#:key inputs #:allow-other-keys)
+             (let ((clang (assoc-ref inputs "clang")))
+               (emacs-substitute-variables ,target-file
+                 ,subst))
+             #t)))))
+    (synopsis syn)
+    (description desc)))
+
 (define-public emacs-clang-format
-  (let ((target-file "clang-format.el"))
-    (package
-      (inherit clang)
-      (name "emacs-clang-format")
-      (source (let ((orig (package-source clang)))
-                (origin
-                  (method (origin-method orig))
-                  (uri (origin-uri orig))
-                  (sha256 (origin-sha256 orig))
-                  (modules '((guix build utils)
-                             (srfi srfi-1)
-                             (ice-9 ftw)))
-                  (snippet
-                   `(begin
-                      ;; Copy target file to source root and delete all other files
-                      (copy-file (string-append "tools/clang-format/" ,target-file)
-                                 ,target-file)
-                      (map delete-file-recursively
-                           (fold delete
-                                 (scandir ".")
-                                 '("." ".." ,target-file)))
-                      #t)))))
-      (build-system emacs-build-system)
-      (inputs
-       `(("clang" ,clang)))
-      (arguments
-       `(#:phases
-         (modify-phases %standard-phases
-           (add-after 'unpack 'configure
-             (lambda* (#:key inputs #:allow-other-keys)
-               (let ((clang (assoc-ref inputs "clang")))
-                 (emacs-substitute-variables ,target-file
-                   ("clang-format-executable"
-                    (string-append clang "/bin/clang-format"))))
-               #t)))))
-      (synopsis "Format code using clang-format")
-      (description "This package allows to filter code through @code{clang-format}
+  (package-from-clang-elisp-file
+   "emacs-clang-format"
+   "tools/clang-format/clang-format.el"
+   "clang-format.el"
+   '("clang-format-executable"
+                    (string-append clang "/bin/clang-format"))
+   "Format code using clang-format"
+   "This package allows to filter code through @code{clang-format}
 to fix its formatting.  @code{clang-format} is a tool that formats
 C/C++/Obj-C code according to a set of style options, see
-@url{http://clang.llvm.org/docs/ClangFormatStyleOptions.html}."))))
+@url{http://clang.llvm.org/docs/ClangFormatStyleOptions.html}."))
 
 (define-public emacs-clang-rename
-  (let ((target-file "clang-rename.el"))
-   (package
-     (inherit clang)
-     (name "emacs-clang-rename")
-     (source (let ((orig (package-source clang)))
-               (origin
-                 (method (origin-method orig))
-                 (uri (origin-uri orig))
-                 (sha256 (origin-sha256 orig))
-                 (file-name (string-append name
-                                           (package-version clang)))
-                 (modules '((guix build utils)
-                            (srfi srfi-1)
-                            (ice-9 ftw)))
-                 (snippet
-                  `(begin
-                     (copy-file (string-append "tools/clang-rename/" ,target-file)
-                                ,target-file)
-                     (map delete-file-recursively
-                          (fold delete
-                                (scandir ".")
-                                '("." ".." ,target-file)))
-                     #t)))))
-     (build-system emacs-build-system)
-     (inputs
-      `(("clang" ,clang)))
-     (arguments
-      `(#:phases
-        (modify-phases %standard-phases
-          (add-after 'unpack 'configure
-            (lambda* (#:key inputs #:allow-other-keys)
-              (let ((clang (assoc-ref inputs "clang")))
-                (emacs-substitute-variables ,target-file
-                  ("clang-rename-binary"
-                   (string-append clang "/bin/clang-rename"))))
-              #t)))))
-     (synopsis "Rename every occurrence of a symbol using clang-rename")
-     (description "This package renames every occurrence of a symbol at point
-using @code{clang-rename}."))))
+  (package-from-clang-elisp-file
+   "emacs-clang-rename"
+   "tools/clang-rename/clang-rename.el"
+   "clang-rename.el"
+   '("clang-rename-binary"
+                   (string-append clang "/bin/clang-rename"))
+   "Rename every occurrence of a symbol using clang-rename"
+   "This package renames every occurrence of a symbol at point
+using @code{clang-rename}."))
-- 
2.19.2