博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python pyrex windows 编译C可执行文件
阅读量:6119 次
发布时间:2019-06-21

本文共 4130 字,大约阅读时间需要 13 分钟。

hot3.png

python写成py文件经过处理转化成pyx文件,以及函数说明文件pyi使用pyrexc.py编译成对应模块的c和h文件
然后写一个main的cpp文件,使用cmake产生vs工程,使用incredBuild编译工程。
以下是一个实例:
python原脚本,功能是更改目录下hcpp文件的修改时间,本地调试修改时间之后导致代码编译时间戳错乱,故写了一个py脚本
#!/bin/python#coding=gbkimport sys,os,time,redef walk_dir(dir):    timenow = time.time()    ncntnum = 0    for root, dirs, files in os.walk(dir, True):        for name in files:            filename = os.path.join(root,name)            mat = re.search('[.](h|cpp|c|hpp)',filename)            if mat:                filechgtime = os.path.getmtime(filename)                if filechgtime > timenow:                    os.utime(filename,(timenow,timenow))                    print '已修改:',filename                    ncntnum += 1                        print '修改数:',ncntnumif __name__ == '__main__':    if len(sys.argv) < 2:        print '添加参数:目录'    else:        walk_dir(sys.argv[1])

文件名为chgFileTM.py,直接拷贝为chgFileTM.pyx,将pyx文件修改如下:

#!/bin/python#coding=gbkimport os,time,redef walk_dir(dir):    timenow = time.time()    ncntnum = 0    for root, dirs, files in os.walk(dir, True):        for name in files:            filename = os.path.join(root,name)            mat = re.search('[.](h|cpp|c|hpp)',filename)            if mat:                filechgtime = os.path.getmtime(filename)                if filechgtime > timenow:                    os.utime(filename,(timenow,timenow))                    print '已修改:',filename                    ncntnum += 1                        print '修改数:',ncntnum    cdef public void c_walk_dir(char* pfir):    try:        walk_dir(pfir)    except Exception , e:        print e
添加一个pyrex格式的函数实现,调用+异常
chgFileTM.pyi文件,函数说明:
 

cdef extern void (c_walk_dir(char* pfir))

确认python安装了pyrex
执行pyrexc.py chgFileTM.pyx
生成了chgFileTM.h以及chgFileTM.c,如果提示错误的话一般是pyx文件空格和tab混用报错,直接用4个空格替换所有tab就行
可以参考下函数的调用,test.cpp
#include "chgFileTM.h"#include 
#include "Python.h"#include "structmember.h"int main(int argc, char *argv[]){ if(argc <= 1) { std::cout<<"参数:目录"<
ps:pyrex的默认处理有问题,编译获得的.h文件不包含#include "Python.h"的引入定义,可以手动修改.h文件也可以修改pyrex的源代码,都是python代码,修改位置如下:
python安装目录\Lib\site-packages\Pyrex\Compiler\ModuleNode.py
generate_extern_c_macro_definition函数下面添加
def generate_python_h_include(self, code):
        code.putln('#include "Python.h"')
generate_h_code函数,self.generate_extern_c_macro_definition(h_code)下面添加self.generate_python_h_include(h_code)
OK了,如果执行错误,那还是空格和tab的问题,替换下就行,再次执行
yrexc.py chgFileTM.pyx
目前:代码准备工作已经完成,剩下的就是自动编译的问题了
考虑下我们的编译平台,下载python源代码,发现windows下的编译是用的vs,我用的是vs2008,选择9.0版本
编译python版本,只要是主要的文件python pythonw工程,采用release版本吧,得到python的dll及lib等文件
把编译获得的dll及lib文件拷贝到python安装目录的libs及dlls等目录,将python的dlls目录添加到path路径
自动编译采用cmake 
incredBuild,要不然自己写cl的编译脚本,比较麻烦
好,编译环境的问题解决了,上我写的自动化脚本
#!D:/GNU/MSYS/bin/sh.exe#edit cmakeif [ $# != 1 ] ; then         echo "USAGE: cmake.sh proj" exit 1;fi makefilelist=CMakeLists.txtPROJECT_NAME=$1FILE_NAME=`ls *.[ch]*`rm -f $makefilelist#工程设置echo -e 'PROJECT(' $PROJECT_NAME ')' '\n' >> $makefilelist  #不用修改设置echo -e 'SET(VC9_DIR $ENV{VC9_DIR})' '\n'\  'SET(PYTHON_DIR $ENV{PYTHON_DIR})' '\n'\  'SET(CMAKE_C_COMPILER  "${VC9_DIR}/bin/cl.exe")' '\n'\  'SET(CMAKE_CXX_COMPILER  "${VC9_DIR}/bin/cl.exe")' '\n'\  'SET(LIBRARY_OUTPUT_PATH  "${PROJECT_BINARY_DIR}")' '\n'\  'include_directories ("${PYTHON_DIR}/include" )' '\n'\  'link_directories ("${PYTHON_DIR}/libs" "${PYTHON_DIR}/Lib" )' '\n' >> $makefilelist  #库和exe设置echo -e 'add_executable('$PROJECT_NAME $FILE_NAME') \n' >> $makefilelist  #执行脚本rm -fr buildmkdir buildcd buildecho 'start cmake'cmake -G  "Visual Studio 9 2008" ..echo 'start build'echo -e BuildConsole.exe $PROJECT_NAME /build /cfg=\"Release\|Win32\" '\n'\  rm -f ../$PROJECT_NAME.exe '\n'\  cp Release/$PROJECT_NAME.exe ../$PROJECT_NAME.exe '\n'\  pause '\n'\  exit > build.batstart build.batcd ..#删除脚本rm -f $makefilelist
使用的是MSYS的shell模拟器执行,如果没有可以考虑安装一下,使用的时候
sh cmake.sh 工程名,直接指定了完成的exe的文件名
一般能自动完成,如果不能,使用vs2008手动编译下看看
比如执行sh cmake.sh chgFileTM
在目录得到chgFileTM.exe
现在直接执行是没问题的,但是离开了拥有python的机器就不行了
拷贝python安装目录DLLS目录下的文件到没安装上的机器就行了
当然要是想简单的话写个打包工具也可以
以上仅仅是windows的做法,在linux,基本都有python,直接的执行效率也不错,觉得也没必要制作打包工具了。

转载于:https://my.oschina.net/u/659405/blog/80209

你可能感兴趣的文章
你是否需要GitHub?
查看>>
C语言程序编写涉及内存的问题
查看>>
一个小程序
查看>>
完美实现在同一个页面中使用不同样式的artDialog样式
查看>>
centos 7添加快捷键
查看>>
Codeforces 86D Powerful array (莫队)
查看>>
mysql 索引总结
查看>>
F5负载均衡虚拟服务器配置FTP端口访问不了
查看>>
时间复杂度和空间复杂度3 - 数据结构和算法05
查看>>
分享两款好玩的单机游戏^_^
查看>>
UsbManager, UsbDevice的简单示例
查看>>
面试题 14:调整数组顺序使奇数位于偶数前面
查看>>
asp.net core教程 (一)
查看>>
如何用docker部署redis cluster
查看>>
java核心技术面试整理
查看>>
MVC的学习步骤
查看>>
史上最全的Linux常用命令
查看>>
iOS - OC NSLocale 本地化信息
查看>>
在 Swift 中调用 OC 代码
查看>>
SQL DML 数据操纵语句
查看>>