新建webrtc项目,编译报错提示很多rtc命名空间下的很多函数为无法解释的外部符号

来源:互联网 发布:python try catch 编辑:程序博客网 时间:2024/06/05 03:34

    之前讲到将webrtc由ninja编译改为了vs2015编译,才发现同样的一份源码使用vs2015编译确实比ninja编译得慢,无奈鄙人vs用习惯了,使用ninja编译会出现很多未知的问题,最恶心的是之前使用ninja编译webrtc项目时居然不能保证编译成功后的代码真正是当前文件所写的代码,这个错误恶心之处在于你以为编译成功了,但是当你调试进入某个代码段时才发现无法调试进入该段。

    vs2015新建webrtc项目,添加对应的头文件和源文件,编译后提示很多形如rtc::***的函数为“无法解析的外部符号”,咋一看这都是没有倒入相应的lib文件的原因,的确是这样但是对于webrtc这个项目来说,要加入的lib文件的个数实在不少,所以不打算使用这种方式。查看了下demo中其他的工程,找了peerconnection_client这个项目,查看其vcxproj文件,发现其中包含了很多这样的字段

<ProjectReference Include=".***.vcxproj">
      <Project>{D012ED19-4A98-F0D4-84F0-0B4BB618D548}</Project>
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>

    “***”为可以在demo总工程下找得到的工程名字,这些工程多半是l生成lib静态库的,于是相关问题可以解释了额,在peerconnection_client的项目属性中并没找到之前编译报错所提示确实的lib文件,其实通过在vcxproj中设置很多个如上所示的xml元素,peerconnection_client在编译的时候能够动态实时地编译对应的lib文件,编译一个peerconnection_client竟然顺带编译了这么多的工程,难怪乎每次编译这个工程要花费至少半个小时,虽然它仅仅只包含了十多个文件,这就是不手动倒入对应lib的代价!用时间来交换编译时lib的一致性,还是可以接受的!

     如上所做,编译不再报rtc命名空间内的函数为“为解析的外部符号”,但是却报了“LIBCMTD.lib(exe_winmain.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中被引用”的错,这可不是没有倒入libcmtd.lib文件的问题,这篇博文很好解释了这点http://blog.sina.com.cn/s/blog_51c1ed050100zhrc.html,就是项目属性->连接器->系统->子系统中的选项和工程类型不一致的问题。

----------------------------------------------

     如果不用上面那种动态链接编译的方式,使用lib静态库导入的方式的话,今天试了一下,当前工程重新编译速度比动态编译链接的方式快太多了,形象一点来说吧,自己新建的同样的一个工程,之前使用动态链接编译的方式,编译起码要半个小时,现在四五分钟就ok了,细思一下发现各自有各自的好处。

     动态链接编译,在本工程编译的时候顺带将要引用的lib重新生成一遍,虽然多花了编译的时间,但是当要生成不同版本的程序的时候就不用再重新手动导入不同版本的其他的lib文件了,比如说Release X86、Relearse X64、Debug X86、Debug X64,直接切换直接编译,方便同一管理版本。

     手动导入想要引入的lib静态文件库,虽然单个工程的编译时间快了很多,但是当要更换某个版本的导入lib文件的时候就麻烦了,这个时候lib可能需要32位的,或者是64位的等,关键的是按照习惯来说,不同版本的lib文件名字需要不一样,这个样的话每改一次又要重新在工程属性中修改要导入的lib文件名,麻烦!

       在我新建的工程中手动导入peerconnection_client所需要的lib静态文件的时候,编译后报错提示LINK : fatal error LNK1104: 无法打开文件“libyuv.lib”“”,按照道理来讲lubyuv,lib文件应该像其他的lib生成工程生成的lib的文件目录下($(OutDir)lib\$(ProjectName)$(TargetExt)),但是libyuv,lib是生成在$(OutDir)$(ProjectName)$(TargetExt下的,只有这一个工程!  这真的不符合常理,只能解释为"webrtc开发团队的刻意为之了",所以暂时不去管它了,导入的时候多指定一个目录即可!

----------------------------------------------------------------------------------

     在后面的编译过程中,又报了一个错误,也是提示LNK:2019错误,基本意思是说在连接boringssl.lib的时候asm中的某些函数是“未解析的外部符号”,很显然这又lib文件包含的问题或者是lib文件没有包含,查找peerconnection_clientvcxproj文件中所有链接编译的lib文件,确实是全都包含了!后来到工程的lib输出文件中查找,在boringssl.lib的下面紧跟着一个boringssl_asm.lib,猜想或许使用动态连接编译的时候,boringssl.lib文件中的什么文件或许是引用到了boringssl_asm.lib文件中的什么东西!到boringssl工程文件下查找果然是找到了相关的文件包含和调用,这就对了,具体的调用细节就不深究了,知道有这个事情就行。至此问题就清晰了,如果没有导入boringssl_asm.lib文件,那么新建的webrtc文件在编译的时候,调用到了boringssl.lib文件中的函数,而这个函数是找不到boringssl_asm.lib文件中函数的,因此会报LNK2019错误,提示boringssl.lib文件中函数调用失败,所以编译失败,于是在工程项目属性中导入boringssl_asm,lib文件,编译,果然再无该错误出现!

0 0
原创粉丝点击