編譯問題

編譯問題

本節彙集了大多數編譯時出現的常見錯誤。

  1. 我用匿名 GIT 服務得到了最新版的 PHP,但是裡面沒有 configure 指令碼!
  2. 我在配置 PHP 和 Apache 一起工作時遇到了問題。說沒找到 httpd.h,但這個檔案明明就在那裡!
  3. 當執行 PHP 配置時( ./configure),遇到類似如下的問題: checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up
  4. 當試圖啟動 Apache 時,得到類似如下錯誤資訊: fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found
  5. 當執行 configure 時,報告說找不到標頭檔案或 GD 庫或 gdbm,或其它的什麼包!
  6. 當編譯 language-parser.tab.c檔案時,報錯說 yytname undeclared。
  7. 當我執行 make時,看上去一切正常,可當連線最後的程式時報告說找不到某些檔案而失敗了。
  8. 當連線 PHP 時,報告說有一些未定義的引用。
  9. 我不知道怎樣把 PHP 和 Apache 1.3 一起編譯。
  10. 我按照所有的步驟在 UNIX 下安裝了PHP 的 Apache 模組版本,但我的 PHP 指令碼被顯示在瀏覽器中或者提示儲存此檔案。
  11. 說要用: --activate-module=src/modules/php4/libphp4.a,但是此檔案根本不存在,於是我改成了 --activate-module=src/modules/php4/libmodphp4.a,結果不行。怎麼回事?
  12. 當我用 --activate-module=src/modules/php4/libphp4.a試著把 PHP 編譯成 Apache 的靜態模組時,報告說我的編譯器不服從 ANSI 標準。
  13. 當我用 --with-apxs編譯 PHP 時得到奇怪的錯誤資訊。
  14. 在 make的過程中,在 microtime 中出錯,還有很多 RUSAGE_之類的東西。
  15. 當帶 MySQL 編譯 PHP 時,可以正確地執行configure,但是在 make的過程中出現了類似以下的錯誤資訊: ext/mysql/ libmysqlclient /my_tempnam.o(.text+0x46): In function my_tempnam': /php4/ext/mysql/ libmysqlclient /my_tempnam.c:103: the use of tempnam' is dangerous, better use mkstemp',這是怎麼回事
  16. 我想升級我的 PHP。上哪裡找到我用來配置目前的 PHP 的 ./configure的參數呢?
  17. 和 GD 庫一起編譯 PHP 時,要麼給出一個奇怪的編譯錯誤,要麼在執行時出現 segfaults。
  18. 當編譯 PHP 時我看到一些隨機的錯誤,好像死了。我用的是 Solaris,不知道有沒有關係。
我用匿名 GIT 服務得到了最新版的 PHP,但是裡面沒有 configure 指令碼!

你必須安裝有 GNU autoconf 包,這樣才可以從 configure.in產生 configure 指令碼。從 GIT 服務中得到源程式后只要在最高層的目錄中執行 ./buildconf即可。(同時要注意,除非你用了 --enable-maintainer-mode選項來執行 configure,否則即使 configure.in檔案更新了,configure 指令碼也不會自動重新產生。所以當你發現 configure.in檔案更新了時要確保手工重新產生 configure 指令碼。有一個癥狀是在 configure 之後或者執行 config.status時在 Makefile 中尋找類似 @VARIABLE@ 的東西。)

我在配置 PHP 和 Apache 一起工作時遇到了問題。說沒找到 httpd.h,但這個檔案明明就在那裡!

你需要告訴 configure/setup 指令碼你的 Apache 源程式最上層的目錄位置。這意味著你需要這樣指定 --with-apache=/path/to/apache不是這樣 --with-apache=/path/to/apache/src

當執行 PHP 配置時( ./configure),遇到類似如下的問題:
checking lex output file root... ./configure: lex: command not found configure: error: cannot find output from lex; giving up

請認真閱讀 PHP 的 安裝說明,並注意要編譯 PHP 需要同時安裝 flex 和 bison。根據設定的不同,可以從原始碼編譯 bison 和 flex,要麼通過已編譯好的發行包,例如 RPM。

當試圖啟動 Apache 時,得到類似如下錯誤資訊:
fatal: relocation error: file /path/to/libphp4.so: symbol ap_block_alarms: referenced symbol not found

該錯誤通常在 Apache 的核心程式被編譯為共享用途的 DSO 庫時發生。請嘗試重新配置 Apache,確保至少使用瞭如下參數:

--enable-shared=max --enable-rule=SHARED_CORE

更多資訊,請閱讀 Apache 頂層目錄的 INSTALL檔案或者 Apache 的 » DSO 手冊

當執行 configure 時,報告說找不到標頭檔案或 GD 庫或 gdbm,或其它的什麼包!

可以通過指定附加的選項讓 configure 指令碼在非標準的路徑中尋找標頭檔案和庫並傳遞給 C 前處理器和聯結器,例如:

    CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
如果用 csh 的變種作為你的登錄 shell(為什麼?),那就是:
    env CPPFLAGS=-I/path/to/include LDFLAGS=-L/path/to/library ./configure
當編譯 language-parser.tab.c檔案時,報錯說 yytname undeclared

需要更新 Bison 的版本。最新版本在 » http://www.gnu.org/software/bison/bison.html

當連線 PHP 時,報告說有一些未定義的引用。

看看連線的這一行命令,確認所有適當的庫都包括在最後了。通常可能漏掉了「-ldl」和你包括的任何數據庫支援所需要的庫。

一些人也報告說在和 Apache 連線時他們不得不緊接著 libphp4.a之後加上「-ldl」。

我不知道怎樣把 PHP 和 Apache 1.3 一起編譯。

這其實很簡單。小心地照著以下步驟來:

  • » http://httpd.apache.org/download.cgi下載最新版的 Apache 1.3。
  • 解壓縮到某處,例如 /usr/local/src/apache-1.3
  • 編譯 PHP,先執行 ./configure --with-apache=/<path>/apache-1.3(用你 apache-1.3 所在的真實路徑替換掉 <path>。)
  • 輸入 make接著是 make install來編譯 PHP 並把必要的檔案拷貝到 Apache 的源程式目錄樹中。
  • 改變目前目錄到 /<path>/apache-1.3/src目錄並編輯 Configuration檔案。新增這一行: AddModule modules/php4/libphp4.a
  • 輸入 ./configure接著是 make
  • 你現在應該有一個包括 PHP 支援的 httpd 可執行程式了!

注意:也可以用新的 Apache ./configure指令碼。參見 Apache 發行包中 README.configure檔案中的說明。也看看 PHP 發行包中的 INSTALL檔案。

我按照所有的步驟在 UNIX 下安裝了PHP 的 Apache 模組版本,但我的 PHP 指令碼被顯示在瀏覽器中或者提示儲存此檔案。

這說明 PHP 模組出於某些原因沒有被呼叫。在尋求更多幫助前先檢查三件事:

  • 確認你執行的 httpd 程式就是你剛剛編譯的新 httpd 程式。執行: /path/to/binary/httpd -l 如果你沒看到 mod_php4.c被列出來那你就沒有執行對程式。找到並正確安裝程式。
  • 確認你在 Apache .conf檔案中加入了正確的 Mime 型別。應該是: AddType application/x-httpd-php .php 也確認 AddType 這一行沒有隱藏在 <Virtualhost> 或者 <Directory> 塊中,這可能會造成你的測試指令碼所在位置沒有被應用到此設定。
  • 最後,Apache 1.2 和 Apache 1.3 之間預設配置檔案的位置改變了。你要確認你新增 AddType 行的檔案就是實際上用的。你可以在你的 httpd.conf 中新增一個明顯的語法錯誤或者其它明顯修改,這可以告訴你是否讀取了正確的檔案。

說要用: --activate-module=src/modules/php4/libphp4.a,但是此檔案根本不存在,於是我改成了 --activate-module=src/modules/php4/libmodphp4.a,結果不行。怎麼回事?

注意 libphp4.a檔案本來就不該存在,apache 程序將建立它!

當我用 --activate-module=src/modules/php4/libphp4.a試著把 PHP 編譯成 Apache 的靜態模組時,報告說我的編譯器不服從 ANSI 標準。

這是一個 Apache 誤報的錯誤資訊,在新的版本中已經修正了。

當我用 --with-apxs編譯 PHP 時得到奇怪的錯誤資訊。

這裡要檢查三件事。首先,出於某些原因當 Apache 產生 apxs Perl 指令碼時,有時沒有正確的編譯和標記變數就結束了。找到你的 apxs 指令碼(用命令 which apxs),有時會在 /usr/local/apache/bin/apxs或者 /usr/sbin/apxs。打開並檢查類似如下的行:

my $CFG_CFLAGS_SHLIB  = ' ';          # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = ' ';          # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = ' ';          # substituted via Makefile.tmpl
如果你看到這幾行,那問題就在這裡。它們可能包含了僅僅空格或者其它不正確的值,例如「q()」。改成這樣:
my $CFG_CFLAGS_SHLIB  = '-fpic -DSHARED_MODULE'; # substituted via Makefile.tmpl
my $CFG_LD_SHLIB      = 'gcc';                   # substituted via Makefile.tmpl
my $CFG_LDFLAGS_SHLIB = q(-shared);              # substituted via Makefile.tmpl
第二個可能的問題僅可能在在 Red Hat 6.1 和 6.2 中發生。Red Hat 發行的 apxs 指令碼壞了。查詢這一行:
my $CFG_LIBEXECDIR    = 'modules';         # substituted via APACI install
如果你看到上面這一行,改成這樣:
my $CFG_LIBEXECDIR    = '/usr/lib/apache'; # substituted via APACI install
最後,如果你重新配置或者重灌了 Apache,在 ./configure之後和 make之前增加一個 make clean命令。

make的過程中,在 microtime 中出錯,還有很多 RUSAGE_之類的東西。

如果 make時遇到類似這樣的問題:

microtime.c: In function `php_if_getrusage':
microtime.c:94: storage size of `usg' isn't known
microtime.c:97: `RUSAGE_SELF' 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' undeclared (first use in this function)
make[3]: *** [microtime.lo] Error 1
make[3]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/master/php-4.0.1/ext/standard'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/master/php-4.0.1/ext'
make: *** [all-recursive] Error 1

你的系統壞了。你需要安裝一個符合你的 glibc 的 glibc-devel 包來修復 /usr/include中的檔案。這和 PHP 絕對沒有任何關係。要證實這一點,試試這個簡單的測試:

$ cat >test.c <<X
#include <sys/resource.h>
X
$ gcc -E test.c >/dev/null
如果出現錯誤,那你就知道標頭檔案壞了。

當帶 MySQL 編譯 PHP 時,可以正確地執行configure,但是在 make的過程中出現了類似以下的錯誤資訊: ext/mysql/ libmysqlclient /my_tempnam.o(.text+0x46): In function my_tempnam': /php4/ext/mysql/ libmysqlclient /my_tempnam.c:103: the use of tempnam' is dangerous, better use mkstemp',這是怎麼回事

首先,我們需要認識到這只是個 警告,而非致命錯誤。由於這條資訊通常是在 make的最後輸出的,所以看起來它可能像是一個致命錯誤,但實際上不是。當然,如果將編譯器設定成遇見警告資訊時停止,則這也可以算是致命錯誤。另外值得一提的是,MySQL 的支援是預設打開的。

注意:

自 PHP 4.3.2 起,你將在編譯(make)結束后看到下面的文字:


Build complete.
(It is safe to ignore warnings about tempnam and tmpnam).

我想升級我的 PHP。上哪裡找到我用來配置目前的 PHP 的 ./configure的參數呢?

要麼在你用來編譯目前的 PHP 的原始碼樹中檢視 config.nice 檔案,如果沒有,只要執行此指令碼:

<?php phpinfo(); ?>
在輸出的頂端顯示了用來配置此 PHP 的 ./configure參數。

和 GD 庫一起編譯 PHP 時,要麼給出一個奇怪的編譯錯誤,要麼在執行時出現 segfaults。

確保你的 GD 庫和 PHP 在連線時使用了用同樣的支援庫(例如 libpng)。

當編譯 PHP 時我看到一些隨機的錯誤,好像死了。我用的是 Solaris,不知道有沒有關係。

當編譯 PHP 時使用非 GNU 的工具會導致問題。確保使用 GNU 工具來確保能夠正確編譯 PHP。例如,在 Solaris 下面不論使用 SunOS BSD 相容或者 Solaris 版本的 sed都不行,但是使用 GNU 或者 Sun POSIX (xpg4) 版本的 sed就可以。相關連線: » GNU sed» GNU flex» GNU bison

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *