PHP 모듈 - php_mysql 빌드하는 방법
그동안, 계속해서 오픈 소스 코드로부터 결과물을 만들어내는 것을 살펴봤는데요.
PHP 소스를 윈도우 환경에서 빌드하기
; https://www.sysnet.pe.kr/2/0/1042
Apache 소스를 윈도우 환경에서 빌드하기
; https://www.sysnet.pe.kr/2/0/1048
윈도우에서 Apache Module 컴파일 (VC++)
; https://www.sysnet.pe.kr/2/0/1051
윈도우에서 Apache Module - Content Handler 컴파일
; https://www.sysnet.pe.kr/2/0/1056
소스 코드로부터 php5apache2_2.dll 생성하는 방법
; https://www.sysnet.pe.kr/2/0/1057
이번이 마지막 편으로, php 확장 모듈을 빌드하는 방법을 알아볼 텐데 기본적으로 제공되는 ext 폴더 안의 확장 모듈 소스 코드 중에 "D:\phpbuild\php53dev\vc9\x86\php-5.3.6\ext\mysql"을 선택해 보았습니다.
"
소스 코드로부터 php5apache2_2.dll 생성하는 방법"에서 (비록 실패했지만) configure 옵션을 지정해 보는 것을 해보았는데요. "configure --help"에 보면 "--with-mysql"도 있기 때문에 우선 그 옵션을 주는 것으로 시작해 보았습니다.
D:\Program Files\Microsoft SDKs\Windows\v6.1>setenv /x86 /xp /debug
D:\Program Files\Microsoft SDKs\Windows\v6.1>cd /d d:\phpbuild
d:\phpbuild>.\bin\phpsdk_setvars.bat
d:\phpbuild>REM phpsdk.bat
d:\phpbuild>cd D:\phpbuild\php53dev\vc9\x86\php-5.3.6
D:\phpbuild\php53dev\vc9\x86\php-5.3.6>configure --disable-all --enable-cli --enable-debug --with-mysql
Saving configure options to config.nice.bat
Checking for cl.exe ... <in default path>
Detected compiler MSVC9 (Visual C++ 2008)
Detected 32-bit compiler
...[생략]...
Build dir: Debug_TS
PHP Core: php5ts_debug.dll and php5ts_debug.lib
Checking for wspiapi.h ... <in default path>
Enabling IPv6 support
Enabling SAPI sapi\cli
Enabling extension ext\date
Enabling extension ext\ereg
Enabling extension ext\pcre
Enabling extension ext\reflection
Enabling extension ext\spl
Checking for timelib_config.h ... ext/date/lib
Enabling extension ext\standard
mysqlnd not found: mysqlnd support in mysql disabled
WARNING: mysql not enabled; mysqlnd is not enabled
...[생략]...
| Build type | Debug |
| Thread Safety | Yes |
| Compiler | MSVC9 (Visual C++ 2008) |
| Architecture | x86 |
-------------------------------------------
Type 'nmake' to build PHP
오~~~ 이번에는 효과가 있습니다. 오류는 발생했지만, 어쨌든 configure가 "--with-mysql" 옵션에 반응을 했다는 것이 중요하지요. ^^ mysqlnd(Mysql Native Client Driver)라... 찾아보니 다음과 같이 정리된 글이 나옵니다.
MySQL Native Driver
; http://php.net/manual/en/book.mysqlnd.php
위의 문서에 링크되어 있는 "Installation"에 가보면 설치 관련 이야기가 나오는데,
Installation on Windows
In the official PHP distributions from 5.3 onwards, MySQL Native Driver is enabled by default, so no additional configuration is required to use it. All MySQL database extensions will use MySQL Native Driver in this case.
즉,,, ^^; 별다르게 해줄 것이 없다는 이야기입니다. 더욱 문제는, 위의 오류로 검색해 봐도 해결책을 제시하는 글이 없었습니다. 아쉽지만, 이번에는 'PHP와 함께 빌드될 수 있다'라는 가능성만 인식하고
php5apache2_2.dll 빌드 때 처럼 직접 "D:\phpbuild\php53dev\vc9\x86\php-5.3.6\ext\mysql" 폴더 안의 소스 코드로 컴파일하기로 했습니다.
(혹시, 위의 configure를 사용해서 빌드하는 방법을 아시는 분이 있다면 댓글 좀 부탁드립니다. ^^)
"D:\phpbuild\php53dev\vc9\x86\php-5.3.6\ext\mysql" 폴더를 보면, mysql.mak 파일과 mysql.dsp 파일이 함께 있습니다. 오호... 그럼 nmake로 빌드가 되겠군요.
D:\phpbuild\php53dev\vc9\x86\php-5.3.6\ext\mysql>nmake /f mysql.mak
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
mysql.mak(13) : fatal error U1052: file '..\../netware/common.mif' not found
Stop.
아쉬운 빌드 결과입니다. netware 폴더에 보니까, sendmail_nw.h, start.c 파일만 존재하고 common.mif 파일은 없었습니다. 아무래도 mysql.mak 파일은 윈도우 빌드용으로 제작된 것은 아닌 것 같습니다. 그래서, 이번에도 mysql.dsp 파일을 Visual Studio로 열어서 '맞춰주는 작업'을 시작했습니다.
Visual Studio 2008에서 로드 후, 곧바로 빌드하면 다음과 같은 오류가 발생합니다.
fatal error LNK1104: cannot open file 'libmySQL.lib'
지난번
php5apache2_2.dll 빌드와 유사한 경우라고 볼 수 있습니다. 프로젝트 속성 창에서 추가 라이브러리에 설정된 경로를 확인해 보니, "..\..\..\MySQL\lib\Debug"라는 항목이 포함되어 있어서 다음과 같이
MySQL이 설치된 폴더에 있는 lib 폴더를 그대로 복사해 주었습니다.
D:\mysql\lib
==> D:\phpbuild\php53dev\vc9\x86\MySQL\lib
다시 빌드하면, 이번엔 다음과 같은 오류들이 발생합니다. (아마도, 다른 분들은 발생하지 않을 수 있습니다.)
error LNK2019: unresolved external symbol __imp__mysqlnd_get_client_info referenced in function _zm_info_mysql
error LNK2019: unresolved external symbol __imp__mysqlnd_connect referenced in function _php_mysql_do_connect
error LNK2019: unresolved external symbol __imp___mysqlnd_init referenced in function _php_mysql_do_connect
error LNK2019: unresolved external symbol __imp__mysqlnd_old_escape_string referenced in function _zif_mysql_escape_string
error LNK2019: unresolved external symbol __imp___mysqlnd_fetch_lengths referenced in function _zif_mysql_fetch_lengths
mysql.dsp 프로젝트에 기본적으로 설정되어 있는 링크해야 할 lib 파일은 다음과 같습니다.
==== Debug_TS 빌드인 경우 ====
- php5ts_debug.lib
- libmySQL.lib
- odbc32.lib
- odbccp32.lib
설치된 MySQL 폴더에서 가져온 libmysql.lib에는 _mysqlnd_get_client_info 함수가 정의되어 있지 않다는 것이니, 남은 php5ts_debug.lib에 정의되어 있어야 한다는 가정을 할 수 있습니다.
제 경우에, 참조하고 있는 php5ts_debug.lib 파일은 제가 직접 PHP를 빌드해서 생성한 것으로 이전에 써둔 글에 따라 기본적인 configure 옵션만 포함한 것이었습니다.
PHP 소스를 윈도우 환경에서 빌드하기
; https://www.sysnet.pe.kr/2/0/1042
그러니까, "configure --disable-all --enable-cli"만으로 PHP를 컴파일하면 MySQL 관련해서 지원 함수들도 모두 누락된다는 것인데요. 실제로 PHP 웹 사이트에서 배포하고 있는 '바이너리 버전'의 "
php-5.3.6-Win32-VC9-x86.zip" 파일 안에 포함된 php5ts.dll을 구해서 "depends.exe (Dependency Walker)"로 확인을 해보니 다음과 같이 mysqlnd_get_client_info 함수 정의를 포함하고 있었습니다.
별수 없군요. 일단은 제가 빌드해서 생성한 PHP 바이너리는 포기하고, PHP 웹 사이트에서 배포 중인 PHP 출력물로 대체하기로 결정했습니다. 이를 위해 php5ts.lib 파일을 (최대한 dsp 파일을 수정하지 않고) 빌드가 자연스럽게 되도록 Debug_TS 폴더에 복사해 주어야 합니다.
"D:\apm_build\php-5.3.6-Win32-VC9-x86\dev\php5ts.lib"
==> D:\phpbuild\php53dev\vc9\x86\php-5.3.6\Debug_TS\php5ts_debug.lib
이제 빌드하면, 정상적으로 "D:\phpbuild\php53dev\vc9\x86\php-5.3.6\Debug_TS" 폴더에 "php_mysql.dll" 파일이 생성됩니다.
실제로 잘 동작하는지 테스트를 해봐야 하는데요. 일단, 위의 빌드 과정에서 제가 직접 빌드한 PHP 결과물에는 여러가지로 부족한 면이 많아서, 아래의 글을 쓰면서 구성했던 Apache/PHP 환경에다,
.NET 개발자가 처음 설치해 본 Apache + PHP
; https://www.sysnet.pe.kr/2/0/1040
이 글에서 빌드한 "php_mysql.dll"을 복사한 후 php.ini에 extension으로 등록시킨 다음 httpd.exe를 실행했습니다. 결과는?
"
PHP Startup: mysql: Unable to initialize module
Module compiled with build ID=API20090626,TS,debug,VC9
PHP compiled with build ID=API20090626,TS,VC9
These options need to match
"
음... 그러니까, Release 모드로 빌드된 PHP 런타임 환경에 Debug 모드로 빌드된 PHP 확장 DLL을 로드할 수 없다는 이야기인데요. ^^; 문제는 Debug/Release 차이만은 아닌 것 같습니다. "build ID"에 API 날짜라든가 컴파일한 Visual C++ 버전 정보까지 들어있는 거 보면 '확장'이라는 말이 왠지 어울리지 않는 구조인 것 같습니다. 그렇다면, 만약 php_mysql.dll 파일의 소스 코드를 변경해서 배포하는 3rd-party 업체가 있다면 수많은 PHP 웹 사이트에서 사용하고 있을 "build ID"에 해당하는 버전의 php_mysql.dll 파일을 유지해야 한다는 결론인데요. 휴~~~~ 제 개인적인 기준으로 보면 말도 안되는 '확장'이군요.
단순 테스트를 위한 현재 상황에서 그나마 다행이라면, "build ID" 중에서 틀린 것이 단지 debug/release 정도이니, 이를 맞춰주려면 2가지 방법으로 해결할 수 있습니다. 즉, PHP 런타임을 mysql 지원이 되도록 해서 디버그 버전으로 빌드하거나, 아니면 php_mysql 프로젝트를 Release_TS 모드로 빌드하는 것입니다.
여기서는, 후자의 방법이 일단 편리하기 때문에 택했습니다. 하지만
"Shift + F2" 디버깅의 편리함을 누리려면 프로젝트 설정에서 몇 가지 추가적인 변경를 해줘야 합니다.
C/C++ / General / Debug Information Format - Program Database (/Zi)
C/C++ / Optimization / Optimization - Disabled (/Od)
Linker / General / Output File - D:\apache\phpmodule\ext\php_mysql.dll
Linker / Debugging / Generate Debug Info - Yes (/DEBUG)
Linker / Debugging / Generate Program Database File - D:\apache\phpmodule\ext\php_mysql.pdb
이렇게 변경하고 다시 빌드한 후, "Shift + F2" 키를 눌러 디버깅을 시작합니다. 그런 다음 웹 브라우저를 실행시켜 지난번에 만들어 두었던
mysql_sample.php 파일을 방문하면 아래와 같이 php_mysql의 소스 코드에 걸어 둔 BP(BreakPoint)가 걸리는 것을 확인할 수 있습니다.
오~~~ 멋지죠~~~!!! ^^
(
첨부한 파일은 위와 같은 설정으로 변경된 mysql 프로젝트입니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]