Microsoft MVP성태의 닷넷 이야기
VC++: 50. PHP 모듈 - php_mysql 빌드하는 방법 [링크 복사], [링크+제목 복사],
조회: 21257
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
[mysql.zip]    
(연관된 글이 2개 있습니다.)

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 폴더를 그대로 복사해 주었습니다.

how_to_build_mysql_ext_1.png

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 함수 정의를 포함하고 있었습니다.

how_to_build_mysql_ext_2.png

별수 없군요. 일단은 제가 빌드해서 생성한 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를 실행했습니다. 결과는?

how_to_build_mysql_ext_3.png

"
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)가 걸리는 것을 확인할 수 있습니다.

how_to_build_mysql_ext_4.png

오~~~ 멋지죠~~~!!! ^^

(첨부한 파일은 위와 같은 설정으로 변경된 mysql 프로젝트입니다.)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 6/27/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




1  2  3  4  5  6  7  8  9  10  11  12  13  [14]  15  ...
NoWriterDateCnt.TitleFile(s)
13287정성태3/16/20233933Windows: 229. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 윈도우를 직접 띄우는 방법파일 다운로드1
13286정성태3/15/20234376Windows: 228. Win32 - 리소스에 포함된 대화창 Template의 2진 코드 해석 방법
13285정성태3/14/20233939Windows: 227. Win32 C/C++ - Dialog Procedure를 재정의하는 방법파일 다운로드1
13284정성태3/13/20234165Windows: 226. Win32 C/C++ - Dialog에서 값을 반환하는 방법파일 다운로드1
13283정성태3/12/20233681오류 유형: 852. 파이썬 - TypeError: coercing to Unicode: need string or buffer, NoneType found
13282정성태3/12/20234001Linux: 58. WSL - nohup 옵션이 필요한 경우
13281정성태3/12/20233963Windows: 225. 윈도우 바탕화면의 아이콘들이 넓게 퍼지는 경우 [2]
13280정성태3/9/20234727개발 환경 구성: 670. WSL 2에서 호스팅 중인 TCP 서버를 외부에서 접근하는 방법
13279정성태3/9/20234234오류 유형: 851. 파이썬 ModuleNotFoundError: No module named '_cffi_backend'
13278정성태3/8/20234239개발 환경 구성: 669. WSL 2의 (init이 아닌) systemd 지원 [1]
13277정성태3/6/20234884개발 환경 구성: 668. 코드 사인용 인증서 신청 및 적용 방법(예: Digicert)
13276정성태3/5/20234544.NET Framework: 2102. C# 11 - ref struct/ref field를 위해 새롭게 도입된 scoped 예약어
13275정성태3/3/20234843.NET Framework: 2101. C# 11의 ref 필드 설명
13274정성태3/2/20234422.NET Framework: 2100. C# - ref 필드로 ref struct 타입을 허용하지 않는 이유
13273정성태2/28/20234178.NET Framework: 2099. C# - 관리 포인터로서의 ref 예약어 의미
13272정성태2/27/20234403오류 유형: 850. SSMS - mdf 파일을 Attach 시킬 때 Operating system error 5: "5(Access is denied.)" 에러
13271정성태2/25/20234344오류 유형: 849. Sql Server Configuration Manager가 시작 메뉴에 없는 경우
13270정성태2/24/20233916.NET Framework: 2098. dotnet build에 /p 옵션을 적용 시 유의점
13269정성태2/23/20234534스크립트: 46. 파이썬 - uvicorn의 콘솔 출력을 UDP로 전송
13268정성태2/22/20235065개발 환경 구성: 667. WSL 2 내부에서 열고 있는 UDP 서버를 호스트 측에서 접속하는 방법
13267정성태2/21/20234955.NET Framework: 2097. C# - 비동기 소켓 사용 시 메모리 해제가 finalizer 단계에서 발생하는 사례파일 다운로드1
13266정성태2/20/20234595오류 유형: 848. .NET Core/5+ - Process terminated. Couldn't find a valid ICU package installed on the system
13265정성태2/18/20234513.NET Framework: 2096. .NET Core/5+ - PublishSingleFile 유형에 대한 runtimeconfig.json 설정
13264정성태2/17/20236047스크립트: 45. 파이썬 - uvicorn 사용자 정의 Logger 작성
13263정성태2/16/20234208개발 환경 구성: 666. 최신 버전의 ilasm.exe/ildasm.exe 사용하는 방법
13262정성태2/15/20235250디버깅 기술: 191. dnSpy를 이용한 (소스 코드가 없는) 닷넷 응용 프로그램 디버깅 방법 [1]
1  2  3  4  5  6  7  8  9  10  11  12  13  [14]  15  ...