terminusdb-labs / swipl-rs

25 stars 6 forks source link

Include building swipl from source as part of crate #26

Closed munro closed 2 years ago

munro commented 2 years ago

Right now I'm having to manually compile swipl v8, and manually add it to my lib path.

It would be nice if this was done for as part of the crate so devs don't have to do anything!

Currently there is the swipl-sys project which looks to be doing it, but it's only v7: https://github.com/remexre/swipl-rs/blob/master/swipl-sys/build.rs

matko commented 2 years ago

There's unfortunately a few problems with getting SWI-prolog as part of the crate.

First, it's somewhat bad style for a build to require internet access (outside of the obvious need to fetch crate dependencies, which happens in one particular phase and can be pre-fetched). It is not obvious at all for a crate user that a crate might do something like that. docs.rs in particular blocks any sort of internet access in build scripts.

Ignoring that, unfortunately, it'd likely not even give you what you actually expect. Since SWI-Prolog v8, it hasn't been possible to use a static build of SWI-Prolog to link with, requiring instead that we link with the dynamic object. This means there's always some sort of run-time dependency to a particular install. If we were to download or build SWI-Prolog as part of this crate, it'd mean having to install SWI-Prolog to some long-lived location. It'd mean that to properly deploy your SWI-Prolog-based rust application, you also always have to ship that install along with it, and ship it in such a way that it is in the same location for anyone that installs it (or the dynamic object would not be found).

Even if we could somehow revitalize the static build of SWI-Prolog, this too wouldn't probably give you what you'd expect, as even the static build of SWI-Prolog requires that all prolog library files are in some known location, which is hardcoded in the static object. So while there's no dependency to a shared object in that case, there'd still be the need to install SWI-Prolog on any user machine anyway, and do it in the same place for every user.

At TerminusDB our use case is not building standalone rust applications that use prolog. Instead, we build a prolog application that uses a rust foreign library. So for us, it's pretty important that the rust build plays well with an existing prolog install, rather than setting up its own environment. As such, it can never be the default behavior to just download a prolog runtime. And given the limitations described above, I just don't see the point of doing so. Yes, as a developer it might be a slight bit more convenient, but unless you intend to build from source everywhere you intend to install your application, it's just not going to work.

Note that you don't actually need to put the swipl libraries on your path. the cargo-swipl tool can take care of a lot. As long as you have some swipl binary on your path, cargo swipl build, cargo swipl test and cargo swipl run will be able to set up the runtime environment for you so that the library is on the path. This has been tested on windows, linux and macOS and works well in all those environments.

One thing I would like to add at some point though is a tool that can modify a binary to hard-code the path to the swipl library, so that in cases of a known install location, standalone applications can be made to work without modifying the environment. That way at least, anyone who installs SWI-Prolog in some known location for a particular platform could run standalone swipl-rs binaries. If this would solve your problems, please let me know.