2009-02-09 5 views
7

현재 Windows 및 Linux에서 단일 명령 줄 도구를 사용하여 제품을 구축하고 있습니다.여러 PDB 파일을 병합하는 방법은 무엇입니까?

Si는 이전의 빌드 시스템에서 허용 한 것보다 더 근원적으로 더 세밀하게 의존 할 수있게 해줍니다. 이것은 우리에게 점진적이고 병렬적인 빌드 기능을 제공합니다.

곧 빌드 프로세스를 설명하기 위해, 우리는 평소 얻을 :

.cpp -- cl.exe --> .obj and .pdb 
multiple .obj and .pdb -- cl.exe --> single .dll .lib .pdb 
multiple .obj and .pdb -- cl.exe --> single .exe .pdb 

MSVC C/C++ 컴파일러가 적절를 지원합니다.

최근 정적 라이브러리를 몇 개 만들 필요가 생겼습니다. 우리가 수집 한 바로는, 정적 라이브러리를 구축하는 프로세스는 다음과 같습니다

multiple .cpp -- cl.exe --> multiple .obj and a single .pdb 
multiple .obj -- lib.exe --> a single .lib 

단 하나의 .pdb는 cl.exe는 모든 .CPP 소스에 대해 한 번 실행되어야한다는 것을 의미한다. 이 단일 실행은이 정적 라이브러리의 빌드를 병렬화 할 수 없음을 의미합니다. 이것은 정말로 불행합니다.

우리는 문서 (사용 가능한 명령 행 옵션)에 추가하고 따라 약간의 조사 :

  • cl.exe 정적 라이브러리
  • 을 구축하는 방법을 알고하지 않습니다
  • lib.exe의 .pdb를 구축하는 방법을 알고하지 않습니다 파일

누구나 여러 PDB 파일을 병합하는 방법을 알고 있습니까? 우리는 정적 라이브러리를위한 느린 빌드를 갖게 될까? Incredibuild와 같은 도구가이 문제를 해결하려면 어떻게해야합니까?

+0

항상 솔리드 스테이트 드라이브에 코드를 넣을 수 있습니다. 빌드가 번개처럼 빠르게 진행됩니다. –

+0

나는 내 스타일 북의 솔리드 스테이트 드라이브에있다. 도움이 되긴하지만 링크는 IO 바운드이며 컴파일은 CPU 바운드입니다. –

답변

5

오랫동안 C++을 수행하지는 않았지만이 article에서 일반적인 헤더에 대한 심볼을 재생성하는 것은 성능 트릭입니다.

각 obj에 정보를 포함 시키려면/Z7을 사용하고 PDB는 만들지 말고이 article과 같은 리베이스로 연결하고 다시 만드십시오.

+0

/Z7의 디버그 정보가/Zi 및/ZI가 생성 한 디버그 정보와 다른가요? egghead 카페 thead (http://support.microsoft.com/kb/258205)에 연결된 문서에 따르면/Z7에서 .dbg 파일이 아닌 .dbdb 파일로 디버그 정보를 추출 할 수 있습니다. –

+1

두 링크가 모두 죽었습니다. ( –

5

PDB 파일을 병합 할 필요가 없습니다.

/Z7을 사용하여 소스 파일을 컴파일하면 CL.EXE 단계에서 PDB가 작성되지 않습니다.

LIB.EXE를 사용하여 디버깅 정보가 포함 된 정적 라이브러리를 만듭니다. 연결하려면 CL.EXE 대신 LINK.EXE를 사용하고/PDB를 사용하여 디버깅 정보의 위치를 ​​지정하십시오.

EXE 및 하나 이상의 DLL이 포함 된 프로세스를 디버깅하는 경우 디버거에 각 이미지 (EXE 또는 DLL)에 대한 PDB를 제공하십시오.

2

병합 PDB 파일은 가능하지만 cl.exe 및 link.exe를 통해서만 수행 할 수 있습니다. PDB 파일을 병합하기위한 독립 실행 형 도구를 알지 못합니다.

링커 (/ VC2005 확인)에/PDB 옵션을 사용하여 대체 pdb 파일 이름을 지정할 수 있습니다.

Microsoft는 또한 .LIB 파일과 함께 PDB 파일 (각 obj에는 해당 PDB 파일이 있음)을 제안합니다.

.LIB 파일 안에 PDB 파일을 보관할 수 없습니다. VC2003으로 시도했는데 실패했습니다.

/Z7로 컴파일하면 .LIB에 대한 PDB 파일을 피할 수 있지만 link.exe가 디버그 정보를 제거하지 않으면 개체 파일이 큽니다. 링커에/debug 옵션이 없으면 exe/dll을 디버깅 할 수 없습니다.

/Fd 옵션을 사용하여 다른 이름을 지정하지 않으면 컴파일러 (cl.exe)가 항상 vcXX.pdb 파일에 기록합니다. cl.exe를 사용하여 "직접"실행 파일을 생성하는 경우에도 vc80.pdb 파일이 생성되고 link.exe는 실행 파일과 동일한 pdb 파일 이름을 생성합니다.

CL/존타 TEST.C

CL.EXE -> vc80.pdb 을 vc80.pdb (이름이 test.obj입니다 파일에 포함)를 읽어 LINK.EXE -> test.pdb

을 cl/Zi/c가 파일을 컴파일 할 때마다 기존의 vcXX.pdb 파일을 덮어 쓰지 않고 수정하려고합니다.

필자는 위와 같은 내용을 반복하여 컴파일러에서 얻었고 sysinternals의 procexp 결과를 캡처하여 분석했습니다. 희망이 도움이됩니다. 당신이 에 디버그 정보와 정적 라이브러리를 재배포 할 않는

0

, 당신은 실제로 PDB 파일을 병합 (또는 디버그 정보를 포함 할 /Z7를 사용) 할 필요가 없습니다.

@zhaorufei 언급 한대로 /Zi을 사용하면 각 개체 파일에는 해당 링커가 사용하는 PDB 파일에 대한 참조가 포함됩니다. 당신이 컴파일을 병렬 처리 할 수 ​​있습니다, 이것은 또한 here 언급이 공유 PDB 파일에 대한 동시 액세스의 문제를 해결하려면 작동하는 이점이

> cl -c foo.cpp -Fo:target/foo.obj -Fd:target/foo.pdb -Zi 
> cl -c bar.cpp -Fo:target/bar.obj -Fd:target/bar.pdb -Zi 

> strings target/foo.obj | grep pdb 
D:\Dev\sample\target\foo.pdb 
> strings target/bar.obj | grep pdb 
D:\Dev\sample\target\bar.pdb 

:

간단히 각각의 고유 한 PDB 파일을 객체주고 /Fd를 사용 네가 원했던 것처럼.

그런 다음 평소와 같이 오브젝트 파일을 링크/아카이브하십시오. VC++는 다양한 종류의 정보를 이미 런타임 링크 설정 및 의존성 라이브러리와 같이 링커에 전달하기 위해 오브젝트 파일에 임베드했습니다. PDB 파일 경로도 다릅니다. 객체에서 정적 라이브러리 만들기 참조를 제거하지 않습니다

> lib -out:target/all.lib target/foo.obj target/bar.obj 
> strings target/all.lib | grep pdb 
D:\Dev\sample\target\bar.pdb 
D:\Dev\sample\target\foo.pdb 

실행 파일 또는 DLL이 라이브러리를 연결하는 링커는 여전히 참조 PDB의에서 디버그 정보에 끌어 최종 PDB 파일에 추가 .

내가 볼 수있는 유일한주의 사항은 경로가 항상 절대 경로이므로 링크를 열기 전에 로컬 또는 다른 컴퓨터로 파일을 이동하면 작동하지 않을 수 있다는 것입니다.

관련 문제