On Wed, Apr 28, 2010 at 12:52:43PM +0000, Vegard Øye wrote:
When a file is compiled, it is /not/ evaluated, except for `defmacro' calls and `require' statements. However, if the compiled file requires other files, those files /are/ evaluated. This means, amongst other things, that if you compile a file which defines some variables with `defvar' and /uses/ those variables, you will get warnings about free variables. Those `defvar' declarations are not evaluated. The preferred way to handle this seems to be to place all the declarations in a separate file and then require it, forcing evaluation. (In Viper's case, that file is viper-init.el.)
No; when a file is compiled, *all* the macros are expanded (i.e. evaluated); that's one of the points of macros, after all -- to be expanded at compile time, not run time. And `defvar's are recognized by the compiler, too, so you definitely should *not* get any warnings, as long as all the `defvar's are put before the variables are first used.
vimpulse-big.el can't do that, of course, since it's a single file. So there's another and uglier way to force evaluation during compilation: wrap the code in (eval-and-compile ...). Of course, you still have to do this /before/ you actually use the variables.
(Interestingly, `defmacro' calls are evaluated regardless. This is so the compiler can substitute the macro expansion for subsequent macro calls. Why couldn't it make the same exception for `defvar'? According to the Reference, section 16.6,
[Y]ou can tell the compiler that a variable is defined using `defvar' with no initial value.
But it doesn't mention the need for using `eval-and-compile' in the compiled file! Way confusing.)
Yeah, it doesn't mention that because it is not the case AFAIK, see above.
So, yeah, vimpulse-big.el. If I got this right, I'll have to define all variables at the beginning of the code, wrapped in (eval-and-compile ...), to silence the compiler completely. Right now it complains a lot (warnings), although it does produce the .elc.
I don't think it makes sense to have multiple features (i.e. `provide' forms) in a single file (this issue was mentioned before). If you want to compile the single file version, shouldn't you instead remove all the provides except `vimpulse' (and reorder the code so it will work, if needed)?
If it could be automated, sure. All the makefile would have to do is remove the last two lines of every file (one `provide' statement and one blank line) before concatenating them. Do you think that's possible as stated, or would one have to use awk or sed and search for "(provide "? (I've never used awk or sed.)
I don't think `make' can do that on its own -- `cat' is an external program, too ;-). You could e.g. just replace `cat' in the makefile with sed "/^(\(provide\|require\) 'vimpulse-/d" That would do what `cat' does, except for all lines providing or requiring 'vimpulse-something, i.e. it would leave `(provide 'vimpulse)' in. Štěpán