How to let a crate be linked against one of several API implementation libraries

The Glk API has many implementations, and in C land it's common to manually specify which library you want to link against (usually by directly specifying the path and lib name, not using a system library). For example Glulxe's Makefile contains

GLKINCLUDEDIR = ../cheapglk
GLKLIBDIR = ../cheapglk
GLKMAKEFILE = Make.cheapglk

#GLKINCLUDEDIR = ../glkterm
#GLKLIBDIR = ../glkterm
#GLKMAKEFILE = Make.glkterm

#GLKINCLUDEDIR = ../xglk
#GLKLIBDIR = ../xglk
#GLKMAKEFILE = Make.xglk

#GLKINCLUDEDIR = ../remglk
#GLKLIBDIR = ../remglk
#GLKMAKEFILE = Make.remglk

What would be a natural Rustic way of allowing for the same?

Is this a case where a build.rs file would be the best option? I guess it could even do exactly like that Makefile and simply have a bunch of options all but one commented out. Or could there be a way to pass an option to the build.rs to tell it which one to choose?

Does anyone know of a Rust project which does something like this which I could consult?

yes, a cargo build script is typically used for this kind of task. many -sys crates uses build scripts to configure the libraries for the linker. a build script can usually automatically detect the correct library path, and environment variables can be used to customize or by-pass the auto-detection procedure. some crate can even build the library from source if the detection fails. some crates also use optional cargo features to select different libraries to link, but this is NOT how cargo features are intended to be used.

you can take a look at llvm-sys's build script, which has rather complex detection logic, users can set environment variables to customize some of the aspects.

1 Like