Is there an easy way to write C code that can access its Git version hash?
是否有一种简单的方法来编写可以访问其Git版本散列的C代码?
I wrote software in C to collect scientific data in a laboratory setting. My code records the data it collects in a .yaml file for later analysis. My experiments change from day-to-day and I often have to modify the code. To keep track of revisions, I use a git repository.
我用C编写软件,在实验室里收集科学数据。我的代码记录了它在.yaml文件中收集的数据,用于以后的分析。我的实验每天都在改变,我经常需要修改代码。为了跟踪修订,我使用git存储库。
I would like to be able to include the Git revision hash as a comment in my .yaml data files. That way, I could look at the .yaml file and know exactly what code was used to generate the data shown in that file. Is there an easy way to do this automatically?
我希望能够将Git修订散列包含在.yaml数据文件中作为注释。这样,我就可以查看.yaml文件,并确切地知道用于生成该文件中显示的数据的代码。有没有一种简单的方法可以自动完成?
11 个解决方案
#1
36
In my program, I hold the git version number and the date of the build in a separate file, called version.c
, which looks like this:
在我的程序中,我保存了git版本号和在一个单独文件中构建的日期,称为版本。c,它是这样的
#include "version.h"
const char * build_date = "2009-11-10 11:09";
const char * build_git_sha = "6b54ea36e92d4907aba8b3fade7f2d58a921b6cd";
There is also a header file, which looks like this:
还有一个头文件,它看起来是这样的:
#ifndef VERSION_H
#define VERSION_H
extern const char * build_date; /* 2009-11-10 11:09 */
extern const char * build_git_sha; /* 6b54ea36e92d4907aba8b3fade7f2d58a921b6cd */
#endif /* VERSION_H */
Both the header file and the C file are generated by a Perl script which looks like this:
头文件和C文件都是由Perl脚本生成的,它看起来像这样:
my $git_sha = `git rev-parse HEAD`;
$git_sha =~ s/\s+//g;
# This contains all the build variables.
my %build;
$build{date} = make_date_time ();
$build{git_sha} = $git_sha;
hash_to_c_file ("version.c", \%build, "build_");
Here hash_to_c_file
does all the work of creating version.c
and version.h
and make_date_time
makes a string as shown.
这里hash_to_c_file完成了创建版本的所有工作。c和版本。h和make_date_time会显示一个字符串。
In the main program, I have a routine
在主程序中,我有一个例行程序。
#include "version.h"
// The name of this program.
const char * program_name = "magikruiser";
// The version of this program.
const char * version = "0.010";
/* Print an ID stamp for the program. */
static void _program_id_stamp (FILE * output)
{
fprintf (output, "%s / %s / %s / %s\n",
program_name, version,
build_date, build_git_sha);
}
I'm not that knowledgeable about git, so I'd welcome comments if there is a better way to do this.
我对git并不了解,所以如果有更好的方法,我欢迎评论。
#2
125
If you are using a make-based build, you can put this in the Makefile:
如果您使用基于标记的构建,可以将其放入Makefile:
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
(See man git describe for what the switches do)
(请参见man git描述开关所做的工作)
then add this to your CFLAGS:
然后将这个添加到您的CFLAGS:
-DVERSION=\"$(GIT_VERSION)\"
Then you can just reference the version directly in the program as though it was a #define:
然后您可以直接在程序中引用该版本,就像它是一个#define:
printf("Version: %s\n", VERSION);
By default this just prints an abbreviated git commit id, but optionally you can tag particular releases with something like:
默认情况下,这只是打印了一个简写的git提交id,但您也可以用类似的方式标记特定的版本:
git tag -a v1.1 -m "Release v1.1"
then it will print out:
然后打印出来:
Version: v1.1-2-g766d
which means, 2 commits past v1.1, with a git commit id beginning with "766d".
这意味着,2提交过去的v1.1,使用git提交id以“766d”开始。
If there are uncommitted changes in your tree, it will append "-dirty".
如果在您的树中有未提交的更改,它将附加“-dirty”。
There is no dependency scanning so you have to do an explicit make clean
to force the version to be updated. This can be solved however.
没有依赖扫描,所以您必须做一个显式的make clean以强制更新版本。但这是可以解决的。
The advantages are that it is simple and doesn't require any extra build dependencies like perl or awk. I have used this approach with GNU automake and with Android NDK builds.
优点是它很简单,不需要像perl或awk这样的额外构建依赖项。我在GNU automake和Android NDK构建中使用了这种方法。
#3
11
I ended up using something very similar to @Kinopiko's answer, but I used awk instead of perl. This is useful if your stuck on windows machines which have awk installed by nature of mingw, but not perl. Here's how it works.
最后,我使用了与@Kinopiko的答案非常相似的东西,但我使用的是awk,而不是perl。如果您在windows机器上安装了awk,而不是perl,这是很有用的。这是它是如何工作的。
My makefile has a line in it that invokes git, date, and awk to create a c file:
我的makefile在其中有一个行,它调用git、日期和awk来创建一个c文件:
$(MyLibs)/version.c: FORCE
$(GIT) rev-parse HEAD | awk ' BEGIN {print "#include \"version.h\""} {print "const char * build_git_sha = \"" $$0"\";"} END {}' > $(MyLibs)/version.c
date | awk 'BEGIN {} {print "const char * build_git_time = \""$$0"\";"} END {} ' >> $(MyLibs)/version.c
Everytime I compile my code, the awk command generates a version.c file that looks like this:
每次我编译代码时,awk命令都会生成一个版本。c文件是这样的:
/* version.c */
#include "version.h"
const char * build_git_sha = "ac5bffc90f0034df9e091a7b3aa12d150df26a0e";
const char * build_git_time = "Thu Dec 3 18:03:58 EST 2009";
I have a static version.h file that looks like this:
我有一个静态版本。h文件是这样的:
/*version.h*/
#ifndef VERSION_H_
#define VERSION_H_
extern const char * build_git_time;
extern const char * build_git_sha;
#endif /* VERSION_H_ */
The rest of my code can now access the build-time and the git hash by simply including the version.h header. To wrap it all up, I tell git to ignore version.c by adding a line to my .gitignore file. This way git isn't constantly giving me merge conflicts. Hope this helps!
我的其余代码现在可以通过简单地包括版本来访问构建时间和git哈希。h头。为了将其打包,我告诉git忽略版本。通过在我的.gitignore文件中添加一行。这样,git就不会不断地给我合并冲突。希望这可以帮助!
#4
9
Your program can shell out to git describe
, either at runtime or as part of the build process.
您的程序可以在运行时或作为构建过程的一部分向git描述。
#5
7
There are two things that you can do:
有两件事你可以做:
-
You can make Git to embed some version information in the file for you.
您可以让Git在文件中嵌入一些版本信息。
The simpler way is to use
ident
attribute, which means putting (for example)更简单的方法是使用ident属性,这意味着put(例如)
*.yaml ident
in
.gitattributes
file, and$Id$
in the appropriate place. It would be automatically expanded to SHA-1 identifier of the contents of the file (blob id): this is NOT file version, or the last commit.在.gitattributes文件中,$Id在适当的地方。它将被自动扩展到文件(blob id)内容的SHA-1标识符:这不是文件版本,也不是最后提交。
Git does support $Id$ keyword in this way to avoid touching files which were not changed during branch switching, rewinding branch etc. If you really want Git to put commit (version) identifier or description in the file, you can (ab)use
filter
attribute, using clean/ smudge filter to expand some keyword (e.g. $Revision$) on checkout, and clean it up for commit.Git支持Id关键字美元以这种方式来避免接触文件中没有改变分支切换、复卷分支等等。如果你真的想要Git将提交(版本)标识符或描述文件,(ab)可以使用过滤器属性,使用清洁/涂抹过滤器扩展一些关键字(例如修改美元)在结帐时,和清理提交。
-
You can make build process to do that for you, like Linux kernel or Git itself does.
您可以让构建过程为您做这些,就像Linux内核或Git本身一样。
Take a look at GIT-VERSION-GEN script and its use in Git Makefile, or for example how this Makefile embeds version information during generation / configuration of
gitweb/gitweb.cgi
file.看看Git - versiongen脚本及其在Git Makefile中的使用,或者举例说明这个Makefile如何在gitweb/gitweb的生成/配置中嵌入版本信息。cgi文件。
GIT-VERSION-GEN uses git describe to generate version description. It needs to work better that you tag (using signed / annotated tags) releases / milestones of your project.
git - versiongen使用git描述生成版本描述。它需要更好的工作,您标记(使用已签名/标注的标记)发布/里程碑的项目。
#6
4
When I need to do this, I use a tag, like RELEASE_1_23
. I can decide what the tag can be without knowing the SHA-1. I commit then tag. You can store that tag in your program anyway that you like.
当我需要这样做时,我使用一个标签,比如RELEASE_1_ 23。我可以在不知道SHA-1的情况下决定标签是什么。我提交标记。你可以把这个标签存储在你的程序中。
#7
3
Based on the answer by njd27, I'm using the a version with dependency scanning, in combination with a version.h file with default values for when the code is built in a different way. All files that include version.h will be rebuilt.
基于njd27的答案,我使用了一个带有依赖扫描的版本,并结合了一个版本。当代码以不同的方式构建时,h文件带有默认值。所有包含版本的文件。h将重建。
It also includes the revision date as a separate define.
它还包括修订日期作为一个单独的定义。
# Get git commit version and date
GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty)
GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ad" --name-only))
# recompile version.h dependants when GIT_VERSION changes, uses temporary file version~
.PHONY: force
version~: force
@echo '$(GIT_VERSION) $(GIT_DATE)' | cmp -s - $@ || echo '$(GIT_VERSION) $(GIT_DATE)' > $@
version.h: version~
@touch $@
@echo Git version $(GIT_VERSION) $(GIT_DATE)
#8
2
I also use git to track changes in my scientific code. i didn't want to use an external program because it limits portability of the code (if someone would want to make changes on MSVS for example).
我也使用git跟踪我的科学代码的变化。我不想使用外部程序,因为它限制了代码的可移植性(如果有人想对MSVS进行更改)。
my solution was to use only the main branch for the calculations and make it output the build time using preprocessor macros __DATE__
and __TIME__
. that way i can check it with git log and see which version i'm using. ref: http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
我的解决方案是只使用主分支进行计算,并使用预处理器宏__DATE__和__TIME__来输出构建时间。这样我就可以用git日志检查它,看看我使用的是哪个版本。裁判:http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
another elegant way to solve the problem is to include git log into the executable. make an object file out of git log and include it into the code. this time the only external program you use is objcopy but there is less coding. ref: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 and Embed data in a C++ program
解决这个问题的另一种优雅的方法是将git登录到可执行文件中。在git日志中创建一个对象文件,并将其包含到代码中。这一次,您使用的唯一外部程序是objcopy,但代码较少。参考:http://www.linuxjournal.com/content/嵌入-文件-可执行-aka-hello-world- 5967,并将数据嵌入到c++程序中。
#9
2
What you need to do is to generate a header file (eg using echo from cmd line) something like this:
您需要做的是生成一个头文件(如使用cmd线的echo):
#define GIT_HASH \
"098709a0b098c098d0e"
To generate it use something like this:
用这样的东西来生成它:
echo #define GIT_HASH \ > file.h
echo " > file.h
echo git status <whatever cmd to get the hash> > file.h
echo " > file.h
Might need to play with the quotes and backslashes a bit to get it to compile, but you get the idea.
可能需要使用引号和反斜杠来编译,但是您可以理解。
#10
1
Yet another variation based on Makefile and shell
另一个基于Makefile和shell的变体。
GIT_COMMIT_FILE=git_commit_filename.h
$(GIT_COMMIT_FILE): phony
$(eval GIT_COMMIT_SHA=$(shell git describe --abbrev=6 --always 2>/dev/null || echo 'Error'))
@echo SHA=$(GIT_COMMIT_SHA)
echo -n "static const char *GIT_COMMIT_SHA = \"$(GIT_COMMIT_SHA)\";" > $(GIT_COMMIT_FILE)
File git_commit_filename.h will end up with a single line containing static const char *GIT_COMMIT_SHA="";
文件git_commit_filename。h将以一个包含静态const char *GIT_COMMIT_SHA="的单行结束;
From https://gist.github.com/larytet/898ec8814dd6b3ceee65532a9916d406
从https://gist.github.com/larytet/898ec8814dd6b3ceee65532a9916d406
#11
0
You can see how I did it for memcached in the original commit.
您可以看到我是如何在原始提交中对memcached进行的。
Basically, tag occasionally, and make sure the thing you deliver comes from make dist
or similar.
基本上,标签偶尔,并确保你交付的东西来自于制造或类似。
#1
36
In my program, I hold the git version number and the date of the build in a separate file, called version.c
, which looks like this:
在我的程序中,我保存了git版本号和在一个单独文件中构建的日期,称为版本。c,它是这样的
#include "version.h"
const char * build_date = "2009-11-10 11:09";
const char * build_git_sha = "6b54ea36e92d4907aba8b3fade7f2d58a921b6cd";
There is also a header file, which looks like this:
还有一个头文件,它看起来是这样的:
#ifndef VERSION_H
#define VERSION_H
extern const char * build_date; /* 2009-11-10 11:09 */
extern const char * build_git_sha; /* 6b54ea36e92d4907aba8b3fade7f2d58a921b6cd */
#endif /* VERSION_H */
Both the header file and the C file are generated by a Perl script which looks like this:
头文件和C文件都是由Perl脚本生成的,它看起来像这样:
my $git_sha = `git rev-parse HEAD`;
$git_sha =~ s/\s+//g;
# This contains all the build variables.
my %build;
$build{date} = make_date_time ();
$build{git_sha} = $git_sha;
hash_to_c_file ("version.c", \%build, "build_");
Here hash_to_c_file
does all the work of creating version.c
and version.h
and make_date_time
makes a string as shown.
这里hash_to_c_file完成了创建版本的所有工作。c和版本。h和make_date_time会显示一个字符串。
In the main program, I have a routine
在主程序中,我有一个例行程序。
#include "version.h"
// The name of this program.
const char * program_name = "magikruiser";
// The version of this program.
const char * version = "0.010";
/* Print an ID stamp for the program. */
static void _program_id_stamp (FILE * output)
{
fprintf (output, "%s / %s / %s / %s\n",
program_name, version,
build_date, build_git_sha);
}
I'm not that knowledgeable about git, so I'd welcome comments if there is a better way to do this.
我对git并不了解,所以如果有更好的方法,我欢迎评论。
#2
125
If you are using a make-based build, you can put this in the Makefile:
如果您使用基于标记的构建,可以将其放入Makefile:
GIT_VERSION := $(shell git describe --abbrev=4 --dirty --always --tags)
(See man git describe for what the switches do)
(请参见man git描述开关所做的工作)
then add this to your CFLAGS:
然后将这个添加到您的CFLAGS:
-DVERSION=\"$(GIT_VERSION)\"
Then you can just reference the version directly in the program as though it was a #define:
然后您可以直接在程序中引用该版本,就像它是一个#define:
printf("Version: %s\n", VERSION);
By default this just prints an abbreviated git commit id, but optionally you can tag particular releases with something like:
默认情况下,这只是打印了一个简写的git提交id,但您也可以用类似的方式标记特定的版本:
git tag -a v1.1 -m "Release v1.1"
then it will print out:
然后打印出来:
Version: v1.1-2-g766d
which means, 2 commits past v1.1, with a git commit id beginning with "766d".
这意味着,2提交过去的v1.1,使用git提交id以“766d”开始。
If there are uncommitted changes in your tree, it will append "-dirty".
如果在您的树中有未提交的更改,它将附加“-dirty”。
There is no dependency scanning so you have to do an explicit make clean
to force the version to be updated. This can be solved however.
没有依赖扫描,所以您必须做一个显式的make clean以强制更新版本。但这是可以解决的。
The advantages are that it is simple and doesn't require any extra build dependencies like perl or awk. I have used this approach with GNU automake and with Android NDK builds.
优点是它很简单,不需要像perl或awk这样的额外构建依赖项。我在GNU automake和Android NDK构建中使用了这种方法。
#3
11
I ended up using something very similar to @Kinopiko's answer, but I used awk instead of perl. This is useful if your stuck on windows machines which have awk installed by nature of mingw, but not perl. Here's how it works.
最后,我使用了与@Kinopiko的答案非常相似的东西,但我使用的是awk,而不是perl。如果您在windows机器上安装了awk,而不是perl,这是很有用的。这是它是如何工作的。
My makefile has a line in it that invokes git, date, and awk to create a c file:
我的makefile在其中有一个行,它调用git、日期和awk来创建一个c文件:
$(MyLibs)/version.c: FORCE
$(GIT) rev-parse HEAD | awk ' BEGIN {print "#include \"version.h\""} {print "const char * build_git_sha = \"" $$0"\";"} END {}' > $(MyLibs)/version.c
date | awk 'BEGIN {} {print "const char * build_git_time = \""$$0"\";"} END {} ' >> $(MyLibs)/version.c
Everytime I compile my code, the awk command generates a version.c file that looks like this:
每次我编译代码时,awk命令都会生成一个版本。c文件是这样的:
/* version.c */
#include "version.h"
const char * build_git_sha = "ac5bffc90f0034df9e091a7b3aa12d150df26a0e";
const char * build_git_time = "Thu Dec 3 18:03:58 EST 2009";
I have a static version.h file that looks like this:
我有一个静态版本。h文件是这样的:
/*version.h*/
#ifndef VERSION_H_
#define VERSION_H_
extern const char * build_git_time;
extern const char * build_git_sha;
#endif /* VERSION_H_ */
The rest of my code can now access the build-time and the git hash by simply including the version.h header. To wrap it all up, I tell git to ignore version.c by adding a line to my .gitignore file. This way git isn't constantly giving me merge conflicts. Hope this helps!
我的其余代码现在可以通过简单地包括版本来访问构建时间和git哈希。h头。为了将其打包,我告诉git忽略版本。通过在我的.gitignore文件中添加一行。这样,git就不会不断地给我合并冲突。希望这可以帮助!
#4
9
Your program can shell out to git describe
, either at runtime or as part of the build process.
您的程序可以在运行时或作为构建过程的一部分向git描述。
#5
7
There are two things that you can do:
有两件事你可以做:
-
You can make Git to embed some version information in the file for you.
您可以让Git在文件中嵌入一些版本信息。
The simpler way is to use
ident
attribute, which means putting (for example)更简单的方法是使用ident属性,这意味着put(例如)
*.yaml ident
in
.gitattributes
file, and$Id$
in the appropriate place. It would be automatically expanded to SHA-1 identifier of the contents of the file (blob id): this is NOT file version, or the last commit.在.gitattributes文件中,$Id在适当的地方。它将被自动扩展到文件(blob id)内容的SHA-1标识符:这不是文件版本,也不是最后提交。
Git does support $Id$ keyword in this way to avoid touching files which were not changed during branch switching, rewinding branch etc. If you really want Git to put commit (version) identifier or description in the file, you can (ab)use
filter
attribute, using clean/ smudge filter to expand some keyword (e.g. $Revision$) on checkout, and clean it up for commit.Git支持Id关键字美元以这种方式来避免接触文件中没有改变分支切换、复卷分支等等。如果你真的想要Git将提交(版本)标识符或描述文件,(ab)可以使用过滤器属性,使用清洁/涂抹过滤器扩展一些关键字(例如修改美元)在结帐时,和清理提交。
-
You can make build process to do that for you, like Linux kernel or Git itself does.
您可以让构建过程为您做这些,就像Linux内核或Git本身一样。
Take a look at GIT-VERSION-GEN script and its use in Git Makefile, or for example how this Makefile embeds version information during generation / configuration of
gitweb/gitweb.cgi
file.看看Git - versiongen脚本及其在Git Makefile中的使用,或者举例说明这个Makefile如何在gitweb/gitweb的生成/配置中嵌入版本信息。cgi文件。
GIT-VERSION-GEN uses git describe to generate version description. It needs to work better that you tag (using signed / annotated tags) releases / milestones of your project.
git - versiongen使用git描述生成版本描述。它需要更好的工作,您标记(使用已签名/标注的标记)发布/里程碑的项目。
#6
4
When I need to do this, I use a tag, like RELEASE_1_23
. I can decide what the tag can be without knowing the SHA-1. I commit then tag. You can store that tag in your program anyway that you like.
当我需要这样做时,我使用一个标签,比如RELEASE_1_ 23。我可以在不知道SHA-1的情况下决定标签是什么。我提交标记。你可以把这个标签存储在你的程序中。
#7
3
Based on the answer by njd27, I'm using the a version with dependency scanning, in combination with a version.h file with default values for when the code is built in a different way. All files that include version.h will be rebuilt.
基于njd27的答案,我使用了一个带有依赖扫描的版本,并结合了一个版本。当代码以不同的方式构建时,h文件带有默认值。所有包含版本的文件。h将重建。
It also includes the revision date as a separate define.
它还包括修订日期作为一个单独的定义。
# Get git commit version and date
GIT_VERSION := $(shell git --no-pager describe --tags --always --dirty)
GIT_DATE := $(firstword $(shell git --no-pager show --date=short --format="%ad" --name-only))
# recompile version.h dependants when GIT_VERSION changes, uses temporary file version~
.PHONY: force
version~: force
@echo '$(GIT_VERSION) $(GIT_DATE)' | cmp -s - $@ || echo '$(GIT_VERSION) $(GIT_DATE)' > $@
version.h: version~
@touch $@
@echo Git version $(GIT_VERSION) $(GIT_DATE)
#8
2
I also use git to track changes in my scientific code. i didn't want to use an external program because it limits portability of the code (if someone would want to make changes on MSVS for example).
我也使用git跟踪我的科学代码的变化。我不想使用外部程序,因为它限制了代码的可移植性(如果有人想对MSVS进行更改)。
my solution was to use only the main branch for the calculations and make it output the build time using preprocessor macros __DATE__
and __TIME__
. that way i can check it with git log and see which version i'm using. ref: http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
我的解决方案是只使用主分支进行计算,并使用预处理器宏__DATE__和__TIME__来输出构建时间。这样我就可以用git日志检查它,看看我使用的是哪个版本。裁判:http://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html
another elegant way to solve the problem is to include git log into the executable. make an object file out of git log and include it into the code. this time the only external program you use is objcopy but there is less coding. ref: http://www.linuxjournal.com/content/embedding-file-executable-aka-hello-world-version-5967 and Embed data in a C++ program
解决这个问题的另一种优雅的方法是将git登录到可执行文件中。在git日志中创建一个对象文件,并将其包含到代码中。这一次,您使用的唯一外部程序是objcopy,但代码较少。参考:http://www.linuxjournal.com/content/嵌入-文件-可执行-aka-hello-world- 5967,并将数据嵌入到c++程序中。
#9
2
What you need to do is to generate a header file (eg using echo from cmd line) something like this:
您需要做的是生成一个头文件(如使用cmd线的echo):
#define GIT_HASH \
"098709a0b098c098d0e"
To generate it use something like this:
用这样的东西来生成它:
echo #define GIT_HASH \ > file.h
echo " > file.h
echo git status <whatever cmd to get the hash> > file.h
echo " > file.h
Might need to play with the quotes and backslashes a bit to get it to compile, but you get the idea.
可能需要使用引号和反斜杠来编译,但是您可以理解。
#10
1
Yet another variation based on Makefile and shell
另一个基于Makefile和shell的变体。
GIT_COMMIT_FILE=git_commit_filename.h
$(GIT_COMMIT_FILE): phony
$(eval GIT_COMMIT_SHA=$(shell git describe --abbrev=6 --always 2>/dev/null || echo 'Error'))
@echo SHA=$(GIT_COMMIT_SHA)
echo -n "static const char *GIT_COMMIT_SHA = \"$(GIT_COMMIT_SHA)\";" > $(GIT_COMMIT_FILE)
File git_commit_filename.h will end up with a single line containing static const char *GIT_COMMIT_SHA="";
文件git_commit_filename。h将以一个包含静态const char *GIT_COMMIT_SHA="的单行结束;
From https://gist.github.com/larytet/898ec8814dd6b3ceee65532a9916d406
从https://gist.github.com/larytet/898ec8814dd6b3ceee65532a9916d406
#11
0
You can see how I did it for memcached in the original commit.
您可以看到我是如何在原始提交中对memcached进行的。
Basically, tag occasionally, and make sure the thing you deliver comes from make dist
or similar.
基本上,标签偶尔,并确保你交付的东西来自于制造或类似。