2010-09-21 112 views
45

我想控制在CMake中找到/鏈接到我的二進制文件的庫的類型。最終目標是生成「儘可能靜態」的二進制文件「」,即靜態鏈接到每個具有可用靜態版本的庫。這一點非常重要,因爲在測試過程中可以使不同系統的二進制文件可移植。CMake:如何生成儘可能靜態的二進制文件「

ATM,這似乎是非常難以實現的FindXXX.cmake包,或者更準確地說是find_library命令總是拿起每當靜態和動態兩種可用的動態庫。

有關如何實現此功能的提示 - 最好以優雅的方式 - 非常歡迎!

+0

不是很愚蠢:http://stackoverflow.com/questions/2113231/making-cmake-choose-static當可能時,這是GCC特定的。 – 2010-09-21 23:51:31

+0

事實上,它不僅僅是gcc特有的,它也是一個不方便的解決方案。在另一個問題上看到我的評論。 – pszilard 2010-09-22 11:06:05

+0

@pszilard你最終找到了解決方案嗎?我正在嘗試用g ++來做同樣的事情。 – augustin 2010-10-28 10:02:04

回答

14

一個製作精良的FindXXX.cmake文件將包含這方面的內容。如果您查看FindBoost.cmake,則可以設置Boost_USE_STATIC_LIBS變量來控制它是否找到靜態庫或共享庫。不幸的是,大多數軟件包都沒有實現這一點。

如果一個模塊使用find_library命令(大多數人),那麼你可以通過CMAKE_FIND_LIBRARY_SUFFIXES變量改變CMake的行爲。下面是從FindBoost.cmake相關CMake的代碼使用:

IF(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ELSE(WIN32) 
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) 
ENDIF(WIN32) 

您可以調用find_package前把這個,或者更好的,你可以修改.cmake文件本身,並回饋給社會做出貢獻。

因爲我在我的項目中使用.cmake文件,我把所有的人都在自己的文件夾源控制範圍內。我這樣做是因爲我發現爲某些庫準備正確的.cmake文件是不一致的,保留我自己的副本允許我進行修改,並確保簽出代碼的每個人都具有相同的生成系統文件。

+0

感謝您的評論,我實際上在同時得出結論,上述是唯一可行的解​​決方案來獲取靜態版本的外部庫檢測。但是,這是一種非常骯髒的方式,我寧願不必指定後綴。不幸的是,基於對CMake郵件列表的討論,似乎Windows有一個相當混亂的庫命名,因此沒有計劃正確實施它。不過,這應該適用於大多數* NIX系統。 – pszilard 2010-11-08 18:47:51

+0

請注意,如果您只想*檢測靜態庫(因此可能會導致配置失敗,那麼上述命令不應將靜態庫文件名預先添加到CMAKE_FIND_LIBRARY_SUFFIXES中,而應將該變量設置爲這些文件名,這會抑制find_ *()函數使用通常的後綴 – mabraham 2014-11-20 00:36:59

+1

來獲取共享庫請注意,如果在隱式鏈接目錄(例如系統路徑)中找到庫,FindXXXX.cmake包的「製作精良」並不重要。在這種情況下,還原爲-XXXXX以允許鏈接器使用其正常分辨率 - 請參閱http://public.kitware.com/pipermail/cmake/2015-January/059702.html – mabraham 2015-02-19 23:37:09

26

我做了一些調查,雖然找不到令人滿意的解決方案,但我確實找到了一個解決方案。

靜態的問題建立歸結爲三件事情:

  1. 建設和鏈接項目的內部庫。

    很簡單,一個只是有翻轉BUILD_SHARED_LIBS開關OFF

  2. 查找靜態版本的外部庫。

    的唯一方法似乎是設置CMAKE_FIND_LIBRARY_SUFFIXES包含所需的文件後綴(ES)(這是一個優先級列表)。

    該解決方案是一個相當「髒」的一個非常反對的CMake的跨平臺的願望。恕我直言,這應該由CMake在幕後處理,但據我瞭解,由於Windows上的「.lib」混淆,似乎CMake開發人員更喜歡當前的實現。

  3. 靜態鏈接系統庫。

CMake提供了一個選項LINK_SEARCH_END_STATIC,該選項基於以下文檔:「結束使用靜態系統庫的鏈接行。「 有人會認爲,就是這樣,問題就解決了。但是,似乎目前的實現不能勝任任務。如果選項打開,CMake會生成一個帶有參數列表的隱式鏈接器調用,參數列表以傳遞給鏈接器的選項包括-Wl,-Bstatic但是,這還不夠,只是指示鏈接器靜態鏈接導致錯誤,在我的情況下:/usr/bin/ld: cannot find -lgcc_s。缺少的是告訴gcc以及我們需要靜態鏈接-static參數,它是產生由C進行連接電話。我認爲這是一個錯誤,但我沒有設法從開發商的確認。

最後,我認爲這一切可以而且應該由CMake在幕後完成,畢竟它不是那麼複雜,除了它在Windows上是不可能的 - 如果這個數字很複雜... ...

+1

不應將「BUILD_SHARED_LIBS」設置爲關閉(所以它*不會*建立共享庫)? – Nooble 2015-06-30 13:50:00

+0

哈哈,在將近五年你是第一個注意到這個錯誤的人。謝謝。 – pszilard 2015-07-02 10:54:29

相關問題