Can I install an executable in $PREFIX/bin using Pkg?


#1

So, in Python, there is a notion of “entry_points” for your package that are scripts which are installed where ever your system looks for executables.

Is this possible with Pkg?


#2

You could perform the installation in your package’s deps/build.jl file, which gets run whenever your package is built. Unfortunately I don’t know if there’s any way to automatically clean up the installed file when your package is removed.


#3

Thanks for the reply. I’ll try to do a deepdive on Pkg one of these days and see if I can’t get something working.


#4

For example, if you have an executable inside your package’s deps folder called foo, you could write a deps/build.jl file that looks like this:

# deps/build.jl

symlink(joinpath(@__DIR__, "foo"), "/usr/local/bin/foo")

That will automatically create the symlink whenever you do pkg> add MyPackage and/or pkg> build MyPackage. Of course, this assumes that foo is compatible with the current operating system and that /usr/local/bin/ is on the path, so your script will probably need to be more complicated if those assumptions don’t hold in your particular use case.


#5

I’ll look at that. I was thinking something more along the lines of a pull-request on Pkg itself that adds support for cross-platform script install and removal, but it may be that my eyes are bigger than my stomach on this one. Probably should start with my own package that integrates with Pkg and see how it goes.


#6

Unlike Python, project environment in Julia does not have a dedicated $PREFIX directory (it’s just two TOML files). So I think it’s a bit tricky to install executables. But I can imagine an API that would copy scripts to $PROJECT/bin (say) where $PROJECT is the directory you have Project.toml. It means that users have to explicitly add, e.g., ~/.julia/environments/v1.1/bin to the PATH. But since there can be multiple Julia versions and multiple environments, I think it’s much safer option.

Another idea: I think you can just write a separate helper package (say) ScriptInstaller based on Pkg for installing and managing Julia scripts in ~/.local/bin/ (and other places in other OSes). The installed script can keep the path to Julia project and julia executable. Users would run ScriptInstaller.add("PACKAGE") which creates a dedicated project, runs Pkg.add("PACKAGE") in it, and then finally install the entry points to ~/.local/bin/ etc.


#7

There is a way, the package manager could be looking for a deps/clean.jl script.


#8

I was thinking something along these lines. It’s not a complete application distribution system, but a way to distribute executables with Julia packages would be a step in the right direction in my book.


#9

Have you heard about BinaryBuilder.jl ? It seems like the perfect usecase for your scenario. Here is a youtube link for a nice explanation: https://www.youtube.com/watch?v=2e0PBGSaQaI


#10

I’m not thinking of binaries, just installing little uncompiled Julia executables somewhere in the user’s $PATH in a manor similar to what Python packages and Ruby gems do.

This is mostly just for my personal use. I have a lot of little python modules with helper scripts attached that like to install all over the place.

However, maybe binaries would be even better? I’ll look at this package, in any case.


#11

Ah, in that case my answer wasn’t helpful. BinaryBuilder (+BinaryProvider) is for making binaries and libraries available for your package.

If you’re just looking for a convenient way to run your julia script from the command line I’d just create a simple bash variable and call julia with something like julia -E "using Test; @test 1 == 1"


#12

I think build_executable from PackageCompiler.jl can in principle do this. There is also ApplicationBuilder.jl (see https://www.youtube.com/watch?v=kSp6d3qSb3I).