- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试从我的 python 源文件创建一个 unix 可执行文件。
我有两个文件,p1.py
和p2.py
p1.py:-
from p2 import test_func
print (test_func())
p2.py:-
def test_func():
return ('Test')
现在,我们可以看到 p1.py
依赖于 p2.py
。我想通过将两个文件组合在一起来制作一个可执行文件。我正在使用 cython。
我将文件名分别更改为 p1.pyx
和 p2.pyx
。
现在,我可以使用 cython 使文件可执行,
cython p1.pyx --embed
它将生成一个名为 p1.c
的 C 源文件。接下来我们可以使用gcc使其可执行,
gcc -Os -I /usr/include/python3.5m -o test p1.c -lpython3.5m -lpthread -lm -lutil -ldl
但是如何将两个文件合并为一个可执行文件?
最佳答案
您必须跳过一些循环才能使其正常工作。
首先,您必须意识到生成的可执行文件是一个非常薄的层,它只是将整个工作委托(delegate)给(即从中调用函数)pythonX.Ym.so
。您可以在调用时看到这种依赖关系
ldd test
...
libpythonX.Ym.so.1.0 => not found
...
因此,要运行该程序,您需要将 LD_LIBRARY_PATH
显示为 libpythonX.Ym.so
的位置,或者使用 - 构建 exe -rpath
选项,否则在 test
动态加载器启动时会抛出类似于
/test: error while loading shared libraries: libpythonX.Ym.so.1.0: cannot open shared object file: No such file or directory
通用构建命令如下所示:
gcc -fPIC <other flags> -o test p1.c -I<path_python_include> -L<path_python_lib> -Wl,-rpath=<path_python_lib> -lpython3.6m <other_needed_libs>
还可以针对 python 库的静态版本进行构建,从而消除对 libpythonX.Ym 的运行时依赖,例如参见此 SO-post .
<小时/>生成的可执行文件test
的行为与Python解释器完全相同。这意味着现在 test
将失败,因为它找不到模块 p2
。
一个简单的解决方案是就地 cythonize p2 模块(cythonize p2.pyx -i
):您将获得所需的行为 - 但是,您必须分发生成的共享对象p2.so
以及 test
。
将两个扩展捆绑到一个可执行文件中很容易 - 只需将两个 cythonized c 文件传递给 gcc:
# creates p1.c:
cython --empbed p1.pyx
# creates p2.c:
cython p2.pyx
gcc ... -o test p1.c p2.c ...
但是现在出现了一个新的(或旧的)问题:生成的 test
可执行文件无法再次找到模块 p2
,因为没有 p2。 py
并且 python 路径上没有 p2.so
。
关于这个问题有两个类似的SO问题,here和 here 。在您的情况下,建议的解决方案有点矫枉过正,在这里,在将 p2 模块导入到 p1.pyx
文件中使其工作之前初始化 p2 模块就足够了:
# making init-function from other modules accessible:
cdef extern object PyInit_p2();
#init/load p2-module manually
PyInit_p2() #Cython handles error, i.e. if NULL returned
# actually using already cached imported module
# no search in python path needed
from p2 import test_func
print(test_func())
如果模块之间存在循环依赖关系,在导入模块之前调用模块的 init 函数(实际上该模块不会真正被导入第二次,只会在缓存中查找)也可以工作。例如,如果模块 p2
导入模块 p3
,模块又导入 p2
。
警告:自 Cython 0.29 起,Cython 对于 Python>=3.5 默认使用多阶段初始化,因此调用 PyInit_p2
是不够的(参见例如 this SO-post ) 。要关闭此多阶段初始化,应将 -DCYTHON_PEP489_MULTI_PHASE_INIT=0
传递给 gcc 或类似于其他编译器。
注意:但是,即使完成上述所有操作,嵌入式解释器仍将需要其标准库(例如,参见此 SO-post ) - 还有更多努力使其真正独立!所以也许有人应该注意@DavidW's advice :
<小时/>"don't do this" is probably the best solution for the vast majority of people.
警告:如果我们将 PyInit_p2()
声明为
from cpython cimport PyObject
cdef extern PyObject *PyInit_p2();
PyInit_p2(); # TODO: error handling if NULL is returned
Cython 将不再处理错误,这是我们的责任。而不是
PyObject *__pyx_t_1 = NULL;
__pyx_t_1 = PyInit_p2(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 4, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_1);
__Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
为object
版本生成,生成的代码变成:
(void)(PyInit_p2());
即没有错误检查!
另一方面使用
cdef extern from *:
"""
PyObject *PyInit_p2(void);
"""
object PyInit_p2()
不适用于 g++ - 必须在声明中添加 extern C
。
关于python - 使用 cython 从多个 pyx 文件生成可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52959902/
所以问题是:如何使用标准 C 库以跨平台方式实现简单的自检可执行文件? 在这里,我正在寻找技术,而不是特定的检查方法(如 CRC 或哈希码),但该技术可能包含更适合某些方法的元素(例如见下文)。 目的
我想构建一个 C++ 可执行文件,以便所有库也附加到可执行文件。构建这样一个可执行文件的方法是什么?因此,每当我在其他 PC(运行 Ubuntu)上使用 g++ 编译我的代码时,它不需要运行该可执行文
我在 Netbeans IDE 8.0.1 中编写了一个名为 SampleChat 的 Java GUI 程序,并使用“clean and build”功能创建了一个 jar 文件。 我进入 Netb
我有两个 DLL,一个用 native C++ 编写,另一个用 C++/CLI 编写。前者被注入(inject)到进程中,并在稍后的时间点加载后者。在调试时,我注意到 native DLL 的断点运行
如何访问可执行文件的机器代码(二进制文件)? 详情 我使用的是 Ubuntu (Linux) 我想访问 .exe 文件(文件遵循 PE 格式)的机器代码(二进制文件) 我正在使用 C 来实现 最佳答案
这个问题在这里已经有了答案: Run java jar file on a server as background process (4 个回答) 关闭1年前. 我正在使用命令提示符运行一个可执行
我的 jar 没有运行,我可以告诉它尝试运行,因为 log4j 文件设法创建日志文件夹,但没有任何 react 并且日志为空白。 我的问题是我在名为 bin 的文件夹中有 jar 文件,在名为 lib
我正在为我教育第一学期的编程考试创建一个程序。它应该向用户显示哥本哈根和其他 6 个城市(在其他时区)的时间。用户还应该能够将城市添加到列表中。我正在用 JAVA 编写程序(下面提供源代码)。当我从
我正在查看雅虎的 YUI 压缩器可执行 jar,他们有这个类,从 list 文件链接为“主类”: package com.yahoo.platform.yui.compressor; import j
问题是:从 Eclipse 导出时可执行 jar 中包含什么?我问这个问题是因为我想知道,例如,如果我在项目根目录中有一个图像,该图像是否会包含在导出中? 澄清:我说的是可运行的 jar 文件(已编辑
我知道这个问题已经被问了很多,并且我已经尝试了 eclipse(Kepler、Ganymede、Galileo)、fatJar、netbeans、blueJ、命令行和手册中的大约 20-30 种不同的
我从 IntelliJ 14.03 中的一个工件构建了一个 .jar。当我尝试在 JRE 中打开它时,没有任何反应。这只是一个简单的 GUI。 提前致谢。 最佳答案 在jar位置运行命令,例如 jav
我使用 eclipse 创建了一个可执行 JAR 文件。我在项目文件夹中有资源当框架打开时不会出现。我的意思是当我双击 JAR 文件时。更多的所以,在我尝试删除 JAR 文件后,我收到一条警告,表明该
我创建了一个尺寸相当大(125,000 kb)的可运行 Jar 文件。当我运行它时,该 jar 文件内的应用程序不会显示,但在任务管理器中 javaw.exe(应链接到该 jar 文件)进程正在运行。
我已经使用 Eclipse(文件->导出)为我的 java 程序创建了一个可执行 jar 文件。 当我双击 jar 时,它工作正常。将 jar 文件复制到另一台计算机(Windows)后,我收到错误“
我用 eclipse indigo 创建了一个可执行的 jar 文件,但是当我双击它时什么也没有发生。但是当我将 java -jar c:/dir/filename.jar 写入 cmd 时,它可以工
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
如何让该 Java 代码在 Eclipse 之外运行? import java.util.*; public class Calculations { public static void main(
今天我第一次启动 jar 文件时遇到问题。现在我知道(解压 jar 后)当我在 Eclipse 中导出并创建程序的 jar 包时,文本文件并没有出现。 为什么文本文件没有与类文件一起出现?我应该将它们
我不知道为什么,但是当我将项目导出到可执行 jar 文件时,有些东西并不像从 eclipse 运行程序一样。一帧不会打开,其中只包含文本。我有另一个内部框架,它是一个分割 Pane ,包含右侧面板上的
我是一名优秀的程序员,十分优秀!