新建webrtc項目,編譯報錯提示很多rtc命名空間下的很多函數爲無法解釋的外部符號

    之前講到將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文件,編譯,果然再無該錯誤出現!

發佈了47 篇原創文章 · 獲贊 17 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章