我如何将git版本信息添加到cython-built .so文件中? [英] How can I add git version info into cython-built .so file?

查看:293
本文介绍了我如何将git版本信息添加到cython-built .so文件中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将我的git commit信息(分支信息和sha1信息)加入我的 cython 编译出来的 .so 文件。例如,我有一个 .pyx 文件,我将它编译为 .so 模块。但问题来了,当我需要调试时,我无法找到它到底是哪个提交。我需要做些什么来支持一些像 ./ demo.so --gitinfo 这样的操作来获取像这样的内容 Branch:master,Commit:* ******



我使用cmake搜索某个网页,讨论使用git commit info的c / c ++可执行文件。

以下是一些相关的网页:

Stackoverflow链接

关于git信息的Github repo



非常感谢!

解决方案

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



由于您特别提到了Git,下面是几点:


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


  • git describe 的输出更有趣,因为它不太可能改变,附近带注释的标签本身并不是应该改变的,尽管这要求制作标签的用户表现出自己的行为 - 并且为您提供了一种方便的线性计数方式:距标签距离以及通常精确指定特定标签的后缀即使没有其他信息,也要提交:

      v2.12.0-190-ge0688e9 

    例如,对于ID以 e0688e9 开头的提交,其大部分可读名称以及其中附近的标签是 v2.12.0 (从某种意义上说,后面的190次提交)。

  • 原始提交ID本身完全唯一地标识提交。 可以使用 ident 属性作为过滤器 - 请参阅 gitattributes文档 - 将原始提交ID嵌入到源文件中。除非构建系统太原始,无法运行 git describe




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

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

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



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



直接在Cython中执行此操作,没有辅助文件



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

 提交c1a008c1555be451047ff9869abe30c753cfc15d 
作者:Chris Torek< chris.torek@gmail.com>
日期:Wed Mar 15 02:03:41 2017 -0700

在编译时建立Git版本

diff --git a / hello.pyx b /hello.pyx
索引da1b827..e3efef9 100644
--- a / hello.pyx
+++ b / hello.pyx
@@ -1,2 +1 ,7 @@ $ b $ 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从Cython导入setup
。从Cython.Distutils.extension导入扩展
+从Cython.Distutils导入build_ext
+
+导入子流程
+导入sys
导入cythonize
+ +
+ proc = subprocess.Popen(['git','describe','--dirty'],stdout = subprocess.PIPE)
+ GIT_VERSION = proc.stdout.read()。rstrip ().encode('utf-8')
+如果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


I want to add my git commit info (branch info and sha1 info) into my cython compiled out .so file.

For example, I have a .pyx file, and I compile it to a .so module. but question comes, when I need to debug it, I can not find which commit exactly it comes. What do I need to do to support some action like ./demo.so --gitinfo to get something like this Branch: master, Commit: ******* ?

I have search some webpage talking about c/c++ executable file with git commit info by using cmake.

Here are some webpage related:
Stackoverflow link
Github repo about git info

Many Thanks!

解决方案

The method by which you can embed a revision indicator into objects made from compiled source depends to great extent on the tools you use to compile the source, and of course on what source-code control system(s) you use to contain the source. The former determines what you can do and how you can run commands. The latter determines what information is important, which commands extract that information, and—to some extent—how to embed that information into a source file, if that can be done directly.

Since you asked specifically about Git, here are a few points:

  • The branch name is essentially irrelevant. Git branch names mean almost nothing: a commit that is name-able via bleek today, might be named via pribble tomorrow.

  • The output from git describe is more interesting, because it is unlikely to change, includes a nearby annotated tag—tags themselves are never supposed to change, though this requires that users making tags behave themselves—and gives you a convenient linear count of "distance from tag" plus a suffix that usually pinpoints a specific commit even without the rest of the information:

    v2.12.0-190-ge0688e9
    

    for instance is a mostly-readable name for a commit whose ID starts with e0688e9, and whose "nearby tag" is v2.12.0 (190 commits later, in some sense).

  • The raw commit ID itself, in full, uniquely identifies the commit.

  • It's possible to use the ident attribute as a filter—see the gitattributes documentation—to embed the raw commit ID in a source file. I would avoid this method myself unless the build system is too primitive to be able to run git describe.

[Edit: fixed this up a bit - you don't want to "import" the version file as a Python file, as that's done at runtime!]

You could, depending on your build system, have your builder do, e.g.:

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

and then build the file. The file itself should not be committed into the repository at all, but rather, built every time (it's always in need of re-generation).

This same method works for most compiled languages, though of course the form of the variable to define, and the syntax for strings and source files, varies from one to another.

Doing this directly in Cython, without an auxiliary file

For Cython in particular, if you use a setup.py, you can extract the Git version in Python code and pass it through as a -D argument during compilation. Here is an actual working example that modifies a basic setup.py to do this, formatted as a Git commit. The hello.pyx and setup.py files are nearly straight out of the 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
 )

这篇关于我如何将git版本信息添加到cython-built .so文件中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆