How do I tell Bazel where Python.h lives?

感情迁移 提交于 2019-12-06 03:28:50

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 the BUILD file to use for them. Here I'm just using build_file_content but if that becomes too complex you can put it in it's own file and reference it instead. The BUILD 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"

new_local_repository(
    name = "python_linux",
    path = "/usr",
    build_file_content = """
cc_library(
    name = "python35-lib",
    srcs = ["lib/python3.5/config-3.5m-x86_64-linux-gnu/libpython3.5.so"],
    hdrs = glob(["include/python3.5/*.h"]),
    includes = ["include/python3.5"],
    visibility = ["//visibility:public"]
)
    """
)

new_local_repository(
    name = "python_win",
    path = "C:/Python35",
    build_file_content = """
cc_library(
    name = "python35-lib",
    srcs = ["libs/python35.lib"],
    hdrs = glob(["include/*.h"]),
    includes = ["include/"],
    visibility = ["//visibility:public"]
)
    """
)

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 the select() function to choose the correct host library to link against based on the configuration.

config_setting(
    name = "linux_x86_64",
    values = {"cpu": "k8"},
    visibility = ["//visibility:public"],
)

config_setting(
    name = "windows",
    values = {"cpu": "x64_windows"},
    visibility = ["//visibility:public"],
)

cc_binary(
    name="python-test",
    srcs = [
        "main.c",
    ],
    deps = select({
        "//:linux_x86_64": [
            "@python_linux//:python35-lib"
        ],
        "//:windows": [
            "@python_win//:python35-lib"
        ]
    })
)

FWIW here's the main.c I was playing around with to get this working.

#include "Python.h"

int main(int argc, char *argv[])
{
  Py_SetProgramName(argv[0]);  /* optional but recommended */
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
                     "print('Today is',ctime(time()))\n");
  Py_Finalize();
  return 0;
}

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 your WORKSPACE file and can just rely on another BUILD file in your repository. If you look at the Bazel repo they check in lots of external dependencies into the third_party directory, so it's a common practice.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!