Emacs script byte compile (with loaded libraries) - emacs

The library suggests I use this in shell scripts to byte compile files:
emacs -batch -f batch-byte-compile files...
When I run this though, many don't compile, complaining because it hasn't loaded one library or another, I guess because it's starting up a new emacs instance without loading these libraries linked in my .emacs.
I keep Emacs running (24.0.50.1, cocoa emacs under Mac OS X, built from the git repo HEAD), with all these libraries loaded (or at least linked), so is it possible to batch compile files and have them find these libraries from this instance of Emacs?
Or is there an easier way to do this?

You probably need a bunch of eval-when-compiles:
eval-when-compile is a Lisp macro in
`byte-run.el'.
(eval-when-compile &rest BODY)
Like progn, but evaluates the body
at compile time if you're compiling.
Thus, the result of the body appears
to the compiler as a quoted constant.
In interpreted code, this is entirely
equivalent to progn.

Related

Using distutils to compile plain C code with unmangled output name

I have a little benchmark suite, which compares different approaches to writing and executing some simple toy Python code, mainly for the purpose of illustrating Cython.
One of the approaches I used to have, was to write the test function in pure C, compile it with a C compiler (getting distutils to find and invoke the compiler for me) then load the library into Python with ctypes, and execute the function.
This worked swimmingly until distutils started embedding the python version and the platform in the name of the file it generates.
In the past I could persuade distutils to compile a C source file called C.c into a library called C.so in the working directory: recent versions of distutils insist on mangling the output name into something of the form build/temp.linux-x86_64-3.6 or (depending on exactly what distutils features I use) some other variaton on that theme.
Is there any way to persuade current versions of distutils to simply call the output C.so in the current working directory? (Alternatively, is there some way to reliably and easily tell ctypes where the library produced by distutils resides?)
[Bonus: How can this idea be expressed portably across Linux, OS X and Windows?]
=================================================================
Edit: for completeness, here is how I used to do it successfully in the past:
pure_C_setup.py:
from distutils.core import setup, Extension
setup(name="ctypes-test",
ext_modules = [Extension("C", ["C.c"])])
With the above setup file, the command python pure_C_setup.py install --install-lib=. used to produce C.so in the working directory; today it produces build/lib.linux-x86_64-3.6/C.cpython-36m-x86_64-linux-gnu.so
Not platform, not even compiler independent, but you might be able to use Extension's extra_link_args to achieve what you want.
For VCPP 2015:
setup(name="ctypes-test",
ext_modules = [Extension("C", ["C.c"], extra_link_args="/OUT:C.pyd")])

Load plugin from specific location

In my computer I have an Emacs plugin installed with the Debian package system, but this plugin is obsolete and I'm trying to install it inside my home directory with package-install. I have installed a newer version, but if I check which version is loaded, the older one is.
I tried with load-file and the global path to the new version, but it still loads the old version.
How can I force the load of the new one? Please, imagine that I'm not the sysadmin of the computer and I cannot uninstall any software package.
When a library contains multiple files one can assume that a single main file will load the others as necessary; but if the directory isn't in the load-path then it won't be able to load them (or at least not those versions), so load-file on its own isn't going to do the trick.
I don't make much use of package.el myself, but I'd really have thought that it would manage the load-path such that it took precedence over anything in site-lisp (which is presumably where the debian package is installing things.)
Try running emacs --no-site-lisp and check that the correct version of the library is loaded. If you don't want anything from the site libraries, then that might even be your solution.
If that works, then check the load-path variable after starting Emacs normally. Unless an absolute path is given, Emacs will look at those directories in sequence, and use the first one which matches. I am guessing that for some reason your site-lisp directory is appearing before the one created by package.el.
Or perhaps the package didn't install correctly at all.
That all said, in Emacs 24.3 at least (package-initialize) is called automatically and I don't think you should need to manually load anything. Check the package-load-list variable.
Edit:
On that last note, refer to cannot open load dired-details.
At the time I hadn't noticed that Emacs doesn't initialize packages until after the user init file has loaded, so you generally will need to initialize them manually in your init file.
Try this
(defun please-load-my-stuff ()
(interactive)
(load "PATH-TO-STUFF/STUFF))
When having access to init, put just form "(load ...)" there.
If more than one file is needed, load-path must be set also that way - before load, so the other required files are accessible.

Delete built-in packages in Emacs

Is it possible to remove built-in Emacs packages like "tetris"? They can't be marked to be deleted in package list as of 24.1. It would be nice to have a minimal installation of Emacs - even though barely useful - by deleting some or all built-in packages. Is it possible to do somehow, and will this ability added in future?
Emacs should start and be useable even if the whole lisp directory is empty (note that we rarely/never test it, so I don't guarantee that it'll work, but at least in principle it should and if it doesn't you should report it with M-x report-emacs-bug). So feel free to remove any and all packages in there you don't find useful, in order to create a trimmed-down version of Emacs.
You could just remove the elc files of all of the packages you want.
For example, in the version of emacs located in the ubuntu repository the tetris package is located in:
/usr/share/emacs/23.3/lisp/play/tetris.elc
If you move or remove it, emacs will continue to work, but you won't be able to play tetris anymore.
You might want to inspect the package--builtins variable. That said - there is little sense in removing any packages installed via package.el since package.el extracts and loads automatically only a package's autoloads - therefore having many installed packages doesn't result in any significant overhead. I'm quite certain that removing built-in packages will never be a feature of package.el.

How can I run SBCL code under a Unix-like operating system in a convenient way?

(David James both wrote the question and an answer. I'll edit it to conform to Stackoverflow standards.)
Using SBCL you can compile Lisp code to machine code.
Like Java, .net, C++ and even C you will need the runtime. So there are two ways to compile Common Lisp code.
First is to make huge binaries which is explained in SBCL documentation. No SBCL needed on target machine.
The other way is a more flexible one, which is to create machine code in a fasl (FASt Load) format. The SBCL runtime is needed on the target machine.
How does the second way work under a Unix-like operating system?
(Answer by David James:)
We are going to make two commands in our system: one for batch compiling Lisp code and the other for easily running Lisp code:
Using your favorite editor, open a file called sbcl.compile. The content should be:
#!/bin/bash
sbcl --noinform --eval "(compile-file \"$1\")" --eval "(quit)" > /dev/null
Now to compile Lisp files use:
# sbcl.compile hello.lisp
This will create a hello.fasl file.
Now to easily run these files, we create a new command. Using your favorite editor open a file called sbcl.run. The content should be:
#!/bin/bash
sbcl --noinform --load "$1" --quit --end-toplevel-options "$#"
Now you may invoke sbcl.run hello.fasl to run the native code.
# sbcl.run hello.fasl
Details are described in the SBCL manual: Starting SBCL
Another option is to add to the runtime all packages/functions/frameworks that you commonly use, and then save this state as a new core file, and use this as your default core while continuing development. I usually find fasls more trouble than they are worth, especially since lisp has the ability to save state in a VM-style core file. I just incrementally update the core as development moves along. And rebuild/update the core using GNU Make.

How can I run a .clj Clojure file I created?

I wrote a small "hello world" program on Linux to get started with the language.
Now I'd like to run it and see what it outputs.
How can I run this code?
What command should I run?
FWIW, I'm interpreting the question here as specifically asking how to run a single file, like a script, versus as a part of a compiled project.
Obviously though, there's a relationship between how and why you would want to run a single file, and how you would want to build a full project, so I weigh that in some as well.
Best choice: the clj tooling
Docs are here:
https://clojure.org/guides/deps_and_cli
This is an official part of the Clojure project, which by itself is a pretty good reason to go this route. However, it has a couple of advantages over the other solutions here:
cleaner dependency resolution model, via deps.edn
also resolve dependencies via git references!
~/.clojure/deps.edn seems to do a better job of cleanly providing reusable functionality via its aliass than ~/.lein/profiles.clj
if you need to load your code in a repl, clj won't choke on a borked src file, like lein repl does
Simply
clj your-code-file.clj
Or if you have dependencies
clj -Sdeps '{:deps {clj-time {:mvn/version "0.14.2"}}}' -M your-code-file.clj
Works well as a shebang in scripts as well!
#!clj -Sdeps '{:deps {clj-time {:mvn/version "0.14.2"}}} -M
(ns my-crazy-script!
(:require ...))
...
I recommend installing with homebrew, which now works on both Mac and Linux. If you're on Windows I'd recommend using the WSL+brew.
The one advantage I see of lein (see below) tooling over clj generally is that lein handles a little more of the process of building and packaging your code base, when you get to that point.
However, there are other ways of handing that (see pack, uberdeps or cambada), and the advantages of clj mentioned above outweigh IMHO.
Babashka
If you are trying to run a single file, as apposed to an entire project, there's a good chance your in "scripting territory".
Unfortunately, the JVM takes a while to boot up, as does Clojure itself.
Via the magic of GraalVM and the SCI, Babashka is able to support most of the Clojure language with blazing fast startup times.
It also comes with quite a few "batteries included" for typical scripting tasks, making it a perfect complement to clj when you want fast-executing, short lived processes.
Once you install it you can simply bb you-code-file.clj, or use #!bb in your shebang.
See the docs for more usage instructions:
https://babashka.org/
With lein & lein-exec
If you prefer lein tooling, or have a ~/.lein/profiles.clj file handy already and don't want to invest in learning clj/deps.edn, you can consider looking at lein-exec.
If you already have a project.clj set up with dependencies, you can of course run lein run -m <yer-namespace>[/<yer-main-fn>].
As mentioned above, the one advantage of lein over clj is that it is a complete build tool, and can make jars/uberjars for you with lein jar or lein uberjar, do deploys and such.
For ClojureScript
I'd recommend http://planck-repl.org/. It now supports (bootstrapped) quick launching of ClojureScript scripts without having to fire up the JVM or Clojure.
Like babashka, this makes it great for scripting.
However, I find babashka both more powerful and more natural for scripting, so I'd start there unless you have a particular reason for wanting to use Cljs (more familiarity with JS/node, need of certain cljs libraries, etc).
For more substantial projects (beyond scripting), you may want to look at Shadlow-CLJS, for its ease of incorporating vanilla JS projects.
And FWIW, Shadow nicely integrates with both deps and lein, and has it's own built in hode code reloading, like figwheel.
With java
You can, of course, as has been suggested in another answer, use
java -cp clojure.jar clojure.main file.clj
But you don't see that in the wild too often, because it's a pain to have to find the path to your clojure.jar and manually composing classpaths for dependencies sucks.
But, you know, to each their own.
You can run script with following command:
java -cp clojure.jar clojure.main file.clj
but it's better to use leiningen, especially when you'll start to add dependencies to your project. lein provides number of commands to run your code (with all necessary dependencies), pack code into archive with lein jar, or create complete, independent archives with lein uberjar that you can run with:
java -jar your_app.jar
command
P.S. You can read how to use lein in following article - it describes base tasks & configurations
Once you've installed lein and the lein-exec plugin, running the .clj file you've created is as simple as
lein exec hello.clj
In case you're passing command line arguments like
lein exec hello.clj arg1 arg2 arg3
you can access them in the 'foo' function in your hello.clj like
(foo *command-line-args*)
For a single clj file you can add,
#!/usr/bin/env java -cp /path/to/clojure-1.2.0.jar clojure.main
to the top of the file and make it executable or you can use leiningen which is a clojure build tool it will create a single jar that has everything packed, then you can just do,
java -jar cool_app.jar
if you just want to execute a single file, how about piping it to the repl like:
cat $PATH_TO_FILE | lein repl
For running a single file through command line use the following commands:
clj -m (NameSpace name)
ex: clj -m Sample
Or if you want to run through repl:
(load-file filelocation)
ex:
(load-file "Sample.clj")
Drip is probably now the best answer to this question (see Drip's wiki for details on using Drip with Clojure).
Cake was incorporated into Leiningen and has since been superseded as the most stable implementation of Clojure automation by Drip - see this answer to a similar question here.
I really like writing small .clj scripts, but sometimes those scripts have dependencies that need to be installed. Since none of the other answers cover that case, I provide an example here. This example is a single-file script that requires the permutations function from the math.combinatorics library.
Cumbersome Mac-only solution
#!/usr/bin/env clj -Sdeps {:deps,{org.clojure/math.combinatorics,{:mvn/version,"0.1.6"}}} -M
; Explanation for the shebang:
; -Sdeps Specify deps in EDN format
; , Clojure interprets commas as whitespace. Without the commas, the EDN is
; broken up into multiple arguments and the command fails. On the
; command line you can use single quotes around the EDN string, but
; Mac shebangs don't support quoting around arguments.
; -M Run the program as a "main" function
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
Linux-only solution
#!/usr/bin/env -S clj -Sdeps '{:deps {org.clojure/math.combinatorics {:mvn/version "0.1.6"}}}' -M
; Explanation for the shebang:
; env -S Allow multiple arguments to be passed to the following command
; -Sdeps Specify deps in EDN format
; -M Run the program as a "main" function
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
Portable solution (Linux and Mac)
See the planck docs for an explanation. It's very clever!
#!/usr/bin/env bash
"exec" "clj" "-Sdeps" "{:deps {org.clojure/math.combinatorics {:mvn/version \"0.1.6\"}}}" "-M" "$0" "$#"
(ns foo
(:use [clojure.math.combinatorics :only (permutations)]))
(dorun (map #(println (apply str %)) (permutations "abcde")))
I had similar issue in running a specific clojure script file out of a clojure project using lein. Then I found a shortcut, thought of sharing the same.
In project.clj file, you can toggle the clojure script file name ( which has main method of course). Following is the statement for this.
:main ^:skip-aot conv.newconv ; here conv is namespace and newconv is the file name .
Note: I am new to clojure and I am not sure why '^:skip-aot` is used, I have not checked that.
Note: This methodology, does not require any plugin to be installed nor any jar file need to be generated. This only requires to change a name in project file.
Assumption: Your clojure project has multiple clojure files, each having main method. I am assuming this is created for testing purpose only. My solution will work for this specific scenario.
Install clojure from the below official link according to your OS
https://clojure.org/guides/install_clojure
Now we can easily execute files by below command tested on mac only. Other complicated steps aren't required now I think.
write a sample print statement in your file hello-world.clj
(println "Hello world")
Run your program with the below command in terminal
clj -M hello-world.clj
It will output
Hello world
Tested on Clojure Version: 1.11.1.1200