Visual Studio 2015下編譯zmq項目下其他項目踩進的項目引用坑


PS.在之前的一篇文章中介紹了如何用Visual Studio 2015編譯zmq,在編譯同解決方案中除了libzmq之外的項目例如inproc_thr時會報錯誤,具如下:

Severity	Code	Description	Project	File	Line	Suppression State
Error	LNK1181	cannot open input file 'libzmq.lib'	inproc_thr	E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\inproc_thr\LINK	1	

    找不到"libzmq.lib"!,怎么回事?。。。在此記錄備忘

爬坑之路:

    (1)右鍵項目,build(編譯),於是開始編譯了,但是報錯,無法打開文件"libzmq.lib",就像文章開頭所提到的,對於vs2015的新特性來說首先想到的就是打開項目,然后點開Reference(引用,其實當時對於C++的reference不了解,這個引用時會在libzmq繼承很多項目包括編譯的屬性的),看看是否有引用,發現有。。。

    

    (2) 對於常規下同一個解決方案中創建的項目來說,直接在Reference中添加項目引用即可,他們會自動尋找項目底下的lib跟dll進行連接,但是zmq整個解決方案生成的結果卻在根目錄(本人的根目錄為E:\zeromq4-1-master\zeromq4-1-master)底下的bin文件夾中,那么將之前生成的lib文件和dll文件(包括libsodium的)copy到libzmq目錄下或者解決方案(本人目錄為E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013)下面不就可以了嗎?於是我這么做了。。。

    

    把lib和dll兩個文件copy到libzmq目錄下面,然后在項目inproc_thr項目右鍵Properties打開屬性,在linker(連接器)-input(輸入)-Additional Dependencies(添加依賴項)中添加了libzmq.lib,然后在linker-General-Additional Library Directories中添加了libzmq的路徑,再次編譯,結果還是報錯了,及時放在解決方案的根目錄之下依舊會出現,報錯如下:

Severity	Code	Description	Project	File	Line	Suppression State
Error	MSB3030	Could not copy the file "E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\inproc_thr\..\..\..\..\..\libzmq\bin\x64\Release\v140\dynamic\libzmq.dll" because it was not found.	inproc_thr	E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\libzmq.import.props	53	

  這個錯誤跟編譯libzmq時因為缺失libsodium時爆出的錯誤幾乎一摸一樣,其實這個因為大意,不難發現添加Additional Library Directories(附加庫目錄)時,會發現Inherited Value(繼承值,注意上面步驟(1)中的綠色標記字)中內容如下,這個內容是從libzmq的項目中繼承過來的,因為在項目Reference中,inproc_thr引用了libzmq

$(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\
$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libzmq)\

  這個東西跟雙擊該編譯錯誤時提示的libzmq.import.props中44行開始的編譯過程一樣,如下

<Target Name="Linkage-libzmq-dynamic" AfterTargets="AfterBuild" Condition="'$(Linkage-libzmq)' == 'dynamic'">
    <Copy Condition="$(Configuration.IndexOf('Debug')) != -1"
          SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.dll"
          DestinationFiles="$(TargetDir)libzmq.dll"
          SkipUnchangedFiles="true" />
    <Copy Condition="$(Configuration.IndexOf('Debug')) != -1"
          SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Debug\$(PlatformToolset)\dynamic\libzmq.pdb"
          DestinationFiles="$(TargetDir)libzmq.pdb"
          SkipUnchangedFiles="true" />
    <Copy Condition="$(Configuration.IndexOf('Release')) != -1"
          SourceFiles="$(ProjectDir)..\..\..\..\..\libzmq\bin\$(PlatformName)\Release\$(PlatformToolset)\dynamic\libzmq.dll"
          DestinationFiles="$(TargetDir)libzmq.dll"
          SkipUnchangedFiles="true" />
  </Target>

     具體的內容解釋可以參考zmq編譯的那篇blog

      (3)具體解決方式如下:

     解決1最簡單粗暴的就是把根目錄的名字從zeromq4-1-master改成libzmq即可(下面的內容可以忽略不看)

     解決2:在項目的reference中將libzmq去掉,在inker(連接器)-input(輸入)-Additional Dependencies(添加依賴項)中可以不用添加libzmq.lib,因為這是必須依賴項,編譯組在編譯工作中預先寫入;然后        重復步驟(2)的過程,如果拷貝libzmq和libsodium的lib以及dll到libzmq目錄下,必須在linker-General-Additional Library Directories(附加庫目錄)中必須將libzmq項目目錄添加進去,可選擇把inherited value那一項的鈎去掉,如果是拷貝到inproc_thr目錄下面,則可以免去這個工作,然后編譯就會顯示編譯成功!

     解決3:如果你有很多個zmq的版本,要區分以前版本的zmq,想要保持現在文件結構名字,

     可以參考如下做法:

     在zmq編譯時提到的libsodium同目錄之下建立一個文件夾,命名libzmq,如圖

      

     然后將zeromq-4-1-master下編譯zmq生成在根目錄的bin文件夾整個拷貝進去,然后在inproc_thr項目再次右鍵,build,成功的編譯過去了

2>------ Build started: Project: inproc_thr, Configuration: ReleaseDEXE x64 ------
2>  ConfigurationType : Application
2>  Configuration     : ReleaseDEXE
2>  PlatformToolset   : v140
2>  TargetPath        : E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\inproc_thr\..\..\..\..\bin\x64\Release\v140\dynamic\inproc_thr.exe
2>  Linkage-libzmq    : dynamic
2>  Linkage-libsodium : dynamic
2>  inproc_thr.vcxproj -> E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\inproc_thr\..\..\..\..\bin\x64\Release\v140\dynamic\inproc_thr.exe
2>  inproc_thr.vcxproj -> E:\zeromq4-1-master\zeromq4-1-master\builds\msvc\vs2013\inproc_thr\..\..\..\..\bin\x64\Release\v140\dynamic\inproc_thr.pdb (Full PDB)
2>  Copying libzmq.dll -> E:\zeromq4-1-master\zeromq4-1-master\bin\x64\Release\v140\dynamic\libzmq.dll
2>  Copying libsodium.dll -> E:\zeromq4-1-master\zeromq4-1-master\bin\x64\Release\v140\dynamic\libsodium.dll
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

  在根目錄(E:\zeromq4-1-master\zeromq4-1-master)的bin文件夾(E:\zeromq4-1-master\zeromq4-1-master\bin\x64\Release\v140\dynamic)下面生成了對應的pdb和exe可執行文檔,如圖

     

     至此,編譯工作完成,對於剩余的其他項目照常執行編譯即可,不需要其他的多余工作,也不需要在屬性的linker里面添加庫名稱和目錄之類的,編譯組的幾成熟型工作已經幫你完成了,libzmq.impoert.props文件在解決方案的根目錄下面,但是同時也因為作者新的版本的析出,文件命名的修改二沒有修改編譯文件,從而導致了一些莫名的麻煩,如果要在捷豹后重新創建解決方案組件工程是最方便的,但是需要了解以來結構來添加相應的文件。對於C++,Reference選項所產生的后果跟C#差不多,如果C#中,不是在共享項目中添加的項目引用,有些額外的文件更新會被忽略掉。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM