2017-06-12 27 views
1

我試圖導入libuv到我的CMake項目,所以我可以鏈接它。我從here安裝libuv 1.12.0,並將其放入C:\Program Files\libuv\CMake導入圖書館目標給予未定義給予未定義的符號在Windows上

project(tls-server LANGUAGES C) 
set(LIBUV_ROOT_DIR "C:\\Program Files\\libuv") 
add_library(libuv SHARED IMPORTED) 
set_property(TARGET libuv PROPERTY IMPORTED_LOCATION "${LIBUV_ROOT_DIR}\\libuv.dll") 
set_property(TARGET libuv PROPERTY IMPORTED_IMPLIB "${LIBUV_ROOT_DIR}\\libuv.lib") 
add_executable(tls-server "${CMAKE_SOURCE_DIR}/src/main.c") 
target_link_libraries(tls-server libuv) 

然而,鑑於上面的代碼我仍然得到在Visual Studio中未定義符號錯誤:

Error message

我該如何解決這個問題?我相信這些路徑都是正確的。我也在使用Windows 10.

+2

你**不能**在MinGW上使用'.lib'文件。 '.lib'用於Visual Studio編譯器和鏈接器,但MinGW及其gcc需要'.a'(或'.dll.a')。使用純C語言,可以從'.def'文件創建'.a'。 – Tsyvarev

+0

@Tsyvarev我明白了。不過,使用Visual Studio生成器也會出現同樣的錯誤。 – HexCoder

回答

1

我終於設法解決了這個問題。

首先,我從目標庫(libuv)重新安裝了二進制文件。然後,我確定我的cmake正在使用cmake -G "Visual Studio 14 2015 Win64"生成x64項目文件。這足以擺脫未定義的符號錯誤。然後,我需要做的就是將libuv.dll文件複製到可執行文件所在的目錄中,並且一切正常。

如果有人知道這個錯誤發生的原因,請發表評論,以便將來幫助其他人更好地指出錯誤的原因。

1

千萬不要在CMake中硬編碼像這樣的庫路徑或名稱。

改爲使用find_library命令,如果提供的庫存在問題,它可以很好地通知您。

特別是在Windows上,因爲系統上沒有默認位置(類似於* nix系統上的/usr/local/lib),所以您可能需要爲庫的位置提供額外的自定義點。我個人比較喜歡使用環境變量這一點,但一個正常的CMake的選項也會做:

project(tls-server LANGUAGES C) 

find_library(LIBUV_LIBRARIES NAMES uv libuv 
    HINTS $ENV{LIBUV_ROOT}) 

add_executable(tls-server ${PROJECT_SOURCE_DIR}/src/main.c) 
target_link_libraries(tls-server ${LIBUV_LIBRARIES}) 

注意CMake的一般永遠沒有複製運行時依賴於正確的位置的呵護!也就是說,如果libuv被構建爲.dll,則在運行程序時必須確保.dll處於正確的路徑中。

你當然可以在CMake中手動插入一個拷貝命令來獲取所有的dll,但這可能非常麻煩。不幸的是,現在還沒有更好的解決方案來解決這個問題。

在這裏使用導入的目標是可能的,但如果您需要將更復雜的屬性傳遞給相關目標,那麼只能取得成效。根據我的經驗,如果依賴項提供fully-fledged package config file,則導入的目標效果最佳。手動編寫導入的目標在增加複雜性方面往往不值得。

+0

這篇文章如何幫助**問題**(「未定義的參考」)? *改進問題中的代碼是好意,但這不是*答案帖子*的主要目的。最近我在meta上看到了相關的問題。 – Tsyvarev

+0

@Tsyvarev未定義的引用不會被檢測到,因爲CMake不檢查硬編碼路徑。通過改進代碼,潛在的問題被解決爲一種副作用,這是一種比痛苦地調試問題更好的方法,同時讓破碎的CMake保持原樣。 StackOverflow不是免費的調試服務。 – ComicSansMS

+0

*有效*您的代碼**在問題文章中完成相同的**(至少對於Visual Studio)。指定* HINTS *或* PATHS *只是硬編碼路徑的跨平臺方式:這隻允許自動選擇庫的前綴/後綴。 (假設您沒有安裝該庫的系統)。 'StackOverflow不是免費的調試服務。「 - 這是針對」一堆代碼沒有任何評論「的情況。實際上,我猜想有關SO的更多90%的問題關於檢測現有代碼中的問題。 – Tsyvarev