3

Is it possible to access a user-defined file-local variable during byte-compilation?

As an example, I am trying to get this code to work:

--- testfilelocals.el ---
;; -*- my-file-local: "foo" -*-

(defun testfilelocals ()
  (eval-when-compile 
    my-file-local))

which fails with a compiler error

testfilelocals.el:5:5:Error: Symbol's value as variable is void: my-file-local

2 Answers 2

2

Looking at the source code in bytecomp.el, one can see that only safe file-local variables are read (see the relevant part of the file below).

This means that if you declare your variable as safe for file-local use, it should be read when you compile your file. You can for example evaluate the following piece of code before you byte-compile the file:

(put 'my-file-local 'safe-local-variable 'stringp)



For reference, here is the relevant part of bytecomp.el:

(let ((buffer-file-name filename)
      (dmm (default-value 'major-mode))
      ;; Ignore unsafe local variables.
      ;; We only care about a few of them for our purposes.
      (enable-local-variables :safe)
      (enable-local-eval nil))
1
  • Thanks for quoting bytecomp.el. I was surprised to find out that loading the uncompiled source file with load-file even after setting the safe-local-variable property will result in a void-variable error when calling (testfilelocals), i.e. there is a disparity between compiled and uncompiled code. The quoted code (especially the comment) indicates that availability of file-local variables at compile time may be an unintended side-effect of the compiler implementation. I planned to modify the behaviour of a macro with those, which doesn't seem possible.
    – kdb
    Commented Sep 6, 2015 at 20:39
0

Maybe because you did not specify major mode where the variables are used:

;; -*- mode: Lisp; my-file-local: "foo" -*-

Most major modes reset all variables upon initialization.

3
  • Actually, I don't think so: trying to byte compile an example file where the mode is specified shows that it doesn't get rid of the problem. Still, your idea was good: the sources of bytecomp.el show that care has been taken to activate emacs-lisp-mode without altering file-local variables. Commented Sep 4, 2015 at 19:31
  • "...I don't think so..." in that case please submit corrections to the manual.
    – Emacs User
    Commented Sep 4, 2015 at 20:12
  • Sorry if my wording was unclear. I'm not saying that what you (or the manual) say is wrong... I'm just saying that I don't think it is the reason why the OP's file-local variable is not set during byte-compilation. You (and the manual), are correct when saying that "most modes kill all local variables as part of their initialization", but - if I understand it correctly - the reason why the OP's file-local variable is not set during byte-compilation is not that it has been killed, but rather that it has never been read in the first place since it was not safe. Commented Sep 4, 2015 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.