我如何告诉 Bazel Python.h 住在哪里?
How do I tell Bazel where Python.h lives?
我正在构建一个 C++ 可执行文件,需要从用户的 Python 安装中#include "Python.h"。
为了在 Bazel 中表达 Python.h(以及它包含的各种头文件),我需要知道 Python include 目录在哪里。这个位置在 Windows 和 Linux 上会有所不同,我想要一个 Bazel 配置来构建它们。
引用存在于 WORKSPACE 根之外的软件的最佳 Bazel 实践是什么?
因此,要告诉 Bazel 关于外部依赖项,您需要使用 Workspace Rules 之一指定外部依赖项的位置,以及 Bazel 与该外部项一起使用的 BUILD
文件依赖。
要让某些东西正常工作 cross-platform,您需要使用 select() 函数让 Bazel select 为您的主机操作系统构建合适的库。
这是完成它的尝试:
首先,我们在项目的根目录中有 WORKSPACE
文件,它定义了两个库和用于它们的 BUILD
文件。在这里我只使用 build_file_content
但如果它变得太复杂你可以把它放在它自己的文件中并引用它。 BUILD
文件公开了 Python 附带的预构建库以及所需的 header 文件。它还为依赖这些库的任何目标添加了一个包含路径,因此您可以 #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"]
)
"""
)
接下来是您的应用程序的 BUILD
文件。这里需要定义一些config_settings。这允许我们为构建定义平台相关设置。我们使用 cpu 值来确定主机 OS.
在 cc_binary
规则中,我们使用 select()
函数根据配置选择正确的宿主库 link。
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 这是 main.c
我正在玩弄以使其正常工作。
#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;
}
另一种方法(也许更简单)是将 python header 和库检查到您的存储库中。您仍然需要使用 select()
来选择正确的库以 link 反对,但至少您不需要向 WORKSPACE
文件添加任何内容,并且可以只依赖另一个 BUILD
文件在您的存储库中。如果您查看 Bazel repo,他们会将大量外部依赖项签入 third_party
目录,因此这是一种常见的做法。
我正在构建一个 C++ 可执行文件,需要从用户的 Python 安装中#include "Python.h"。
为了在 Bazel 中表达 Python.h(以及它包含的各种头文件),我需要知道 Python include 目录在哪里。这个位置在 Windows 和 Linux 上会有所不同,我想要一个 Bazel 配置来构建它们。
引用存在于 WORKSPACE 根之外的软件的最佳 Bazel 实践是什么?
因此,要告诉 Bazel 关于外部依赖项,您需要使用 Workspace Rules 之一指定外部依赖项的位置,以及 Bazel 与该外部项一起使用的 BUILD
文件依赖。
要让某些东西正常工作 cross-platform,您需要使用 select() 函数让 Bazel select 为您的主机操作系统构建合适的库。
这是完成它的尝试:
首先,我们在项目的根目录中有 WORKSPACE
文件,它定义了两个库和用于它们的 BUILD
文件。在这里我只使用 build_file_content
但如果它变得太复杂你可以把它放在它自己的文件中并引用它。 BUILD
文件公开了 Python 附带的预构建库以及所需的 header 文件。它还为依赖这些库的任何目标添加了一个包含路径,因此您可以 #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"]
)
"""
)
接下来是您的应用程序的 BUILD
文件。这里需要定义一些config_settings。这允许我们为构建定义平台相关设置。我们使用 cpu 值来确定主机 OS.
在 cc_binary
规则中,我们使用 select()
函数根据配置选择正确的宿主库 link。
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 这是 main.c
我正在玩弄以使其正常工作。
#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;
}
另一种方法(也许更简单)是将 python header 和库检查到您的存储库中。您仍然需要使用 select()
来选择正确的库以 link 反对,但至少您不需要向 WORKSPACE
文件添加任何内容,并且可以只依赖另一个 BUILD
文件在您的存储库中。如果您查看 Bazel repo,他们会将大量外部依赖项签入 third_party
目录,因此这是一种常见的做法。