[C] VC++ 워닝과 LNK4099 에 관한 의견


URL : http://www.tomatowax.com/ZeroboardXE/7349 

Visual C++ & Warning LNK4099 : PDB

1. 개요

VC++ 환경에서 외부 라이브러리를 링크하면 가끔 LNK4099 워닝이 발견될 수 있습니다. LNK 에 적혀있듯이 이것은 링크와 관련된 워닝입니다. LNK4099 워닝은 해당 라이브러리가 디버그 목적으로 이용될 수 있는 디버깅 정보를 생성하였는데 생성된 디버깅 정보가 라이브러리 혹은 외부에 .pdb 파일로 어플리케이션에 전달되지 않고 있기 때문에 발생하는 워닝입니다. 보통 warning LNK4099: '*.pdb' PDB was not found 와 같은 형태로 워닝이 출력되며, 사용자는 이를 무시할 수 있습니다. 이 워닝은 단순하게 링크한 라이브러리의 디버깅을 지원하느냐 안하느냐 (정확히는 디버깅 시 화면 출력에 소스가 보여질 수 있느냐 아니냐, 아닐 경우는 어셈으로 표시됨) 의 문제일 뿐이므로 실행과는 전혀 무관합니다. 다만 이 워닝이 라이브러리의 생성자의 입장이라면 신중히 생각해봐야 할 문제입니다.

해당 워닝은 라이브러리를 링크하는 경로가 잘못되었을 때도 발생하기도 한다는데, 근본적인 원인은 디버깅 정보를 '어디에서도' 찾을 수 없기 때문입니다. 다른말로는 라이브러리가 생성된 환경과 링크하는 환경이 달라서 디버깅 정보를 얻어오지 못하였기 때문입니다. 디버깅 정보는 pdb 파일로 생성되어 외부에 위치하거나 라이브러리 자체에 포함되어 제공될 수 있습니다. (다만 이 경우 용량이 훨씬 커지게 됩니다.) 물론 디버깅 정보는 최종 라이브러리에 포함되지 않을 수 있습니다. 이는 해당 워닝의 발생은 라이브러리 개발자의 배포 정책이 우선시 작용한다는 것을 의미합니다.


2. 어플리케이션 개발자

외부 라이브러리를 링크 타임에 링크시켜주기만 하면 되는 어플리케이션 개발자라면, 이 문제에 대한 대안책은 여러가지가 나와있습니다. 현재 한국의 검색을 통해서도 제법 공유되고 있습니다. 다만 정확한 정보나 검증은 이루어지지 않고, 대부분의 스크랩 형태가 많아 보입니다.

2-1. Release 로 컴파일하기

어플리케이션을 Debug 가 아니라 Release 로 컴파일 하면 디버깅 정보와 무관해지므로 해당 워닝이 제거된다고 합니다. 하지만 필자의 경우에는 라이브러리가 Release 로 생성되었더라도 무관하게 워닝은 발생되었습니다. 하지만 몇몇 의견을 보아, 어플리케이션이 Release 모드일 경우 워닝이 사라지기도 하는 것으로 보입니다.

2-2. 워닝 표시 안하기

보통 워닝은 경우에 따라 다르지만, VC++ 이 단순하게 통보하는 목적으로의 워닝과 크게 사용자가 개의치 않아도 되는 워닝도 있습니다. 물론 워닝 중에서는 사용자가 반드시 인지해야하는 치명적인 워닝도 포함될 수 있지만, 그렇지 않은 경우에는 상당히 눈엣가시입니다. 이러한 경우 사용자는 선택적으로 워닝을 일시적인 Disable 을 적용시킬 수 있습니다. 다만 워닝은 대부분 프로그래머가 정확히 인지하고 있어야 되는 내용들이므로, 이렇게 일시적으로 워닝의 표시를 무시해버리는 방법은 저는 별로 추천하지 않습니다.

워닝을 Disable 시켜버리는 방법은 두가지가 있습니다. 사용자는 헤더에서 바로 워닝을 Off 할 수 있으며, 혹은 Command Line 에 추가하여 Off 할 수 있습니다. 아래와 같은 방법으로 사용하며, xxxx 자리에는 해당 워닝 번호를 입력하시면 됩니다. (지금의 경우라면 4099 입니다.)

- #pragma warning(disable:xxxx)
- /nowarn: xxxx


2-3. 기타

어플리케이션 개발자는 라이브러리 자체를 수정할 수 있는 권한이 없으므로 이 외의 방법에 대해서는 다른 방법을 강구해야합니다. 현재로서는 제가 몇차례 컴파일 해본 결과, 외부 라이브러리 자체가 컴파일 될 적에 다른 환경 설정을 통해 변화되는 것이 중요하지 사용자의 입장에서는 크게 해당 워닝에 대해 조작할 수 있는 선택이 적은 것 같습니다. 실제로 상용 라이브러리의 경우에도 이러한 워닝을 '방치' 한 채 사용자에게 배포를 하는 경우도 있다고 합니다. 외부 라이브러리를 사용하는 입장이라면, 해당 워닝 발생 시 라이브러리 개발자에게 연락하여 해결 방법에 대해 논해보는 것이 좋겠습니다.


3. 외부 라이브러리 개발자

개요에 적고 시작하였듯이, 이 워닝의 전적인 책임은 모두 외부 라이브러리 개발자에게 있습니다. 다만 외부 라이브러리 개발자는 신중한 선택을 해야합니다. 해당 워닝은 pdb 에 담기는 디버깅 정보를 lib 파일에 포함함으로써 간단하게 해결 할 수 도 있지만, 대신 라이브러리의 컴파일 시간이 길어지고 라이브러리 자체의 용량이 훨씬 커지게 됩니다. 뿐만아니라, 사실 디버깅 정보를 배출한다는 것은 소스를 공개한다는 것과 유사합니다. 디버깅 정보를 공개하는 수준에 따라서는 동일하기도 합니다. 이것은 '프로그램 데이터베이스' 가 디버깅을 위해 라이브러리의 Map 을 생성하기 때문입니다. 개발자는 선택적으로 사용자에게 어느 정도 수준의 디버깅 정책을 펼칠것인지에 대한 선택을 해야합니다.

3-1. 디버깅 정보 포함하기

Project [Configuration Properties]

1) C/C++ > General > Debug Information Format : Program Database (/Zi)
2) C/C++ > Code Generation > Enable Minimal Rebuild : No
3) C/C++ > Command Line > Additional Options : /Yl - 추가

사용자에게 디버깅 정보를 얼마나 공개하여 제공할 것인지에 대해서는 신중하게 선택하여 효율적인 제공과 개발을 하시기 바랍니다.

3-2. 디버깅 정보 삭제하기

해당 워닝은 외부 라이브러리가 디버깅 정보를 배출하였음에도, 배출된 정보를 얻어올 수 없으므로 '처음부터 라이브러리가 디버깅 정보를 배출하지 않은 것 처럼' 작동하겠다는 것을 의미합니다. 다르게 생각해보면, 외부 라이브러리 개발자가 어차피 외부에 디버깅 정보를 제공하지 않을 예정이라면, 그냥 처음부터 디버깅 정보를 삭제함으로써 사용자가 워닝 때문에 스트레스 받지 않도록 하는 것이 옳습니다. 다음과 같이 해결할 수 있습니다.

Project [Configuration Properties]

C/C++ > General > Debug Information Format : Disabled


4. 마무리

보통 라이브러리 개발과 어플리케이션 개발을 동시에 맡고 있거나, 혹은 라이브러리의 풀 소스가 제공되는 환경이라면 비교적 쉽게 해결할 수 있는 문제입니다. 다만, MS 관련 라이브러리나 외부 기타 라이브러리가 라이브러리 단에서 해결되어질 수 없는 문제라면, 상당히 머리아프고 귀찮은 워닝일 수 있습니다. 경우에 따라서는 수 백 줄의 워닝이 표시되기도 하고, 결과적으로 컴파일 타임을 느리게 만들거나 개발자를 어지럽게 만들기 때문입니다. 이 경우에는 워닝의 표시를 없애버리는 방법밖에 없긴 한데, 워닝을 임시적으로 없앤다는 것 자체가 사실 상당히 찝찝하긴 합니다. 다만 몇몇 경우에서는 라이브러리의 연결 주소라던가, 혹은 헤더 인클루드에 따라서 해당 워닝이 사라지기도 하오니 (라이브러리 헤더에서 특수한 조치를 하여 내가 워닝을 꺼버리는 부담을 덜어준다던가) 필히 라이브러리 사용 정책 문서를 잘 확인해보시기 바랍니다.


'DevelopNow > errorLog' 카테고리의 다른 글

Run-Time Check Failure #2 - Stack Around the variable ~~  (0) 2009.10.28
C4800  (0) 2009.08.07
warning C4311 / C4312  (0) 2009.06.21
warring error 도 잡자! ㅋㅋㅋ  (0) 2009.05.23
API/MFC C1010 error  (0) 2009.05.14

댓글

Designed by JB FACTORY