我如何将git版本信息添加到cython-built .so文件中? [英] How can I add git version info into cython-built .so file?
问题描述
我想将我的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分支名称几乎没有任何意义:今天通过 从 例如,对于ID以
bleek
命名的提交可能会通过 pribble
明天命名。
git describe
的输出更有趣,因为它不太可能改变,附近带注释的标签本身并不是应该改变的,尽管这要求制作标签的用户表现出自己的行为 - 并且为您提供了一种方便的线性计数方式:距标签距离以及通常精确指定特定标签的后缀即使没有其他信息,也要提交:
v2.12.0-190-ge0688e9
e0688e9
开头的提交,其大部分可读名称以及其中附近的标签是 v2.12.0
(从某种意义上说,后面的190次提交)。 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 viapribble
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" isv2.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 rungit 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屋!