我们目前正在使用单一命令行工具在Windows和Linux上构建我们的产品。
Si far的工作很好,允许我们构建源代码,并且具有比我们以前的构建系统允许的更好的依赖性。这为我们带来了很好的增量和并行构建功能。
为了简要描述构建过程,我们得到了通常的结果:
.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 :(得分:5)
我很长一段时间没有完成C ++,但是从这个article开始,这似乎是停止重新创建常用标题符号的性能技巧。
您可以尝试/ Z7在每个obj中嵌入信息,而不是创建PDB,然后使用rebase链接并重新创建它,如此article。
答案 1 :(得分:5)
无需合并PDB文件。
使用/ Z7编译源文件,以避免在CL.EXE步骤中创建PDB。
使用LIB.EXE创建包含嵌入式调试信息的静态库。使用LINK.EXE而不是CL.EXE进行链接,使用/ PDB指定调试信息的位置。
如果您正在使用EXE和一个或多个DLL调试进程,请为调试器提供每个映像(EXE或DLL)的PDB。
答案 2 :(得分:2)
可以合并PDB文件,但只能通过cl.exe和link.exe来完成。 我不知道合并PDB文件的任何立法工具。
您可以使用/ PDB选项链接器(我检查过VC2005)来指定备用pdb文件名。
Microsoft建议还包括PDB文件(每个obj都有相应的PDB文件)以及.LIB文件。
您无法将.LIB文件中的PDB文件存档,我用VC2003尝试过,失败了。
使用/ Z7编译可以避免.LIB的PDB文件,但是目标文件很大,除非link.exe剥离调试信息。如果链接器没有/ debug选项,则无法调试exe / dll。
编译器(cl.exe)始终写入vcXX.pdb文件,除非您使用/ Fd选项指定其他名称。 即使您使用cl.exe“直接”生成可执行文件,它也会生成一个vc80.pdb文件,然后link.exe将生成与可执行文件相同的pdb文件名。
cl / Zi test.c
cl.exe - > vc80.pdb link.exe读取vc80.pdb(该名称嵌入在test.obj文件中) - > test.pdb
每次cl / Zi / c编译一个文件时,它都会尝试修改现有的vcXX.pdb文件,而不是覆盖它。
我通过一次又一次地使用编译器获得上述结论,然后捕获sysinternals的procexp结果并对其进行分析。希望它有所帮助。
答案 3 :(得分:1)
除非您想使用调试信息重新分发静态库,否则您实际上不需要合并任何PDB文件(或使用/Z7
嵌入调试信息)。
正如@zhaorufei所提到的,当使用/Zi
时,每个目标文件都包含对其PDB文件的引用,然后链接器将使用该文件。
只需使用/Fd
为每个对象提供唯一的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
这样做的好处是可以解决并发访问here共享PDB文件的问题,因此您可以按照自己的意愿并行化编译步骤。
然后像往常一样链接/存档目标文件。 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文件中。
我能看到的唯一警告是路径始终是绝对路径,因此如果您在链接之前将文件移动到本地或另一台机器上,这可能不起作用。