2012-12-31 58 views
1

我有一個具體的問題,它可以作爲一個更一般的問題的上下文。包裝和圖書館管理與安裝,以及與cmake的接口

有一個叫做LAMMPS的科學軟件包,它通常用作可執行文件。但是,它支持用作「庫」。爲了嘗試做正確的事情,我把它放在/ usr/local/lib/lammps中。它包含一個lammps/src /目錄,它有大約40個源文件。使用提供的說明,我將lammps編譯爲lammps/src/liblammps_serial.so中的.so文件。

我在「〜/ code/ljtube /」中也有單獨的代碼。這使用cmake來嘗試查找庫。因此,我寫了一個FindLAMMPS.txt,以便我可以在我的CMakeLists中使用

FIND_PACKAGE (lammps) 

。我修改了libtool配置文件以便在/ usr/local /中成功搜索。我發現它在/ usr/local/lib /中搜索.so文件,在/ usr/local/include /中搜索.h文件。所以我做了一個到/ usr/local/lib /中的.so文件的動態鏈接,並且將.h文件從lammps/src /複製到/ usr/local/include /。

CMake現在可以找到這兩個文件,但它不能鏈接到lammps/src /中的任何其他文件。對於我想包含的每個.h's(group.h,fix.h,force.h,pair.h等)需要單獨做FIND_PACKAGE似乎是荒謬的。將整個.h文件包轉儲到/ usr/local/include /目錄中似乎也很荒謬。我將在本地和集羣上使用此代碼,並可能將其分發給其他組成員。

如何使CMake在/ usr/local/lib/lammps/src /的位置找到我想要查找的內容而無需硬編碼?更通用的說法是,我應該如何管理這些大型軟件包,以便讓它們易於鏈接到我編寫的代碼中,即使原始開發人員沒有使用最佳約定? (作爲一個方面說明,我使用共享庫,因爲它看起來是正確的選擇,但我沒有特別嫁給它,我應該使用靜態庫嗎?有沒有辦法讓CMake找到一個已經編譯好的相對於當前源代碼目錄的庫,這可能是一個更好的方法來實現它?我知道我將在多個項目中使用LAMMPS,所以從表面上看本地共享副本似乎最有意義。)

回答

1

通常,find_package調用會生成一個變量,指定包的「includes」文件夾的路徑。然後這將通過include_directories添加到調用者的CMakeLists.txt中。

例如,使用find_package的提升,你可以這樣做:

find_package(Boost) # sets ${Boost_INCLUDE_DIRS} and ${Boost_LIBRARIES} 
if(Boost_FOUND) 
    include_directories(${Boost_INCLUDE_DIRS}) 
    add_executable(foo foo.cc) 
    target_link_libraries(foo ${Boost_LIBRARIES}) 
endif() 


關於你側面說明,你可以使用find_library和/或find_path找到給出的庫及其頭一個已知的位置。

這兩個命令都可以以避免在常見位置搜索的方式調用,例如,通過將PATHS設置爲已知位置並在查找命令中使用NO_DEFAULT_PATH

另一種替代方法是讓您的項目使用ExternalProject_Add函數,該函數在this article中有更詳細的描述。從這篇文章:

ExternalProject_Add功能可以說「從互聯網上下載該項目,運行它的配置階段,建立並安裝它」

一個缺點這種方法是您的每個項目最終都會擁有自己的第三方源代碼和lib副本。

+0

這絕對是答案的一半。我的問題的很大一部分是**如何哄騙cmake找到所有的文件_在共同locations_; cmake不會在.h文件中查看lammps/src /。當然,一些分佈式軟件有很多必須被引用的.h文件,並且它們並不全部放在/ usr/include /中! 此外,ExternalProject_Add真棒,很好找。 –

+0

很高興有一些用途的答案。至於查找標題,我希望所有需要對外部用戶可用的標題位於單個「包含」文件夾中。這個單根可以在/ usr/include /中,但是用戶只需要找到那個文件夾即可。如果有這樣的子目錄,它們應該反映在用戶代碼的#include語句中,但最終只有一個「包含」文件夾。庫的用戶不應該要求分散在源文件夾中的所有其他頭文件。 – Fraser