[英]Compile C++ file with Python.h import using Bazel
I want to compile a C++ file which uses Python embedding. 我想编译一个使用Python嵌入的C ++文件。 Therefore I #include in my C++ source.
因此,我#include在我的C ++源代码中。 When using g++ as compiler I would specify the following flags:
当使用g ++作为编译器时,我将指定以下标志:
g++ -o pybridge pybridge.cc -I/usr/include/python2.7/ -lpython2.7 g ++ -o pybridge pybridge.cc -I / usr / include / python2.7 / -lpython2.7
I want to use Bazel for compilation now and tried the following target rule: 我现在想使用Bazel进行编译,并尝试了以下目标规则:
cc_binary(
name = "pybridge",
srcs = ["pybridge.cc"],
copts = ["-I/usr/include/python2.7/"],
linkopts = ["-lpython2.7"]
)
Running bazel build
gives error messages like this: 运行
bazel build
会给出如下错误消息:
pybridge.cc:(.text+0x10): undefined reference to Py_Initialize
Bazel executes your build in a sandbox, to prevent it from accessing random resources on your system that won't be present on, say, your coworker's system. Bazel在沙箱中执行您的构建,以防止其访问您的系统中不存在的随机资源,例如您的同事的系统中不存在的资源。
This means that, unless you've declared a file (like the Python library) as a dependency, Bazel won't put it in the sandbox and your build won't be able to find it. 这意味着,除非您将文件(如Python库)声明为依赖项,否则Bazel不会将其放在沙箱中,并且您的构建将无法找到它。
There are two options: 有两种选择:
The easy one is to build with --spawn_strategy=standalone
( bazel build --spawn_strategy=standalone :pybridge
). 最简单的方法是使用
--spawn_strategy=standalone
进行构建( bazel build --spawn_strategy=standalone :pybridge
)。 This tells Bazel not to use sandboxing for this build. 这告诉Bazel在此构建中不要使用沙箱。 Note that, as far as Bazel knows, nothing has changed between the sandboxed and non-sandboxed run, so you'll have to clean before re-running without sandboxing, or you'll just get the cached error.
请注意,据Bazel所知,沙盒运行和非沙盒运行之间没有任何变化,因此您必须在重新运行之前先进行清理,而无需沙盒操作,否则您只会得到缓存的错误。
The harder option is to declare /usr/lib/libpython2.7.so
as an input to your build. 较难的选择是声明
/usr/lib/libpython2.7.so
作为构建的输入。 If you want to do that, add the following to the WORKSPACE file: 如果要这样做,请将以下内容添加到WORKSPACE文件中:
local_repository(
name = "system_python",
path = "/usr/lib/python2.7/config-x86_64-linux-gnu", # Figure out where it is on your system, this is where it is on mine
build_file_content = """
cc_library(
name = "my-python-lib",
srcs = ["libpython2.7.so"],
visibility = ["//visibility:public"],
)
""",
)
Then in your BUILD file, instead of linkopts = ["-lpython2.7"]
, add deps = ["@system_python//:my-python-lib"]
. 然后在您的BUILD文件中,而不是
linkopts = ["-lpython2.7"]
,添加deps = ["@system_python//:my-python-lib"]
。 Then Bazel will understand that your build depends on libpython2.7.so (and include it in the sandbox). 然后,Bazel将了解您的构建依赖于libpython2.7.so(并将其包含在沙箱中)。
( Tried commenting on OP's post but I lack the required karma. ) ( 试图评论OP的职位,但我缺少必需的业力。 )
FWIW, I've had problems linking against Python 2.7's libraries (on Windows), even when I didn't use Bazel but ran the linker manually, so this problem may be unrelated to Bazel. FWIW,即使在我不使用Bazel而是手动运行链接器的情况下,也无法在Python 2.7的库(在Windows上)上进行链接,因此此问题可能与Bazel无关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.