【问题标题】:How can I add git version info into cython-built .so file?如何将 git 版本信息添加到 cython 构建的 .so 文件中?
【发布时间】:2017-03-15 02:42:15
【问题描述】:

我想将我的 git 提交信息(分支信息和 sha1 信息)添加到我的 cython 编译出的 .so 文件中。

例如,我有一个.pyx 文件,我将它编译为.so 模块。但是问题来了,当我需要调试它时,我找不到它到底是哪个提交。我需要做些什么来支持./demo.so --gitinfo 之类的操作才能获得类似Branch: master, Commit: ******* 的东西?

我已经使用 cmake 搜索了一些关于带有 git commit 信息的 c/c++ 可执行文件的网页。

这里有一些网页相关:
Stackoverflow link
Github repo about git info

非常感谢!

【问题讨论】:

  • 您实际上无法执行 demo.so 比拟您的提案 - 它是一个共享库

标签: python c++ git compilation cython


【解决方案1】:

您可以将修订指示器嵌入到由已编译源代码生成的对象中的方法在很大程度上取决于您用于编译源代码的工具,当然也取决于您用于包含哪些源代码控制系统来源。前者决定了您可以做什么以及如何运行命令。后者决定了哪些信息是重要的,哪些命令提取了该信息,以及——在某种程度上——如何将这些信息嵌入到源文件中,如果可以直接完成的话。

由于您专门询问了 Git,这里有几点:

  • 分支名称本质上是不相关的。 Git 分支名称几乎没有任何意义:今天可以通过bleek 命名的提交,明天可能通过pribble 命名。

  • git describe 的输出更有趣,因为它不太可能改变,包括附近的带注释标签——标签本身从不应该改变,尽管这要求制作标签的用户表现自己——并为您提供方便的“与标签的距离”的线性计数,加上一个后缀,即使没有其余信息,通常也能精确定位特定的提交:

    v2.12.0-190-ge0688e9
    

    例如,对于 ID 以 e0688e9 开头且“附近标签”为 v2.12.0 (在某种意义上是 190 次提交)的提交来说,这是一个可读性最强的名称。

  • 完整的原始提交 ID 本身唯一标识提交。

  • 可以使用ident 属性作为过滤器——参见the gitattributes documentation——将原始提交ID 嵌入到源文件中。我自己会避免这种方法,除非构建系统太原始而无法运行git describe

[编辑:稍微修复一下 - 你不想将版本文件“导入”为 Python 文件,因为这是在运行时完成的!]

根据您的构建系统,您可以让您的构建器执行,例如:

echo 'DESCRIBE = "' $(git describe --dirty) '"' > gitignored.pyx

然后构建文件。文件本身根本不应该提交到存储库中,而是每次都构建(它总是需要重新生成)。

同样的方法适用于大多数编译语言,当然要定义的变量的形式以及字符串和源文件的语法各不相同。

直接在 Cython 中执行此操作,无需辅助文件

特别是对于 Cython,如果您使用 setup.py,则可以在 Python 代码中提取 Git 版本,并在编译期间将其作为 -D 参数传递。这是一个实际的工作示例,它修改了基本的setup.py 来执行此操作,格式为 Git 提交。 hello.pyxsetup.py 文件几乎直接来自 initial Cython compilation example

commit c1a008c1555be451047ff9869abe30c753cfc15d
Author: Chris Torek <chris.torek@gmail.com>
Date:   Wed Mar 15 02:03:41 2017 -0700

    build in Git version at compile time

diff --git a/hello.pyx b/hello.pyx
index da1b827..e3efef9 100644
--- a/hello.pyx
+++ b/hello.pyx
@@ -1,2 +1,7 @@
 def say_hello_to(name):
     print("Hello %s!" % name)
+
+cdef extern from *:
+    char *BUILD_VERSION
+
+version = BUILD_VERSION
diff --git a/setup.py b/setup.py
index 6e6bc70..7c6d07c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,23 @@
 from distutils.core import setup
 from Cython.Build import cythonize
+from Cython.Distutils.extension import Extension
+from Cython.Distutils import build_ext
+
+import subprocess
+import sys
+
+proc = subprocess.Popen(['git', 'describe', '--dirty'], stdout=subprocess.PIPE)
+GIT_VERSION = proc.stdout.read().rstrip().encode('utf-8')
+if proc.wait():
+    sys.exit('git describe --dirty failed: exit code {}'.format(proc.wait()))
+
+extensions = [
+    Extension('hello', ['hello.pyx'],
+        extra_compile_args=['-D', 'BUILD_VERSION="{}"'.format(GIT_VERSION)]),
+]

 setup(
     name='Hello world app',
-    ext_modules=cythonize("hello.pyx"),
+    cmdclass={'build_ext': build_ext},
+    ext_modules=extensions
 )

【讨论】:

  • 哇!谢谢,我会试着理解它并使用cmake来构建.pyx
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 2016-01-17
  • 2015-04-24
  • 2022-12-06
  • 1970-01-01
  • 2014-12-09
相关资源
最近更新 更多