Python 设置工具验证文件是否已修改

Python 设置工具验证文件是否已修改,python,caching,setuptools,Python,Caching,Setuptools,我想添加一个具有扩展功能的build命令。具体来说,它编译一个Go共享库。这是一个漫长的过程,而且Go源代码很少被修改。因此 问题 有没有办法让setuptools记住文件运行时的最后修改日期,或者我需要更严格的构建工具(如SCons)。我不在乎它是否通过时间戳或任何其他简单的策略来识别最近性 以下是有关守则: class BuildGo(build_py): ''' Build Go bindings before building Python extension

我想添加一个具有扩展功能的
build
命令。具体来说,它编译一个Go共享库。这是一个漫长的过程,而且Go源代码很少被修改。因此

问题 有没有办法让
setuptools
记住文件运行时的最后修改日期,或者我需要更严格的构建工具(如SCons)。我不在乎它是否通过时间戳或任何其他简单的策略来识别最近性


以下是有关守则:

class BuildGo(build_py):
    '''
    Build Go bindings before building Python extension
    '''

    def run(self):
        # What should go into go_sources_modified?
        if self.go_sources_modified():
            self.compile_go()
        build_py.run(self)

    def compile_go(self):
        version = None
        refusal = 'Will not compile Go bindings'
        try:
            version = subprocess.check_output(['go', 'version'])
        except subprocess.CalledProcessError:
            print('Didn\'t find Go compiler.')
            print(refusal)
            return
        match = re.search(br'go(\d+)\.(\d+)\.(\d+)', version)
        if match:
            version = tuple(map(int, match.group(1, 2, 3)))
        else:
            print('Unrecognized version of Go compiler: {}'.format(version))
            print(refusal)
            return
        req_version = 1, 9, 1
        if version < req_version:
            print('You need Go compiler version higher than: {}'.format(
                req_version,
            ))
            print(refusal)
            return
        try:
            result = subprocess.check_output([
                'go',
                'build',
                '-v',
                '-buildmode=c-shared',
                '-o',
                SHLIB_LOCATION,
                SHLIB_PACKAGE,
            ])
            print(result)
        except subprocess.CalledProcessError as e:
            print(e.stderr)
            raise
class BuildGo(build\u py):
'''
在构建Python扩展之前构建Go绑定
'''
def运行(自):
#什么应该进入go\u sources\u modified?
如果self.go\u sources\u modified():
self.compile_go()
构建副本运行(自我)
def编译_go(自我):
版本=无
拒绝='将不编译Go绑定'
尝试:
版本=子流程。检查输出(['go','version'])
除了subprocess.CalledProcessError之外:
打印('未找到Go编译器')
打印(拒绝)
返回
匹配=重新搜索(br'go(\d+)\(\d+)\(\d+),版本)
如果匹配:
version=tuple(映射(int,match.group(1,2,3)))
其他:
打印('无法识别的Go编译器版本:{}'。格式(版本))
打印(拒绝)
返回
需求版本=1,9,1
如果版本
您可以使用
distutils.dep_util
模块中的函数来检查自上次构建库以来是否修改了任何go源:

from distutils.dep_util import newer_group

class BuildGo(build_py):
    ...

    def go_sources_modified(self):
        gosrc = pathlib.Path('go/src/lib')
        go_sources = list(str(f.resolve()) for f in gosrc.rglob('*.go'))
        golib = 'go/pkg/mylib.a'
        return newer_group(go_sources, golib)

不,不可能。你必须自己去实施一些事情。@phd好吧,消极的结果就是结果。你可以将此作为答案发布,我会接受。谢谢,这确实有效,并且涵盖了我的所有需求。这只是对其他人的一个警告:这不是一个100%正确的解决方案,因为Go源不一定包含在
*.Go
(例如,您可以有
*.s
汇编源)模式中,而不是所有的
*.Go
文件都构成包源。(例如,您可以进行测试
*\u test.go
)。更准确的版本应该是这样的:
go list-f'{.CgoFiles}'$package
+对于
GoFiles
,加上对于所有导入的包都是一样的。@wvxvw是的,不幸的是,我不是go方面的专家。如果您知道如何从python代码调用此函数并处理文件列表,请随时改进我的答案!