I'm building a C++ executable that needs to #include "Python.h" from the user's Python installation.
To express Python.h (and the various header files it includes) in Bazel, I need to know where the Python include directory is. This location will be different on Windows and Linux, and I'd like a single Bazel configuration to build them both.
What's the best Bazel practice for referencing software that exists outside of the WORKSPACE root?
So to tell Bazel about external dependencies you need to use one of the Workspace Rules to specify the location of the external dependency, as well as the
BUILD
file for Bazel to use with that external dependency.To have something work cross-platform you need to use the select() function to have Bazel select the proper library to build against for your host operating system.
Here's a stab at accomplishing it:
First we have the
WORKSPACE
file in your project's root that defines the two libraries and theBUILD
file to use for them. Here I'm just usingbuild_file_content
but if that becomes too complex you can put it in it's own file and reference it instead. TheBUILD
file here exposes the prebuild library shipped with Python along with the header files needed. It also adds an include path for any targets that depend on these libraries so you can do#include "Python.h"
Next the
BUILD
file for your application. Here you need to define some config_settings. This allows us to define platform dependent settings for our build. We use the cpu value to determine the host OS.In the
cc_binary
rule we use theselect()
function to choose the correct host library to link against based on the configuration.FWIW here's the
main.c
I was playing around with to get this working.Another way (and perhaps simpler) is checking the python headers and libraries into your repository. You will still need to use
select()
to choose the correct library to link against but at least you won't need to add anything to yourWORKSPACE
file and can just rely on anotherBUILD
file in your repository. If you look at the Bazel repo they check in lots of external dependencies into thethird_party
directory, so it's a common practice.