ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Building eMule 0.47c with Visual Studio .NET 2003
    Computer/Programming 2008. 10. 3. 22:05
    eMule 바이너리를 비교할 때 pdb 파일을 이용하기 위하여 eMule 0.47c를 build 해야 했다.
    여러 번의 시행착오 끝에 겨우 성공하면서 많은 것을 배웠다.

    먼저 eMule 소스 디렉토리의 readme 를 읽어 보면

    1. Crypto++ v5.1 @ http://www.cryptopp.com/
    2. zlib v1.2.2 @ http://www.gzip.org/zlib/
    3. id3lib v3.8.3 @ http://sourceforge.net/projects/id3lib/
    4. (for MobileMule only!) DirectX SDK pnglib: @ http://www.libpng.org/pub/png/libpng.html
    5. ResizableLib 1.3 @ http://sourceforge.net/projects/resizablelib/


    를 다운로드 하고 static library를 만들고 그것을 eMule 프로젝트에서 이용한다고 말한다.
    그래서 이것들을 다운로드 하고 각각을 VS.NET 2003에서 열어
    (프로젝트 파일이 이전 버전으로 된 것은 변환해 주어야 한다)
    각각을 빌드 해 준다.

    여기서 한 가지 주의점! 영문 VS.NET 2003에서 열어야 한다.
    한글 VS.NET 2003으로 하면 project property가 수정할 수 없도록 disable 된다.

    빌드 옵션이 중요하다. 특히 여러 라이브러리를 이용하기 때문에,
    컴파일 자체는 문제 없이 되어서 OBJ 파일들은 정상적으로 생성되지만,
    링크 할 때 Name Conflict가 일어나기 쉽상이다.
    또 다른 버전의 Visual Studio를 사용하여 스태틱 라이브러리를 만든다면,
    각 스태틱 라이브러리가 서로 다른 버전의 DLL들을 사용하게 되는 경우가 생긴다.
    예를 들면 MSVCRT70.dll MSVCRT80.DLL 등 같은 이름이지만 다른 버전을 포함하게 되면
    정말 골치 아파진다. export 키워드를 써서 해결하려고 해도 손볼 곳이 한 두 곳이 아니다.
    이런 경우 해결책은 전체를 같은 버전으로 빌드 하고 연결하던지,
    아니면 소스 코드 전체를 한 프로젝트에 몰아 넣어서 해결할 수도 있다.
    프로젝트 2개 정도라면 소스 코드 전체를 한 프로젝트로 만들 수도 있겠지만 이것은 좀 무리인 듯 하다.
    따라서 각각의 라이브러리들을 전부 영문 VS.NET 2003에서 열도록 한다.

    또한, 스태틱 라이브러리를 이용하기 위해서는 전체 라이브러리간의 빌드 옵션이 일치해야 한다는 것.
    각각을
    • Release
    • /MT (Multi-threaded)
    로 해서 빌드해 준다. 이것을 해 주지 않으면 실패!

    그리고 eMule 솔루션 파일을 열고 빌드한 라이브러리를 추가해 준다.
    솔루션 옵션을 열어 Linker ->Additional Dependencies에 추가한다.
    cryptolib.lib zlib.lib id3lib.lib pnglib.lib ResizableLib.lib 이 추가된다.

    그래도 수많은 LNK2005, LNK2001 에러가 발생한다.
    먼저 LNK2005 에러는 여러 스태틱 라이브러리를 쓸 때 같은 이름의 함수들이 많기 때문이다.
    소스 코드들을 살펴보면 그 중 하나의 이유가 zlib을 여러 라이브러리에 포함하고 있기 때문에, zlib이 여러 번 나타난다. 이런 식으로 이름이 충돌 나는 것이 많은데 이것을 단순한 방법으로 해결한다.
    각각을 VS.NET 2003으로 컴파일하면서 DLL 버전이 일치된 상태이기 때문에 겹치는 것은 무시하면 된다.
    따라서 링크 옵션의 명령행 옵션에
    /FORCE:MULTIPLE'
    를 추가한다.
    이렇게 하면 LNK2005 에러를 피해갈 수 있다.

    LNK2005 에러를 그리고 나서도 남는 것은 LNK2001 에러이다.
    LNK2001 에러는 맞는 이름을 찾지 못하여 함수간에 연결 자체가 되지 않는 것이다.
    소스 코드를 살펴 보면 eMule의 인터페이스 클래스 중에서 ResizableLib 의 클래스를 상속하여 사용하는 것을 알 수 있다. 이 부분메서 LNK2001 문제가 생기는데 문제가 생기는 부분을 읽어봐도 특별한 에러의 이유를 찾기 힘들다. 상속하고 있는 상위 클래스의 멤버 함수를 단순히 호출하고 있을 뿐.
    링크 에러 메시지를 살펴 보면 함수 첫번째 파라미터 부분이 wchar_t* 타입을 요구하고 있음을 알 수 있다.
    즉 유니코드로 메시지를 전달하고 있는 것.
    그런데 ResizableLib에서는 유니코드를 사용하고 있지 않고 Multibyte character를 사용하고 있음을 코드와 프로젝트 속성에서 확인할 수가 있다.
    따라서 ResizableLib을 Unicode로 다시 빌드해 준다.
    이 때 ResizableLib의 옵션에서 Character Set 을 Use Unicode Character Set으로 해 주고
    C++의 Language 옵션에 들어가서 Treat wchar_t as Built-in type을 해 주어야 원래 Multibyte 용으로 개발된 ResizableLib이 Unicode용으로 바뀌게 된다.

    그리고 나서 Build하면 OK!!!
    eMule의 바이너리가 만들어지고 정상적으로 실행되는 것을 볼 수 있다!!!
Designed by Tistory.