<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/faq.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'zh',
  ),
  'this' => 
  array (
    0 => 'faq.build.php',
    1 => '编译问题',
    2 => '编译问题',
  ),
  'up' => 
  array (
    0 => 'faq.php',
    1 => 'FAQ',
  ),
  'prev' => 
  array (
    0 => 'faq.installation.php',
    1 => '安装',
  ),
  'next' => 
  array (
    0 => 'faq.using.php',
    1 => '使用 PHP',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'zh',
    'path' => 'faq/build.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="faq.build" class="chapter">
 <h1 class="title">编译问题</h1>

 
 <p class="para">本节汇集了大多数编译时出现的常见错误。</p>
 <div class="qandaset"><ol class="qandaset_questions"><li><a href="#faq.build.configure">
    我用匿名 GIT 服务得到了最新版的 PHP，但是里面没有 configure 脚本！
   </a></li><li><a href="#faq.build.configuring">
    我在配置 PHP 和 Apache 一起工作时遇到了问题。说没找到 
     httpd.h，但这个文件明明就在那里！
   </a></li><li><a href="#faq.build.lex">
    当运行 PHP 配置时（
     ./configure），遇到类似如下的问题：
    
     checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up
    
   </a></li><li><a href="#faq.build.apache-sharedcore">
    当试图启动 Apache 时，得到类似如下错误信息：
    
     fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found
    
   </a></li><li><a href="#faq.build.not-found">
    当运行 configure 时，报告说找不到头文件或 GD 库或 gdbm，或其它的什么包！
   </a></li><li><a href="#faq.build.yytname">
     当编译 
      language-parser.tab.c文件时，报错说 
      yytname undeclared。
    </a></li><li><a href="#faq.build.link">
     当我运行 
      make时，看上去一切正常，可当连接最后的程序时报告说找不到某些文件而失败了。
    </a></li><li><a href="#faq.build.undefined">
     当连接 PHP 时，报告说有一些未定义的引用。
    </a></li><li><a href="#faq.build.not-running">
     我按照所有的步骤在 UNIX 下安装了PHP 的 Apache 模块版本，但我的 PHP 脚本被显示在浏览器中或者提示保存此文件。
    </a></li><li><a href="#faq.build.activate-module">
     说要用：
      --activate-module=src/modules/php4/libphp4.a，但是此文件根本不存在，于是我改成了 
      --activate-module=src/modules/php4/libmodphp4.a，结果不行。怎么回事？
    </a></li><li><a href="#faq.build.ansi">
     当我用 
      --activate-module=src/modules/php4/libphp4.a试着把 PHP 编译成 Apache 的静态模块时，报告说我的编译器不服从 ANSI 标准。
    </a></li><li><a href="#faq.build.apxs">
     当我用 
      --with-apxs编译 PHP 时得到奇怪的错误信息。
    </a></li><li><a href="#faq.build.microtime">
     在 
      make的过程中，在 microtime 中出错，还有很多 
      RUSAGE_之类的东西。
    </a></li><li><a href="#faq.build.mysql.tempnam">
     
      当带 MySQL 编译 PHP 时，可以正确地运行 configure，但是在
      make 的过程中出现了类似以下的错误信息： 
      ext/mysql/libmysqlclient/my_tempnam.o(.text+0x46): In function 
      my_tempnam&#039;: /php4/ext/mysql/libmysqlclient/my_tempnam.c:103: the 
      use of tempnam&#039; is dangerous, better use mkstemp&#039;，这是怎么回事？
     
    </a></li><li><a href="#faq.build.upgrade">
     我想升级我的 PHP。上哪里找到我用来配置目前的 PHP 的 
      ./configure的参数呢？
    </a></li><li><a href="#faq.build.gdlibs">
     和 GD 库一起编译 PHP 时，要么给出一个奇怪的编译错误，要么在运行时出现 segfaults。
    </a></li><li><a href="#faq.installation.needgnu">
     当编译 PHP 时我看到一些随机的错误，好像死了。我用的是 Solaris，不知道有没有关系。
    </a></li></ol></div>
  <dl class="qandaentry" id="faq.build.configure">
   <dt><strong>
    我用匿名 GIT 服务得到了最新版的 PHP，但是里面没有 configure 脚本！
   </strong></dt>
   <dd class="answer">
    <p class="para">你必须安装有 GNU autoconf 包，这样才可以从 
     <var class="filename">configure.in</var>生成 configure 脚本。从 GIT 服务中得到源程序后只要在最高层的目录中运行 
     <strong class="command">./buildconf</strong>即可。（同时要注意，除非你用了 
     <code class="literal">--enable-maintainer-mode</code>选项来运行 <strong class="command">configure</strong>，否则即使 
     <var class="filename">configure.in</var>文件更新了，configure 脚本也不会自动重新生成。所以当你发现 
     <var class="filename">configure.in</var>文件更新了时要确保手工重新生成 configure 脚本。有一个症状是在 configure 之后或者运行 
     <var class="filename">config.status</var>时在 Makefile 中寻找类似 @VARIABLE@ 的东西。）</p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.build.configuring">
   <dt><strong>
    我在配置 PHP 和 Apache 一起工作时遇到了问题。说没找到 
     <var class="filename">httpd.h</var>，但这个文件明明就在那里！
   </strong></dt>
   <dd class="answer">
    <p class="para">你需要告诉 configure/setup 脚本你的 Apache 源程序最上层的目录位置。这意味着你需要这样指定 
     <strong class="option configure">--with-apache=/path/to/apache</strong>而
     <em>不是</em>这样 
     <strong class="option configure">--with-apache=/path/to/apache/src</strong>。</p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.build.lex">
   <dt><strong>
    当运行 PHP 配置时（
     <code class="literal">./configure</code>），遇到类似如下的问题：
    
     <div class="example-contents screen">checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up</div>
    
   </strong></dt>
   <dd class="answer">
    <p class="para">请认真阅读 PHP 的
     <a href="install.unix.php" class="link">安装</a>说明，并注意要编译 PHP 需要同时安装 flex 和 bison。根据设置的不同，可以从源代码编译 bison 和 flex，要么通过已编译好的发行包，例如 RPM。</p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.build.apache-sharedcore">
   <dt><strong>
    当试图启动 Apache 时，得到类似如下错误信息：
    
     <div class="example-contents screen">fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found</div>
    
   </strong></dt>
   <dd class="answer">
    <p class="para">该错误通常在 Apache 的核心程序被编译为共享用途的 DSO 库时发生。请尝试重新配置 Apache，确保至少使用了如下参数：</p>
    <p class="para">
     <div class="example-contents screen">--enable-shared=max --enable-rule=SHARED_CORE</div>
    </p>
    <p class="para">更多信息，请阅读 Apache 顶层目录的 
     <var class="filename">INSTALL</var>文件或者 Apache 的 
     <a href="http://httpd.apache.org/docs/current/dso.html" class="link external">&raquo;&nbsp;DSO 手册</a>。</p>
   </dd>
  </dl>
  <dl class="qandaentry" id="faq.build.not-found">
   <dt><strong>
    当运行 configure 时，报告说找不到头文件或 GD 库或 gdbm，或其它的什么包！
   </strong></dt>
   <dd class="answer">
    <p class="para">可以通过指定附加的选项让 configure 脚本在非标准的路径中寻找头文件和库并传递给 C 预处理器和连接器，例如： 
     <div class="example-contents">
<div class="cdata"><pre>
    CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
</pre></div>
         </div>
如果用 csh 的变种作为你的登录 shell（为什么？），那就是： 
         <div class="example-contents">
<div class="cdata"><pre>
    env CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
</pre></div>
         </div>
</p>
     </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.yytname">
    <dt><strong>
     当编译 
      <var class="filename">language-parser.tab.c</var>文件时，报错说 
      <code class="literal">yytname undeclared</code>。
    </strong></dt>
    <dd class="answer">
     <p class="para">需要更新 Bison 的版本。最新版本在 
      <a href="http://www.gnu.org/software/bison/bison.html" class="link external">&raquo;&nbsp;http://www.gnu.org/software/bison/bison.html</a>。</p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.link">
    <dt><strong>
     当我运行 
      <strong class="command">make</strong>时，看上去一切正常，可当连接最后的程序时报告说找不到某些文件而失败了。
    </strong></dt>
    <dd class="answer">
     <p class="para">一些旧版本的 make 没有正确将 functions 目录下编译后的文件放到同一个目录下。试试运行 
      <strong class="command">cp *.o functions</strong>然后再运行 
      <strong class="command">make</strong>看看有没有什么帮助。如果成功了，那你确实需要更新到最新版的 GNU make。</p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.undefined">
    <dt><strong>
     当连接 PHP 时，报告说有一些未定义的引用。
    </strong></dt>
    <dd class="answer">
     <p class="para">看看连接的这一行命令，确认所有适当的库都包括在最后了。通常可能漏掉了“-ldl”和你包括的任何数据库支持所需要的库。</p>
     <p class="para">一些人也报告说在和 Apache 连接时他们不得不紧接着 
      <var class="filename">libphp4.a</var>之后加上“-ldl”。</p>
    </dd>
   </dl>

   <dl class="qandaentry" id="faq.build.not-running">
    <dt><strong>
     我按照所有的步骤在 UNIX 下安装了PHP 的 Apache 模块版本，但我的 PHP 脚本被显示在浏览器中或者提示保存此文件。
    </strong></dt>
    <dd class="answer">
     <p class="para">这说明 PHP 模块出于某些原因没有被调用。在寻求更多帮助前先检查三件事： 
      <ul class="itemizedlist">
       <li class="listitem">
        <span class="simpara">确认你运行的 httpd 程序就是你刚刚编译的新 httpd 程序。运行： 
         <code class="literal">/path/to/binary/httpd -l</code></span>
        <span class="simpara">如果你没看到 
         <var class="filename">mod_php4.c</var>被列出来那你就没有运行对程序。找到并正确安装程序。</span>
       </li>
       <li class="listitem">
        <span class="simpara">确认你在 
         <code class="literal">Apache .conf</code>文件中加入了正确的 Mime 类型。应该是： 
         <code class="literal">AddType application/x-httpd-php .php</code>
        </span>
        <span class="simpara">也确认 AddType 这一行没有隐藏在 &lt;Virtualhost&gt; 或者 &lt;Directory&gt; 块中，这可能会造成你的测试脚本所在位置没有被应用到此设置。</span>
       </li>
       <li class="listitem">
        <span class="simpara">最后，Apache 1.2 和 Apache 1.3 之间默认配置文件的位置改变了。你要确认你添加 AddType 行的文件就是实际上用的。你可以在你的 <var class="filename">httpd.conf</var> 中添加一个明显的语法错误或者其它明显修改，这可以告诉你是否读取了正确的文件。</span>
       </li>
      </ul></p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.activate-module">
    <dt><strong>
     说要用：
      <code class="literal">--activate-module=src/modules/php4/libphp4.a</code>，但是此文件根本不存在，于是我改成了 
      <code class="literal">--activate-module=src/modules/php4/libmodphp4.a</code>，结果不行。怎么回事？
    </strong></dt>
    <dd class="answer">
     <p class="para">注意 
      <var class="filename">libphp4.a</var>文件本来就不该存在，apache 进程将创建它！</p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.ansi">
    <dt><strong>
     当我用 
      <code class="literal">--activate-module=src/modules/php4/libphp4.a</code>试着把 PHP 编译成 Apache 的静态模块时，报告说我的编译器不服从 ANSI 标准。
    </strong></dt>
    <dd class="answer">
     <p class="para">这是一个 Apache 误报的错误信息，在新的版本中已经修正了。</p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.apxs">
    <dt><strong>
     当我用 
      <strong class="option configure">--with-apxs</strong>编译 PHP 时得到奇怪的错误信息。
    </strong></dt>
    <dd class="answer">
     <p class="para">这里要检查三件事。首先，出于某些原因当 Apache 生成 apxs Perl 脚本时，有时没有正确的编译和标记变量就结束了。找到你的 apxs 脚本（用命令 
      <strong class="command">which apxs</strong>），有时会在 
      <var class="filename">/usr/local/apache/bin/apxs</var>或者 
      <var class="filename">/usr/sbin/apxs</var>。打开并检查类似如下的行： 
      <div class="example-contents">
<div class="cdata"><pre>
my $CFG_CFLAGS_SHLIB  = &#039; &#039;;          # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = &#039; &#039;;          # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = &#039; &#039;;          # substituted via Makefile.tmpl
</pre></div>
         </div>
如果你看到这几行，那问题就在这里。它们可能包含了仅仅空格或者其它不正确的值，例如“q()”。改成这样： 
         <div class="example-contents">
<div class="cdata"><pre>
my $CFG_CFLAGS_SHLIB  = &#039;-fpic -DSHARED_MODULE&#039;; # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = &#039;gcc&#039;;                   # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = q(-shared);              # substituted via Makefile.tmpl
</pre></div>
         </div>
第二个可能的问题仅可能在在 Red Hat 6.1 和 6.2 中发生。Red Hat 发行的 apxs 脚本坏了。查找这一行： 
         <div class="example-contents">
<div class="cdata"><pre>
my $CFG_LIBEXECDIR    = &#039;modules&#039;;         # substituted via APACI install
</pre></div>
         </div>
如果你看到上面这一行，改成这样： 
         <div class="example-contents">
<div class="cdata"><pre>
my $CFG_LIBEXECDIR    = &#039;/usr/lib/apache&#039;; # substituted via APACI install
</pre></div>
         </div>
最后，如果你重新配置或者重装了 Apache，在 
         <strong class="command">./configure</strong>之后和 
         <strong class="command">make</strong>之前增加一个 
         <strong class="command">make clean</strong>命令。</p>
     </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.microtime">
    <dt><strong>
     在 
      <strong class="command">make</strong>的过程中，在 microtime 中出错，还有很多 
      <code class="literal">RUSAGE_</code>之类的东西。
    </strong></dt>
    <dd class="answer">
     <p class="para">如果 
      <strong class="command">make</strong>时遇到类似这样的问题： 
      <div class="example-contents">
<div class="cdata"><pre>
microtime.c: In function `php_if_getrusage&#039;:
microtime.c:94: storage size of `usg&#039; isn&#039;t known
microtime.c:97: `RUSAGE_SELF&#039; undeclared (first use in this function)
microtime.c:97: (Each undeclared identifier is reported only once
microtime.c:97: for each function it appears in.)
microtime.c:103: `RUSAGE_CHILDREN&#039; undeclared (first use in this function)
make[3]: *** [microtime.lo] Error 1
make[3]: Leaving directory `/home/master/php-4.0.1/ext/standard&#039;
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/master/php-4.0.1/ext/standard&#039;
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/master/php-4.0.1/ext&#039;
make: *** [all-recursive] Error 1
</pre></div>
      </div>

     </p>
     <p class="para">
      你的系统坏了。你需要安装一个符合你的 glibc 的 glibc-devel 包来修复 
      <var class="filename">/usr/include</var> 中的文件。这和 PHP 绝对没有任何关系。要证实这一点，试试这个简单的测试： 
     <div class="example-contents">
<div class="cdata"><pre>
$ cat &gt;test.c &lt;&lt;X
#include &lt;sys/resource.h&gt;
X
$ gcc -E test.c &gt;/dev/null
</pre></div>
      </div>

      如果出现错误，那你就知道头文件坏了。
     </p>
    </dd>
   </dl>
   
   <dl class="qandaentry" id="faq.build.mysql.tempnam">
    <dt><strong>
     
      当带 MySQL 编译 PHP 时，可以正确地运行 configure，但是在
      <code class="literal">make</code> 的过程中出现了类似以下的错误信息： 
      <em>ext/mysql/libmysqlclient/my_tempnam.o(.text+0x46): In function 
      my_tempnam&#039;: /php4/ext/mysql/libmysqlclient/my_tempnam.c:103: the 
      use of tempnam&#039; is dangerous, better use mkstemp&#039;</em>，这是怎么回事？
     
    </strong></dt>
    <dd class="answer">
     <p class="para">
      首先，我们需要认识到这只是个<code class="literal">警告</code>，而非致命错误。由于这条信息通常是在 
      <code class="literal">make</code> 的最后输出的，所以看起来它可能像是一个致命错误，但实际上不是。当然，如果将编译器设置成遇见警告信息时停止，则这也可以算是致命错误。另外值得一提的是，MySQL
      的支持是默认打开的。
     </p>
     <blockquote class="note"><p><strong class="note">注意</strong>: 
      <p class="para">
       自 PHP 4.3.2 起，你将在编译（make）结束后看到下面的文字：
      </p>
      <p class="para">
       <div class="example-contents screen"><br />
        Build complete.<br />
        (It is safe to ignore warnings about tempnam and tmpnam).<br />
       </div>
      </p>
     </p></blockquote>
    </dd>
   </dl>
   
   <dl class="qandaentry" id="faq.build.upgrade">
    <dt><strong>
     我想升级我的 PHP。上哪里找到我用来配置目前的 PHP 的 
      <strong class="command">./configure</strong>的参数呢？
    </strong></dt>
    <dd class="answer">
     <p class="para">要么在你用来编译当前的 PHP 的源码树中查看 config.nice 文件，如果没有，只要运行此脚本： 
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php phpinfo</span><span style="color: #007700">(); </span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

      在输出的顶端显示了用来配置此 PHP 的 
      <strong class="command">./configure</strong>参数。
      </p>
     </dd>
   </dl>
   <dl class="qandaentry" id="faq.build.gdlibs">
    <dt><strong>
     和 GD 库一起编译 PHP 时，要么给出一个奇怪的编译错误，要么在运行时出现 segfaults。
    </strong></dt>
    <dd class="answer">
     <p class="para">确保你的 GD 库和 PHP 在连接时使用了用同样的支持库（例如 libpng）。</p>
    </dd>
   </dl>
   <dl class="qandaentry" id="faq.installation.needgnu">
    <dt><strong>
     当编译 PHP 时我看到一些随机的错误，好像死了。我用的是 Solaris，不知道有没有关系。
    </strong></dt>
    <dd class="answer">
     <p class="para">当编译 PHP 时使用非 GNU 的工具会导致问题。确保使用 GNU 工具来确保能够正确编译 PHP。例如，在 Solaris 下面不论使用 SunOS BSD 兼容或者 Solaris 版本的 
      <code class="literal">sed</code>都不行，但是使用 GNU 或者 Sun POSIX (xpg4) 版本的 
      <code class="literal">sed</code>就可以。相关连接：
      <a href="http://www.gnu.org/software/sed/sed.html" class="link external">&raquo;&nbsp;GNU sed</a>，
      <a href="http://www.gnu.org/software/flex/flex.html" class="link external">&raquo;&nbsp;GNU flex</a>，
      <a href="http://www.gnu.org/software/bison/bison.html" class="link external">&raquo;&nbsp;GNU bison</a>。</p>
    </dd>
   </dl>
          
</div>
<?php manual_footer($setup); ?>