在Windows系統中使用VC9、VC11編譯32位、64位PHP及其擴充

來源:互聯網
上載者:User

標籤:

項目中需要使用runkit模組實現AOP,但是團隊成員的開發環境都是Windows,而runkit模組官方沒有提供Windows環境下的dll擴充,只能自己編譯。

下面是編譯過程的分類總結。(作業系統環境為Windows 10 64位中文旗艦版)

  • PHP的編譯版本
    這裡的版本指的不是PHP的發行版本,如5.3、7.0,而是指編譯時間所使用的編譯器、程式架構和是否為安全執行緒。
    這些資訊可以在phpinfo中列印出來。

    中所使用的PHP,是使用Miscrosoft Visual 2012中的MSVC11編譯的,程式架構為x86(即32位),非安全執行緒(NTS)。

    中的PHP,是使用Miscrosoft Visual 2012中的MSVC11編譯的,程式架構為x64(即64位),安全執行緒(TS)。

    略有不同,沒有專門的清單項目說明編譯器版本、程式架構,只能從編譯時間的配置中看到相關資訊。這裡的PHP,是使用Miscrosoft Visual 6中的MSVC6編譯的,程式架構為x86(即32位),安全執行緒(Thread Safety = enabled)。

    最後這一張,是使用Miscrosoft Visual 2008中的MSVC9編譯的,程式架構為x86(即32位),安全執行緒(TS)。
    本文只討論MSVC9和MSVC11編譯兩種情況。
  • 準備PHP-SDK和PHP源碼
    以下步驟無論編譯哪種版本的PHP,都是必須的。
    • 下載PHP-SDK:
      在http://windows.php.net/downloads/php-sdk/中可以找到,下載其中的php-sdk-binary-tools-20110915.zip
    • 解壓到C:\php-sdk檔案夾
    • 開啟命令列,執行如下命令:

      cd c:\php-sdk\
      bin\phpsdk_buildtree.bat phpdev
      會在c:\php-sdk檔案夾下產生phpdev檔案夾,其中包含vc6、vc8、vc9子檔案夾。
      如果使用MSVC11編譯PHP,就複製c:\php-sdk\phpdev\vc9到c:\php-sdk\phpdev\vc11。
      如果使用MSVC14編譯PHP,就複製c:\php-sdk\phpdev\vc9到c:\php-sdk\phpdev\vc14。

    • 下載相應版本的PHP的編譯時間依賴包,見http://windows.php.net/downloads/php-sdk/。
      將其解壓至相應編譯檔案夾下的x86或x64檔案夾下,覆蓋其中的deps檔案夾。注意要與要編譯的PHP發行版本和程式架構一致,如編譯php5.4.x的32位版本則解壓deps-5.4-vc9-x86.7z,如編譯php5.5.x的64位版本則解壓deps-5.6-vc11-x64.7z,依此類推。
      php5.4.x和php5.3.x通常需要使用vc9編譯,因此其依賴檔案解壓到c:\php-sdk\phpdev\vc9\x86或c:\php-sdk\phpdev\vc9\x64。
      php5.5.x和php5.6.x通常需要使用vc11編譯,因此其依賴檔案解壓到c:\php-sdk\phpdev\vc11\x86或c:\php-sdk\phpdev\vc11\x64。
      而php7.0.x則需要vc14編譯,因此其依賴檔案解壓到c:\php-sdk\phpdev\vc14\x86或c:\php-sdk\phpdev\vc14\x64。
    • 下載所需要的PHP源檔案,在http://windows.php.net/download/、http://php.net/downloads.php、http://php.net/releases/、http://windows.php.net/downloads/releases/archives/幾處都可以找到。
      將其解壓制相應的編譯檔案夾下。
      例如:
      將php-5.4.45.tar.gz解壓到c:\php-sdk\phpdev\vc9\x86\php-5.4.45或c:\php-sdk\phpdev\vc9\x64\php-5.4.45下,以分別編譯其32位和64位版本。
      將php-5.6.16.tar.gz則解壓到c:\php-sdk\phpdev\vc11\x86\php-5.6.16或c:\php-sdk\phpdev\vc11\x64\php-5.6.16下。
    • 如果是編譯PHP擴充,則到相應的地址下載源碼,本文是以runkit為例,在http://pecl.php.net/package/runkit。
      將下載到的源碼解壓到PHP源碼的ext檔案夾下,本例是分別解壓到c:\php-sdk\phpdev\vc9\x86\php-5.4.45\ext\runkit、c:\php-sdk\phpdev\vc9\x64\php-5.4.45\ext\runkit、c:\php-sdk\phpdev\vc11\x86\php-5.6.16\ext\runkit、c:\php-sdk\phpdev\vc11\x64\php-5.6.16\ext\runkit。
  • 準備編譯環境:
    • 使用MSVC9編譯PHP,需要下載安裝Windows SDK 6.1,此地址下載的是線上安裝版。也可以在http://download.microsoft.com/download/a/4/2/a4282359-1d35-4648-a7a7-d85e3bfe81ac/6.0.6001.16621.148.WindowsSDK_LonghornServer_IDS04_idw.WindowsSDK.DVD.Release.iso下載離線安裝包。
      如需編譯32位版本,在安裝Windows SDK 6.1時,要注意選擇安裝x86編譯器,否則會出現找不到cl.exe的問題。
    • 使用MSVC11編譯PHP,可以下載Visual Studio 2012 Express for Windows Desktop,有線上安裝版和離線安裝版(ISO)。
    • 兩個工具不衝突,可以同時安裝在同一系統下。

下面是具體的編譯步驟,有些內容會出現重複,是為了讓偷懶的同學按圖索驥,有樣學樣:)

  • 使用MSVC9編譯PHP5.4.33的32位版(本例為編譯runkit.dll)
    • 安裝Windows SDK 6.1,注意安裝時選擇x86編譯器。
    • 將下載的php-sdk-binary-tools-20110915.zip解壓到c:\php-sdk。
    • 開啟Windows命令列,輸入如下命令:
      cd c:\php-sdk
      bin\phpsdk_buildtree.bat phpdev
    • 將下載的php-5.4.45.tar.gz解壓到c:\php-sdk\phpdev\vc9\x86\php-5.4.45。
    • 將下載的deps-5.4-vc9-x86.7z解壓到c:\php-sdk\phpdev\vc9\x86\deps覆蓋原deps檔案夾。
    • 將下載的http://pecl.php.net/get/runkit-1.0.4.tgz解壓到c:\php-sdk\phpdev\vc9\x86\php-5.4.45\ext檔案夾,注意檔案夾的名稱不要帶版本號碼,本例應為runkit,而非runkit-1.0.4。
    • 在c:\php-sdk\phpdev\vc9\x86下建立obj檔案夾,用於存放最終的php.exe及相關的dll檔案。
    • 點擊開始菜單,選擇Microsoft Windows SDK V6.1>CMD Shell,啟動編譯命令列。
    • 輸入如下指令:
      setenv /x86 /xp /release(此行命令執行成功,命令列的文字將變為綠色)
      cd c:\php-sdk
      bin\phpsdk_setvars.bat
      cd phpdev\vc9\x86\php-5.4.45
      buildconf
      configure --disable-all --enable-cli --enable-runkit=shared --enable-object-out-dir=..\obj
      如需編譯非安全執行緒版 (nts版),將上面最後一行換成
      configure --disable-all --enable-cli --enable-runkit=shared --disable-zts --enable-object-out-dir=..\obj
      最終執行
      nmake
    • 在obj中有Release(安全執行緒版-ts版)或Release_nts(非安全執行緒版-nts版)檔案夾,其中的php.exe及php-runkit.dll即為編譯結果。
    • 將php-runkit.dll檔案放入PHP安裝資料夾的ext檔案夾中,修改php.ini,加入extension=php_runkit.dll,重新啟動PHP服務即可。
  • 使用MSVC9編譯PHP5.4.33的64位版(本例為編譯runkit.dll)
    • 安裝Windows SDK 6.1,注意安裝時選擇x86編譯器。
    • 將下載的php-sdk-binary-tools-20110915.zip解壓到c:\php-sdk。
    • 開啟Windows命令列,輸入如下命令:
      cd c:\php-sdk
      bin\phpsdk_buildtree.bat phpdev
    • 將下載的php-5.4.45.tar.gz解壓到c:\php-sdk\phpdev\vc9\x64\php-5.4.45。
    • 將下載的deps-5.4-vc9-x86.7z解壓到c:\php-sdk\phpdev\vc9\x64\deps覆蓋原deps檔案夾。
    • 將下載的http://pecl.php.net/get/runkit-1.0.4.tgz解壓到c:\php-sdk\phpdev\vc9\x64\php-5.4.45\ext檔案夾,注意檔案夾的名稱不要帶版本號碼,本例應為runkit,而非runkit-1.0.4。
    • 在c:\php-sdk\phpdev\vc9\x64下建立obj檔案夾,用於存放最終的php.exe及相關的dll檔案。
    • 點擊開始菜單,選擇Microsoft Windows SDK V6.1>CMD Shell,啟動編譯命令列。
    • 輸入如下指令:與上面編譯32位程式明顯不同的是,不需要執行 setenv /x86 /xp /release
      cd c:\php-sdk
      bin\phpsdk_setvars.bat
      cd phpdev\vc9\x64\php-5.4.45
      buildconf
      configure --disable-all --enable-cli --enable-runkit=shared --enable-object-out-dir=..\obj
      如需編譯非安全執行緒版 (nts版),將上面最後一行換成
      configure --disable-all --enable-cli --enable-runkit=shared --disable-zts --enable-object-out-dir=..\obj
      最終執行
      nmake
    • 在obj中有Release(安全執行緒版-ts版)或Release_nts(非安全執行緒版-nts版)檔案夾,其中的php.exe及php-runkit.dll即為編譯結果。
    • 將php-runkit.dll檔案放入PHP安裝資料夾的ext檔案夾中,修改php.ini,加入extension=php_runkit.dll,重新啟動PHP服務即可。
  • 使用MSVC11編譯PHP5.4.33的32位版(本例為編譯runkit.dll)
    • 安裝Visual Studio 2012 Express for Windows Desktop。
    • 將下載的php-sdk-binary-tools-20110915.zip解壓到c:\php-sdk。
    • 開啟Windows命令列,輸入如下命令:
      cd c:\php-sdk
      bin\phpsdk_buildtree.bat phpdev
    • 將下載的php-5.6.16.tar.gz解壓到c:\php-sdk\phpdev\vc11\x64\php-5.6.16。
    • 將下載的deps-5.6-vc11-x64.7z解壓到c:\php-sdk\phpdev\vc11\x64\deps覆蓋原deps檔案夾。
    • 將下載的http://pecl.php.net/get/runkit-1.0.4.tgz解壓到c:\php-sdk\phpdev\vc11\x64\php-5.6.16\ext檔案夾,注意檔案夾的名稱不要帶版本號碼,本例應為runkit,而非runkit-1.0.4。
    • 在c:\php-sdk\phpdev\vc11\x64下建立obj檔案夾,用於存放最終的php.exe及相關的dll檔案。
    • 點擊開始菜單,選擇Microsoft Visual Studio 2012>Visual Studio Tools>VS2012 x64 Cross Tools Command Prompt,啟動編譯命令列。
    • 輸入如下指令:
      cd c:\php-sdk
      bin\phpsdk_setvars.bat
      cd phpdev\vc11\x64\php-5.6.16
      buildconf
      configure --disable-all --enable-cli --enable-runkit=shared --enable-object-out-dir=..\obj
      如需編譯非安全執行緒版 (nts版),將上面最後一行換成
      configure --disable-all --enable-cli --enable-runkit=shared --disable-zts --enable-object-out-dir=..\obj
      最終執行
      nmake
    • 在obj中有Release(安全執行緒版-ts版)或Release_nts(非安全執行緒版-nts版)檔案夾,其中的php.exe及php-runkit.dll即為編譯結果。
    • 將php-runkit.dll檔案放入PHP安裝資料夾的ext檔案夾中,修改php.ini,加入extension=php_runkit.dll,重新啟動PHP服務即可。
  • 使用MSVC11編譯PHP5.4.33的64位版(本例為編譯runkit.dll)
    • 安裝Visual Studio 2012 Express for Windows Desktop。
    • 將下載的php-sdk-binary-tools-20110915.zip解壓到c:\php-sdk。
    • 開啟Windows命令列,輸入如下命令:
      cd c:\php-sdk
      bin\phpsdk_buildtree.bat phpdev
    • 將下載的php-5.6.16.tar.gz解壓到c:\php-sdk\phpdev\vc11\x86\php-5.6.16。
    • 將下載的deps-5.6-vc11-x86.7z解壓到c:\php-sdk\phpdev\vc11\x86\deps覆蓋原deps檔案夾。
    • 將下載的http://pecl.php.net/get/runkit-1.0.4.tgz解壓到c:\php-sdk\phpdev\vc11\x86\php-5.6.16\ext檔案夾,注意檔案夾的名稱不要帶版本號碼,本例應為runkit,而非runkit-1.0.4。
    • 在c:\php-sdk\phpdev\vc11\x86下建立obj檔案夾,用於存放最終的php.exe及相關的dll檔案。
    • 點擊開始菜單,選擇Microsoft Visual Studio 2012>Visual Studio Tools>VS2012 x86 Native Tools Command Prompt,啟動編譯命令列。
    • 輸入如下指令:
      cd c:\php-sdk
      bin\phpsdk_setvars.bat
      cd phpdev\vc11\x86\php-5.6.16
      buildconf
      configure --disable-all --enable-cli --enable-runkit=shared --enable-object-out-dir=..\obj
      如需編譯非安全執行緒版 (nts版),將上面最後一行換成
      configure --disable-all --enable-cli --enable-runkit=shared --disable-zts --enable-object-out-dir=..\obj
      最終執行
      nmake
    • 在obj中有Release(安全執行緒版-ts版)或Release_nts(非安全執行緒版-nts版)檔案夾,其中的php.exe及php-runkit.dll即為編譯結果。
    • 將php-runkit.dll檔案放入PHP安裝資料夾的ext檔案夾中,修改php.ini,加入extension=php_runkit.dll,重新啟動PHP服務即可。

可能遇到的問題:

  • 如果遇到There is no script engine for file extension ".js"錯誤,說明Windows的jscript引擎沒有正確註冊,可按如下步驟解決:
    • 以管理員身份開啟命令列:
    • 執行如下指令:

      regsvr32 %WINDIR%\System32\jscript.dll
      regsvr32 %WINDIR%\SysWOW64\jscript.dll

    • 產生一個jscript.reg的檔案,內容如下:

      Windows Registry Editor Version 5.00

      [HKEY_CLASSES_ROOT\.js]
      @="jsfile"

      [HKEY_CLASSES_ROOT\.js\PersistentHandler]
      @="{5e941d80-bf96-11cd-b579-08002b30bfeb}"

      [HKEY_CLASSES_ROOT\JSFile]
      "FriendlyTypeName"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,\
        00,6f,00,6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,\
        32,00,5c,00,77,00,73,00,68,00,65,00,78,00,74,00,2e,00,64,00,6c,00,6c,00,2c,\
        00,2d,00,34,00,38,00,30,00,34,00,00,00

      [HKEY_CLASSES_ROOT\JSFile\ScriptEngine]
      @="JScript"

      [HKEY_CLASSES_ROOT\JSFile\ScriptHostEncode]
      @="{85131630-480C-11D2-B1F9-00C04F86C324}"

      [HKEY_CLASSES_ROOT\JSFile\Shell]
      @="Open"

      [HKEY_CLASSES_ROOT\JSFile\Shell\Open\Command]
      @=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
        00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,57,00,53,00,\
        63,00,72,00,69,00,70,00,74,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,00,31,\
        00,22,00,20,00,25,00,2a,00,00,00

      [HKEY_CLASSES_ROOT\JSFile\Shell\Open2]
      @=hex(2):4f,00,70,00,65,00,6e,00,20,00,26,00,77,00,69,00,74,00,68,00,20,00,43,\
        00,6f,00,6d,00,6d,00,61,00,6e,00,64,00,20,00,50,00,72,00,6f,00,6d,00,70,00,\
        74,00,00,00
      "MUIVerb"=hex(2):40,00,25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,\
        6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,\
        00,77,00,73,00,68,00,65,00,78,00,74,00,2e,00,64,00,6c,00,6c,00,2c,00,2d,00,\
        34,00,35,00,31,00,31,00,00,00

      [HKEY_CLASSES_ROOT\JSFile\Shell\Open2\Command]
      @=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
        00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,43,00,53,00,\
        63,00,72,00,69,00,70,00,74,00,2e,00,65,00,78,00,65,00,20,00,22,00,25,00,31,\
        00,22,00,20,00,25,00,2a,00,00,00

      [HKEY_CLASSES_ROOT\JSFile\Shell\Print\Command]
      @=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
        00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,4e,00,6f,00,\
        74,00,65,00,70,00,61,00,64,00,2e,00,65,00,78,00,65,00,20,00,2f,00,70,00,20,\
        00,25,00,31,00,00,00

      [HKEY_CLASSES_ROOT\JSFile\ShellEx\DropHandler]
      @="{60254CA5-953B-11CF-8C96-00AA00B8708C}"

      [HKEY_CLASSES_ROOT\JSFile\ShellEx\PropertySheetHandlers\WSHProps]
      @="{60254CA5-953B-11CF-8C96-00AA00B8708C}"

      [HKEY_CLASSES_ROOT\JScript]
      @="JScript Language"

      [HKEY_CLASSES_ROOT\JScript\CLSID]
      @="{f414c260-6ac0-11cf-b6d1-00aa00bbbb58}"

      [HKEY_CLASSES_ROOT\JScript\OLEScript]

    • 雙擊該檔案,點擊確定,將其匯入註冊表即可。
  • 如果在使用MSVC9編譯32位PHP時,遇到Checking for cl.exe ... <not found>錯誤,就表示在安裝Windows SDK 6.1時,忘記選擇x86編譯器。

PS:

  • 以上的步驟中,其實有很多是不需要按部就班的,尤其是檔案夾結構。c:\php-sdk,其實可以放在任意盤符下。只要在開始編譯前,執行一上:x:\php-sdk\bin\php-setvars.bat就可以了(x:為php-sdk所在盤符)。
  • phpdev及其下的各級檔案夾也是不需要的,尤其是x86和x64檔案夾,並不是放錯了就不行的,那隻是方便辨識最後編譯的結果。只要將deps和php源碼放在同一個檔案夾下,比如在d:建立php-source檔案夾,其下放置desp、obj和php-5.6.16子檔案夾(嗯,obj放哪兒也無所謂,在編譯時間直接將輸出結果的位置指向到obj就行了),進入php-5.6.16檔案夾進行編譯即可。

實踐過程中,主要參考如下三篇文章,僅向原作者致謝:

  • Build your own PHP on Windows
  • windows環境下php和Php擴充編譯,擴充dll檔案編譯
  • 解決Win7下There is no script engine for file extension ".js"

在Windows系統中使用VC9、VC11編譯32位、64位PHP及其擴充

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.