ch11ng / exwm

Emacs X Window Manager
2.85k stars 136 forks source link

Add a `Makefile` to the repo. The `Makefile` should support generation of autoloads too. #619

Open emacksnotes opened 5 years ago

emacksnotes commented 5 years ago

Motivation

I wanted to test drive some of the recent fixes in the repo. But I couldn't find a convenient way to switch from the ELPA directory to a local checkout.

Add a Makefile to the repo. The Makefile should support generation of autoloads too.

I have cooked up the following based on how Org mode's git repo does it build. The copyright is theirs. My contribution is merely to strip down the source files to their essential components. The suggestion you see down below are sourced from:

  1. https://code.orgmode.org/bzg/org-mode/src/master/mk/org-fixup.el
  2. https://code.orgmode.org/bzg/org-mode/src/master/mk/default.mk

exwm-fixup.el

(require 'autoload)

(defun exwm-make-exwm-loaddefs ()
  "Make the file exwm-loaddefs.el in the current directory.
This function is internally used by the build system and should
be used by foreign build systems or installers to produce this
file in the installation directory of Exwm mode.  Exwm will not
work correctly if this file is not up-to-date."
  (interactive)
  (with-temp-buffer
    (set-visited-file-name "exwm-loaddefs.el")
    (insert ";;; exwm-loaddefs.el --- autogenerated file, do not edit\n;;\n;;; Code:\n")
    (let ((files (directory-files default-directory
                  nil "^exwm-.*\\.el$")))
      (mapc (lambda (f) (generate-file-autoloads f)) files))
    (insert "\f\n(provide 'exwm-loaddefs)\n")
    (insert "\f\n;; Local Variables:\n;; version-control: never\n")
    (insert ";; no-byte-compile: t\n;; no-update-autoloads: t\n")
    (insert ";; coding: utf-8\n;; End:\n;;; exwm-loaddefs.el ends here\n")
    (let ((inhibit-read-only t))
      (save-buffer))))

Makefile


# Name of your emacs binary
EMACS   = emacs

# start Emacs with no user and site configuration
# EMACSQ = -vanilla # XEmacs
EMACSQ  = $(EMACS)  -Q

# Using emacs in batch mode.
BATCH   = $(EMACSQ) -batch \
      -L "~/.emacs.d/elpa/xelb-0.17/" \
      -L "."

# Emacs must be started in toplevel directory
BATCHO  = $(BATCH)

# Emacs must be started in lisp directory
BATCHL  = $(BATCH) \
      --eval '(add-to-list '"'"'load-path "~/.emacs.d/elpa/xelb-0.17/")' \
      --eval '(add-to-list '"'"'load-path "./")'

# How to generate org-loaddefs.el
MAKE_ORG_INSTALL = $(BATCHL) \
      --eval '(load "org-compat.el")' \
      --eval '(load "../mk/org-fixup.el")' \
      --eval '(org-make-org-loaddefs)'

# How to byte-compile the whole source directory
ELCDIR  = $(BATCHL) \
      --eval '(batch-byte-recompile-directory 0)'

# How to byte-compile a single file
ELC = $(BATCHL) \
      --eval '(batch-byte-compile)'

elc:
    $(ELCDIR)
    rm exwm-loaddefs.el
    $(BATCHO) -l exwm-fixup.el --eval '(exwm-make-exwm-loaddefs)'

Additional Note

Another alternative would be this: Let the make create an ELPA-compatible tar, and then do a package-install on that tar. This way byte-compilation and autoload generation would be offloaded to package.el.

Related Issues

  1. https://github.com/ch11ng/xelb/issues/24
  2. https://github.com/ch11ng/exwm/issues/618
ch11ng commented 5 years ago

Another alternative would be this: Let the make create an ELPA-compatible tar, [...]

Actually we do it in a similar way. The elpa repo (http://git.savannah.gnu.org/cgit/emacs/elpa.git) has a Makefile for packaging ELPA packages. make would compile all packages and make archive would generate the package. But since XELB and EXWM are hosted in another branch of that repo, you'll have to make subdirectories for them in the 'packages' directory first (other packages there can be removed BTW).

Org-mode predates ELPA and has its own way for packaging. You'll find it treated specially if you check that Makefile.

emacksnotes commented 5 years ago

Add a Makefile to the repo. The Makefile should support generation of autoloads too.

The elpa repo (http://git.savannah.gnu.org/cgit/emacs/elpa.git) has a Makefile for packaging ELPA packages. make would compile all packages and make archive would generate the package. But since XELB and EXWM are hosted in another branch of that repo, you'll have to make subdirectories for them in the 'packages' directory first (other packages there can be removed BTW).

You have made some changes based on my issues / suggestions. I wanted to test drive some of these recent fixes. When I updated the exwm through the package manager, I realized that it didn't contain the commit https://github.com/ch11ng/exwm/commit/5b9f4b0851d27e8132a930dfbfec0b94099a4c9f.

Since, a package update for pulling the recent fixes didn't work, I took the Makefile route. It is then I discovered that there is a Makefile.

exwm (xelb etc) is a GNU package. So, isn't it /necessary/ that the build instructions /must/ be part of the code repo? I note that exwm is part of externals of GNU ELPA and it is this repo i.e., the github repo that is the authoritative repo for exwm. So, it follows that the build instructions /must/ be available on /this/ repo. I am a bit disapponted that exwm doesn't conform to the norm expected of a GNU package.

As an Emacs user, I don't mind reading up documentation or code. But your suggestions forces me to read checkout GNU elpa and readup on it's build infrastructure etc. This extra step is a bit detracts from primary goal of test driving recent fixes or enhancements.

In other words, my request to you is this: Push your changes--atleast the bug-fixes--to ELPA as immediately as possible. This way an interested user has an easy way to test drive the HEAD of the github repo.

That said, I will followup with your ELPA build suggestions ...

emacksnotes commented 5 years ago

In other words, my request to you is this: Push your changes--atleast the bug-fixes--to ELPA as immediately as possible. This way an interested user has an easy way to test drive the HEAD of the github repo.

Put differently, I am looking for GNU ELPA's equivalent for MELPA Unstable.

I see that exwm declares itself as version 0.22.1 (i..e, I see exwm 0.22.1 external Emacs X Window Manager),

while the git checkout says it is 0.22.26

$ git describe --tags
0.22-26-g5b9f4b0
emacksnotes commented 5 years ago

Actually we do it in a similar way. The elpa repo (http://git.savannah.gnu.org/cgit/emacs/elpa.git) has a Makefile for packaging ELPA packages. make would compile all packages and make archive would generate the package. But since XELB and EXWM are hosted in another branch of that repo, you'll have to make subdirectories for them in the 'packages' directory first (other packages there can be removed BTW).

That said, I will followup with your ELPA build suggestions ...

For the sake of record, this is what I did

  1. Checkout elpa
$ git checkout git://git.savannah.gnu.org/emacs/elpa.git
  1. Checkout externals
$ make externals
  1. In packages subdir, remove all packages other than exwm and xelb

Why waste time compiling packages that you don't want from git.

  1. Build xelb and exwm
$ make
  1. Use package manager, and delete exwm and xelb

  2. Update load-path

(require 'cl-lib)

(dolist (dir '("~/src/elpa/packages/xelb/"
           "~/src/elpa/packages/exwm/"
           ))
  (cl-pushnew dir load-path))

Now, I am able to use the exwm from git HEAD.


To track your git repo, I believe I need to do this ...

In order to track this git repo, all I need to do is do

$ cd packages/xelb
$  git pull

$ cd ../exwm
$ git pull

$ cd ..
$ make
emacksnotes commented 5 years ago

exwm (xelb etc) is a GNU package. So, isn't it /necessary/ that the build instructions /must/ be part of the code repo? I note that exwm is part of externals of GNU ELPA and it is this repo i.e., the github repo that is the authoritative repo for exwm. So, it follows that the build instructions /must/ be available on /this/ repo. I am a bit disapponted that exwm doesn't conform to the norm expected of a GNU package.

For ideological reasons (wink wink), you may want to add support for make in xelb and exwm directories.

emacksnotes commented 5 years ago

For ideological reasons (wink wink), you may want to add support for make in xelb and exwm directories.

My need is NOT so much a build infrastructure, but to have an easy way to update to (and test) the latest exwm code.

To that end, (and assuming that you are particular that exwm and xelb shouldn't be part of MELPA), you may want to create ch11ng.github.io repository with the following directory structure

ch11ng.github.io/elpa:
.
..
archive-contents
xelb-0.17.tar
exwm-0.22.1.tar

and ask the users to update their package-archives with

(custom-set-variables
 '(package-archives
   (quote
    (("exwm" . "https://ch11ng.github.io/elpa/")))))

Just my 2 cents.

(Now that I have the build setup, the above request doesn't concern me any more. Nevertheless, it would be of interest to folks who have the same need as the one I registered here)

ch11ng commented 5 years ago

Usually adding local git repo to load-path is enough, as specified in the wiki. I find it fast enough to run code not compiled, but it's perhaps unacceptable for users who would compile their init.el.

emacksnotes commented 5 years ago

Add a Makefile to the repo. The Makefile should support generation of autoloads too.

Usually adding local git repo to load-path is enough, as specified in the wiki. I find it fast enough to run code not compiled, but it's perhaps unacceptable for users who would compile their init.el.

My concern is not "faster initing or loading", but generation of "autoload cookies". (Look at the heading for this issue. It clearly mentions autoloads).

My main gripe is, the entry point to sesssion managers-- exwm-enable--has no autoload cookie. When the entry point to exwm has no autoloads, one needs to require it. The require-s could be done away if only all the entry point had a cookie, and the load path contained an autoload file.

In olden times, any user new to Emacs, and wanting to install a file off of emacswiki, had one biggest hurdle: How the heck do I change my load-path and I know NO elisp. Once package-manager made it's appearance this problem no longer exists. I am digressing ...

Please add a autoload cookie to exwm-enable and also other entry points like (exwm-config-default(?)). Once that is done, the configuration examples and wiki guide need no longer bother about taking pains to list (require 'exwm), or (require 'exwm-config) etc.

ch11ng commented 5 years ago

I believe autoload is usually for interactive commands. In configuration I think it's a good practice to always use require (or other equivalents) to make sure the right package is used predictably. I've seen too many times users wasted time debugging a wrong version of package loaded.

Please add a autoload cookie to exwm-enable and also other entry points like (exwm-config-default(?)).

They are not commands and has no effect when called after EXWM has been initialized.

emacksnotes commented 5 years ago

I believe autoload is usually for interactive commands

In my understanding, autoload maps a symbol--it can be any symbol--to the library it is defined. So, that whenever the symbol is referenced--say by doing C-h v or C-h f or use in an actual execution of the code--the associated library code gets loaded on demand. It has been quite some time I left the university, but I believe the autoloads are like thunks

According to `(info "(elisp) Autoload")

 You can autoload macros and keymaps as well as ordinary functions.

Please add a autoload cookie to exwm-enable and also other entry points like (exwm-config-default(?)).

They are not commands and has no effect when called after EXWM has been initialized.

If you add an autoload cookie to exwm-enable then it will be available to the session manager's command line, without having that command line having to do a require. i.e., the autoload cookie on that function helps with actually setting up EXWM.

ch11ng commented 5 years ago

Please add a autoload cookie to exwm-enable and also other entry points like (exwm-config-default(?)).

They are not commands and has no effect when called after EXWM has been initialized.

If you add an autoload cookie to exwm-enable then it will be available to the session manager's command line, without having that command line having to do a require. i.e., the autoload cookie on that function helps with actually setting up EXWM.

I'm fine with exwm-enable (and will do that). exwm-config-default, as explained in other threads, is not intended for every user and will be left out.

emacksnotes commented 4 years ago

(A note / Heads-up on a compilation warning)

When I compiled exwm today, I got the following warning

~/src/elpa$ make
Byte compiling packages/exwm/exwm-workspace.el

In exwm-workspace-move-window:
packages/exwm/exwm-workspace.el:875:20:Warning:
    ‘run-window-configuration-change-hook’ is an obsolete function (as of
    27.1).
Byte compiling packages/exwm/exwm-xim.el

~/src/elpa$ emacs --version
GNU Emacs 27.0.50
Copyright (C) 2019 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

C-h v run-window-configuration-change-hook says,

run-window-configuration-change-hook is a built-in function in ‘C
source code’.

(run-window-configuration-change-hook &optional FRAME)

  This function is obsolete since 27.1.

Run ‘window-configuration-change-hook’ for FRAME.
If FRAME is omitted or nil, it defaults to the selected frame.

This function should not be needed any more and will be therefore
considered obsolete.

[back]

The NEWS entry says

Window change functions have been redesigned.

Hooks reacting to window changes run now only when redisplay detects that a change has actually occurred. Six hooks are now provided: window-buffer-change-functions (run after window buffers have changed), window-size-change-functions (run after a window was assigned a new buffer or size), window-configuration-change-hook (like the former but run also when a window was deleted), window-selection-change-functions (run when the selected window changed) and window-state-change-functions and window-state-change-hook (run when any of the preceding ones is run). Applications can enforce running the latter two using the new function set-frame-window-state-change. window-scroll-functions are unaffected by these changes.

In addition, a number of functions now allow the caller to detect what has changed since last redisplay: window-old-buffer returns for any window the buffer it showed at that time. old-selected-window and old-selected-frame return the window and frame that were selected during last redisplay. window-old-pixel-width (renamed from window-pixel-width-before-size-change), window-old-pixel-height (renamed from window-pixel-height-before-size-change), window-old-body-pixel-width and window-old-body-pixel-height return the total and body sizes of any window during last redisplay.

Also run-window-configuration-change-hook is declared obsolete.

See the section "(elisp) Window Hooks" in the Elisp manual for a detailed explanation of the new behavior.

ch11ng commented 4 years ago

Thanks! I did notice it recently. Fixed in 8b05c2a30d112e5deaf1196fccfcc2d1eb273756.