5

我正在为我的系统编译几个不同版本的 Python,我想知道在源代码中定义启动横幅的位置,以便我可以为每个版本更改它。例如,当解释器启动时,它会显示

Python 3.3.1 (default, Apr 28 2013, 10:19:42) 
[GCC 4.7.2 20121109 (Red Hat 4.7.2-8)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

我想将字符串更改default为其他内容以表明我正在使用哪个版本,但我也对整个 shebang 的组装方式感兴趣。这是在哪里定义的?

4

2 回答 2

14

让我们grep用来进入球场。我不会费心搜索,default因为我会得到太多结果,但我会尝试Type "Help",它不应该出现太多次。如果是 C 字符串,引号将被转义。我们应该先查找 C 字符串,然后再查找 Python 字符串。

Python $ grep 'Type \\"help\\"' . -Ir
./Modules/main.c:    "Type \"help\", \"copyright\", \"credits\" or \"license\" " \

它在Modules/main.c,在Py_Main()。更多的挖掘给了我们这条线:

fprintf(stderr, "Python %s on %s\n",
    Py_GetVersion(), Py_GetPlatform());

因为“on”在格式字符串中,Py_GetPlatform()必须是linux而且Py_GetVersion()必须给出我们想要的字符串...

Python $ grep Py_GetVersion . -Irl
...
./Python/getversion.c
...

看起来很有希望...

PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s",
              PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler());

我们必须要Py_GetBuildInfo(),因为它在括号内...

Python $ grep Py_GetBuildInfo . -Irl
...
./Modules/getbuildinfo.c
...

这看起来有点太明显了。

const char *
Py_GetBuildInfo(void)
{
    static char buildinfo[50 + sizeof(HGVERSION) +
                          ((sizeof(HGTAG) > sizeof(HGBRANCH)) ?
                           sizeof(HGTAG) : sizeof(HGBRANCH))];
    const char *revision = _Py_hgversion();
    const char *sep = *revision ? ":" : "";
    const char *hgid = _Py_hgidentifier();
    if (!(*hgid))
        hgid = "default";
    PyOS_snprintf(buildinfo, sizeof(buildinfo),
                  "%s%s%s, %.20s, %.9s", hgid, sep, revision,
                  DATE, TIME);
    return buildinfo;
}

所以,default是 Mercurial 分支的名称。通过检查 makefile,我们可以确定这来自宏HGTAG。名为 makefile 的变量HGTAG会生成该变量,并且该变量作为命令运行。所以,

简单的解决方案

在构建 Python 时,

Python $ ./configure
Python $ make HGTAG='echo awesome'
Python $ ./python
Python 3.2.3 (awesome, May  1 2013, 21:33:27) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
于 2013-05-02T04:07:41.477 回答
0

看起来如果您在构建之前添加一个 mercurial 标签,那么default将被替换为您的标签名称(来源Modules/getbuildinfo.c:: _Py_hgidentifier()

基本上似乎它选择了名称default,因为那是分支的名称。看起来解释器是使用标签名称构建的,如果存在的话,或者如果tip当前工作副本上不存在标签(除了 ),则使用分支的名称。

于 2013-05-02T04:23:23.373 回答