all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* [PROPOSAL] Builder, a build system integration for Emacs
@ 2023-05-21 10:21 BTuin
  2023-05-21 12:11 ` Philip Kaludercic
                   ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: BTuin @ 2023-05-21 10:21 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 10851 bytes --]

Table of Contents
─────────────────

1. The problem it tries to solve
2. How it works
.. 1. Build system detection
.. 2. Configure and compile
.. 3. Project only or not?
.. 4. Command formatting
.. 5. `function-modification'
.. 6. Configuration
3. Open questions
.. 1. Local configuration
.. 2. Build directory name
.. 3. Build system detection
.. 4. Tramp support
.. 5. Flexibility
.. 6. Adding a build system
.. 7. Other
4. Conclusion


Hello, I would like to propose a new package to integrate in Emacs,
"Builder".  It provides integration with build systems, to ease the
configuration and the compilation process, by automatically detecting
the build system and proposing relevant commands.

Big disclaimer: I do not know many build systems, I do not have a lot of
experience in programming, I do not know (E)lisp very well, and English
is not my first language.  Now that you are definitely sold on it, let's
have a deeper explanation!

As far as I know, Emacs does not provide a convenient way to use build
systems, like CMake, Meson, Autotools, Cargo, Dune, and so on.  I know
your can configure the compilation command with local variables, but:
• You cannot have a choice, like `cmake .. -DCMAKE_BUILD_TYPE=Release'
   or `cmake .. -DCMAKE_BUILD_TYPE=Debug'
• It requires to set it up manually
• There is no (convenient?) way to have a configuration phase and a
   compilation phase.  (like `cmake ..' followed by `make')

With Builder, you just run `builder-configure' which set up the build
system, and `builder-compile' to compile the project.
`builder-configure' allow you to easily switch between release and
debug.

You can try it with the `builder-demo/' directory found inside this git
repository: <https://gitlab.com/btuin2/builder.git>

There are more explanations in the README.org.


1 The problem it tries to solve
═══════════════════════════════

   Builder tries to solve two issues at the same time: being convenient
   and being easy to configure.  Independently they are not *that*
   difficult to solve, but together it gets really complex.  For example,
   some build systems need to run their command /outside/ the build
   directory, while others need to run it /inside/.  Also, some commands
   need to be modified according to the state of the project: Meson needs
   the flag `--reconfigure' if it was already configured.


2 How it works
══════════════

2.1 Build system detection
──────────────────────────

   The first step is the detection of the build system.  It simply checks
   in a list of files which one exists and it returns a list of build
   system identifiers.  For instance if both CMake and Meson are
   available, it returns the list `("cmake" "meson")'.

   Notice that the detection is completely separated from build systems
   addition.  This is a deliberate design choice to make it more
   versatile, for example to filter results or have a cache system (both
   not implemented).


2.2 Configure and compile
─────────────────────────

   The configuration is a first step for some build systems (Autotools,
   CMake, Meson)… Indeed they are not actually build systems, but build
   system /generator/ (not that it really matters).  `builder-configure'
   and `builder-compile' respectively provide, well, configuration and
   compilation.  They both do what you would expect by proposing relevant
   commands and running the selected one at the right place.


2.3 Project only or not?
────────────────────────

   You will quickly notice that many functions have the argument
   `variable'.  I am not really sure about this one, but it would allow
   to use a build system not located at the root of a project.  I guess
   it is useful for monorepo projects?  I did minimal testing on it and
   it seems to works.


2.4 Command formatting
──────────────────────

   Commands pass though the function `builder-format-command' before
   being run.  It uses the function `format-spec` with predefined
   specifiers, such as `%n` for the number of cores, `%b` for the build
   directory name…  For example "mycommand -proc %n –dir %b" becomes
   "mycommand -proc 4 –dir build".


2.5 `function-modification'
───────────────────────────

   A pretty neat feature is `function-modification': before running, the
    command is modified by a function.  Its power is showcased with the
    Dune build system and CMake Presets, because you can chose a specific
    target from a list, and the command is modified as needed!  Some
    details need to be investigated though: should the command pass
    through `builder-format-command' before being send to the function?
    After?  Or let the function take care of it?


2.6 Configuration
─────────────────

   The configuration of a build system is hierarchical: at toplevel, it
   affects every instruction from the build system, but you can configure
   each instruction independently.  For example, you don't need to
   specify manually that each CMake command need to run inside the
   directory, but you can still customize a specific command.

   In the following example, both "debug" and "fast" commands are
   executed inside the build directory, and "release" is executed at the
   root of the project.

   ┌────
   │ (builder-add-build-system
   │  :build-system-id "gcc"
   │  :compile '(:inside-directory t ;; Affects all instructions
   │             :instructions
   │             ((:name "debug"
   │               :command "gcc main.c -g")
   │              (:name "release"
   │               :command "gcc main.c -O2"
   │               ;; Overrides the higher level :inside-directory
   │               :inside-directory nil)
   │              (:name "fast"
   │               :command "gcc main.c -Ofast"))))
   └────


3 Open questions
════════════════

   This is a list of problems I don't have a definitive answer to.
   Suggestions are most welcome.


3.1 Local configuration
───────────────────────

   It's necessary to have a way to locally configure a project to add
   commands, specify the build directory…  But I don't really know how to
   do that.  Should it affect the whole project?  Only a specific
   directory (e.g. only `project-root/subdir')?  I know that local
   variables are a thing in Emacs, but they are not a good solution for
   this since they are actually *buffer* variables.  So changing the
   local configuration would require to reload each local variable even
   unrelated one that could have been modified on a per buffer basis.
   Also, the commands cannot be considered as safe, so opening a file
   trigger a warning each time (unless you mark the values as safe).

   It would be a good idea to discuss with the Projectile package devs
   about it, to agree on a common solution if they wish.

   I have implemented an alternative, dir-val.el.  The variables are
   stored in a tree, each node corresponding to a directory.  The
   variables are "hierarchical".  If you have a directory
   `/dirA/dirB/dirC' and you set a variable to `dirB', then `dirC' will
   also access it.  But you can also change the value only for `dirC'.

   I'm wondering if this is actually useful.  Would project variables be
   enough?


3.2 Build directory name
────────────────────────

   This is harder to solve than it seems.  I would like to have a
   mechanism to change it easily, so you can have `build-release' and
   `build-debug' directories, allowing you to conveniently switch between
   release and debug without having to recompile the whole project each
   time you switch.  BUT: some tools have specific expectations about
   this name.  `clangd' expects it to be named `build', and I'm pretty
   sure that the OCaml ecosystem expect it to be named `_build'.  Also,
   how to know which directory to use to execute a command, as
   "configure" and "compile" may have different names?  With a cache?
   With a regex to select candidates?  Local configuration only?

   I really would like to have this feature implemented.  Currently you
   can chose to modify the build directory name according to the current
   git branch (which is pretty reliable), but it would be really useful
   to have `build-release' and `build-debug' directories.


3.3 Build system detection
──────────────────────────

   Currently there are few build systems added to the list.  But there
   could be hundreds.  How well would it scale?  Especially on slow file
   systems?


3.4 Tramp support
─────────────────

   I don't use Tramp and have never used it.  I don't think it would be
   too hard to support it, but the detection could be a problem if there
   are too many build systems.


3.5 Flexibility
───────────────

   Is Builder good enough to support every build system?  To accommodate
   most use cases?  As I said I don't have a lot of experience in build
   systems, so suggestions are welcome.


3.6 Adding a build system
─────────────────────────

   A build system is added with `builder-add-build-system'.  Is it good
   enough?  I fear it is a bit too error prone because it's easy to mess
   with parenthesis and keywords location.  How to solve that?  With a
   macro?  EIEIO?


3.7 Other
─────────

   Some other are listed in the README and there are probably many other
   issues I did not think about.


4 Conclusion
════════════

   I hope you will find this package useful.  Please tell me if this is
   unclear, needs more documentation, or if you have issues.

   Currently only a few build systems are supported.  You can already use
   it to build Emacs with the build system `autotools'.
   `builder-configure' and `builder-compile' are respectively bind to
   `C-x p C' and `C-x p c'.  `builder-configure' will create a directory
   named "build" and run `../configure' from it, and `builder-compile'
   will run `make -jN' with N the number of cores on your processor (the
   result of `num-processor').

   I think this package is far from ready, but I need to know if the
   design is sound enough and future proof.

   Obviously I will need to sign the copyright assignment.

[-- Attachment #2: builder.el --]
[-- Type: text/x-emacs-lisp, Size: 28927 bytes --]

;;; builder.el --- Build a project and run it -*- lexical-binding: t; -*-

;;; Copyright (C) 2022  BTuin
;;; Version: 0.1
;;; Package-Requires: ((emacs "28.1"))
;;; Homepage: https://gitlab.com/btuin2/builder

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;; This package provides functions to ease the use of build systems with Emacs.

;;; Code:

(require 'project)
(require 'json)
(require 'cl-lib)

;; only used to get the current branch name to create the build dir
(require 'vc-git)

;; Global variables

(defgroup builder nil
  "Customizations for Builder."
  :version 2
  :group 'tools)

(defvar builder--infos (make-hash-table :test 'equal)
  "Hash table storing the informations about the build systems.
The key is the build systemd ID, a (lowercase?) string corresponding to the
name of the build system.  For example, the key of CMake is \"cmake\".

The value for each key is a plist with multiple keys.
Those keys are symbols, and currently are `:compile',
`:configure' and `:priority'.

For `:compile' and `:configure', the attached values are
also plists.  Those plist, called instructions, have keys that are also
symbols.  Those symbols are:
`:inside-directory': whether the instructions should be executed inside
the build directory or inside its parent directory.
`:function-modification': a function with two arguments, COMMAND and DIRECTORY.
COMMAND, a string, is the command to execute inside a shell.  Those functions
exist because some build systems need to add arguments in different situations.
For example, Meson needs the flag \"--reconfigure\" if it was already
configured once before.
At this level, `:function-modification' applies to every instructions.
`:instructions': a list of instructions. This is the deepest level. Detailled
below.

An instruction is a plist containing a command, a name, and optionnaly some
parameters. The values are:
`:name': a string used to display when asking the user.
`:command': a string, the command to execute in a shell. Before execution,
it is formatted by the function `#'builder-format-command'. See its
documentation for more informations.
`:function-modification': see `:function-modification' detailled upwards. At
this level, only applies to this instruction.

`:priority' is an integer. It is used to change the display order when
asking the user. Greater value means greater priority.")

(defcustom builder-dir-name "build"
  "Default build directory name."
  :type 'string
  :version "28.1"
  :group 'builder)

(defcustom builder-cache-file (locate-user-emacs-file "projects-builder")
  "Cache file.
Currently unused."
  :type 'file
  :version "28.1"
  :group 'builder)

(defcustom builder-enable-multiple-build-directories nil
  "Currently unused.
If set to true, use one directory per build system configuration.
For example, configuring CMake in debug mode will use the directory
\"build-cmake-debug\"."
  :type 'boolean
  :safe t
  :version "29.1"
  :group 'builder)

(defcustom builder-build-dir-name-function #'builder-get-build-dir-name-default
  "A function that return the name of the build directory."
  :type 'function
  :safe t
  :version "29.1"
  :group 'builder)


(defvar builder-build-system-files
  '(("cmake" . "CMakeLists.txt")
    ("cmake-presets" . "CMakePresets.json")
    ("meson" . "meson.build")
    ("autotools". ("configure" "configure.ac"))
    ("make" . "Makefile")
    ("cargo" . "Cargo.toml")
    ("dune" . "dune-project")))


(define-key project-prefix-map "C" 'builder-configure)
(define-key project-prefix-map "c" 'builder-compile)

\f
;; General functions


(cl-defun builder-compilation-buffer-name-function-creator (&key build-system-id name type)
  "Return a *function* which return the name of the compilation buffer.
BUILD-SYSTEM-ID is the name of the build system (e.g. \"cmake\", \"make\"...).
NAME is the type of build, such as \"debug\", \"release\"...
TYPE is the type of command, such as \"compile\", \"configure\"..."
  (lambda (mode) (concat "*" (downcase mode) " "
                         " <"
                         (project-name (project-current))
                         "> "
                         type
                         build-system-id " "
                         name
                         "*")))

(defun builder-get-build-dir-name-default (&rest _)
  "Return the build dir name given by the customizable variable BUILD-DIR-NAME."
  (let ((build-dir-name (or builder-dir-name
                            "build")))
    build-dir-name))

(defun builder-get-build-dir-name-vc-branch (&rest _)
  "Return BUILD-DIR-NAME concatenated with the current branch.
For example, if the project is set on the branch \"bugfix\", the returned
name is \"build-bugfix\"."
  (let ((build-dir-name (or builder-dir-name
                            "build"))
        (current-vc-backend (vc-responsible-backend "." t)))
    (concat
     build-dir-name "-"
     (cond ((string= current-vc-backend "Git")
            (car (vc-git-branches)))
           (t (message "Could not determine branch name from version control"))))))

(defun builder-get-build-dir-name-with-build-configuration (configuration &rest _)
  "Return BUILD-DIR-NAME concatenated with CONFIGURATION (WARNING!!! BROKEN).
WARNING!!!  The implementation is actually completely broken, beacause the
configuration and the compilation instructions need to have exactly the same
name.  This needs to be rethought.  Maybe use a some kind of regex to get
the name of the directory? Like \"build(\\-.+)?\"?
Original documentation below.
CONFIGURATION is the build system configuration.  For example, if you want to
build the project in release mode, the result will be \"build-release\".
This is useful if you want to quickly switch between release and debug,
as some build systems will need a complete recompilation."
  (let ((build-dir-name (or builder-dir-name
                            "build")))
    (concat
     build-dir-name "-" configuration)))

(defun builder--get-build-dir-parent (&optional directory)
  "Return the absolute path of the build directory's parent.
DIRECTORY is the parent of the build directory, relative to
the project root or can an asbolute path.  If nil, the
project root is returned."
  (if directory
      (expand-file-name directory (project-root (project-current)))
    (project-root (project-current))))


(defun builder--get-build-dir-name-absolute (&optional directory)
  "Return the absolute path of the build directory.
If set, DIRECTORY is the parent directory of the build dir.
DIRECTORY is relative to the project root, or can be absolute."
  (expand-file-name
   (funcall builder-build-dir-name-function)
   (builder--get-build-dir-parent directory)))


(defun builder--get-path-relative-to-project (directory)
  "Return DIRECTORY relative to the project root."
  (file-relative-name directory (project-root (project-current))))


(defun builder-reload-dir-locals-project ()
  "Update buffer variables set by the file \"dir-locals.el\".
Currently unused, was created to experiment with dir-locals.el to
create project-local instructions."
  (interactive)
  (let ((dir (project-root (project-current)))
        (enable-local-variables t))
    (dolist (buffer (buffer-list))
      (with-current-buffer buffer
        (when (equal default-directory dir)
          (hack-dir-local-variables-non-file-buffer))))))


(defun builder--detect-build-systems-list (directory)
  "Return a list of detected build systems inside DIRECTORY.
DIRECTORY is either absolute or relative to the root of the project."
  (let ((directory (builder--get-build-dir-parent directory))
        (detected-build-systems (list)))
    (dolist (system-file-list builder-build-system-files)
      (dolist (system-file (ensure-list (cdr system-file-list)))
        (when (file-exists-p (expand-file-name system-file directory))
          (cl-pushnew (car system-file-list) detected-build-systems :test #'equal))))
      detected-build-systems))


(defun builder-detect-build-system (&optional directory)
  "Return the identifier of one detected and selected build system.
The detection occurs inside DIRECTORY if set, otherwise at the root
of the project.  If there are multiple build systems, asks the user
to select one.
Return nil if no build system is detected."
  (let ((build-system-list (builder--detect-build-systems-list
                            (or directory
                                (builder--get-build-dir-parent)))))
    (cond ((zerop (length build-system-list))
           nil)
          ((length= build-system-list 1)
           (message (car build-system-list)))
          (t
           (completing-read "Select build system: " build-system-list nil t)))))


(cl-defun builder-add-build-system (&key build-system-id
                                          configure
                                          compile
                                          priority)
  "Add a build system to the hash table BUILDER--INFOS.
BUILD-SYSTEM-ID is a string indentifying the build system.
CONFIGURE is a plist containing the instructions for the configuration.
COMPILE is a plist containing the instructions for the configuration.
PRIORITY is an integer used to chose the display order of the build system"
  (let ((build-system-infos nil))
    (setq build-system-infos
          (plist-put build-system-infos :configure configure))
    (setq build-system-infos
          (plist-put build-system-infos :compile compile))
    (setq build-system-infos
          (plist-put build-system-infos :priority (or priority
                                                      0)))
    (puthash build-system-id build-system-infos builder--infos)))


(cl-defun builder-add-instruction (&key build-system-id
                                         type
                                         instruction)
  "Add an instruction to the global table.
BUILD-SYSTEM-ID is the identifier of the build system (a string).
TYPE is either :configure or :compile.
INSTRUCTION is a plist with a key :name, a key :command and other
optional keys."
  (let* ((build-infos (gethash build-system-id builder--infos))
         (type-infos (plist-get build-infos type ))
         (instructions-list (plist-get type-infos  :instructions)))
    (cl-pushnew instruction instructions-list
                :test (lambda (x y) (string-equal (plist-get x :name)
                                                  (plist-get y :name))))
    (setq build-infos (plist-put build-infos type
                                 (plist-put type-infos :instructions instructions-list)))
    (puthash build-system-id build-infos builder--infos)))


(cl-defun builder-remove-instruction (&key build-system-id
                                            type
                                            name)
  "Remove an instruction from the global table.
BUILD-SYSTEM-ID is the identifier of the build system (a string).
TYPE is either :configure or :compile.
NAME is the name of the instruction to remove."
  (let* ((build-infos (gethash build-system-id builder--infos))
         (type-infos (plist-get build-infos type ))
         (instructions-list (plist-get type-infos  :instructions)))
    (setq instructions-list
          (cl-remove-if (lambda (x) (string-equal (plist-get x :name)
                                                  name)) instructions-list))
    (setq build-infos (plist-put build-infos type
                                 (plist-put type-infos :instructions instructions-list)))
    (puthash build-system-id build-infos builder--infos)))


(defun builder--get-instruction-priority (instruction)
  "Get the priority of an instruction.
INSTRUCTION is a plist that may contain the key `:priority',
linking to an integer.
If the key is not present, the priority is 0."
  (let ((priority (plist-get instruction :priority)))
    (if priority
        priority
      0)))

(defun builder--compare-instructions-priority (x y)
  "Compare the priority of the instructions X and Y.
Returns true if X has a lower priority than Y."
  (< (builder--get-instruction-priority x)
     (builder--get-instruction-priority y)))


(defun builder--get-instruction-list (build-system-id instruction-type)
  "Return a list of instructions for the build system.
BUILD-SYSTEM-ID is a string identifying the build system,
such as \"cmake\" or \"meson\".
INSTRUCTION-TYPE is a symbol, such as `:config' or `:compile'."
  (let* ((instructions ())
         (build-system-data (gethash build-system-id builder--infos))
         (global-instruction-type-data (plist-get build-system-data instruction-type)))
    (dolist (new-instruction (plist-get global-instruction-type-data :instructions))
      (cl-pushnew
       (dolist (symbol '(:inside-directory
                         :function-modification)
                       new-instruction)
         (let ((value (plist-get global-instruction-type-data symbol)))
           (if (plist-member new-instruction symbol)
               new-instruction
             (setq new-instruction (plist-put new-instruction symbol value)))))
       instructions
       :test (lambda (x y)
               (string-equal
                (plist-get x :name)
                (plist-get y :name)))))
    ;; Not sure if the priority system actually works, nor if it is desirable...
    (sort instructions #'builder--compare-instructions-priority)))


(defun builder--find-in-list-of-plist (plist-list value key)
  "In a list of plist, return the plist matching the value VALUE for the key KEY.
PLIST-LIST is a list of plist, such as
`((:name \"name1\" ...) (:name \"name2\"...))'"
  (cl-find value plist-list :test (lambda (str pl)
                                    (string-equal str (plist-get pl key)))))


(defun builder--select-instruction (instruction-list message)
  "Ask the user to select an instruction from INSTRUCTION-LIST.
INSTRUCTION-LIST is a list of plist, and the function displays
the `:name' value of each plist to make the choice.
It also displays the string MESSAGE to the user."
  (cond ((length= instruction-list 1)
         (plist-get (car instruction-list) :name))
        ((length> instruction-list 1)
         (completing-read
          message
          (cl-map 'list (lambda (x) (plist-get x :name)) instruction-list)))))

(defun builder-format-command (command &optional directory)
  "Format the string COMMAND by replacing format specifications.
It uses the function `format-spec'.
DIRECTORY is the parent of the build directory.

There are multiple format specifications.
`%b' is the build directory name, quotted with `shell-quote-argument'.
`%n' is the number of processors (core) availables.  Provided by the
function `num-processors'.
`%p' is the absolute path of the parent of the build directory, quotted
with `shell-quote-argument'
`%f' is the absolute path of the build directory, quotted with
`shell-quote-argument'

For example, if you want a \"make\" command that use all of your cores, you
can use the string \"cmake -j%n\".  If your processor has 4 cores, it will
be transformed to \"cmake -j4\"."
  (format-spec
   (or command "")
   `((?b . ,(shell-quote-argument (funcall builder-build-dir-name-function)))
     (?n . ,(num-processors))
     (?p . ,(shell-quote-argument (builder--get-build-dir-parent directory)))
     (?f . ,(shell-quote-argument (builder--get-build-dir-name-absolute directory))))))


(cl-defun builder--execute-command (&key instruction directory)
  "Execute the command from INSTRUCTION.
INSTRUCTION is a plist with the key `:command', with a string command as
a value.
MESSAGE is displayed to the user when asked to confirm the command.
DIRECTORY the parent of the build directory.
MODIFICATION-FUNC is a function modifying the command."
  (let* ((build-dir-absolute-directory
          (builder--get-build-dir-name-absolute directory))
         (formatted-command
          (builder-format-command (plist-get instruction :command) directory))
         (work-directory nil)
         (inside-directory (plist-get instruction :inside-directory)))
    (when (not (file-directory-p build-dir-absolute-directory))
      ;; Should we ask before creating the directory?
      (make-directory build-dir-absolute-directory))
    (if inside-directory
        (setq work-directory build-dir-absolute-directory)
      (setq work-directory (builder--get-build-dir-parent directory)))
    (let ((default-directory work-directory))
      (compile (read-string
                (concat
                 (when inside-directory
                   (concat "[in \""
                           (builder--get-path-relative-to-project work-directory)
                           "\"] "))
                 "Command: ")
                (if (plist-get instruction :function-modification)
                    (funcall (plist-get instruction :function-modification)
                             formatted-command
                             directory)
                  formatted-command))))))


;;;###autoload
(defun builder-configure (&optional directory)
  "Configure the build system.

The configuration of a build system is a step happening before compilation.
Some \"build systems\", such as Autotools or CMake are not actually build
systems. They are in reality build systems generator. Their goal is to
create Makefiles (or equivalent), which will then be used to compile the
project.
During this phase, some options are set, such as whether the project is
compiled in debug or release mode, which files need to be compiled,
or compile-time values.

This function detects which build systems are available at the project root,
or at DIRECTORY if set.  DIRECTORY is either absolute or relative to the
project root.
It then asks to select a build system, and finally to chose an available
instruction from the build system."
  (interactive)
  (let* ((build-system-id
          (builder-detect-build-system directory))
         (selected-name nil)
         (instruction-list
          (builder--get-instruction-list build-system-id :configure))
         (instruction nil))
    (if build-system-id
        (progn (setq selected-name (builder--select-instruction
                                    instruction-list
                                    (concat "Select type of configuration for "
                                            build-system-id ":")))
               (setq instruction (builder--find-in-list-of-plist
                                  instruction-list selected-name
                                  :name))
               (let ((compilation-buffer-name-function
                      ;; How does this even work??
                      ;; Isn't lexical binding supposed to prevent that?
                      (builder-compilation-buffer-name-function-creator
                       :type "configure"
                       :build-system-id build-system-id
                       :name selected-name)))
                 (builder--execute-command
                  :instruction instruction
                  :directory directory)))
      (message "No known build system detected"))))


;; Should builder-compile and builder-configure exists?
;; Should they be one function with one parameter? Why? Why not?
;; Arguements for keeping them separated:
;; - Can change one without affecting the other
;; - There is not a lot of logic inside anyway, would merging them be actually useful?
;; Arguments againts:
;; - Duplication of logic
;; - Creating a new one require to copy the code. For instance, projectile has 5
;;   relevant functions, configure, compile, package, install, test (and run,
;;   but this is a special case). Keeping five copies of virtually the same
;;   function seems a bad idea.
;;;###autoload
(defun builder-compile (&optional directory)
  "Compile the project.
This function detects which build systems are available at the project root,
or at DIRECTORY if non-nil.
It then asks to select a build system, and then to chose an available
instruction from the build system."
  (interactive)
  (let* ((build-system-id
          (builder-detect-build-system directory))
         (selected-name nil)
         (instruction-list
          (builder--get-instruction-list build-system-id :compile))
         (instruction nil))
    (if build-system-id
        (progn(setq selected-name (builder--select-instruction
                                   instruction-list
                                   (concat "Select type of compilation for "
                                           build-system-id ":")))
              (setq instruction (builder--find-in-list-of-plist
                                 instruction-list selected-name
                                 :name))
              (let ((compilation-buffer-name-function
                     ;; How does this even work??
                     ;; Isn't lexical binding supposed to prevent that?
                     (builder-compilation-buffer-name-function-creator
                      :type "compile"
                      :build-system-id build-system-id
                      :name selected-name)))
                (builder--execute-command
                 :instruction instruction
                 :directory directory)))
      (message "No known build system detected"))))

\f
;; Build system specific functions

(cl-defun builder--meson-configure-modify-command (command directory)
  "If Meson is already configured, append \"--reconfigure\" to COMMAND.
It checks in the build directory, the child of DIRECTORY, if the file
\"meson-private\" exists.  DIRECTORY is either absolute or relative
to the project root."
  (let ((build-dir-absolute-name (builder--get-build-dir-name-absolute directory)))
    (if (file-directory-p (expand-file-name "meson-private" build-dir-absolute-name))
        (concat command " --reconfigure")
      command)))


(defun builder--cmake-presets-modify-command (command directory)
  "Ask the user to chose a preset from the file \"CMakePresets.json\".
It appends \"--preset=PRESET\" to COMMAND, with PRESET being the
selected preset.
It looks for the file \"CmakePresets.json\" at DIRECTORY.  DIRECTORY is either
 absolute or relative to the project root."
  (let
      ((cmake-presets-directory
        (expand-file-name
         "CMakePresets.json"
         (or directory
             (project-root (project-current)))))
       (selectioned-preset nil))
    (setq selectioned-preset
          (when
              (and
               (json-available-p)
               (file-exists-p cmake-presets-directory))
            (let
                ((presets-content
                  (with-temp-buffer
                    (insert-file-contents cmake-presets-directory)
                    (goto-char
                     (point-min))
                    (json-read)))
                 (presets-table (make-hash-table)))
              (seq-doseq
                  (preset-name
                   (cdr
                    (assoc 'configurePresets presets-content)))
                (puthash
                 (cdr (assoc 'name preset-name))
                 (cdr (assoc 'displayName preset-name))
                 presets-table))
              (when (not (hash-table-empty-p presets-table))
                (completing-read "Select preset: " presets-table nil t)))))
    (if selectioned-preset
        (concat command " --preset=" selectioned-preset)
      (error "No preset selected"))))


(defun builder--dune-modify-command-compile (command directory)
  "Ask user to chose a dune target.
It recursively reads the dune files inside \"bin\" located inside DIRECTORY to
 find the name of the executable.  Each dune file contains can contain at most
one parameter \"executable\" xor (exclusive or) \"executables\".
It then reads the value of the paramter \"name\" (resp. \"names\").
COMMAND is the command to modify.
TODO: add a setting to change the directory, as \"bin\" may not be
the right directory."
  (let* ((working-directory (builder--get-build-dir-parent
                             directory))
         (source-dir (expand-file-name
                      "bin"
                      working-directory))
         (candidates ()))
    (dolist (dune-file (directory-files-recursively source-dir "^dune$"))
      (with-temp-buffer
        (insert "(progn ")
        (insert-file-contents dune-file)
        (goto-char (point-max))
        (insert ")")
        (goto-char (point-min))
        (let* ((content (cdr (read (current-buffer))))
               (sexp nil)
               (res nil))
          (while (and (setq sexp (caar content)) (not res))
            (cond
             ((eq 'executable sexp)
              (cl-pushnew
               (file-relative-name
                (file-name-concat
                 (file-name-parent-directory dune-file)
                 (concat
                  (symbol-name (car (alist-get 'name (cdar content))))
                  ".exe"))
                working-directory)
               candidates))
             ((eq 'executables sexp)
              (setq candidates
                    (append candidates
                            (mapcar
                             (lambda (name)
                               (file-relative-name
                                (file-name-concat
                                 (file-name-parent-directory dune-file)
                                 (concat
                                  name
                                  ".exe"))
                                working-directory))
                             (mapcar #'symbol-name
                                     (alist-get 'names (cdar content))))))))
            (setq content (cdr content))))))
    (concat
     command
     (when candidates
       (let ((choice
              (shell-quote-argument
               (completing-read "Select target:"
                                (cons "all" candidates)
                                nil t))))
         (if (not (string-equal "all" choice))
             (concat " " choice)))))))



\f
;; Add build systems

(builder-add-build-system
 :build-system-id "cmake"
 :configure '(:inside-directory t
              :instructions
              ((:name "release"
                :command "cmake .. -DCMAKE_BUILD_TYPE=release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON")
              (:name "debug"
               :command "cmake .. -DCMAKE_BUILD_TYPE=debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON")))
 :compile '(:instructions
            ((:name "parallel"
              :command "cmake --build %b --parallel %n"))))

(builder-add-build-system
 :build-system-id "meson"
 :configure '(:instructions
              ((:name "release"
                :command "meson setup %b --buildtype=release")
               (:name "debug"
                :command "meson setup %b --buildtype=debug"))
              :function-modification builder--meson-configure-modify-command)
 :compile '(:instructions
            ((:name "default"
              :command "meson compile -C %b"))))


(builder-add-build-system
 :build-system-id "cmake-presets"
 :configure '(:instructions
              ((:name "default"
                :command "cmake"))
              :function-modification builder--cmake-presets-modify-command)
 :compile '(:instructions
            ((:name "parallel"
              :command "cmake --build %b --parallel %n"))))


(builder-add-build-system
 :build-system-id "autotools"
 :configure '(:instructions
              ((:name "configure"
                :command "../configure"
                :inside-directory t)
               (:name "autoconf"
                :command "autoconf")))
 :compile '(:instructions
            ((:name "parallel"
              :command "make -j%n"))
            :inside-directory t))


(builder-add-build-system
 :build-system-id "make"
 :compile '(:instructions
            ((:name "parallel"
              :command "make -j%n"))))

(builder-add-build-system
 :build-system-id "cargo"
 :compile '(:instructions
            ((:name "release"
              :command "cargo build --release")
             (:name "debug"
              :command "cargo build"))))

(builder-add-build-system
 :build-system-id "dune"
 :compile '(:instructions
            ((:name "compile"
              :command "dune build"
              :function-modification builder--dune-modify-command-compile))))


(provide 'builder)
;;; builder.el ends here

[-- Attachment #3: dir-var.el --]
[-- Type: text/x-emacs-lisp, Size: 8744 bytes --]

;;; dir-var.el --- Directory variables -*- lexical-binding: t; -*-

;;; Copyright (C) 2023  BTuin
;;; Version: 0.1
;;; Package-Requires: ((emacs "28.1"))
;;; Homepage: https://gitlab.com/btuin2/builder

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;; This package provides project variables.

;;; Code:


(require 'project)
(require 'map)
(require 'cl-lib)


(defvar dir-var--table (make-hash-table :test 'equal))

(defcustom dir-var-file-name "emacs-project-variables-cache.el"
  "Name of file in which project variable are written."
  :type 'file
  :group 'builder)



(defvar dir-var--tree '("" nil))

;; node structure : (name list-of-subnodes plist-of-variables-with-values)

(defun dir-var--make-node (id &optional subnodes variables)
  "Create a node.
ID is the identifier of the node, a string.
SUBNODES if a list of nodes.
VARIABLES is a plist, the properties are the name of the variable (a symbol)
 and the values are their value."
  (cons id (cons subnodes variables)))

(defun dir-var--get-node-subnodes (node)
  "Return the subnodes of NODE."
  (cadr node))

(defun dir-var--get-node-name (node)
  "Return the name of NODE (its ID)."
  (car node))

(defun dir-var--get-node-variables (node)
  "Return the plist containing the variables of NODE."
  (caddr node))

(defun dir-var--node-equal-p (node1 node2)
  "Check if the nodes NODE1 and NODE2 are equal.
Two nodes are equal when their names are equal."
  (string-equal (dir-var--get-node-name node1)
                (dir-var--get-node-name node2)))

(defun dir-var--find-subnode (node name)
  "Find a subnode in the list of subnodes of NODE.
NAME is the name of the subnode to find."
  (seq-find (lambda (x)
              (string-equal (dir-var--get-node-name x)
                            name))
            (dir-var--get-node-subnodes node)))


(defun dir-var--insert-node-in-parent (parent-node node)
  "Insert NODE in PARENT-NODE subnodes list."
  (let ((subnodes (dir-var--get-node-subnodes parent-node)))
    (let ((subnodes (if node
                        (cons
                         node
                         (cl-remove-if (lambda (x) (dir-var--node-equal-p x node)) subnodes))
                      subnodes)))
      (setf parent-node (dir-var--make-node
                         (dir-var--get-node-name parent-node)
                         subnodes
                         (dir-var--get-node-variables parent-node))))))


(defun dir-var--set-node-variable (node variable value)
  "Return NODE with the variable VARIABLE set to VALUE."
  (let ((variable-plist (dir-var--get-node-variables node)))
    (dir-var--make-node
     (dir-var--get-node-name node)
     (dir-var--get-node-subnodes node)
     (list (plist-put variable-plist variable value)))))


(defun dir-var--get-node-variable-value (node variable)
  "Get the value of VARIABLE stored in NODE."
  (plist-get (dir-var--get-node-variables node) variable))


(defun dir-var--node-variable-exists-p (node variable)
  "Return non-nil if VARIABLE is stored in NODE."
  (plist-member (dir-var--get-node-variables node) variable))

(defun dir-var--remove-node-variable (node variable)
  "Return NODE without the variable VARIABLE."
  (let ((variable-plist (dir-var--get-node-variables node)))
    (dir-var--make-node
     (dir-var--get-node-name node)
     (dir-var--get-node-subnodes node)
    (list (map-delete variable-plist variable)))))


(defun dir-var--insert-variable (root dir-split variable value)
  "Return a new tree with the variable inserted.
ROOT is the root node of the tree.
DIR-SPLIT is a list of string.  It is the full path of the directory
splitted a each file separator.  For example, on UNIX systems, the
corresponding splitted path of \"/home/user/project/source\" is
the list (\"home\" \"user\" \"project\" \"source\").
VARIABLE is the symbol to refer to the variable.
VALUE is the value of the variable."
  (if (car dir-split)
      (let ((subnode (or
                      (dir-var--find-subnode root (car dir-split))
                      (dir-var--make-node (car dir-split)))))
        (dir-var--insert-node-in-parent
         root
         (dir-var--insert-variable subnode (cdr dir-split) variable value)))
    (dir-var--set-node-variable root variable value)))


(defun dir-var--variable-get-value (root dir-split variable)
  "Return the value of VARIABLE.

ROOT is the root node of the tree
DIR-SPLIT is a list of string.  It is the full path of the directory
splitted a each file separator.  For example, on UNIX systems, the
corresponding splitted path of \"/home/user/project/source\" is
the list (\"home\" \"user\" \"project\" \"source\")."
  (let ((value nil)
        (node root))
    (while (and dir-split node)
      (setq node (dir-var--find-subnode node (car dir-split)))
      (setq value (or (dir-var--get-node-variable-value node variable)
                      value))
      (setq dir-split (cdr dir-split)))
    value))


(defun dir-var--remove-empty-subnodes (node)
  "Return NODE without its empty subnodes.
A subnode is empty if it does not contain any variable or subnode."
  (dir-var--make-node
   (dir-var--get-node-name node)
   (cl-remove-if-not
    (lambda (node)(or (dir-var--get-node-subnodes node)
                      (dir-var--get-node-variables node)))
    (dir-var--get-node-subnodes node))
   (dir-var--get-node-variables node)))


(defun dir-var--remove-variable (root dir-split variable)
  "Return the tree without the variable VARIABLE stored at DIR-SPLIT.
ROOT is the root node of the tree.
DIR-SPLIT is a list of string.  It is the full path of the directory splitted
at each file separator.  For example, on UNIX systems, the corresponding
splitted path of \"/home/user/project/source\" is the list
 (\"home\" \"user\" \"project\" \"source\")."
  (if (car dir-split)
      (let ((subnode (or
                      (dir-var--find-subnode root (car dir-split))
                      (dir-var--make-node (car dir-split)))))
        (dir-var--remove-empty-subnodes
         (dir-var--insert-node-in-parent
          root
          (dir-var--remove-variable subnode (cdr dir-split) variable))))
    (dir-var--remove-node-variable root variable)))


(defun dir-var--split-directory (&optional directory)
  "Split the full path of DIRECTORY in a list.
If DIRECTORY is nil, the variable DEFAULT-DIRECTORY is used instead.
If DIRECTORY is not an absolute path, it is relative to DEFAULT-DIRECTORY."
  (cl-remove-if
   #'string-empty-p
   (file-name-split (expand-file-name (or directory
                                          default-directory)))))

(defun dir-var-insert (variable value &optional directory)
  "Set a variable for DIRECTORY and its subdirectories.
VARIABLE is the name of a variable, a symbol.
VALUE is the value of the variable, it can be anything.
DIRECTORY is an optional parameter.  If it is not set, the current directory
 is used."
  (let ((splitted-path (dir-var--split-directory directory)))
    (setq dir-var--tree
          (dir-var--insert-variable dir-var--tree splitted-path variable value))))

(defun dir-var-get (variable &optional directory)
  "Get the value of VARIABLE at DIRECTORY.
DIRECTORY is an optional parameter.  If it is not set, the current directory
 is used."
  (let ((splitted-path (dir-var--split-directory directory)))
    (dir-var--variable-get-value dir-var--tree splitted-path variable)))


(defun dir-var-variable-exists-p (variable &optional directory)
  "Return non-nil if the variable VARIABLE is defined in DIRECTORY or parents.
DIRECTORY is an optional parameter.  If it is not set, the current directory
is used.

For exemple, with the path \"/home/user/project/source\", if the
variable \"var1\" is set in the directory \"project\", this function returns
non-nil for the directory \"source\"."
  (let ((dir-split (dir-var--split-directory directory))
        (node dir-var--tree)
        (exists nil))
    (while (and (not exists) dir-split node)
      (setq exists (dir-var--node-variable-exists-p node variable))
      (setq node (dir-var--find-subnode node (car dir-split)))
      (setq dir-split (cdr dir-split)))))


(provide 'dir-var)
;;; dir-var.el ends here

[-- Attachment #4: dir-var-test.el --]
[-- Type: text/x-emacs-lisp, Size: 3071 bytes --]

;;; dir-var-test.el --- Directory variables -*- lexical-binding: t; -*-

;;; Copyright (C) 2023  BTuin
;;; Homepage: https://gitlab.com/btuin2/builder

;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;; This package provides tests for dir-var-el.

;;; Code:

(require 'ert)

;; "require" does not work for some reason, "dir-var.el" is not found.
;; (require 'dir-var)


(ert-deftest dir-var-set-variable-test ()
  (should
   (equal
    (dir-var--set-node-variable
     (dir-var--set-node-variable
      (dir-var--make-node "name")
      'var "test")
     'var "value")
    '("name" nil (var "value")))))


(ert-deftest dir-var-insert-variable-test ()
  (should
   (equal
    (dir-var--insert-variable
     (dir-var--insert-variable
      (dir-var--make-node "test")
      (list "1" "2" "3" "4")
      'var1 "value1")
     (list "1" "2" "5")
     'var2 "value2")
   '("test"
     (("1"
       (("2"
	 (("5" nil
	   (var2 "value2"))
	  ("3"
	   (("4" nil
	     (var1 "value1")))))))))))))

(ert-deftest dir-var-remove-variable-test ()
  (should
   (equal
    (dir-var--remove-variable
     (dir-var--insert-variable
      (dir-var--insert-variable
       (dir-var--make-node "test")
       (list "1" "2" "3" "4")
       'var1 "value1")
      (list "1" "2" "5")
      'var2 "value2")
     (list "1" "2" "3" "4")
     'var1)
    '("test"
      (("1"
        (("2"
	  (("5" nil
	    (var2 "value2")))))))))))


(ert-deftest dir-var-get-variable-test ()
  (let ((tree (dir-var--make-node "test")))
    (setq tree (dir-var--insert-variable
                tree
                (list "1" "2" "3" "4")
                'var1 "value1"))
    (setq tree (dir-var--insert-variable
                tree
                (list "1" "2" "5")
                'var2 "value2"))
    (setq tree (dir-var--insert-variable
                tree
                (list "1" "2" "3")
                'var3 "value3"))
    (should
     (equal
      (dir-var--variable-get-value
       tree
       (list "1" "2" "3" "4")
       'var1)
      "value1"))
    (should
     (equal
      (dir-var--variable-get-value
       tree
       (list "1" "2" "5")
       'var2)
      "value2"))
    (should
     (equal
      (dir-var--variable-get-value
       tree
       (list "1" "2" "3" "4")
       'var3)
      "value3"))
    (should
     (equal
      (dir-var--variable-get-value
       tree
       (list "1" "2" "5")
       'var3)
      nil))))


(provide 'dir-var-test)
;;; dir-var-test.el ends here

[-- Attachment #5: README.org --]
[-- Type: text/org, Size: 10575 bytes --]

* Introduction

Simple Emacs package to ease the use of build systems.  By default it will use the directory ~build~ at the root of the project.
It uses Emacs' built-in project.el.

*THIS IS A WORK IN PROGRESS!*
This package is not and should not be considered as stable.  Expect unexpected changes at any time.

** Presentation
Project compilation with Emacs is often tedious: there is no built-in system to easily run CMake, Meson or others with a single function, meaning you need to keep a terminal open to run the commands.

*Builder* aims to solve this problem by automatically detecting available build systems for the project, and by proposing a command that will run in a compilation buffer.

There is currently no way to have project local configuration, but this is a planned feature.

* Usage

By default it will use or create the directory ~build~ at the root of a project to generate the build system.  You can change the name globally with the customizable variable ~builder-dir-name~.

To run, just launch the function ~builder-configure~ or ~builder-compile~.

There are demos in the ~builder-demo~ directory.

** Add a build system
*** Detection
You must first make the system detectable.  To do this, you add an element to the alist ~builder--build-system-files~.  The car of an element is the identifier of the system (a string, such as "make", "cargo", "cmake"...), and the cdr is the name of the characteristic file of the build system, located at the project's root.  For "make" it is a file named "Makefile", for "cmake" it is "CMakeLists.txt" and so on.
You can add an element to the list like this:
#+BEGIN_SRC elisp
(add-to-list builder-build-system-files '("make" "Makefile"))
#+END_SRC

*** Add the information
Once the build system is detectable, you need to add the information about the instructions. It works like that:

#+BEGIN_SRC elisp
(builder-add-build-system
 :build-system-id "meson"
 :configure '(:instructions
              ((:name "release"
                :command "meson setup %b --buildtype=release")
               (:name "debug"
                :command "meson setup %b --buildtype=debug"))
              :function-modification builder--meson-configure-modify-command)
 :compile '(:instructions
            ((:name "default"
              :command "meson compile -C %b"))))
#+END_SRC

There are many things to note:
- ~:build-system-id "meson"~: the build system identifier.  Be careful to not mistype it and to check the case!
- ~:configure~ and ~:compile~: currently there a two type of instructions. /configure/ and /compile/.  They both take the same kind of arguments, a ~plist~ with those keys:
  + ~:instructions~: a list of /instructions/, a ~plist~ including a /command/, a name and other optional parameters
    - ~:name~: mandatory, the name of the instruction (a string)
    - ~:command~: mandatory, the command to run (a string). Before execution, it is formatted by ~builder-format-command~.  For example, if the build directory name is "build" on a computer with 4 processor cores, "cmake --build %b --parallel %n" is transformed to "cmake --build \"build\" --parallel 4".  See the doctring of ~builder-format-command~ for more information.
    - ~function--modification~: a function that take in argument a command (a string) and a directory.  The returned value is the command to execute.  Very useful if the command needs information only available at runtime. For example, to reconfigure /meson/ the flag ~--reconfigure~ needs to be added at the end of the command. ~:function-modification builder--meson-configure-modify-command~ automates this.  ~function--modification~ is either instruction specific or global to the whole list of instructions (see below).
  + ~function--modification~: at this level, it affects all instructions of the instruction list.  Same behaviour as described above.
- ~:inside-directory t~ (not demonstrated here): whether the command needs to run inside or outside the build directory (a boolean).  Like ~function--modification~, it can be instruction specific or not.  False by default.
      

** Features
*** Main features
**** Build system detection
Automatically detects your build system and only show relevant commands!

**** Modification of the command on the fly
Some build systems have specific needs.  For instance, CMake's presets are stored into a JSon file.  Builder automatically reads this file, and propose you available targets.
Meson needs the flag ~--reconfigure~ if it was already configured. /Builder/ automatically appends it to the command when needed.

** All features
*** Build directory
- [X] Allow to change the default name
- [ ] Multiple out-of-tree builds (removed because it was utterly broken)
- [X] Possibility to have one build directory per branch
- [X] Chose whether to run the command inside or outside the directory
*** Detection
- [X] Detect the build system
- [X] Change the location of the search
- [X] In case of multiple build systems, allow to select one
- [ ] Override the detection locally
*** Configure/compilation
- [X] Chose between debug/release (or others)
- [ ] *Easily* customize the command locally or globally
- [X] Edit the command on the fly
- [ ] Per project history
- [X] Command formatting with format strings
*** Program execution
- [ ] Run the result of the compilation from Emacs


* Design
** Definitions
/Builder/ makes the artificial distinction between a command and an instruction:
- Command : the plain text sent to the shell.  For example, "make -j2" is a command.
- Instruction : a structure containing a command and other information.  For example, the following is an instruction:
#+BEGIN_SRC elisp
(:name "default" :command "cmake" :function-modification #'my-function)
#+END_SRC



** Build system detection
In the current implementation, build systems are detected by checking if specific files exist.  For example, CMake is detected if a file ~CMakeLists.txt~ exists in the project directory.
Then, the user is asked to select the build system from the list.  It then returns a string, the identifier of the build system.
You may notice that the detection is completely independent from the instructions.  This is a deliberate choice, to allow better flexibility. For example, you could implement rules to only show a build system if some conditions are true; or to not display a build system if an alternative is also present.

** Build system table
Information about build systems are stored in the variable ~builder--infos~.  This is a hash table with build system ids as keys (e.g. "cmake", "meson"...).  See the related doctring for more information.


** Instruction specific vs global
Some settings can be set for a specific instruction, or for all instructions of the instruction list (globally).  This is the case for ~function--modification~ for example.  If it is set globally it can still be overridden on a per instruction basis.  This is extremely useful if you want to exclude some instructions from the function without too much hassle.  For example you can set this parameter to ~nil~ for a specific instruction, while all of the other while use your function.

** Project variables
Currently there is no system to customize commands on a per project basis.  The existing Emacs directory variables could be used, but there are some issues with that.  The variables are actually *buffer* local, so changing the command would require to reload *every* open buffer, which would cause issues if some variables were modified.
Also, the security system is great, but since commands cannot be safe, a warning would appear every time you open a buffer unless you set the values as safe (how much of a problem is that?).

* Open questions
- Should ~:function-modification~ be executed before ~builder-format-command~?  After?  Should ~builder-format-command~ not being called at all if ~function-modification~ is set?
- Force build systems to use ~builder-dir-name~?  Let them use their own defaults?  For example OCaml uses ~_build~ by default.
- Is the design sound enough?  Could it theoretically support every past, present, and future build systems?
- Is ~:function-modification~ well designed?
- Are directory variable useful? Would project variable be sufficient?
- More specifiers in ~builder-format-command~?
- How to implement local variables?  Leverage the existing infrastructure?
- Should ~builder-compile~ and ~builder-configure~ be merged?  Do they have virtually any difference?
- Is a priority system useful (to rank available commands)?
- Is the detection system able to handle hundreds of build systems?  If it is not, what should be done?
- ~builder-get-build-dir-name-with-build-configuration~ is kind of broken (and now removed), because the name of the configuration is only known at build time...  Which means the function does not work correctly if it is not called from ~builder-compile~ or ~builder-configure~...  It means that the configuration instruction and the compilation instruction need to have exactly the same name... Is there a better way to implement this functionality?

* Troubleshooting
** My build system is not detected!
Make sure you added a file to ~builder-build-system-files~ (and that there is not typo in the file name)!
** No commands are proposed!
SO your build system is detected, but there is an error when you selected it. Did you use the function ~builder-add-build-system~?  Are you sure you used the same identifier as for ~builder-build-system-files~?  They both need to have the same case.
** Some configuration doesn't work!
So some configurations such as ~:function-modification~ or ~:inside-directory~ have no effect?  Be careful with the parenthesis:
#+BEGIN_SRC elisp
  (builder-add-build-system
   :build-system-id "autotools"
   :configure '(:instructions
                ((:name "configure"
                  :command "../configure")
                 :inside-directory t)))
#+END_SRC
This example is incorrect: ~:inside-directory~ should be in the same context as ~:name~ (notice the parenthesis after ~:command "../configure"~).
This is the correct version:
#+BEGIN_SRC elisp
  (builder-add-build-system
   :build-system-id "autotools"
   :configure '(:instructions
                ((:name "configure"
                  :command "../configure"
                  :inside-directory t))))
#+END_SRC

* Contributing
I plan to propose this package to Emacs upstream, so if you want to contribute you have to sign the [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Copyright-Assignment.html][copyright assignment]].

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 10:21 [PROPOSAL] Builder, a build system integration for Emacs BTuin
@ 2023-05-21 12:11 ` Philip Kaludercic
  2023-05-21 14:56   ` Augustin Chéneau (BTuin)
  2023-05-21 17:24 ` Jim Porter
  2023-05-22 22:00 ` Richard Stallman
  2 siblings, 1 reply; 101+ messages in thread
From: Philip Kaludercic @ 2023-05-21 12:11 UTC (permalink / raw)
  To: BTuin; +Cc: emacs-devel


Your proposal sounds interesting, and I think it is worth adding to GNU
or NonGNU ELPA.  Do you have a preference?  Also, it would be nice if
you could host the files in a Git repository somewhere, so that the ELPA
build-system can mirror your changes.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 12:11 ` Philip Kaludercic
@ 2023-05-21 14:56   ` Augustin Chéneau (BTuin)
  0 siblings, 0 replies; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-21 14:56 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

Le 21/05/2023 à 14:11, Philip Kaludercic a écrit :
> 
> Your proposal sounds interesting, and I think it is worth adding to GNU
> or NonGNU ELPA.  Do you have a preference?  Also, it would be nice if
> you could host the files in a Git repository somewhere, so that the ELPA
> build-system can mirror your changes.

Well I think it could be directly integrated inside Emacs, since there 
is a related TODO in `project.el', I quote:

* "Build tool related functionality.  Start with a `project-build'
   command, which should provide completions on tasks to run, and
   maybe allow entering some additional arguments.  This might
   be handled better with a separate API, though.  Then we won't
   force every project backend to be aware of the build tool(s) the
   project is using."


Otherwise I prefer GNU Elpa.

And the project is hosted here, sorry it wasn't clear:
<https://gitlab.com/btuin2/builder>







^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 10:21 [PROPOSAL] Builder, a build system integration for Emacs BTuin
  2023-05-21 12:11 ` Philip Kaludercic
@ 2023-05-21 17:24 ` Jim Porter
  2023-05-21 19:33   ` Augustin Chéneau (BTuin)
  2023-05-22 22:00 ` Richard Stallman
  2 siblings, 1 reply; 101+ messages in thread
From: Jim Porter @ 2023-05-21 17:24 UTC (permalink / raw)
  To: BTuin, emacs-devel

On 5/21/2023 3:21 AM, BTuin wrote:
> Hello, I would like to propose a new package to integrate in Emacs,
> "Builder".  It provides integration with build systems, to ease the
> configuration and the compilation process, by automatically detecting
> the build system and proposing relevant commands.

This loos interesting. I've actually been working (though not much 
lately) on a similar project by the name of "taco" (Tool Aware 
COmpilation[1]): https://github.com/jimporter/taco

I haven't had time to look over your project in detail, but I see a few 
main differences. The biggest one is that taco divides the build process 
into mostly-independent stages. For example, an Autotools project uses 
three stages: preconfigure (generate "configure" from "configure.ac"), 
configure (generate "Makefile" from "configure"), and build (run the 
Makefile). This way, other build configurators that generate Makefiles 
can just piggyback on the "Make" builder for the actual compilation.

[1] I'm sure I'd need to tweak this name to put it on GNU ELPA though 
(something like "taco-build" for the package identifier might make sense...)




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 17:24 ` Jim Porter
@ 2023-05-21 19:33   ` Augustin Chéneau (BTuin)
  2023-05-21 19:58     ` Jim Porter
  0 siblings, 1 reply; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-21 19:33 UTC (permalink / raw)
  To: Jim Porter; +Cc: emacs-devel

Le 21/05/2023 à 19:24, Jim Porter a écrit :
> This loos interesting. I've actually been working (though not much 
> lately) on a similar project by the name of "taco" (Tool Aware 
> COmpilation[1]): https://github.com/jimporter/taco
> 

Nice, thanks for letting me know!

> I haven't had time to look over your project in detail, but I see a few 
> main differences. The biggest one is that taco divides the build process 
> into mostly-independent stages. For example, an Autotools project uses 
> three stages: preconfigure (generate "configure" from "configure.ac"), 
> configure (generate "Makefile" from "configure"), and build (run the 
> Makefile). This way, other build configurators that generate Makefiles 
> can just piggyback on the "Make" builder for the actual compilation.
> 

Interestingly I already thought about chaining build systems, but I 
wasn't sure how to implement it.
Unfortunately the main drawback of your method is that you can't easily 
switch between a debug or release mode (if I understood your code 
correctly).
Also, what if an intermediate step is used in two different context, 
both with different next step?

I thought of something with a list of targets names, but I'll need to 
think more deeply.
Currently you could achieve the same manually, but I agree it's not very 
convenient.





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 19:33   ` Augustin Chéneau (BTuin)
@ 2023-05-21 19:58     ` Jim Porter
  2023-05-21 21:36       ` John Yates
  2023-05-22 16:35       ` Augustin Chéneau (BTuin)
  0 siblings, 2 replies; 101+ messages in thread
From: Jim Porter @ 2023-05-21 19:58 UTC (permalink / raw)
  To: Augustin Chéneau (BTuin); +Cc: emacs-devel

On 5/21/2023 12:33 PM, Augustin Chéneau (BTuin) wrote:
> Interestingly I already thought about chaining build systems, but I 
> wasn't sure how to implement it.
> Unfortunately the main drawback of your method is that you can't easily 
> switch between a debug or release mode (if I understood your code 
> correctly).

Well, the main reason for that is that I just haven't implemented that 
yet, since I'd want to go well beyond just a debug/release toggle. For 
example, this feature could probably be useful for configuring *any* 
kind of build variant, including things like cross-compilation. I 
haven't figured out a sufficiently-generic way to handle that across 
many build systems though.

Currently, the way I tend to use taco is just to let it give me an 
appropriate template for the compile command, which I hand-edit. For the 
configuration step, I often add some extra options, but I only need to 
do that when I'm setting up a build; for actually compiling a project, 
the default is usually what I want.

> Also, what if an intermediate step is used in two different context, 
> both with different next step?

I think that should be fine. For example, CMake can generate Makefile or 
Ninja files, depending on what flags you pass. Once it does that, it 
should be easy to see what the next step is retrospectively by looking 
at the files in your build dir.

(This could get a bit trickier for something like meson, which seems to 
want you to use its own `meson compile` wrapper, even though it uses 
Ninja as the default build backend. But in that case, I think you'd just 
need to scan for an appropriate sentinel file for meson in the build 
dir, and then have the "meson compile step" be higher priority than the 
generic "Ninja compile step".)

> I thought of something with a list of targets names, but I'll need to 
> think more deeply.
> Currently you could achieve the same manually, but I agree it's not very 
> convenient.

This is something I've thought a bit about too: right now, taco is only 
good for compiling a project, but it doesn't help for things like 
running unit tests, building HTML documentation, etc. That will take 
some careful thought though, since some build systems let you define 
arbitrary build targets for things like this, and others treat targets 
specially. For example, `make test` is just a normal Make target like 
any other, but `meson test` is (somewhat) special; I could call my Make 
"test" target anything I like (e.g. "check"), but I don't think meson is 
so flexible.

Another lower-level option for targets is to take advantage of Emacs' 
built-in Pcomplete code. Pcomplete can handle completing command-line 
arguments for lots of commands, and if you added some Pcomplete handlers 
for "make" that let you tab-complete Make targets, then you could 
probably use that in Builder (or taco) as well. This has the additional 
benefit that you get nice tab-completion in M-x shell too.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 19:58     ` Jim Porter
@ 2023-05-21 21:36       ` John Yates
  2023-05-22 16:35       ` Augustin Chéneau (BTuin)
  1 sibling, 0 replies; 101+ messages in thread
From: John Yates @ 2023-05-21 21:36 UTC (permalink / raw)
  To: Jim Porter; +Cc: Augustin Chéneau (BTuin), emacs-devel

On Sun, May 21, 2023 at 3:59 PM Jim Porter <jporterbugs@gmail.com> wrote:
>
> since I'd want to go well beyond just a debug/release toggle.

+1.  At work I regularly build debug, coverage, valgrind, multiple
xsans and release.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-21 19:58     ` Jim Porter
  2023-05-21 21:36       ` John Yates
@ 2023-05-22 16:35       ` Augustin Chéneau (BTuin)
  2023-05-23  0:44         ` Po Lu
  1 sibling, 1 reply; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-22 16:35 UTC (permalink / raw)
  To: emacs-devel

Le 21/05/2023 à 21:58, Jim Porter a écrit :
> On 5/21/2023 12:33 PM, Augustin Chéneau (BTuin) wrote:
>> Interestingly I already thought about chaining build systems, but I 
>> wasn't sure how to implement it.
>> Unfortunately the main drawback of your method is that you can't 
>> easily switch between a debug or release mode (if I understood your 
>> code correctly).
> 
> Well, the main reason for that is that I just haven't implemented that 
> yet, since I'd want to go well beyond just a debug/release toggle. For 
> example, this feature could probably be useful for configuring *any* 
> kind of build variant, including things like cross-compilation. I 
> haven't figured out a sufficiently-generic way to handle that across 
> many build systems though.
> 
Oh I didn't mean a simple toggle, I meant an arbitrary command variant. 
For instance with Builder you can define a "debug2", "compile_arm" or 
any other command.

Maybe you could do something like this with Taco:
(cmake
  (build-step . configure)
  (project-file . "CMakeLists.txt")
  (working-directory srcdir)
  (commands
   (release . "cmake" "-G" "Unix Makefiles" builddir)
   (option . "cmake" "-G" "Unix Makefiles" "-DMY_OPTION=yes" buildir))
  (next-step build (make . parallel)))
(make
  (build-step . build)
  (project-file . "Makefile")
  (working-directory builddir)
  (commands
   (default . "make")
   (parallel . "make" "-j4")))

> Currently, the way I tend to use taco is just to let it give me an 
> appropriate template for the compile command, which I hand-edit. For the 
> configuration step, I often add some extra options, but I only need to 
> do that when I'm setting up a build; for actually compiling a project, 
> the default is usually what I want.
> 
>> Also, what if an intermediate step is used in two different context, 
>> both with different next step?
> 
> I think that should be fine. For example, CMake can generate Makefile or 
> Ninja files, depending on what flags you pass. Once it does that, it 
> should be easy to see what the next step is retrospectively by looking 
> at the files in your build dir.
> 
> (This could get a bit trickier for something like meson, which seems to 
> want you to use its own `meson compile` wrapper, even though it uses 
> Ninja as the default build backend. But in that case, I think you'd just 
> need to scan for an appropriate sentinel file for meson in the build 
> dir, and then have the "meson compile step" be higher priority than the 
> generic "Ninja compile step".)
> 
That's why I went with the idea that each build system uses its own 
command to compile, but that's still not ideal as you can't change 
globally the "make" command...


>> I thought of something with a list of targets names, but I'll need to 
>> think more deeply.
>> Currently you could achieve the same manually, but I agree it's not 
>> very convenient.
> 
> This is something I've thought a bit about too: right now, taco is only 
> good for compiling a project, but it doesn't help for things like 
> running unit tests, building HTML documentation, etc. That will take 
> some careful thought though, since some build systems let you define 
> arbitrary build targets for things like this, and others treat targets 
> specially. For example, `make test` is just a normal Make target like 
> any other, but `meson test` is (somewhat) special; I could call my Make 
> "test" target anything I like (e.g. "check"), but I don't think meson is 
> so flexible.
> 
Yes, this is getting complex very quickly.
I think that separating targets is simpler, so you have a known list of 
targets (configure, compile, package, install, test, and run), and you 
can treat each case and build system separately.  The price to pay is a 
lower interoperability between build systems, but I'm not sure if the 
additional complexity worth it anyway.
But I would be interested if you manage to solve it properly!

> Another lower-level option for targets is to take advantage of Emacs' 
> built-in Pcomplete code. Pcomplete can handle completing command-line 
> arguments for lots of commands, and if you added some Pcomplete handlers 
> for "make" that let you tab-complete Make targets, then you could 
> probably use that in Builder (or taco) as well. This has the additional 
> benefit that you get nice tab-completion in M-x shell too.
> 
Nice, thank you!  I wasn't aware of its existence, I'll try it.










^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-21 10:21 [PROPOSAL] Builder, a build system integration for Emacs BTuin
  2023-05-21 12:11 ` Philip Kaludercic
  2023-05-21 17:24 ` Jim Porter
@ 2023-05-22 22:00 ` Richard Stallman
  2023-05-23  8:36   ` Philip Kaludercic
  2 siblings, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-22 22:00 UTC (permalink / raw)
  To: BTuin; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > As far as I know, Emacs does not provide a convenient way to use build
  > systems,

Isn't "use build systems" what M-x compile does?
Assuming that each bui;d system provides a shell command to invoke it,
M-x compile can run that command and build the package.

It can also parse the error messages and find the loci of problems.
GNU tools use our standard format for error messages, but M-x compile
handles various others.  We want to extend it to handle whatever
formats are useful to handle.

Let's not duplicate what we already have.  If we implement facilities
to do other jobs, let's make them work with what we already have.

  > • It requires to set it up manually

It requires setting up, but that doesn't have to be done manually.
Whatever code is used to set things up, a Lisp program can call
that and then call M-x compile.

  > • You cannot have a choice, like `cmake .. -DCMAKE_BUILD_TYPE=Release'
  >    or `cmake .. -DCMAKE_BUILD_TYPE=Debug'

Surely we can do any of these things in code that would call M-x ocmpile

  > • There is no (convenient?) way to have a configuration phase and a
  >    compilation phase.  (like `cmake ..' followed by `make')

If you implement something fancier that runs two build programs,
it can use M-x compile once to run the first, and call M-x compile
again to run the second.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-22 16:35       ` Augustin Chéneau (BTuin)
@ 2023-05-23  0:44         ` Po Lu
  2023-05-23 21:10           ` Augustin Chéneau (BTuin)
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-23  0:44 UTC (permalink / raw)
  To: Augustin Chéneau (BTuin); +Cc: emacs-devel

"Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:

> Oh I didn't mean a simple toggle, I meant an arbitrary command
> variant. For instance with Builder you can define a "debug2",
> "compile_arm" or any other command.

I don't understand how this works; before you can change targets, you
need to regenerate the build system for your program by running
configure.

Are you saying that in Builder, `configure' is an extra step, run each
time the target changes?



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-22 22:00 ` Richard Stallman
@ 2023-05-23  8:36   ` Philip Kaludercic
  2023-05-23 11:18     ` Eli Zaretskii
                       ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: Philip Kaludercic @ 2023-05-23  8:36 UTC (permalink / raw)
  To: Richard Stallman; +Cc: BTuin, emacs-devel

Richard Stallman <rms@gnu.org> writes:

> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
> [[[ whether defending the US Constitution against all enemies,     ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
>   > As far as I know, Emacs does not provide a convenient way to use build
>   > systems,
>
> Isn't "use build systems" what M-x compile does?
> Assuming that each bui;d system provides a shell command to invoke it,
> M-x compile can run that command and build the package.

The issue is not what M-x compile, but that with a lot of modern
programming languages the build systems are complex but automatable, to
a point that it would be nice if Emacs could detect the necessary
information to invoke the right command or sequence of commands.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23  8:36   ` Philip Kaludercic
@ 2023-05-23 11:18     ` Eli Zaretskii
  2023-05-23 12:13       ` Po Lu
  2023-05-23 18:46       ` Augustin Chéneau (BTuin)
  2023-05-24  3:34     ` David Masterson
  2023-05-28 21:17     ` Björn Bidar
  2 siblings, 2 replies; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-23 11:18 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: rms, btuin, emacs-devel

> From: Philip Kaludercic <philipk@posteo.net>
> Cc: BTuin <btuin@mailo.com>,  emacs-devel@gnu.org
> Date: Tue, 23 May 2023 08:36:13 +0000
> 
> Richard Stallman <rms@gnu.org> writes:
> 
> > Isn't "use build systems" what M-x compile does?
> > Assuming that each bui;d system provides a shell command to invoke it,
> > M-x compile can run that command and build the package.
> 
> The issue is not what M-x compile, but that with a lot of modern
> programming languages the build systems are complex but automatable, to
> a point that it would be nice if Emacs could detect the necessary
> information to invoke the right command or sequence of commands.

You mean, to guess a good value for compile-command?



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23 11:18     ` Eli Zaretskii
@ 2023-05-23 12:13       ` Po Lu
  2023-05-23 18:46       ` Augustin Chéneau (BTuin)
  1 sibling, 0 replies; 101+ messages in thread
From: Po Lu @ 2023-05-23 12:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Philip Kaludercic, rms, btuin, emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Philip Kaludercic <philipk@posteo.net>
>> Cc: BTuin <btuin@mailo.com>,  emacs-devel@gnu.org
>> Date: Tue, 23 May 2023 08:36:13 +0000
>> 
>> Richard Stallman <rms@gnu.org> writes:
>> 
>> > Isn't "use build systems" what M-x compile does?
>> > Assuming that each bui;d system provides a shell command to invoke it,
>> > M-x compile can run that command and build the package.
>> 
>> The issue is not what M-x compile, but that with a lot of modern
>> programming languages the build systems are complex but automatable, to
>> a point that it would be nice if Emacs could detect the necessary
>> information to invoke the right command or sequence of commands.
>
> You mean, to guess a good value for compile-command?

Perhaps we could do so based on the major mode and the current
directory.

For instance, if a Makefile is present within the current directory,
defaulting to `make -k' should work.

Similarly, C programs can make do with just `make foo', where foo is the
base name of the file being visited.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23 11:18     ` Eli Zaretskii
  2023-05-23 12:13       ` Po Lu
@ 2023-05-23 18:46       ` Augustin Chéneau (BTuin)
  2023-05-24  6:32         ` Juri Linkov
  1 sibling, 1 reply; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-23 18:46 UTC (permalink / raw)
  To: emacs-devel

Le 23/05/2023 à 13:18, Eli Zaretskii a écrit :
>> From: Philip Kaludercic <philipk@posteo.net>
>> Cc: BTuin <btuin@mailo.com>,  emacs-devel@gnu.org
>> Date: Tue, 23 May 2023 08:36:13 +0000
>>
>> Richard Stallman <rms@gnu.org> writes:
>>
>>> Isn't "use build systems" what M-x compile does?
>>> Assuming that each bui;d system provides a shell command to invoke it,
>>> M-x compile can run that command and build the package.
>>
>> The issue is not what M-x compile, but that with a lot of modern
>> programming languages the build systems are complex but automatable, to
>> a point that it would be nice if Emacs could detect the necessary
>> information to invoke the right command or sequence of commands.
> 
> You mean, to guess a good value for compile-command?
> 

I realize that my initial message may have not been clear, my apologies.

This is exactly what Builder does: if you want to compile, it will 
detect which build systems are present in the project and provide you 
choices of commands to execute.  You can see that as an autocomplete for 
M-x compile.

After asking you to chose the command, it will actually pass the string 
to the function `compile'.  So it doesn't re-implement anything.
It's just a layer over `compile', to remove repetitive tasks.

I know you can customize `compile-command', but you can only have one 
value by project, you need to set it for each project and you can't 
switch between values.  It doesn't help you if you want to switch to 
debug or another target, or to run tests, or if you have multiple build 
systems on your project.


I hope it's easier to understand!





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-23  0:44         ` Po Lu
@ 2023-05-23 21:10           ` Augustin Chéneau (BTuin)
  2023-05-23 21:17             ` Óscar Fuentes
                               ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-23 21:10 UTC (permalink / raw)
  To: emacs-devel

Le 23/05/2023 à 02:44, Po Lu a écrit :
> "Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:
> 
>> Oh I didn't mean a simple toggle, I meant an arbitrary command
>> variant. For instance with Builder you can define a "debug2",
>> "compile_arm" or any other command.
> 
> I don't understand how this works; before you can change targets, you
> need to regenerate the build system for your program by running
> configure.
> 
> Are you saying that in Builder, `configure' is an extra step, run each
> time the target changes?
> 

Yes, it is.

Let's illustrate with an hypothetical workflow: you work on Emacs, and 
you want to easily switch between multiple configurations, say "minimal" 
which enable very few features to ease debugging and "regular" which 
enable many features, such as pgtk, json, native compilation... (and 
possibly many other variants, there is no limit of number).

First, you execute `builder-configure' which detects the build system, 
finds Autotools and asks you to chose between "minimal", "regular", and 
others.  Once you've chosen, the minibuffer is filled with the "minimal" 
command (for example `../configure --without-threads 
--without-toolkit-scroll-bars`.  You press enter, the command is 
executed in a compile buffer.

Then, you need to compile.  You call `builder-compile', and you may have 
to chose between multiple targets, for example "default" with the value 
"make" and "parallel" with the value "make -jN", N being the number of 
cores on you processor.  Once you've chosen, the same as for configure 
happens, the command is executed in a compilation buffer.

If you want to change to the "regular" configuration target, you call 
`builder-configure` and select this target.  Then, you call 
`builder-compile` to compile the project.

So each time you want to change the target you call `builder-configure`. 
  But with out of tree builds, it could be possible to create one build 
directory for each configuration, which would remove the need to execute 
the configuration step each time you want to change.  It's not yet 
available as it is really not trivial to implement, but I'll try to find 
a satisfying solution.





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-23 21:10           ` Augustin Chéneau (BTuin)
@ 2023-05-23 21:17             ` Óscar Fuentes
  2023-05-24  6:09             ` Dirk-Jan C. Binnema
  2023-05-25 10:42             ` Po Lu
  2 siblings, 0 replies; 101+ messages in thread
From: Óscar Fuentes @ 2023-05-23 21:17 UTC (permalink / raw)
  To: emacs-devel

"Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:

> First, you execute `builder-configure' which detects the build system,
> finds Autotools and asks you to chose between "minimal", "regular",
> and others.  Once you've chosen, the minibuffer is filled with the
> "minimal" command (for example `../configure --without-threads
> --without-toolkit-scroll-bars`.  You press enter, the command is
> executed in a compile buffer.
>
> Then, you need to compile.  You call `builder-compile', and you may
> have to chose between multiple targets, for example "default" with the
> value "make" and "parallel" with the value "make -jN", N being the
> number of cores on you processor.  Once you've chosen, the same as for
> configure happens, the command is executed in a compilation buffer.

This looks ideal for a Magit-like UI interface (IIRC Emacs has a
built-in equivalent.)




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23  8:36   ` Philip Kaludercic
  2023-05-23 11:18     ` Eli Zaretskii
@ 2023-05-24  3:34     ` David Masterson
  2023-05-24 10:26       ` Philip Kaludercic
  2023-05-28 21:17     ` Björn Bidar
  2 siblings, 1 reply; 101+ messages in thread
From: David Masterson @ 2023-05-24  3:34 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: Richard Stallman, BTuin, emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

> Richard Stallman <rms@gnu.org> writes:
>
>> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
>> [[[ whether defending the US Constitution against all enemies,     ]]]
>> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>>
>>   > As far as I know, Emacs does not provide a convenient way to use build
>>   > systems,
>>
>> Isn't "use build systems" what M-x compile does?
>> Assuming that each bui;d system provides a shell command to invoke it,
>> M-x compile can run that command and build the package.
>
> The issue is not what M-x compile, but that with a lot of modern
> programming languages the build systems are complex but automatable, to
> a point that it would be nice if Emacs could detect the necessary
> information to invoke the right command or sequence of commands.

Isn't this the province of EDE (Emacs Development Environment)?

-- 
David Masterson



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-23 21:10           ` Augustin Chéneau (BTuin)
  2023-05-23 21:17             ` Óscar Fuentes
@ 2023-05-24  6:09             ` Dirk-Jan C. Binnema
  2023-05-24 21:35               ` Richard Stallman
  2023-05-25 10:42             ` Po Lu
  2 siblings, 1 reply; 101+ messages in thread
From: Dirk-Jan C. Binnema @ 2023-05-24  6:09 UTC (permalink / raw)
  To: emacs-devel


On Tuesday May 23 2023, Augustin Chéneau (BTuin) wrote:

> Le 23/05/2023 à 02:44, Po Lu a écrit :
>> "Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:
>> 
>>> Oh I didn't mean a simple toggle, I meant an arbitrary command
>>> variant. For instance with Builder you can define a "debug2",
>>> "compile_arm" or any other command.
>> I don't understand how this works; before you can change targets, you
>> need to regenerate the build system for your program by running
>> configure.
>> Are you saying that in Builder, `configure' is an extra step, run each
>> time the target changes?
>> 
>
> Yes, it is.
>
> Let's illustrate with an hypothetical workflow: you work on Emacs, and you want
> to easily switch between multiple configurations, say "minimal" which enable
> very few features to ease debugging and "regular" which enable many features,
> such as pgtk, json, native compilation... (and possibly many other variants,
> there is no limit of number).
>
> First, you execute `builder-configure' which detects the build system, finds
> Autotools and asks you to chose between "minimal", "regular", and others.  Once
> you've chosen, the minibuffer is filled with the "minimal" command (for example
> `../configure --without-threads --without-toolkit-scroll-bars`.  You press
> enter, the command is executed in a compile buffer.
>
> Then, you need to compile.  You call `builder-compile', and you may have to
> chose between multiple targets, for example "default" with the value "make" and
> "parallel" with the value "make -jN", N being the number of cores on you
> processor.  Once you've chosen, the same as for configure happens, the command
> is executed in a compilation buffer.
>
> If you want to change to the "regular" configuration target, you call
> `builder-configure` and select this target.  Then, you call `builder-compile` to
> compile the project.
>
> So each time you want to change the target you call `builder-configure`.   But
> with out of tree builds, it could be possible to create one build directory for
> each configuration, which would remove the need to execute the configuration
> step each time you want to change.  It's not yet available as it is really not
> trivial to implement, but I'll try to find a satisfying solution.

Sounds useful!

I did some experiments in this area; I'm using some (private for now)
code to do something like that; it does some detection (e.g a ´cargo' or
a 'meson' project, 'autotools' project), and generates an alist per
project-type, which maps 'verbs' like 'build', 'run', 'test' to
project-type-specific commands, e.g. this specifies detection of a
rust project and the accompanying verbs.

--8<---------------cut here---------------start------------->8---
(defvar breeze-cargo-project
  ((and (fboundp 'rust-mode) (locate-dominating-file "." "Cargo.toml")) .
   ((build . rust-compile)
    (run   . rust-run)
    (test  . rust-test)))
  "A project we can build with cargo/rust-mode?")
--8<---------------cut here---------------end--------------->8---

and I can now map a common key binding for building or testing etc. the
current project. In many cases _ultimately_ it's just a fancy way to
fill `compile-command', but depending on the project it can be anything.

Some of my projects don't quite fit the generic type, so I allow for
overriding on a per-project basis; e.g. when there are a few different
things to build, I use a transient as the build command:

--8<---------------cut here---------------start------------->8---
  (transient-define-prefix build-my-special-targets()
    "Transient for special build commands."
    [:class transient-columns
	    ["Build"
	     ("a" "Build A" (lambda ()
               (interactive) (build-special "a")))
             ("b" "Build B" (lambda ()
               (interactive) (build-special "b")))  
             ("c" "Build C" (lambda ()
               (interactive) (build-special "c")))   ]])
--8<---------------cut here---------------end--------------->8---

so I get some nice menu.

It'd  be great to have such a facility in emacs.

Kind regards,
Dirk.

-- 
Dirk-Jan C. Binnema                  Helsinki, Finland
e:djcb@djcbsoftware.nl           w:www.djcbsoftware.nl
gpg: 6987 9CED 1745 9375 0F14 DA98 11DD FEA9 DCC4 A036



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23 18:46       ` Augustin Chéneau (BTuin)
@ 2023-05-24  6:32         ` Juri Linkov
  2023-05-24 20:09           ` Augustin Chéneau (BTuin)
  0 siblings, 1 reply; 101+ messages in thread
From: Juri Linkov @ 2023-05-24  6:32 UTC (permalink / raw)
  To: Augustin Chéneau (BTuin); +Cc: emacs-devel

> This is exactly what Builder does: if you want to compile, it will detect
> which build systems are present in the project and provide you choices of
> commands to execute.  You can see that as an autocomplete for M-x compile.
>
> After asking you to chose the command, it will actually pass the string to
> the function `compile'.  So it doesn't re-implement anything.
> It's just a layer over `compile', to remove repetitive tasks.
>
> I know you can customize `compile-command', but you can only have one value
> by project, you need to set it for each project and you can't switch
> between values.  It doesn't help you if you want to switch to debug or
> another target, or to run tests, or if you have multiple build systems on
> your project.

Like 'tex-compile-commands', a new variable 'compile-commands' could
support a list of default commands.  You can fill it with default values,
then the user can select one of them by using completion.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-24  3:34     ` David Masterson
@ 2023-05-24 10:26       ` Philip Kaludercic
  0 siblings, 0 replies; 101+ messages in thread
From: Philip Kaludercic @ 2023-05-24 10:26 UTC (permalink / raw)
  To: David Masterson; +Cc: Richard Stallman, BTuin, emacs-devel

David Masterson <dsmasterson@gmail.com> writes:

> Philip Kaludercic <philipk@posteo.net> writes:
>
>> Richard Stallman <rms@gnu.org> writes:
>>
>>> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
>>> [[[ whether defending the US Constitution against all enemies,     ]]]
>>> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>>>
>>>   > As far as I know, Emacs does not provide a convenient way to use build
>>>   > systems,
>>>
>>> Isn't "use build systems" what M-x compile does?
>>> Assuming that each bui;d system provides a shell command to invoke it,
>>> M-x compile can run that command and build the package.
>>
>> The issue is not what M-x compile, but that with a lot of modern
>> programming languages the build systems are complex but automatable, to
>> a point that it would be nice if Emacs could detect the necessary
>> information to invoke the right command or sequence of commands.
>
> Isn't this the province of EDE (Emacs Development Environment)?

I might be wrong, but I am under the impression that EDE is not actively
maintained, and that newer systems like project and Eglot have taken
over.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-24  6:32         ` Juri Linkov
@ 2023-05-24 20:09           ` Augustin Chéneau (BTuin)
  0 siblings, 0 replies; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-24 20:09 UTC (permalink / raw)
  To: emacs-devel

Le 24/05/2023 à 08:32, Juri Linkov a écrit :
>> This is exactly what Builder does: if you want to compile, it will detect
>> which build systems are present in the project and provide you choices of
>> commands to execute.  You can see that as an autocomplete for M-x compile.
>>
>> After asking you to chose the command, it will actually pass the string to
>> the function `compile'.  So it doesn't re-implement anything.
>> It's just a layer over `compile', to remove repetitive tasks.
>>
>> I know you can customize `compile-command', but you can only have one value
>> by project, you need to set it for each project and you can't switch
>> between values.  It doesn't help you if you want to switch to debug or
>> another target, or to run tests, or if you have multiple build systems on
>> your project.
> 
> Like 'tex-compile-commands', a new variable 'compile-commands' could
> support a list of default commands.  You can fill it with default values,
> then the user can select one of them by using completion.
> 

Of course, but then you'll want to filter according to the available 
build systems on the project to make it more convenient, because there 
are a lot of build systems.
Also, you'd want to create categories (such as compile, test, 
configure...) so you don't have to search for your command.
Add some facilities to make it more configurable and flexible...
And finally you would have, well, more or less Builder  :D

`tex-compile-commands' works fine because its scope is very limited: 
only one "build system".  But with Make, Autotools, CMake, Meson, Cargo, 
Xmake, Dune, QMake, ASDF, and many, many more, it would get messy very 
quickly.





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-24  6:09             ` Dirk-Jan C. Binnema
@ 2023-05-24 21:35               ` Richard Stallman
  2023-05-24 23:32                 ` Jim Porter
  2023-05-25  0:11                 ` Gregory Heytings
  0 siblings, 2 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-24 21:35 UTC (permalink / raw)
  To: Dirk-Jan C. Binnema; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > I did some experiments in this area; I'm using some (private for now)
  > code to do something like that; it does some detection (e.g a ´cargo' or
  > a 'meson' project, 'autotools' project), and generates an alist per
  > project-type, which maps 'verbs' like 'build', 'run', 'test' to
  > project-type-specific commands, e.g. this specifies detection of a
  > rust project and the accompanying verbs.

Just to remind people, Cargo is not a model we should follow.
From what I'm told, it is not merely a program to run locally,
like Make or ld, but a sort of server.

I think that means it leads people to do their building in someone
else's server, rather than on your own computer.  For moral reasons,
that is not good.

ISTR that Cargo has a catalog of libraries, some of them nonfree,
and that this makes it hard to build a Rust package and ensure
no nonfree library is used.

If I'm mistaken about any of this, please let me know.
In any case, we should make sure that whatever WE recommend
does not have these problems.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-24 21:35               ` Richard Stallman
@ 2023-05-24 23:32                 ` Jim Porter
  2023-05-25  0:11                 ` Gregory Heytings
  1 sibling, 0 replies; 101+ messages in thread
From: Jim Porter @ 2023-05-24 23:32 UTC (permalink / raw)
  To: rms, Dirk-Jan C. Binnema; +Cc: emacs-devel

On 5/24/2023 2:35 PM, Richard Stallman wrote:
> I think that means it leads people to do their building in someone
> else's server, rather than on your own computer.  For moral reasons,
> that is not good.

I don't think this is true, though I'm not an expert on Cargo. When you 
build your Cargo project via `cargo build`, it will download the source 
code for any dependent libraries from crates.io and then build them all 
on your computer. (The Cargo manual makes this a bit confusing by 
talking about "binary packages", but those are really "packages that 
produce an executable program", not "packages distributed as precompiled 
binaries".)

I suppose it would be possible to distribute precompiled data in some 
form on crates.io (similar to how the Linux kernel has binary blobs), 
but I'm not aware of this happening in practice.

> ISTR that Cargo has a catalog of libraries, some of them nonfree,
> and that this makes it hard to build a Rust package and ensure
> no nonfree library is used.

This I'm not sure about. The documentation[1] says: "The crate registry 
at crates.io distributes the source code of your packages, so it 
primarily hosts code that is open source." The word "primarily" makes me 
somewhat concerned, and I don't see any further documentation on the matter.

For Rust developers who are concerned about licensing of dependencies, 
there's "cargo-deny"[2], which (among other things) lets you ensure that 
your dependencies' licenses are acceptable to you. That requires the 
user to set all this up, but it would then provide an automated way to 
ensure you only use free libraries.

[1] https://doc.rust-lang.org/book/ch14-02-publishing-to-crates-io.html
[2] https://crates.io/crates/cargo-deny



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-24 21:35               ` Richard Stallman
  2023-05-24 23:32                 ` Jim Porter
@ 2023-05-25  0:11                 ` Gregory Heytings
  2023-05-25  4:00                   ` tomas
  1 sibling, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25  0:11 UTC (permalink / raw)
  To: Richard Stallman; +Cc: Dirk-Jan C. Binnema, emacs-devel


>
> Just to remind people, Cargo is not a model we should follow. From what 
> I'm told, it is not merely a program to run locally, like Make or ld, 
> but a sort of server.
>
> I think that means it leads people to do their building in someone 
> else's server, rather than on your own computer.  For moral reasons, 
> that is not good.
>
> ISTR that Cargo has a catalog of libraries, some of them nonfree, and 
> that this makes it hard to build a Rust package and ensure no nonfree 
> library is used.
>
> If I'm mistaken about any of this, please let me know. In any case, we 
> should make sure that whatever WE recommend does not have these 
> problems.
>

You are mistaken.

Cargo is a program that runs locally, not a server.  It works like make, 
except that it may communicate with the crates.io repository, to fetch a 
copy of the source code (and the license) of the libraries you need to 
build a given Rust program, and that are not yet available locally.

The Rust compiler invoked by Cargo also runs locally, it does not build 
Rust programs on someone else's server.

There are currently 115402 available libraries in the crates.io 
repository, and out of these the vast majority (at least 110000) use free 
software licenses.

In any case, it is very easy to ensure that no non-free library are used 
when (or before) building a Rust program: just type "cargo tree -f '{p}: 
{l}'" to recursively display the licenses of all dependencies of the 
program.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  0:11                 ` Gregory Heytings
@ 2023-05-25  4:00                   ` tomas
  2023-05-25  6:53                     ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: tomas @ 2023-05-25  4:00 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1003 bytes --]

On Thu, May 25, 2023 at 12:11:28AM +0000, Gregory Heytings wrote:
> 
> > 
> > Just to remind people, Cargo is not a model we should follow. From what
> > I'm told, it is not merely a program to run locally, like Make or ld,
> > but a sort of server.


> You are mistaken.

Technically right, but...

> Cargo is a program that runs locally, not a server.  It works like make,
> except that it may communicate with the crates.io repository, to fetch a
> copy of the source code (and the license) of the libraries you need to build
> a given Rust program, and that are not yet available locally.

... akin to npm (the Node package manager of the Javascript world), it
downloads half of the Internet while building and makes your life miserable
if you want to avoid that.

The new models just make it slightly more inconvenient to stay free.

Can we call this pattern neo-proprietary?

(A bit tongue-in-cheek, but that's exactly how I think things are
changing)

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  4:00                   ` tomas
@ 2023-05-25  6:53                     ` Gregory Heytings
  2023-05-25  7:48                       ` Eli Zaretskii
                                         ` (3 more replies)
  0 siblings, 4 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25  6:53 UTC (permalink / raw)
  To: tomas; +Cc: emacs-devel


>> Cargo is a program that runs locally, not a server.  It works like 
>> make, except that it may communicate with the crates.io repository, to 
>> fetch a copy of the source code (and the license) of the libraries you 
>> need to build a given Rust program, and that are not yet available 
>> locally.
>
> ... akin to npm (the Node package manager of the Javascript world), it 
> downloads half of the Internet while building and makes your life 
> miserable if you want to avoid that.
>
> The new models just make it slightly more inconvenient to stay free.
>

You are spreading FUD.  When you want to compile, say, Emacs, you need to 
either download the binaries of the libraries that are not yet available 
locally and their headers, or download the source of these libraries and 
build them.  Doing that does not "donwload half of the Internet".  After 
this you need to run the "configure" script which checks which libraries 
(and sometimes which versions of these libraries) are available.

Cargo does all that for you.

>
> Can we call this pattern neo-proprietary?
>

No, we cannot.  There is no relation whatsoever between software 
proprietariness and this elegant solution to the problem of library 
dependencies.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  6:53                     ` Gregory Heytings
@ 2023-05-25  7:48                       ` Eli Zaretskii
  2023-05-25  9:33                         ` Gregory Heytings
  2023-05-25 13:16                         ` chad
  2023-05-25  7:55                       ` tomas
                                         ` (2 subsequent siblings)
  3 siblings, 2 replies; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-25  7:48 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

> Date: Thu, 25 May 2023 06:53:56 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: emacs-devel@gnu.org
> 
> 
> >> Cargo is a program that runs locally, not a server.  It works like 
> >> make, except that it may communicate with the crates.io repository, to 
> >> fetch a copy of the source code (and the license) of the libraries you 
> >> need to build a given Rust program, and that are not yet available 
> >> locally.
> >
> > ... akin to npm (the Node package manager of the Javascript world), it 
> > downloads half of the Internet while building and makes your life 
> > miserable if you want to avoid that.
> >
> > The new models just make it slightly more inconvenient to stay free.
> >
> 
> You are spreading FUD.  When you want to compile, say, Emacs, you need to 
> either download the binaries of the libraries that are not yet available 
> locally and their headers, or download the source of these libraries and 
> build them.  Doing that does not "donwload half of the Internet".  After 
> this you need to run the "configure" script which checks which libraries 
> (and sometimes which versions of these libraries) are available.
> 
> Cargo does all that for you.

FWIW, I don't trust tools that "do all that for me".  When building a
package that needs some prerequisite, I want to:

  . understand the reasons for the dependencies, and consider whether
    I really need whatever features need each one of them (if they are
    optional);
  . examine the license of each dependency, and see whether it is
    kosher;
  . skim the documentation of each dependency and see whether what it
    does is something I'd like to allow on my system;
  . search the Internet for any problems with each dependency on
    platforms about which I care, and decide which version of the
    dependency I want to download and install, and perhaps also what
    patches I should apply to fix those problems proactively

I'm not aware of any "do-everything-for-me" build tool which will
allow me to do all of the above.  They all "know better" what is good
for me.  So I don't trust them.  And yes, it means installing packages
takes me much more time and effort.  But that is justified when I'm
doing this on my main development systems which must be very stable
(as opposed on scratch systems about whose stability I don't care
much).

I think what Cargo does is cater to users who are none the wiser, and
want Someone Else(TM) to make decisions for them.  Sadly, this is
where our world is going in the recent years, pulled by MS and its
workalikes.  Sadly, many GNU/Linux distributions look and feel like MS
workalikes.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  6:53                     ` Gregory Heytings
  2023-05-25  7:48                       ` Eli Zaretskii
@ 2023-05-25  7:55                       ` tomas
  2023-05-25  8:44                         ` Gregory Heytings
  2023-05-25 10:38                       ` Po Lu
  2023-05-26 22:59                       ` Lynn Winebarger
  3 siblings, 1 reply; 101+ messages in thread
From: tomas @ 2023-05-25  7:55 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 716 bytes --]

On Thu, May 25, 2023 at 06:53:56AM +0000, Gregory Heytings wrote:

[...]

> > The new models just make it slightly more inconvenient to stay free.
> > 
> 
> You are spreading FUD [...]

Convenience, as FUD is in the eye of the beholder. We know what
we are talking about, so let everyone decide for herself.

[...]

> > Can we call this pattern neo-proprietary?
> > 
> 
> No, we cannot.  There is no relation whatsoever between software
> proprietariness and this elegant solution to the problem of library
> dependencies.

Agani, let's agree to differ here. I know my position here might
be controversial and I don't expect anyone to agree with me.

With all due respect.

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  7:55                       ` tomas
@ 2023-05-25  8:44                         ` Gregory Heytings
  0 siblings, 0 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25  8:44 UTC (permalink / raw)
  To: tomas; +Cc: emacs-devel


>> You are spreading FUD [...]
>
> Convenience, as FUD is in the eye of the beholder. We know what we are 
> talking about, so let everyone decide for herself.
>

You conveniently elide the largest part of my post, in which I explained 
why what you wrote, namely that building a Rust program "downloads half of 
the Internet while building and makes your life miserable if you want to 
avoid that", is plain wrong.  This is not something that is "in the eye of 
the beholder".




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  7:48                       ` Eli Zaretskii
@ 2023-05-25  9:33                         ` Gregory Heytings
  2023-05-25 11:28                           ` Eli Zaretskii
  2023-05-25 13:16                         ` chad
  1 sibling, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25  9:33 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tomas, emacs-devel


>
> FWIW, I don't trust tools that "do all that for me".  When building a 
> package that needs some prerequisite, I want to:
>
> . understand the reasons for the dependencies, and consider whether I 
> really need whatever features need each one of them (if they are 
> optional);
>

A Rust program can declare optional dependencies, which you can enable 
with a command line flag to Cargo.  Typically these optional dependencies 
will be documented in the program README.

>
> . examine the license of each dependency, and see whether it is kosher;
>

See my previous post: you can easily examine the licences of the optional 
(and non-optional) dependencies with "cargo tree -f '{p}: {l}'".

>
> . skim the documentation of each dependency and see whether what it does 
> is something I'd like to allow on my system;
>

That's also easy to do: "cargo doc --package <name> --open" builds the 
documentation of the given package, and opens it in your browser. 
Another option is "cargo tree -f '{p}: {r}'" which will print the URL of 
the repository of each dependency, or "cargo tree --package <name> -f 
'{p}: {r}'" if you only want the dependencies of a specific package.

>
> . search the Internet for any problems with each dependency on platforms 
> about which I care, and decide which version of the dependency I want to 
> download and install, and perhaps also what patches I should apply to 
> fix those problems proactively
>

Cargo, like distro package managers, manages versions for you.  But you 
can force a distro package manager to download a specific version of a 
package, and likewise you can force Cargo to fetch and build a specific 
version of a library if you want.  You are also free to modify the version 
requirement indicated by the library author in the Cargo.toml file (at 
your own risk, of course, as this might break the build).

>
> I'm not aware of any "do-everything-for-me" build tool which will allow 
> me to do all of the above.
>

Now you are ;-)




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  6:53                     ` Gregory Heytings
  2023-05-25  7:48                       ` Eli Zaretskii
  2023-05-25  7:55                       ` tomas
@ 2023-05-25 10:38                       ` Po Lu
  2023-05-25 11:44                         ` Gregory Heytings
  2023-05-26 22:59                       ` Lynn Winebarger
  3 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-25 10:38 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> You are spreading FUD.  When you want to compile, say, Emacs, you need
> to either download the binaries of the libraries that are not yet
> available locally and their headers, or download the source of these
> libraries and build them.  Doing that does not "donwload half of the
> Internet".  After this you need to run the "configure" script which
> checks which libraries (and sometimes which versions of these
> libraries) are available.
>
> Cargo does all that for you.
>
>>
>> Can we call this pattern neo-proprietary?
>>
>
> No, we cannot.  There is no relation whatsoever between software
> proprietariness and this elegant solution to the problem of library
> dependencies.

The GNU project has had a long standing objection to package
repositories which include non-free software.  For this exact reason,
Debian, which itself is 100% free software, is not considered an FSF
endorsed operating system.

gnu-misc-discuss is the place to debate this policy, not here.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-23 21:10           ` Augustin Chéneau (BTuin)
  2023-05-23 21:17             ` Óscar Fuentes
  2023-05-24  6:09             ` Dirk-Jan C. Binnema
@ 2023-05-25 10:42             ` Po Lu
  2023-05-25 19:36               ` Augustin Chéneau (BTuin)
  2 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-25 10:42 UTC (permalink / raw)
  To: Augustin Chéneau (BTuin); +Cc: emacs-devel

"Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:

> First, you execute `builder-configure' which detects the build system,
> finds Autotools and asks you to chose between "minimal", "regular",
> and others.  Once you've chosen, the minibuffer is filled with the
> "minimal" command (for example `../configure --without-threads
> --without-toolkit-scroll-bars`.  You press enter, the command is
> executed in a compile buffer.

How does Builder determine what is ``minimal'' and what is ``regular'',
given what I assume is M4 trace output from autom4te?



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  9:33                         ` Gregory Heytings
@ 2023-05-25 11:28                           ` Eli Zaretskii
  2023-05-25 11:53                             ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-25 11:28 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

> Date: Thu, 25 May 2023 09:33:14 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: tomas@tuxteam.de, emacs-devel@gnu.org
> 
> > I'm not aware of any "do-everything-for-me" build tool which will allow 
> > me to do all of the above.
> 
> Now you are ;-)

No, I am not.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 10:38                       ` Po Lu
@ 2023-05-25 11:44                         ` Gregory Heytings
  2023-05-25 12:02                           ` Po Lu
  2023-05-26 21:16                           ` Richard Stallman
  0 siblings, 2 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25 11:44 UTC (permalink / raw)
  To: Po Lu; +Cc: tomas, emacs-devel


>
> The GNU project has had a long standing objection to package 
> repositories which include non-free software.  For this exact reason, 
> Debian, which itself is 100% free software, is not considered an FSF 
> endorsed operating system.
>

You are confusing two different things: distros which distribute binaries 
to end-users (Debian and others) and source code repositories.  The Rust 
repository crates.io is in the latter category, just like sr.ht for 
example, which allows non-free licenses and is nonetheless "good enough to 
recommend".

>
> gnu-misc-discuss is the place to debate this policy, not here.
>

Richard started this subthread here, and asked to be corrected.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 11:28                           ` Eli Zaretskii
@ 2023-05-25 11:53                             ` Gregory Heytings
  2023-05-25 13:09                               ` Eli Zaretskii
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25 11:53 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tomas, emacs-devel


>>> I'm not aware of any "do-everything-for-me" build tool which will 
>>> allow me to do all of the above.
>>
>> Now you are ;-)
>
> No, I am not.
>

You asked specific questions, to which I provided specific answers.  If 
they were unclear, or if you have further questions, feel free to ask.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 11:44                         ` Gregory Heytings
@ 2023-05-25 12:02                           ` Po Lu
  2023-05-25 12:08                             ` Gregory Heytings
  2023-05-26 21:16                           ` Richard Stallman
  1 sibling, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-25 12:02 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> You are confusing two different things: distros which distribute
> binaries to end-users (Debian and others) and source code
> repositories.  The Rust repository crates.io is in the latter
> category, just like sr.ht for example, which allows non-free licenses
> and is nonetheless "good enough to recommend".

The distinction is between package repositories which distribute
software for use, and services which merely provide storage to users.

If sr.ht were being used as a package archive, the same objections would
be applied to it.

> Richard started this subthread here, and asked to be corrected.

Richard asked for information regarding Cargo, so he could evaluate
whether or not Emacs should integrate with it.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 12:02                           ` Po Lu
@ 2023-05-25 12:08                             ` Gregory Heytings
  2023-05-26  0:52                               ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25 12:08 UTC (permalink / raw)
  To: Po Lu; +Cc: tomas, emacs-devel


>> You are confusing two different things: distros which distribute 
>> binaries to end-users (Debian and others) and source code repositories. 
>> The Rust repository crates.io is in the latter category, just like 
>> sr.ht for example, which allows non-free licenses and is nonetheless 
>> "good enough to recommend".
>
> The distinction is between package repositories which distribute 
> software for use, and services which merely provide storage to users.
>

No, the GNU ethical repository criteria apply to "service[s] for publicly 
hosting free source code", which is exactly what crates.io is for.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 11:53                             ` Gregory Heytings
@ 2023-05-25 13:09                               ` Eli Zaretskii
  2023-05-25 14:36                                 ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-25 13:09 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

> Date: Thu, 25 May 2023 11:53:29 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: tomas@tuxteam.de, emacs-devel@gnu.org
> 
> 
> >>> I'm not aware of any "do-everything-for-me" build tool which will 
> >>> allow me to do all of the above.
> >>
> >> Now you are ;-)
> >
> > No, I am not.
> >
> 
> You asked specific questions, to which I provided specific answers.  If 
> they were unclear, or if you have further questions, feel free to ask.

The answers were clear, but they didn't present any solutions to the
issues I brought up.  None of the tools I'm aware of, including
Cargo, support interactive selection of dependencies based on their
features and requirements, nor provide any decision support for the
kind of decisions I described.  They allow you to specify a version,
but leave the actual decision process to you.  And if that is the
case, why do I need them? I can easily build stuff myself once I've
figured out which versions of what dependencies I need.

And there's no need for you to work hard to try to represent the
problems as having their solutions.  Those build tools do not intend
to solve those problems, they don't even consider them problems.  They
"know better".  The facilities you described are nothing more than lip
service.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  7:48                       ` Eli Zaretskii
  2023-05-25  9:33                         ` Gregory Heytings
@ 2023-05-25 13:16                         ` chad
  2023-05-25 19:38                           ` Augustin Chéneau (BTuin)
  2023-05-26 21:32                           ` Richard Stallman
  1 sibling, 2 replies; 101+ messages in thread
From: chad @ 2023-05-25 13:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Gregory Heytings, tomas, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1143 bytes --]

On Thu, May 25, 2023 at 3:49 AM Eli Zaretskii <eliz@gnu.org> wrote:

>
> FWIW, I don't trust tools that "do all that for me".  When building a
> package that needs some prerequisite, I want to:
> [...]
>

This is laudable but also requires effort, sometimes non trivial effort;
witness the extra hoops required to get functional tree-sitter "support"
inside emacs. Cargo is a (fairly slight, actually) evolution of the
strategy I first saw back in the mid-90's with CPAN (the "Comprehensive
Perl Archive Network"), through CTAN (similar for TeX), ruby, python, etc.

I do agree that the default setup of cargo tends a little too much towards
DWIMishness for my taste, but it's not hard to turn that down AND it
removes many of the most annoying parts of library version management/hell.

In this particular case, unless I'm misreading, the OP is suggesting that a
generic "builder" layer could include cargo as one of the many build
management systems that is widely used to create (usually libre) software,
rather than suggesting it as a model that either Emacs or the FSF should
follow.

I hope that helps,
~Chad

[-- Attachment #2: Type: text/html, Size: 1591 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 13:09                               ` Eli Zaretskii
@ 2023-05-25 14:36                                 ` Gregory Heytings
  2023-05-25 16:20                                   ` Eli Zaretskii
                                                     ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25 14:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tomas, emacs-devel


>
> The answers were clear, but they didn't present any solutions to the 
> issues I brought up.  None of the tools I'm aware of, including Cargo, 
> support interactive selection of dependencies based on their features 
> and requirements, nor provide any decision support for the kind of 
> decisions I described.  They allow you to specify a version, but leave 
> the actual decision process to you.  And if that is the case, why do I 
> need them? I can easily build stuff myself once I've figured out which 
> versions of what dependencies I need.
>
> And there's no need for you to work hard to try to represent the 
> problems as having their solutions.  Those build tools do not intend to 
> solve those problems, they don't even consider them problems.  They 
> "know better".  The facilities you described are nothing more than lip 
> service.
>

Then I guess I don't understand what these problems are, and what kind of 
solution you are after.  Let's take a concrete example of a popular Rust 
program: ripgrep.  All you need to build it is:

git clone https://github.com/BurntSushi/ripgrep
cargo build --release

or (even simpler):

cargo install ripgrep

That (relatively simple) program depends on no less than 37 Rust 
libraries, and has two optional build options, "pcre2" and "simd-accel". 
If you activate these two options the program depends on 45 libraries. 
What would you want do do with those 45 libraries?  What do you mean in 
this concrete case by "interactive selection of dependencies based on 
their features and requirements"?

Another popular (slightly more complex) Rust program is Alacritty (a 
terminal emulator).  That one depends on 131 Rust libraries.  Again, what 
would you want to do with all those libraries?  Why would you want to 
build that program with a version of a Rust library that is different from 
what the authors of that program recommend?

One thing that might be unclear in this discussion is that Rust libraries 
are compiled in the program, they are not dynamic libraries.  A Rust 
program can of course also depend on non-Rust libraries, e.g. Alacritty 
depends on the Freetype library (and on other libraries).  These non-Rust 
dependencies are not managed by Cargo.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 14:36                                 ` Gregory Heytings
@ 2023-05-25 16:20                                   ` Eli Zaretskii
  2023-05-25 16:40                                     ` tomas
  2023-05-25 19:23                                     ` Gregory Heytings
  2023-05-26  0:54                                   ` Po Lu
  2023-05-26 21:16                                   ` Richard Stallman
  2 siblings, 2 replies; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-25 16:20 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

> Date: Thu, 25 May 2023 14:36:40 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: tomas@tuxteam.de, emacs-devel@gnu.org
> 
> > The answers were clear, but they didn't present any solutions to the 
> > issues I brought up.  None of the tools I'm aware of, including Cargo, 
> > support interactive selection of dependencies based on their features 
> > and requirements, nor provide any decision support for the kind of 
> > decisions I described.  They allow you to specify a version, but leave 
> > the actual decision process to you.  And if that is the case, why do I 
> > need them? I can easily build stuff myself once I've figured out which 
> > versions of what dependencies I need.
> >
> > And there's no need for you to work hard to try to represent the 
> > problems as having their solutions.  Those build tools do not intend to 
> > solve those problems, they don't even consider them problems.  They 
> > "know better".  The facilities you described are nothing more than lip 
> > service.
> >
> 
> Then I guess I don't understand what these problems are, and what kind of 
> solution you are after.  Let's take a concrete example of a popular Rust 
> program: ripgrep.  All you need to build it is:
> 
> git clone https://github.com/BurntSushi/ripgrep
> cargo build --release
> 
> or (even simpler):
> 
> cargo install ripgrep
> 
> That (relatively simple) program depends on no less than 37 Rust 
> libraries, and has two optional build options, "pcre2" and "simd-accel". 
> If you activate these two options the program depends on 45 libraries. 
> What would you want do do with those 45 libraries?  What do you mean in 
> this concrete case by "interactive selection of dependencies based on 
> their features and requirements"?

I don't see how I can add anything to what I described already, and in
detail; see

  https://lists.gnu.org/archive/html/emacs-devel/2023-05/msg00578.html

What I'd like is for the installation procedure to present the
information I need for making those decisions, and help me make them.

Btw, I was only talking about optional dependencies.  For mandatory
dependencies, the only important aspect is whether I'd need to upgrade
libraries I already have to newer versions, and if so, whether those
newer versions will cause compatibility problems with programs I have
installed that use those libraries.  This is also something a typical
package installation will not let me control: they will just upgrade
the other programs as well, whether I want that or not.

Anyway, I don't see why we should continue this sub-thread: I just
wanted to express my deep mistrust of any such "automatic installation
and build" packages; YMMV.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 16:20                                   ` Eli Zaretskii
@ 2023-05-25 16:40                                     ` tomas
  2023-05-25 19:23                                     ` Gregory Heytings
  1 sibling, 0 replies; 101+ messages in thread
From: tomas @ 2023-05-25 16:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Gregory Heytings, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 557 bytes --]

On Thu, May 25, 2023 at 07:20:56PM +0300, Eli Zaretskii wrote:

[...]

> Btw, I was only talking about optional dependencies.  For mandatory
> dependencies, the only important aspect is whether I'd need to upgrade
> libraries I already have to newer versions, and if so, whether those
> newer versions will cause compatibility problems with programs I have
> installed that use those libraries [...]

Perhaps I'm not up to date, but ISTR that rust can only build
statically linked binaries. In that case, this might be moot :)

Cheers
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 16:20                                   ` Eli Zaretskii
  2023-05-25 16:40                                     ` tomas
@ 2023-05-25 19:23                                     ` Gregory Heytings
  2023-05-26  0:57                                       ` Po Lu
                                                         ` (2 more replies)
  1 sibling, 3 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-25 19:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: tomas, emacs-devel


>
> For mandatory dependencies, the only important aspect is whether I'd 
> need to upgrade libraries I already have to newer versions, and if so, 
> whether those newer versions will cause compatibility problems with 
> programs I have installed that use those libraries.
>

This is the misconception I pointed to in my previous post: Rust libraries 
are not dynamic libraries, they are compiled into the program.  This 
eliminates all compatibility problems: you can have as many programs as 
you want on your computer, each one compiled with a different version of a 
given library.  And the point of the crates.io repository is to ensure 
that all versions of all libraries will forever be available, to ensure 
that a Rust program that depends on a specific version of a library will 
remain compilable.

>
> This is also something a typical package installation will not let me 
> control: they will just upgrade the other programs as well, whether I 
> want that or not.
>

This is a separate question, and I don't know which package manager you 
have in mind, but at least with Debian's package manager what you describe 
doesn't happen.  You can always review what will be upgraded.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 10:42             ` Po Lu
@ 2023-05-25 19:36               ` Augustin Chéneau (BTuin)
  0 siblings, 0 replies; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-25 19:36 UTC (permalink / raw)
  To: emacs-devel

Le 25/05/2023 à 12:42, Po Lu a écrit :
> "Augustin Chéneau (BTuin)" <btuin@mailo.com> writes:
> 
>> First, you execute `builder-configure' which detects the build system,
>> finds Autotools and asks you to chose between "minimal", "regular",
>> and others.  Once you've chosen, the minibuffer is filled with the
>> "minimal" command (for example `../configure --without-threads
>> --without-toolkit-scroll-bars`.  You press enter, the command is
>> executed in a compile buffer.
> 
> How does Builder determine what is ``minimal'' and what is ``regular'',
> given what I assume is M4 trace output from autom4te?
> 

Here "minimal" and "regular" were just placeholder names.  They could 
have been named "random_name1" and "random_name2" for that matter.

It was meant to show that you could define your own targets manually 
(i.e. a command associated with a name) to conveniently execute them 
rather than having to rewrite them entirely each time you need them.

I don't know if it's actually possible to determine what is "minimal" 
and what is "regular" from M4, but if such a thing is possible you could 
provide a lisp function to Builder that would automatically supply you 
with the suitable commands.





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 13:16                         ` chad
@ 2023-05-25 19:38                           ` Augustin Chéneau (BTuin)
  2023-05-26 21:32                           ` Richard Stallman
  1 sibling, 0 replies; 101+ messages in thread
From: Augustin Chéneau (BTuin) @ 2023-05-25 19:38 UTC (permalink / raw)
  To: emacs-devel

Le 25/05/2023 à 15:16, chad a écrit :
> In this particular case, unless I'm misreading, the OP is suggesting 
> that a generic "builder" layer could include cargo as one of the many 
> build management systems that is widely used to create (usually libre) 
> software, rather than suggesting it as a model that either Emacs or the 
> FSF should follow.
> 
> I hope that helps,
> ~Chad

You're indeed not misreading, than you.





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 12:08                             ` Gregory Heytings
@ 2023-05-26  0:52                               ` Po Lu
  0 siblings, 0 replies; 101+ messages in thread
From: Po Lu @ 2023-05-26  0:52 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> No, the GNU ethical repository criteria apply to "service[s] for
> publicly hosting free source code", which is exactly what crates.io is
> for.

Cargo (the subject of debate) is a package manager, and it uses such a
service as a package repository.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 14:36                                 ` Gregory Heytings
  2023-05-25 16:20                                   ` Eli Zaretskii
@ 2023-05-26  0:54                                   ` Po Lu
  2023-05-26 21:16                                   ` Richard Stallman
  2 siblings, 0 replies; 101+ messages in thread
From: Po Lu @ 2023-05-26  0:54 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Eli Zaretskii, tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> Another popular (slightly more complex) Rust program is Alacritty (a
> terminal emulator).  That one depends on 131 Rust libraries.  Again,
> what would you want to do with all those libraries?  Why would you
> want to build that program with a version of a Rust library that is
> different from what the authors of that program recommend?

I would recommend instead installing xterm, which is part of the X
Consortium's distribution of the X window system.  It has no
dependencies outside the distribution except for system libraries that
can be found on any Unix system.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 19:23                                     ` Gregory Heytings
@ 2023-05-26  0:57                                       ` Po Lu
  2023-05-27  0:24                                         ` Gregory Heytings
  2023-05-26  5:57                                       ` Eli Zaretskii
  2023-05-26 21:16                                       ` Richard Stallman
  2 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-26  0:57 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Eli Zaretskii, tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> This is the misconception I pointed to in my previous post: Rust
> libraries are not dynamic libraries, they are compiled into the
> program.  This eliminates all compatibility problems: you can have as
> many programs as you want on your computer, each one compiled with a
> different version of a given library.  And the point of the crates.io
> repository is to ensure that all versions of all libraries will
> forever be available, to ensure that a Rust program that depends on a
> specific version of a library will remain compilable.

And what happens when the compiler changes to no longer compile old
programs?  Or if I want to re-link the object code for a Rust program
with a different version of one of its dependencies?

Symbol versioning solves all compatibility problems with dynamic
libraries, BTW.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 19:23                                     ` Gregory Heytings
  2023-05-26  0:57                                       ` Po Lu
@ 2023-05-26  5:57                                       ` Eli Zaretskii
  2023-05-26 21:16                                       ` Richard Stallman
  2 siblings, 0 replies; 101+ messages in thread
From: Eli Zaretskii @ 2023-05-26  5:57 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

> Date: Thu, 25 May 2023 19:23:35 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: tomas@tuxteam.de, emacs-devel@gnu.org
> 
> > For mandatory dependencies, the only important aspect is whether I'd 
> > need to upgrade libraries I already have to newer versions, and if so, 
> > whether those newer versions will cause compatibility problems with 
> > programs I have installed that use those libraries.
> 
> This is the misconception I pointed to in my previous post: Rust libraries 
> are not dynamic libraries, they are compiled into the program.

This is not a misconception, at least not mine: I was talking about
package installers in general, not just about Cargo.  (You will see
that this particular issue was absent from my OP.)

> > This is also something a typical package installation will not let me 
> > control: they will just upgrade the other programs as well, whether I 
> > want that or not.
> 
> This is a separate question, and I don't know which package manager you 
> have in mind

None.  Package managers that I envision don't exist.

> but at least with Debian's package manager what you describe 
> doesn't happen.  You can always review what will be upgraded.

"Review" doesn't get near what I'd expect from a decent installer.

Once again, why do you continue arguing?  I just wanted to explain my
POV, which I realize is very unconventional.  You don't need to agree.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 19:23                                     ` Gregory Heytings
  2023-05-26  0:57                                       ` Po Lu
  2023-05-26  5:57                                       ` Eli Zaretskii
@ 2023-05-26 21:16                                       ` Richard Stallman
  2023-05-27  0:25                                         ` Gregory Heytings
  2023-05-27 14:55                                         ` Brian Cully via Emacs development discussions.
  2 siblings, 2 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-26 21:16 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: eliz, tomas, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > This is the misconception I pointed to in my previous post: Rust libraries 
  > are not dynamic libraries, they are compiled into the program.  This 
  > eliminates all compatibility problems: you can have as many programs as 
  > you want on your computer, each one compiled with a different version of a 
  > given library.

I have trouble understanding that.  Before dynamic libraries, we used
static libraries.  Each library was a .o file, made by compilation.

But how can each program have its own version of one and the same
library?  Does Rust store all libraries as **source code**
and recompile each library each time that library is linked
into a program?

I don't know anything technically about Rust.  Others here may be in
the same boat with me.  So please explain the things you need us to
know.



-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 14:36                                 ` Gregory Heytings
  2023-05-25 16:20                                   ` Eli Zaretskii
  2023-05-26  0:54                                   ` Po Lu
@ 2023-05-26 21:16                                   ` Richard Stallman
  2023-05-27  0:26                                     ` Gregory Heytings
  2 siblings, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-26 21:16 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: eliz, tomas, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > Then I guess I don't understand what these problems are, and what kind of 
  > solution you are after.  Let's take a concrete example of a popular Rust 
  > program: ripgrep.  All you need to build it is:

  > git clone https://github.com/BurntSushi/ripgrep
  > cargo build --release

  > or (even simpler):

  > cargo install ripgrep

  > That (relatively simple) program depends on no less than 37 Rust 
  > libraries, and has two optional build options, "pcre2" and "simd-accel". 
  > If you activate these two options the program depends on 45 libraries. 
  > What would you want do do with those 45 libraries?  What do you mean in 
  > this concrete case by "interactive selection of dependencies based on 
  > their features and requirements"?

Where does cargo get the list of libraries to consider using?
Does it have a default list that it normally considers?
If so, where is that specified?

Are all the libraries in that default list free/libre?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 11:44                         ` Gregory Heytings
  2023-05-25 12:02                           ` Po Lu
@ 2023-05-26 21:16                           ` Richard Stallman
  2023-05-27  0:26                             ` Gregory Heytings
  1 sibling, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-26 21:16 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: luangruo, tomas, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > > The GNU project has had a long standing objection to package 
  > > repositories which include non-free software.  For this exact reason, 
  > > Debian, which itself is 100% free software, is not considered an FSF 
  > > endorsed operating system.
  > >

  > You are confusing two different things: distros which distribute binaries 
  > to end-users (Debian and others) and source code repositories.

We make a distinction, but it's not exacty that distinction as described
in the lines above.

On one hand, we have distros.  A distro lists programs that in
principle you may wish to install side by side in one computer.  (Yes,
it has more wrinkles than that, but that's the basic point.)  You're
likely to see all of them as choices for what you might install.

On the other hand, we have repo sites where in principle anyone can
put a program.  Those programs are not all meant to be potentially
used together.  They may even be written for different platforms.
Basically, the packages in a repo site are not a menu of packages to
install.  Being interested in one package there does not mean you want
to know about the other packages hosted there.

That fundamental difference in purpose is the reason that we use
different criteria for judging distros and judging repo sites.  Their
respective criteria are based on their purposes.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25 13:16                         ` chad
  2023-05-25 19:38                           ` Augustin Chéneau (BTuin)
@ 2023-05-26 21:32                           ` Richard Stallman
  2023-05-27  9:45                             ` Yuri Khan
  1 sibling, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-26 21:32 UTC (permalink / raw)
  To: chad; +Cc: eliz, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > This is laudable but also requires effort, sometimes non trivial effort;
  > witness the extra hoops required to get functional tree-sitter "support"
  > inside emacs. Cargo is a (fairly slight, actually) evolution of the
  > strategy I first saw back in the mid-90's with CPAN (the "Comprehensive
  > Perl Archive Network"), through CTAN (similar for TeX), ruby, python, etc.

The fact that they all work basically the same way could be the reason
why many (or all?) of them have the sameproblem.

As I understand it, each of these library-choosing systems uses a
collection of libraries built up over the years.  Maybe it acceses
them using a network server, or maybe via a program that has a list of
all the libraries in that collection and crucial information about
each one.

So when you say to link a certain program, the library-choosing
systems figures out which of the libraries in that collection provide
symbols that the program needs.  And it links with them.

Is all that correct?

If so, I can now explain concretely the problem I am concerned about.

For each language, the people who build up the collection of libraries
have included some libraries that are not free.

Therefore, if the program you ask to build refers to symbols provided
by a nonfree library, you will get a linked executable that uses a
nonfree library.  For us, that is no good!  You should get an error
message.

You've said that these various library-choosing systems are designed
to work similarly, but they may not be entirely similar in this
regard.  Some of them may avoid this problem.  If so, I would be glad
to learn which ones do avoid it, and how each does so.

In the systems which do have this problem, we can't just accept it.
Fixing it is necessary for us.  They have not, as far as I know, done
much to help us.  I hope we can convince them to help, but if not,
we need to fork.

If the developers of some of these library-choosing systems have added
features that make this easier, I would be very glad.


-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-25  6:53                     ` Gregory Heytings
                                         ` (2 preceding siblings ...)
  2023-05-25 10:38                       ` Po Lu
@ 2023-05-26 22:59                       ` Lynn Winebarger
  2023-05-28 21:22                         ` Björn Bidar
  3 siblings, 1 reply; 101+ messages in thread
From: Lynn Winebarger @ 2023-05-26 22:59 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: tomas, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1951 bytes --]

On Thu, May 25, 2023, 2:55 AM Gregory Heytings <gregory@heytings.org> wrote:

>
> >> Cargo is a program that runs locally, not a server.  It works like
> >> make, except that it may communicate with the crates.io repository, to
> >> fetch a copy of the source code (and the license) of the libraries you
> >> need to build a given Rust program, and that are not yet available
> >> locally.
> >
> > ... akin to npm (the Node package manager of the Javascript world), it
> > downloads half of the Internet while building and makes your life
> > miserable if you want to avoid that.
> >
> > The new models just make it slightly more inconvenient to stay free.
> >
>
> You are spreading FUD.  When you want to compile, say, Emacs, you need to
> either download the binaries of the libraries that are not yet available
> locally and their headers, or download the source of these libraries and
> build them.  Doing that does not "donwload half of the Internet".  After
> this you need to run the "configure" script which checks which libraries
> (and sometimes which versions of these libraries) are available.
>
> Cargo does all that for you.
>
> >
> > Can we call this pattern neo-proprietary?
> >
>
> No, we cannot.  There is no relation whatsoever between software
> proprietariness and this elegant solution to the problem of library
> dependencies.
>


"Elegant" is a strong characterization of the practice of "vendoring"
source dependencies, which you describe here.  It's useful if you are
maintaining a replicable build process common in corporate software
environments and projects meant to distribute prebuilt binaries to the
mass-market.  Vendoring is distinctly unfriendly to users that want to
build or tinker with it locally using locally available (and user-vetted)
libraries, i.e. classic free software users.

Can "crates.io" be replaced by a different package repository, or
configured to work with whatever is available locally?

Lynn

[-- Attachment #2: Type: text/html, Size: 2912 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26  0:57                                       ` Po Lu
@ 2023-05-27  0:24                                         ` Gregory Heytings
  0 siblings, 0 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-27  0:24 UTC (permalink / raw)
  To: Po Lu; +Cc: Eli Zaretskii, tomas, emacs-devel


>
> And what happens when the compiler changes to no longer compile old 
> programs?
>

You are apparently unaware that Rust guarantees backward compatility of 
source code.  Code that builds with a (stable) version N of the Rust 
compiler should build with any later version M > N.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 21:16                                       ` Richard Stallman
@ 2023-05-27  0:25                                         ` Gregory Heytings
  2023-05-28 10:20                                           ` Madhu
  2023-05-27 14:55                                         ` Brian Cully via Emacs development discussions.
  1 sibling, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-27  0:25 UTC (permalink / raw)
  To: Richard Stallman; +Cc: eliz, tomas, emacs-devel


>> This is the misconception I pointed to in my previous post: Rust 
>> libraries are not dynamic libraries, they are compiled into the 
>> program.  This eliminates all compatibility problems: you can have as 
>> many programs as you want on your computer, each one compiled with a 
>> different version of a given library.
>
> I have trouble understanding that.  Before dynamic libraries, we used 
> static libraries.  Each library was a .o file, made by compilation.
>

Rust libraries are neither dynamic (compiled separately and loaded at run 
time) nor static (compiled separately and linked at build time), they are 
always compiled together with the program.

>
> But how can each program have its own version of one and the same 
> library?  Does Rust store all libraries as **source code** and recompile 
> each library each time that library is linked into a program?
>

Yes, that's how it works.  For example, there are 25 versions of the 
"itoa" library (which does the opposite of the well-known "atoi" 
function), and you could have 25 different Rust programs on your computer, 
each one using on a different version of that library.  If you build these 
programs yourself, you will end up, in your local CARGO_HOME directory, 
with a copy of the source code of the 25 versions of that library: 
itoa-0.1.0, ..., itoa-1.0.6.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 21:16                                   ` Richard Stallman
@ 2023-05-27  0:26                                     ` Gregory Heytings
  2023-05-27  2:37                                       ` Ruijie Yu via Emacs development discussions.
                                                         ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-27  0:26 UTC (permalink / raw)
  To: Richard Stallman; +Cc: eliz, tomas, emacs-devel


>
> Where does cargo get the list of libraries to consider using?
>

The dependencies of a Rust program/library are specified (manually) by the 
author of that program/library, in a (structured) text file.  The source 
code of the libraries on which the program/library depends are downloaded 
(by Cargo) from the crates.io registry, and kept in a local cache 
(CARGO_HOME, by default $HOME/.cargo).

>
> Are all the libraries in that default list free/libre?
>

No, some libraries/programs in the crates.io registry are non-free (but 
their source code is always available).  This is because, to use your 
words in your other post, the crates.io registry is a "repo site where in 
principle anyone can put a program", and not a list of "programs that in 
principle you may wish to install side by side in one computer".

As I said in an earlier post, there are currently 115402 available 
libraries/programs in the crates.io registry, and out of these the vast 
majority (at least 110000) use free software licenses.  The recommended 
license for Rust libraries/programs is a dual MIT/Apache-2.0 (which is how 
Rust itself is licensed), but users are not forced to use these licenses.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 21:16                           ` Richard Stallman
@ 2023-05-27  0:26                             ` Gregory Heytings
  2023-05-28 21:47                               ` Richard Stallman
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-27  0:26 UTC (permalink / raw)
  To: Richard Stallman; +Cc: luangruo, tomas, emacs-devel


>> You are confusing two different things: distros which distribute 
>> binaries to end-users (Debian and others) and source code repositories.
>
> We make a distinction, but it's not exacty that distinction as described 
> in the lines above.
>

Indeed, my words were not accurate enough.

>
> On one hand, we have distros.  A distro lists programs that in principle 
> you may wish to install side by side in one computer.  (Yes, it has more 
> wrinkles than that, but that's the basic point.)  You're likely to see 
> all of them as choices for what you might install.
>
> On the other hand, we have repo sites where in principle anyone can put 
> a program.  Those programs are not all meant to be potentially used 
> together.  They may even be written for different platforms. Basically, 
> the packages in a repo site are not a menu of packages to install. 
> Being interested in one package there does not mean you want to know 
> about the other packages hosted there.
>
> That fundamental difference in purpose is the reason that we use 
> different criteria for judging distros and judging repo sites.  Their 
> respective criteria are based on their purposes.
>

With that clarified distinction, the crates.io registry is clearly in the 
category of "repo sites where in principle anyone can put a program" (or 
library).




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  0:26                                     ` Gregory Heytings
@ 2023-05-27  2:37                                       ` Ruijie Yu via Emacs development discussions.
  2023-05-28 21:48                                       ` Richard Stallman
  2023-05-28 21:48                                       ` Richard Stallman
  2 siblings, 0 replies; 101+ messages in thread
From: Ruijie Yu via Emacs development discussions. @ 2023-05-27  2:37 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, eliz, tomas, emacs-devel


Gregory Heytings <gregory@heytings.org> writes:

>>
>> Where does cargo get the list of libraries to consider using?
>>
>
> The dependencies of a Rust program/library are specified (manually) by the
> author of that program/library, in a (structured) text file.  The source code of
> the libraries on which the program/library depends are downloaded (by Cargo)
> from the crates.io registry, and kept in a local cache (CARGO_HOME, by default
> $HOME/.cargo).
>
>>
>> Are all the libraries in that default list free/libre?
>>
>
> No, some libraries/programs in the crates.io registry are non-free (but their
> source code is always available).  This is because, to use your words in your
> other post, the crates.io registry is a "repo site where in principle anyone can
> put a program", and not a list of "programs that in principle you may wish to
> install side by side in one computer".
>
> As I said in an earlier post, there are currently 115402 available
> libraries/programs in the crates.io registry, and out of these the vast majority
> (at least 110000) use free software licenses.  The recommended license for Rust
> libraries/programs is a dual MIT/Apache-2.0 (which is how Rust itself is
> licensed), but users are not forced to use these licenses.

And, to follow up on that, you can always specify replacement registries
in your user configuration (I don't recall if you can do so in any
system configuration).  Since a registry is just a git repository hosted
online or locally, you can fork the crates.io repository, and then you
are free to modify it as you see fit, such as filtering out unsuitable
libraries (e.g., those who transitively depend on any non-libre
libraries).

-- 
Best,


RY



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
@ 2023-05-27  7:12 Payas Relekar
  0 siblings, 0 replies; 101+ messages in thread
From: Payas Relekar @ 2023-05-27  7:12 UTC (permalink / raw)
  To: Lynn Winebarger; +Cc: Gregory Heytings, tomas, emacs-devel

Lynn Winebarger <owinebar@gmail.com> writes:

> Can "crates.io" be replaced by a different package repository, or
> configured to work with whatever is available locally?

Yes, and it is a very simple config change:
https://doc.rust-lang.org/cargo/reference/registries.html#using-an-alternate-registry

--



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 21:32                           ` Richard Stallman
@ 2023-05-27  9:45                             ` Yuri Khan
  2023-05-28 21:48                               ` Richard Stallman
  0 siblings, 1 reply; 101+ messages in thread
From: Yuri Khan @ 2023-05-27  9:45 UTC (permalink / raw)
  To: rms; +Cc: chad, eliz, emacs-devel

On Sat, 27 May 2023 at 04:33, Richard Stallman <rms@gnu.org> wrote:

> So when you say to link a certain program, the library-choosing
> systems figures out which of the libraries in that collection provide
> symbols that the program needs.  And it links with them.

It does not work that way. No build system I have used recently, and
maybe ever, solves for you equations like “I want symbols x, y, and z,
find me a set of libraries to link with”.

The author of a program selects libraries to work with and specifies
them explicitly in the program build configuration. If those
libraries, in turn, depend on other libraries, a build system resolves
the full transitive closure of dependencies. If the program and each
library specify constraints on versions of their dependencies, the
build system is expected to validate that they are all satisfied,
and/or to find a set of versions that together satisfy all
constraints.

Checking library licenses for mutual compatibility and for
compatibility with the program’s intended license is solely the
programmer’s responsibility.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 21:16                                       ` Richard Stallman
  2023-05-27  0:25                                         ` Gregory Heytings
@ 2023-05-27 14:55                                         ` Brian Cully via Emacs development discussions.
  1 sibling, 0 replies; 101+ messages in thread
From: Brian Cully via Emacs development discussions. @ 2023-05-27 14:55 UTC (permalink / raw)
  To: rms; +Cc: Gregory Heytings, eliz, tomas, emacs-devel


Richard Stallman <rms@gnu.org> writes:

> I have trouble understanding that.  Before dynamic libraries, we 
> used
> static libraries.  Each library was a .o file, made by 
> compilation.
>
> But how can each program have its own version of one and the 
> same
> library?  Does Rust store all libraries as **source code**
> and recompile each library each time that library is linked
> into a program?

More than that, each Rust program can have many versions of any 
particular symbol.

If program A links in libraries B and C, and B links with D 
version 1, while C links with D version 2, then A will have 
symbols from both versions of D linked in with it.

It is able to do this because when Rust does name mangling, the 
names are mangled with library metadata, including version, so 
that the symbols in the object file equivalent have unique names.

It's worth noting that Rust doesn't use standard .a/.so/.o files, 
but something like them called with a .rlib extension, which 
contains extra information not available in the aforementioned 
formats.

-bjc



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  0:25                                         ` Gregory Heytings
@ 2023-05-28 10:20                                           ` Madhu
  2023-05-28 12:38                                             ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Madhu @ 2023-05-28 10:20 UTC (permalink / raw)
  To: emacs-devel

* Gregory Heytings <3a315ddd3aa7d7cda74e @heytings.org> :
Wrote on Sat, 27 May 2023 00:25:25 +0000:
>>> This is the misconception I pointed to in my previous post: Rust
>>> libraries are not dynamic libraries, they are compiled into the
>>> program.  This eliminates all compatibility problems: you can have
>>> as many programs as you want on your computer, each one compiled
>>> with a different version of a given library.
>> I have trouble understanding that.  Before dynamic libraries, we
>> used static libraries.  Each library was a .o file, made by
>> compilation.
> Rust libraries are neither dynamic (compiled separately and loaded at
> run time) nor static (compiled separately and linked at build time),
> they are always compiled together with the program.
>> But how can each program have its own version of one and the same
>> library?  Does Rust store all libraries as **source code** and
>> recompile each library each time that library is linked into a
>> program?
>>
>
> Yes, that's how it works.  For example, there are 25 versions of the
> "itoa" library (which does the opposite of the well-known "atoi"
> function), and you could have 25 different Rust programs on your
> computer, each one using on a different version of that library.  If
> you build these programs yourself, you will end up, in your local
> CARGO_HOME directory, with a copy of the source code of the 25
> versions of that library: itoa-0.1.0, ..., itoa-1.0.6.

This (and in golang) is the spiritual equivalent of having (and
shipping) every variant of functions in all released versions glibc
available, and a program may "link" to any of the versions. Where
"linking" means compiling all the sourcees, using the current llvm
satisfying the hardware and build requirements including memory and
hardware and obligatory traffic to the repo homeservers (no payas you
cannot change crates.io, you can only add a second repo server, and
change all your config files to use it)

Conventional thinking would abhor at the horror of having all versions
of all glibc functions all the time, even if you have got the whole
thing from a repo server. Now why is this is a good idea?  The folk
investing in it and the jobs and also investing in the hardware and
bandwidth probably know.














^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 10:20                                           ` Madhu
@ 2023-05-28 12:38                                             ` Po Lu
  2023-05-29 22:03                                               ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-28 12:38 UTC (permalink / raw)
  To: Madhu; +Cc: emacs-devel

Madhu <enometh@meer.net> writes:

> Conventional thinking would abhor at the horror of having all versions
> of all glibc functions all the time, even if you have got the whole
> thing from a repo server.

You _do_ have all versions of all symbols exported by glibc available,
at all times.  Glibc implements symbol versioning extremely well.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: Builder, a build system integration for Emacs
  2023-05-23  8:36   ` Philip Kaludercic
  2023-05-23 11:18     ` Eli Zaretskii
  2023-05-24  3:34     ` David Masterson
@ 2023-05-28 21:17     ` Björn Bidar
  2 siblings, 0 replies; 101+ messages in thread
From: Björn Bidar @ 2023-05-28 21:17 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: Richard Stallman, BTuin, emacs-devel

Philip Kaludercic <philipk@posteo.net> writes:

> Richard Stallman <rms@gnu.org> writes:
>
>> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
>> [[[ whether defending the US Constitution against all enemies,     ]]]
>> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>>
>>   > As far as I know, Emacs does not provide a convenient way to use build
>>   > systems,
>>
>> Isn't "use build systems" what M-x compile does?
>> Assuming that each bui;d system provides a shell command to invoke it,
>> M-x compile can run that command and build the package.
>
> The issue is not what M-x compile, but that with a lot of modern
> programming languages the build systems are complex but automatable, to
> a point that it would be nice if Emacs could detect the necessary
> information to invoke the right command or sequence of commands.

This is what projectile's project types do. I think these would be a
good fit to port to project.el since these are about more than building
but also testing and debugging etc.

I think it impossible to get a one size fits all tool that will abstract
all project types.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-26 22:59                       ` Lynn Winebarger
@ 2023-05-28 21:22                         ` Björn Bidar
  2023-05-29 22:38                           ` Richard Stallman
  2023-05-29 22:38                           ` Richard Stallman
  0 siblings, 2 replies; 101+ messages in thread
From: Björn Bidar @ 2023-05-28 21:22 UTC (permalink / raw)
  To: Lynn Winebarger; +Cc: Gregory Heytings, tomas, emacs-devel

Lynn Winebarger <owinebar@gmail.com> writes:

> On Thu, May 25, 2023, 2:55 AM Gregory Heytings <gregory@heytings.org> wrote:
>
>>
>> >> Cargo is a program that runs locally, not a server.  It works like
>> >> make, except that it may communicate with the crates.io repository, to
>> >> fetch a copy of the source code (and the license) of the libraries you
>> >> need to build a given Rust program, and that are not yet available
>> >> locally.
>> >
>> > ... akin to npm (the Node package manager of the Javascript world), it
>> > downloads half of the Internet while building and makes your life
>> > miserable if you want to avoid that.
>> >
>> > The new models just make it slightly more inconvenient to stay free.
>> >
>>
>> You are spreading FUD.  When you want to compile, say, Emacs, you need to
>> either download the binaries of the libraries that are not yet available
>> locally and their headers, or download the source of these libraries and
>> build them.  Doing that does not "donwload half of the Internet".  After
>> this you need to run the "configure" script which checks which libraries
>> (and sometimes which versions of these libraries) are available.
>>
>> Cargo does all that for you.
>>
>> >
>> > Can we call this pattern neo-proprietary?
>> >
>>
>> No, we cannot.  There is no relation whatsoever between software
>> proprietariness and this elegant solution to the problem of library
>> dependencies.
>>
>
>
> "Elegant" is a strong characterization of the practice of "vendoring"
> source dependencies, which you describe here.  It's useful if you are
> maintaining a replicable build process common in corporate software
> environments and projects meant to distribute prebuilt binaries to the
> mass-market.  Vendoring is distinctly unfriendly to users that want to
> build or tinker with it locally using locally available (and user-vetted)
> libraries, i.e. classic free software users.

Not just to users but anyone that has to deal with the software in the
long run.
These "package-managers" or in case of Rust in some even compilers
(since you don't really invoke rustc) make it so easy to vendor
libraries that most/many don't have a stable ABI or API. 

> Can "crates.io" be replaced by a different package repository, or
> configured to work with whatever is available locally?

If I understand corrrectly earlier that is possible but I would assume
that is a hard task to do since you would have to mirror all the
packages that already commonly used.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  0:26                             ` Gregory Heytings
@ 2023-05-28 21:47                               ` Richard Stallman
  2023-05-29 22:05                                 ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-28 21:47 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: luangruo, tomas, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > You are apparently unaware that Rust guarantees backward compatility of 
  > source code.

I am unware of almost _everything_ about Rust, except what people have
told me.  I have never learned the Rust language

Other people have told me that Rust changes very often, that it is
unstable.  You're telling me something different that conflicts with
what they told me.

I hope you are the one who is right, because that would be clearer.


-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  0:26                                     ` Gregory Heytings
  2023-05-27  2:37                                       ` Ruijie Yu via Emacs development discussions.
@ 2023-05-28 21:48                                       ` Richard Stallman
  2023-05-29 22:05                                         ` Gregory Heytings
  2023-05-28 21:48                                       ` Richard Stallman
  2 siblings, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-28 21:48 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

You've told me a lot of pertinent info about how Cargo works.
Thank you for going to that effort.  I think that due to your help
I now understand the issue enough to reach tentative conclusions.

The conclusions say that we have a problem.  The reasoning is
explained below.

  > > Where does cargo get the list of libraries to consider using?
  > >

  > The dependencies of a Rust program/library are specified (manually) by the 
  > author of that program/library, in a (structured) text file.  The source 
  > code of the libraries on which the program/library depends are downloaded 
  > (by Cargo) from the crates.io registry, and kept in a local cache 
  > (CARGO_HOME, by default $HOME/.cargo).

I expected it was something like this, but I didn't know.
Now I know.  Thanks.

  > No, some libraries/programs in the crates.io registry are non-free

I was worried about that.

So if you build a Rust program Foo, its dependencies will cause some libraries
to be loaded from crates.io, and their dependencies will cause other libraries to be loaded from crates.io, and so on recursively.  Is that right?

And if any of those libraries specifies a nonfree dependency, that nonfree code
will get compiled into the program Foo -- right?

If so, that puts freedom at risk.  It means that any time you build a
Rust program that you have not thoroughly studied, you don't know
whether it will incorporate nonfree software.

Have I made any mistake in this reasoning?

If it is correct so far, I think that implies that the standard
version of Cargo is unacceptable in a free system.  With the standard
version of Cargo, all the packages in crates.io are virtually include
in the system distro.  If crates.io contains any nonfree package,
then any system distro that includes Cargo virtually includes that
nonfree package, so it is not a free distro.

Our distros must be free -- so I think it follows that our distros
cannot include unmodified Cargo.

Have I made any mistake in this reasoning?

  >   Since a registry is just a git repository hosted
  > online or locally, you can fork the crates.io repository, and then you
  > are free to modify it as you see fit, such as filtering out unsuitable
  > libraries (e.g., those who transitively depend on any non-libre
  > libraries).

Maybe we need to make such a fork of crates.io, delete all nonfree
packages, and modify our version of Cargo to use that.

How do packages get approved for inclusion in crates.io?
There are both freedom issues and security issues.

I think we should move this to gnu-prog-disc.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  0:26                                     ` Gregory Heytings
  2023-05-27  2:37                                       ` Ruijie Yu via Emacs development discussions.
  2023-05-28 21:48                                       ` Richard Stallman
@ 2023-05-28 21:48                                       ` Richard Stallman
  2 siblings, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-28 21:48 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  >  This is because, to use your 
  > words in your other post, the crates.io registry is a "repo site where in 
  > principle anyone can put a program", and not a list of "programs that in 
  > principle you may wish to install side by side in one computer".

You've quoted my words, but in a different context.  I was trying to
explain what makes two kinds of collections of packages different, not
giving definitions of them.

crates.io is a different kind of collection of packages.  It is not
like savannah.gnu.org or github.com.  It is also not like trisquel.org
or debian.org.  It is something else.  It is a collection of packages
that are ALL virtually included in your system, if it uses Cargo.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-27  9:45                             ` Yuri Khan
@ 2023-05-28 21:48                               ` Richard Stallman
  2023-05-29  8:03                                 ` Yuri Khan
  0 siblings, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-28 21:48 UTC (permalink / raw)
  To: Yuri Khan; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > The author of a program selects libraries to work with and specifies
  > them explicitly in the program build configuration. If those
  > libraries, in turn, depend on other libraries, a build system resolves
  > the full transitive closure of dependencies. If the program and each
  > library specify constraints on versions of their dependencies, the
  > build system is expected to validate that they are all satisfied,
  > and/or to find a set of versions that together satisfy all
  > constraints.

Thanks for explaining this.

What sort of "constraints on versions of their dependencies" are possible?
Are these numeric comparisons?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 21:48                               ` Richard Stallman
@ 2023-05-29  8:03                                 ` Yuri Khan
  2023-05-30 21:47                                   ` Richard Stallman
  0 siblings, 1 reply; 101+ messages in thread
From: Yuri Khan @ 2023-05-29  8:03 UTC (permalink / raw)
  To: rms; +Cc: emacs-devel

On Mon, 29 May 2023 at 04:48, Richard Stallman <rms@gnu.org> wrote:

> What sort of "constraints on versions of their dependencies" are possible?
> Are these numeric comparisons?

A version number is typically a triple of integers, written as
major.minor.patch. A total ordering is defined on version numbers,
using lexicographic order on these three components: 2.0.0 < 2.0.1 <
2.0.10 < 2.1.15 < 3.0.0.

There is a widely used convention (called *semantic versioning*
<https://semver.org/>) that a library author increments the patch
version when the changes are both forward and backward compatible;
minor version when the changes are only backward compatible (a program
depending on the older API builds and runs successfully with a newer
implementation); and major version when introducing breaking changes.

With that convention, the most useful type of version constraint is a
half-open interval expressing “I want version x.y.0 or higher, but
strictly lower than z.0.0”.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 12:38                                             ` Po Lu
@ 2023-05-29 22:03                                               ` Gregory Heytings
  2023-05-29 22:42                                                 ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-29 22:03 UTC (permalink / raw)
  To: Po Lu; +Cc: Madhu, emacs-devel


>> Conventional thinking would abhor at the horror of having all versions 
>> of all glibc functions all the time, even if you have got the whole 
>> thing from a repo server.
>
> You _do_ have all versions of all symbols exported by glibc available, 
> at all times.  Glibc implements symbol versioning extremely well.
>

Do you remember that Emacs 27.1, released in August 2020, cannot be 
compiled without a patch, because of an incompatible change in Glibc 2.34, 
released less than a year later, in August 2021?




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 21:47                               ` Richard Stallman
@ 2023-05-29 22:05                                 ` Gregory Heytings
  2023-05-30 13:03                                   ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-29 22:05 UTC (permalink / raw)
  To: Richard Stallman; +Cc: luangruo, tomas, emacs-devel


>> You are apparently unaware that Rust guarantees backward compatility of 
>> source code.
>
> I am unware of almost _everything_ about Rust
>

The "you" above was not you (Richard) ;-)

>
> Other people have told me that Rust changes very often, that it is 
> unstable.
>

That's incorrect, unless you use Rust's "nightly" version, which is its 
experimental branch.  Rust's "stable" is stable, and code that builds with 
a stable version of the Rust compiler should build with any later stable 
version of the Rust compiler.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 21:48                                       ` Richard Stallman
@ 2023-05-29 22:05                                         ` Gregory Heytings
  2023-05-30 13:01                                           ` Po Lu
  2023-05-30 21:52                                           ` Richard Stallman
  0 siblings, 2 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-29 22:05 UTC (permalink / raw)
  To: Richard Stallman; +Cc: emacs-devel


>
> So if you build a Rust program Foo, its dependencies will cause some 
> libraries to be loaded from crates.io, and their dependencies will cause 
> other libraries to be loaded from crates.io, and so on recursively.  Is 
> that right?
>

That is right.

>
> And if any of those libraries specifies a nonfree dependency, that 
> nonfree code will get compiled into the program Foo -- right?
>

That is right.

>
> If so, that puts freedom at risk.  It means that any time you build a 
> Rust program that you have not thoroughly studied, you don't know 
> whether it will incorporate nonfree software.
>
> Have I made any mistake in this reasoning?
>

The mistake is that those who care about software freedom can easily check 
whether a program incorporates non-free code, _without_ thoroughly 
studying that program.

There are at least two options to do that, which were already mentioned 
upthread: (1) running "cargo tree -f '{l}'", which will display the 
license of each of the dependencies of the program, recursively (that 
option works out of the box), and (2) installing a plugin for cargo, named 
"cargo deny", which is itself free software, and with which you can check, 
again recursively, whether all the dependencies of a program are free 
(more precisely: have a license that is present in the list of licenses 
you have chosen to allow).

>
> I think we should move this to gnu-prog-disc.
>

I'm not subscribed to that mailing list, which AFAIK is an internal 
mailing list with restricted access.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 21:22                         ` Björn Bidar
@ 2023-05-29 22:38                           ` Richard Stallman
  2023-05-29 22:38                           ` Richard Stallman
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-29 22:38 UTC (permalink / raw)
  To: Björn Bidar; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > If I understand corrrectly earlier that is possible but I would assume
  > that is a hard task to do since you would have to mirror all the
  > packages that already commonly used.

Maybe we could set up a virtual repo that rejects a certain specified
list of bad packages, and fetches the rest from crates.io.

Is there a reliable way to tell whether any given package in crates.io
is nonfree?  That would be needed.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-28 21:22                         ` Björn Bidar
  2023-05-29 22:38                           ` Richard Stallman
@ 2023-05-29 22:38                           ` Richard Stallman
  2023-05-30  4:28                             ` tomas
  1 sibling, 1 reply; 101+ messages in thread
From: Richard Stallman @ 2023-05-29 22:38 UTC (permalink / raw)
  To: Björn Bidar; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

I've never seen "vendor" used as a verb, and I don't understand it.
Could you explain to me what that means?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:03                                               ` Gregory Heytings
@ 2023-05-29 22:42                                                 ` Po Lu
  2023-05-30  7:26                                                   ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-29 22:42 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Madhu, emacs-devel

But Emacs binaries built with an older version of glibc will continue to work, as the symbols exported by that older version continue to be available.

On May 30, 2023 6:03:47 AM GMT+08:00, Gregory Heytings <gregory@heytings.org> wrote:
>
>>> Conventional thinking would abhor at the horror of having all versions of all glibc functions all the time, even if you have got the whole thing from a repo server.
>> 
>> You _do_ have all versions of all symbols exported by glibc available, at all times.  Glibc implements symbol versioning extremely well.
>> 
>
>Do you remember that Emacs 27.1, released in August 2020, cannot be compiled without a patch, because of an incompatible change in Glibc 2.34, released less than a year later, in August 2021?
>



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:38                           ` Richard Stallman
@ 2023-05-30  4:28                             ` tomas
  0 siblings, 0 replies; 101+ messages in thread
From: tomas @ 2023-05-30  4:28 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 590 bytes --]

On Mon, May 29, 2023 at 06:38:30PM -0400, Richard Stallman wrote:
> [[[ To any NSA and FBI agents reading my email: please consider    ]]]
> [[[ whether defending the US Constitution against all enemies,     ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> 
> I've never seen "vendor" used as a verb, and I don't understand it.
> Could you explain to me what that means?

This means to include external source code into your source tree.

Welcome to corporate-driven newspeak, where everyone is trying to
sell you a thing :)

Cheers
-- 
tomás

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:42                                                 ` Po Lu
@ 2023-05-30  7:26                                                   ` Gregory Heytings
  2023-05-30 12:54                                                     ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-05-30  7:26 UTC (permalink / raw)
  To: Po Lu; +Cc: Madhu, emacs-devel


>> Do you remember that Emacs 27.1, released in August 2020, cannot be 
>> compiled without a patch, because of an incompatible change in Glibc 
>> 2.34, released less than a year later, in August 2021?
>
> But Emacs binaries built with an older version of glibc will continue to 
> work, as the symbols exported by that older version continue to be 
> available.
>

And how is that relevant?  What is being discussed (and was objected to 
and characterized as a "horror") in this subthread is the fact that all 
versions of a library are available at compile time, to ensure that 
programs that depend on a given version of that library can still be built 
when later, possibly incompatible, versions of the library have been 
released.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30  7:26                                                   ` Gregory Heytings
@ 2023-05-30 12:54                                                     ` Po Lu
  2023-05-30 15:08                                                       ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-30 12:54 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Madhu, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> And how is that relevant?  What is being discussed (and was objected
> to and characterized as a "horror") in this subthread is the fact that

The fact that, in Madhu's own words:

  This (and in golang) is the spiritual equivalent of having (and
  shipping) every variant of functions in all released versions glibc
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  available, and a program may "link" to any of the versions. Where
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

all versions of all symbols exported from glibc are available at any
time, and can thus be used by the run-time link editor.

Anyway, I'm skeptical this will work out in practice: what if in ten
years, some version N.X.Y of a dependency depends on language features
last implemented in a version of the compiler that no longer works on a
new system?  The Rust compiler is not known for being stable, as people
apparently very rarely use only the ``stable'' features of the compiler.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:05                                         ` Gregory Heytings
@ 2023-05-30 13:01                                           ` Po Lu
  2023-05-30 15:08                                             ` Gregory Heytings
  2023-05-30 21:52                                           ` Richard Stallman
  1 sibling, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-30 13:01 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> The mistake is that those who care about software freedom can easily
> check whether a program incorporates non-free code, _without_
> thoroughly studying that program.
>
> There are at least two options to do that, which were already
> mentioned upthread: (1) running "cargo tree -f '{l}'", which will
> display the license of each of the dependencies of the program,
> recursively (that option works out of the box), and (2) installing a
> plugin for cargo, named "cargo deny", which is itself free software,
> and with which you can check, again recursively, whether all the
> dependencies of a program are free (more precisely: have a license
> that is present in the list of licenses you have chosen to allow).

Since that plug in is not included in a default installation of Cargo,
it is still unacceptable.  And displaying each license of each package
in a deep dependency tree counts as ``studying'' in my book.

In fact, it should not be possible to install non-free software by any
means presented by the package manager; using sources which are enabled
by default or mentioned in its documentation, for example: Debian does
not enable their `non-free' repository by default, but does provide
instructions telling you how to do so.  FSF-approved GNU distributions
do neither.

> I'm not subscribed to that mailing list, which AFAIK is an internal
> mailing list with restricted access.

AFAIK, the GNU project does not make public internal policy discussions.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:05                                 ` Gregory Heytings
@ 2023-05-30 13:03                                   ` Po Lu
  2023-05-31 22:29                                     ` Richard Stallman
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-30 13:03 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, tomas, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

>>> You are apparently unaware that Rust guarantees backward
>>> compatility of source code.
>>
>> I am unware of almost _everything_ about Rust
>>
>
> The "you" above was not you (Richard) ;-)
>
>>
>> Other people have told me that Rust changes very often, that it is
>> unstable.
>>
>
> That's incorrect, unless you use Rust's "nightly" version, which is
> its experimental branch.  Rust's "stable" is stable, and code that
> builds with a stable version of the Rust compiler should build with
> any later stable version of the Rust compiler.

Except that a large quantity of code utilizes ``unstable'' features.
As a result, changes to the ``nightly'' compiler often break large
amounts of code, without a centralized place where the breakage can
be fixed (i.e. Gnulib.)



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 12:54                                                     ` Po Lu
@ 2023-05-30 15:08                                                       ` Gregory Heytings
  2023-05-30 16:50                                                         ` chad
  2023-05-31  1:14                                                         ` Po Lu
  0 siblings, 2 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-30 15:08 UTC (permalink / raw)
  To: Po Lu; +Cc: Madhu, emacs-devel


>
> The Rust compiler is not known for being stable, as people apparently 
> very rarely use only the ``stable'' features of the compiler.
>

Both parts of that (unsubstantiated) sentence are wrong.  The truth is 
that, like any program that is not frozen, but evolving, the price to pay 
when you use the testing/development/unstable branch is to accept a 
certain degree of unstability.  This is the case for Emacs as well.  If 
what you need is stability, you should use the stable branch, which is, 
for that matter, the one that is installed by default.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 13:01                                           ` Po Lu
@ 2023-05-30 15:08                                             ` Gregory Heytings
  2023-05-31  1:16                                               ` Po Lu
  2023-05-31 22:28                                               ` Richard Stallman
  0 siblings, 2 replies; 101+ messages in thread
From: Gregory Heytings @ 2023-05-30 15:08 UTC (permalink / raw)
  To: Po Lu; +Cc: Richard Stallman, emacs-devel


>> There are at least two options to do that, which were already mentioned 
>> upthread: (1) running "cargo tree -f '{l}'", which will display the 
>> license of each of the dependencies of the program, recursively (that 
>> option works out of the box), and (2) installing a plugin for cargo, 
>> named "cargo deny", which is itself free software, and with which you 
>> can check, again recursively, whether all the dependencies of a program 
>> are free (more precisely: have a license that is present in the list of 
>> licenses you have chosen to allow).
>
> Since that plug in is not included in a default installation of Cargo,
>

Typing "cargo install cargo-deny" is all you need to install it.

Designers of a language cannot force all users of that language to make 
their software free.  They can incite them to do so, and can provide them 
with tools to do so.

>
> it is still unacceptable.
>

What makes you believe that you can decide what is acceptable and what is 
not?  Richard is asking for facts, your categorical judgements are out of 
place here.

>
> And displaying each license of each package in a deep dependency tree 
> counts as ``studying'' in my book.
>

I was replying to Richard, who said "It means that any time you build a 
Rust program that you have not thoroughly studied, you don't know whether 
it will incorporate nonfree software."  Displaying a list of licenses and 
checking that it doesn't contain any non-kosher ones is evidently not 
"thoroughly studying" a program.  And you can even create a short shell 
script to simplify your task, something like:

cargo tree -f '{p}: {l}' | sed 's/^[^a-z0-9]*//' | sort | uniq | grep -Ev '\(\*\)$|^build-dependencies] *$|MIT|Apache-2.0|GPL|BSD|ISC|MPL|Zlib'




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 15:08                                                       ` Gregory Heytings
@ 2023-05-30 16:50                                                         ` chad
  2023-05-31  1:14                                                         ` Po Lu
  1 sibling, 0 replies; 101+ messages in thread
From: chad @ 2023-05-30 16:50 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Po Lu, Madhu, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 985 bytes --]

On Tue, May 30, 2023 at 11:09 AM Gregory Heytings <gregory@heytings.org>
wrote:

> > The Rust compiler is not known for being stable, as people apparently
> > very rarely use only the ``stable'' features of the compiler.
> If
> what you need is stability, you should use the stable branch, which is,
> for that matter, the one that is installed by default.
>

I will add that I have used several rust-based packages over the last
several years, both as part of dabbling a bit with the language's unusual
features and as part of a decades long side-interest in reimplementations
of the Unix/Posix "standard user and developer toolset" (that started with
getting GNU on early SVR4 systems and has also included "rewrite everything
in perl", at least 4 different versions of  unix-y toolchain for Windows, 3
of same for macOS, and busybox). I've never used the nightly (or beta)
toolchain for any of these, and have never needed to do so.

I hope that helps,
~Chad

[-- Attachment #2: Type: text/html, Size: 1384 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29  8:03                                 ` Yuri Khan
@ 2023-05-30 21:47                                   ` Richard Stallman
  0 siblings, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-30 21:47 UTC (permalink / raw)
  To: Yuri Khan; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > > What sort of "constraints on versions of their dependencies" are possible?
  > > Are these numeric comparisons?

  > A version number is typically a triple of integers, written as
  > major.minor.patch.

Thanks.  That is what I needed to know.  With no prior information
about the meaning of "constraints on versions", I could envision a
wide range of possibile meanings for "versions" -- I didn't know that
it meant specifically something like this.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-29 22:05                                         ` Gregory Heytings
  2023-05-30 13:01                                           ` Po Lu
@ 2023-05-30 21:52                                           ` Richard Stallman
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-30 21:52 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > There are at least two options to do that, which were already mentioned 
  > upthread: (1) running "cargo tree -f '{l}'", which will display the 
  > license of each of the dependencies of the program, recursively (that 
  > option works out of the box),

It is useful that that feature exists, but it can't by itself correct
this problem.  The problem is that cargo will link programs with
nonfree libraries if they specify those libraries.

A free distro must not _by default_ offer any nonfree libraries for
linking.  If a user requests explicitly to link with specified nonfree
modules, the linker will do it, but a free distro never does that _on
its own initiative_ or suggests doing that.

-f would help a person building a Rust program find out whether it
would use any nonfree libraries, but (1) searching its output for all
the nonfree licenses could take some time and knowledge, and (2) not
all users will bother to check that.

                                  and (2) installing a plugin for cargo, named 
  > "cargo deny", which is itself free software, and with which you can check, 
  > again recursively, whether all the dependencies of a program are free 
  > (more precisely: have a license that is present in the list of licenses 
  > you have chosen to allow).

It may be able to do the job with this feature.  But we might want to
modify Cargo so that it blocks those licenses unconditionally.

Also, do Rust users make a habit of looking at the list of packages in
crates.io in other ways?  Either thru features of Cargo, or directly
thru various network protocols?

  > > I think we should move this to gnu-prog-disc.

It is simply that this issue is not really on topic for emacs-devel.
I feel we should save it for discussion of developing GNU Emacs.

  > I'm not subscribed to that mailing list, which AFAIK is an internal 
  > mailing list with restricted access.

It is meant for people participating in developing GNU.  Are you
working on developing GNU Emacs?  If so, that includes you.

Or I can cc you in the messages of this discussion and ask
others to do likewise.

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 15:08                                                       ` Gregory Heytings
  2023-05-30 16:50                                                         ` chad
@ 2023-05-31  1:14                                                         ` Po Lu
  2023-06-05  1:09                                                           ` Gregory Heytings
  1 sibling, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-05-31  1:14 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Madhu, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> Both parts of that (unsubstantiated) sentence are wrong.  The truth is
> that, like any program that is not frozen, but evolving, the price to
> pay when you use the testing/development/unstable branch is to accept
> a certain degree of unstability.

The problem starts when people begin doing this often.

This is not the case with a C compiler.  For example, I can compile most
C and C++ software currently in existence with GCC 4.0.  And most such
software will also work fine GCC 13.1.

Could you do the same with a Rust compiler from 2006, or even 2015?



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 15:08                                             ` Gregory Heytings
@ 2023-05-31  1:16                                               ` Po Lu
  2023-06-02 21:38                                                 ` Richard Stallman
  2023-06-05  1:10                                                 ` Gregory Heytings
  2023-05-31 22:28                                               ` Richard Stallman
  1 sibling, 2 replies; 101+ messages in thread
From: Po Lu @ 2023-05-31  1:16 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> Typing "cargo install cargo-deny" is all you need to install it.

It isn't installed by default, with no documentation describing how to
remove it.

> Designers of a language cannot force all users of that language to
> make their software free.  They can incite them to do so, and can
> provide them with tools to do so.

Unfortunately not.  But they can make it as difficult as reasonably
possible.

> What makes you believe that you can decide what is acceptable and what
> is not?  Richard is asking for facts, your categorical judgements are
> out of place here.

Richard just repeated precisely what I said in his reply to you.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 15:08                                             ` Gregory Heytings
  2023-05-31  1:16                                               ` Po Lu
@ 2023-05-31 22:28                                               ` Richard Stallman
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-31 22:28 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: luangruo, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  >   Richard is asking for facts,

I appreciate the factual information you're giving me.

                                   your categorical judgements are out of 
  > place here.

Maybe, but maybe not.  The reason these facts are important is for
figuring out what the GNU criteria for a free distro imply about a
distro containing Cargo.  The criteria are stated in
https://gnu.org/distros/free-system-distribution-guidelines.html.

Maybe Po Lu is familiar with these criteria and is anticipating our
conclusions.

  > Typing "cargo install cargo-deny" is all you need to install it.

To qualify as a free distro, the distro should even invite the user to
link the user's programs with nonfree software.  It must not invite
the user ti set a flag to permit that.  It must not offer to include
nonfree software virtually in the installation.

Of course, given free software the users can always change it and
override anything.  A free system cannot stop you from making any
change you choose to make.  If you want to install some nonfree
packages and put them into the libraries to use by default, you can.

But the free distro should not offer a shorthand way to do that.

So, what can we conclude about cargo-deny?

First, what the precise default behavior of cargo-deny?  Is its
default action to reject anything listed on crates.io with a nonfree
license?  If so, there might be an error in crates.io and some nonfree
package might be listed as free.  We need to have a way to override
that listing.

Second, installation of cargo-deny should be automatic.  It's not good
enough to tell users, "Don't forget to install cargo-deny so that your
system doesn't virtually contain nonfree Rust libraries!"

Third, I am not sure whether just installing cargo-deny is robust
enough as a way to exclude nonfree packages from our distro.
Installing (in a virtual sense) all the nonfree Rust packages should
not be so easy as deleting one file.

Maybe we should rename Cargo to Embargo and patch it so that it always
runs cargo-deny.  We could make a symlink from `cargo' to `embargo'
so that scripts don't break.

But we might develop free replacements for some of those nonfree
libraries.  We would want our version of Cargo to see them and use
them rather than the nonfree ones in crates.io.  We might want to
make asite free-crates.io which contains only the free packages
and make Cargo use that instead.

free-crates.io could implement a virtual copy, so that after the
list of its own packages (which will all be free), it would look
in crates.io and use the free packags found there.






-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-30 13:03                                   ` Po Lu
@ 2023-05-31 22:29                                     ` Richard Stallman
  0 siblings, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-05-31 22:29 UTC (permalink / raw)
  To: Po Lu; +Cc: gregory, tomas, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > Except that a large quantity of code utilizes ``unstable'' features.
  > As a result, changes to the ``nightly'' compiler often break large
  > amounts of code, without a centralized place where the breakage can
  > be fixed (i.e. Gnulib.)

Does this include programs we would want to include as package
in a distro for people to install?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-31  1:16                                               ` Po Lu
@ 2023-06-02 21:38                                                 ` Richard Stallman
  2023-06-05  1:10                                                 ` Gregory Heytings
  1 sibling, 0 replies; 101+ messages in thread
From: Richard Stallman @ 2023-06-02 21:38 UTC (permalink / raw)
  To: gregory; +Cc: emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > > Designers of a language cannot force all users of that language to
  > > make their software free.

That is a red herring.  We are not trying to "force" anyone to do aything.

The moral issue for us is not about what others do.
It is about what WE do.  We want to avoid recommending
any nonfree programs for installation.

Distributing a distro that contains unmodified Cargo and unmodified
crates.io virtually includs all the contents of crates.io, including
the nonfree package in it.  If we do that, WE will be morally responsible
for leading users toward using those packages.

So we need to avoid doing that.

The question is, how can we include Cargo and yet NOT do that?

-- 
Dr Richard Stallman (https://stallman.org)
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-31  1:14                                                         ` Po Lu
@ 2023-06-05  1:09                                                           ` Gregory Heytings
  2023-06-05  5:29                                                             ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-06-05  1:09 UTC (permalink / raw)
  To: Po Lu; +Cc: Madhu, emacs-devel


>
> This is not the case with a C compiler.  For example, I can compile most 
> C and C++ software currently in existence with GCC 4.0.  And most such 
> software will also work fine GCC 13.1.
>
> Could you do the same with a Rust compiler from 2006, or even 2015?
>

Your claim that Rust is not backward compatible being wrong, you now 
suggest that it should be forward compatible as well?  It isn't, of 
course, otherwise the language would be frozen.  And why would compiling 
recent programs with old versions of the compiler be useful, when all you 
have to do is to install a more recent version of the compiler?  Being 
able to compile old programs with a recent version of a compiler is, in 
practice, way more useful than being able to compile recent programs with 
an old version of a compiler.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-05-31  1:16                                               ` Po Lu
  2023-06-02 21:38                                                 ` Richard Stallman
@ 2023-06-05  1:10                                                 ` Gregory Heytings
  2023-06-05  5:19                                                   ` Po Lu
  1 sibling, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-06-05  1:10 UTC (permalink / raw)
  To: Po Lu; +Cc: Richard Stallman, emacs-devel


>> What makes you believe that you can decide what is acceptable and what 
>> is not?  Richard is asking for facts, your categorical judgements are 
>> out of place here.
>
> Richard just repeated precisely what I said in his reply to you.
>

No, he didn't.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  1:10                                                 ` Gregory Heytings
@ 2023-06-05  5:19                                                   ` Po Lu
  2023-06-05  8:17                                                     ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-06-05  5:19 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> No, he didn't.

Might I suggest you read <E1q4UJ9-00023F-51@fencepost.gnu.org>?



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  1:09                                                           ` Gregory Heytings
@ 2023-06-05  5:29                                                             ` Po Lu
  2023-06-05  8:17                                                               ` Gregory Heytings
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-06-05  5:29 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Madhu, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> Your claim that Rust is not backward compatible being wrong, you now

It's not.  The Linux kernel, for example, requires a ``nightly'' Rust
compiler for its Rust code.  To add insult to injury, that code does not
compile with GCC.

> suggest that it should be forward compatible as well?  It isn't, of
> course, otherwise the language would be frozen.

We are debating how _stable_ the language is, and backwards
compatibility is just one aspect.

Standard C is remarkably stable; embarassments such as the soon-to-be
included ``generic'' string functions aside, what has compiled in the
future will likely compile in the fast as well, and vice versa.

I think that the same could not be said for any other widely available
language.

> And why would compiling recent programs with old versions of the
> compiler be useful, when all you have to do is to install a more
> recent version of the compiler?

Because there are systems which are not supported by newer compilers.
Each new compiler is also slower than previous ones, and uses more
memory.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  5:19                                                   ` Po Lu
@ 2023-06-05  8:17                                                     ` Gregory Heytings
  2023-06-05  9:00                                                       ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-06-05  8:17 UTC (permalink / raw)
  To: Po Lu; +Cc: Richard Stallman, emacs-devel


>> No, he didn't.
>
> Might I suggest you read <E1q4UJ9-00023F-51@fencepost.gnu.org>?
>

You do not need to suggest it, I did read that reasoned and nuanced post.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  5:29                                                             ` Po Lu
@ 2023-06-05  8:17                                                               ` Gregory Heytings
  2023-06-05  9:06                                                                 ` Po Lu
  0 siblings, 1 reply; 101+ messages in thread
From: Gregory Heytings @ 2023-06-05  8:17 UTC (permalink / raw)
  To: Po Lu; +Cc: Madhu, emacs-devel


>> suggest that it should be forward compatible as well?  It isn't, of 
>> course, otherwise the language would be frozen.
>
> We are debating how _stable_ the language is, and backwards 
> compatibility is just one aspect.
>

No, that's not what we are discussing.  Once again, "what is being 
discussed (and was objected to and characterized as a "horror") in this 
subthread is the fact that all versions of a library are available at 
compile time, to ensure that programs that depend on a given version of 
that library can still be built when later, possibly incompatible, 
versions of the library have been released."

You now conveniently try to shift the focus on "the language".

>
> Standard C is remarkably stable; embarassments such as the soon-to-be 
> included ``generic'' string functions aside, what has compiled in the 
> future will likely compile in the fast as well, and vice versa.
>

That's abstract theory (and it ignores the fact that even the "Standard C" 
language evolves: C23 will be released in a few months).  In practice, 
Emacs 27, released less than three years ago, cannot be compiled anymore 
without a patch.

In contrast, a Rust program that compiles, together with its dependencies, 
with a stable release of the Rust compiler, compiles with any later stable 
release of the Rust compiler.

And with this I bow out of this thread.




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  8:17                                                     ` Gregory Heytings
@ 2023-06-05  9:00                                                       ` Po Lu
  0 siblings, 0 replies; 101+ messages in thread
From: Po Lu @ 2023-06-05  9:00 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Richard Stallman, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> You do not need to suggest it, I did read that reasoned and nuanced post.

And how is Richard's second conclusion different from mine, regarding
the adequacy of ``solutions'' such as cargo-deny and manually listing
the licenses used by each package?

As was pointed out, I am familiar with the criteria used to evaluate
package repositories included in free operating systems.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  8:17                                                               ` Gregory Heytings
@ 2023-06-05  9:06                                                                 ` Po Lu
  2023-06-17  3:34                                                                   ` Yilkal Argaw
  0 siblings, 1 reply; 101+ messages in thread
From: Po Lu @ 2023-06-05  9:06 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Madhu, emacs-devel

Gregory Heytings <gregory@heytings.org> writes:

> No, that's not what we are discussing.  Once again, "what is being
> discussed (and was objected to and characterized as a "horror") in
> this subthread is the fact that all versions of a library are
> available at compile time, to ensure that programs that depend on a
> given version of that library can still be built when later, possibly
> incompatible, versions of the library have been released."
>
> You now conveniently try to shift the focus on "the language".

Since different versions of various libraries require different versions
of the language, it is a very relevant subject.

> That's abstract theory (and it ignores the fact that even the
> "Standard C" language evolves: C23 will be released in a few months).

Standard C evolves, yet it takes pains to remain compatible with
previously written code.  Very few programs require anything newer than
C99.

> In practice, Emacs 27, released less than three years ago, cannot be
> compiled anymore without a patch.

Except that it can be compiled with a single update to Gnulib, a
procedure that everyone knows how to perform.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PROPOSAL] Builder, a build system integration for Emacs
  2023-06-05  9:06                                                                 ` Po Lu
@ 2023-06-17  3:34                                                                   ` Yilkal Argaw
  0 siblings, 0 replies; 101+ messages in thread
From: Yilkal Argaw @ 2023-06-17  3:34 UTC (permalink / raw)
  To: Po Lu; +Cc: Gregory Heytings, Madhu, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1845 bytes --]

I don't understand why the discussion devolved to the merits of cargo. The
original proposal for the builder package would be useful as a general
feature to work with any build system. If I have a build system X I wrote
myself which fulfills all the gnu ethical requirements, it would allow me
to have a convenient generic way to interact with it through compile and
the build systems cli. If that is the case I don't see the harm in having a
general way to suggest completions for compile based on project basis.

With Regards
Yilkal Argaw

On Mon, Jun 5, 2023 at 12:07 PM Po Lu <luangruo@yahoo.com> wrote:

> Gregory Heytings <gregory@heytings.org> writes:
>
> > No, that's not what we are discussing.  Once again, "what is being
> > discussed (and was objected to and characterized as a "horror") in
> > this subthread is the fact that all versions of a library are
> > available at compile time, to ensure that programs that depend on a
> > given version of that library can still be built when later, possibly
> > incompatible, versions of the library have been released."
> >
> > You now conveniently try to shift the focus on "the language".
>
> Since different versions of various libraries require different versions
> of the language, it is a very relevant subject.
>
> > That's abstract theory (and it ignores the fact that even the
> > "Standard C" language evolves: C23 will be released in a few months).
>
> Standard C evolves, yet it takes pains to remain compatible with
> previously written code.  Very few programs require anything newer than
> C99.
>
> > In practice, Emacs 27, released less than three years ago, cannot be
> > compiled anymore without a patch.
>
> Except that it can be compiled with a single update to Gnulib, a
> procedure that everyone knows how to perform.
>
>

[-- Attachment #2: Type: text/html, Size: 2368 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2023-06-17  3:34 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-21 10:21 [PROPOSAL] Builder, a build system integration for Emacs BTuin
2023-05-21 12:11 ` Philip Kaludercic
2023-05-21 14:56   ` Augustin Chéneau (BTuin)
2023-05-21 17:24 ` Jim Porter
2023-05-21 19:33   ` Augustin Chéneau (BTuin)
2023-05-21 19:58     ` Jim Porter
2023-05-21 21:36       ` John Yates
2023-05-22 16:35       ` Augustin Chéneau (BTuin)
2023-05-23  0:44         ` Po Lu
2023-05-23 21:10           ` Augustin Chéneau (BTuin)
2023-05-23 21:17             ` Óscar Fuentes
2023-05-24  6:09             ` Dirk-Jan C. Binnema
2023-05-24 21:35               ` Richard Stallman
2023-05-24 23:32                 ` Jim Porter
2023-05-25  0:11                 ` Gregory Heytings
2023-05-25  4:00                   ` tomas
2023-05-25  6:53                     ` Gregory Heytings
2023-05-25  7:48                       ` Eli Zaretskii
2023-05-25  9:33                         ` Gregory Heytings
2023-05-25 11:28                           ` Eli Zaretskii
2023-05-25 11:53                             ` Gregory Heytings
2023-05-25 13:09                               ` Eli Zaretskii
2023-05-25 14:36                                 ` Gregory Heytings
2023-05-25 16:20                                   ` Eli Zaretskii
2023-05-25 16:40                                     ` tomas
2023-05-25 19:23                                     ` Gregory Heytings
2023-05-26  0:57                                       ` Po Lu
2023-05-27  0:24                                         ` Gregory Heytings
2023-05-26  5:57                                       ` Eli Zaretskii
2023-05-26 21:16                                       ` Richard Stallman
2023-05-27  0:25                                         ` Gregory Heytings
2023-05-28 10:20                                           ` Madhu
2023-05-28 12:38                                             ` Po Lu
2023-05-29 22:03                                               ` Gregory Heytings
2023-05-29 22:42                                                 ` Po Lu
2023-05-30  7:26                                                   ` Gregory Heytings
2023-05-30 12:54                                                     ` Po Lu
2023-05-30 15:08                                                       ` Gregory Heytings
2023-05-30 16:50                                                         ` chad
2023-05-31  1:14                                                         ` Po Lu
2023-06-05  1:09                                                           ` Gregory Heytings
2023-06-05  5:29                                                             ` Po Lu
2023-06-05  8:17                                                               ` Gregory Heytings
2023-06-05  9:06                                                                 ` Po Lu
2023-06-17  3:34                                                                   ` Yilkal Argaw
2023-05-27 14:55                                         ` Brian Cully via Emacs development discussions.
2023-05-26  0:54                                   ` Po Lu
2023-05-26 21:16                                   ` Richard Stallman
2023-05-27  0:26                                     ` Gregory Heytings
2023-05-27  2:37                                       ` Ruijie Yu via Emacs development discussions.
2023-05-28 21:48                                       ` Richard Stallman
2023-05-29 22:05                                         ` Gregory Heytings
2023-05-30 13:01                                           ` Po Lu
2023-05-30 15:08                                             ` Gregory Heytings
2023-05-31  1:16                                               ` Po Lu
2023-06-02 21:38                                                 ` Richard Stallman
2023-06-05  1:10                                                 ` Gregory Heytings
2023-06-05  5:19                                                   ` Po Lu
2023-06-05  8:17                                                     ` Gregory Heytings
2023-06-05  9:00                                                       ` Po Lu
2023-05-31 22:28                                               ` Richard Stallman
2023-05-30 21:52                                           ` Richard Stallman
2023-05-28 21:48                                       ` Richard Stallman
2023-05-25 13:16                         ` chad
2023-05-25 19:38                           ` Augustin Chéneau (BTuin)
2023-05-26 21:32                           ` Richard Stallman
2023-05-27  9:45                             ` Yuri Khan
2023-05-28 21:48                               ` Richard Stallman
2023-05-29  8:03                                 ` Yuri Khan
2023-05-30 21:47                                   ` Richard Stallman
2023-05-25  7:55                       ` tomas
2023-05-25  8:44                         ` Gregory Heytings
2023-05-25 10:38                       ` Po Lu
2023-05-25 11:44                         ` Gregory Heytings
2023-05-25 12:02                           ` Po Lu
2023-05-25 12:08                             ` Gregory Heytings
2023-05-26  0:52                               ` Po Lu
2023-05-26 21:16                           ` Richard Stallman
2023-05-27  0:26                             ` Gregory Heytings
2023-05-28 21:47                               ` Richard Stallman
2023-05-29 22:05                                 ` Gregory Heytings
2023-05-30 13:03                                   ` Po Lu
2023-05-31 22:29                                     ` Richard Stallman
2023-05-26 22:59                       ` Lynn Winebarger
2023-05-28 21:22                         ` Björn Bidar
2023-05-29 22:38                           ` Richard Stallman
2023-05-29 22:38                           ` Richard Stallman
2023-05-30  4:28                             ` tomas
2023-05-25 10:42             ` Po Lu
2023-05-25 19:36               ` Augustin Chéneau (BTuin)
2023-05-22 22:00 ` Richard Stallman
2023-05-23  8:36   ` Philip Kaludercic
2023-05-23 11:18     ` Eli Zaretskii
2023-05-23 12:13       ` Po Lu
2023-05-23 18:46       ` Augustin Chéneau (BTuin)
2023-05-24  6:32         ` Juri Linkov
2023-05-24 20:09           ` Augustin Chéneau (BTuin)
2023-05-24  3:34     ` David Masterson
2023-05-24 10:26       ` Philip Kaludercic
2023-05-28 21:17     ` Björn Bidar
  -- strict thread matches above, loose matches on Subject: below --
2023-05-27  7:12 [PROPOSAL] " Payas Relekar

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.