2014-06-18 71 views
1

我在cmake-baed boost鏈接問題上掙扎,我在stackoverflow上搜索,但在其他論壇上卻無濟於事。使用cmake連接boost庫lib.8.0

我正在編譯一個C++程序套件(取決於不同的庫,除了Boost),這個套件已經安裝了Boost(我知道完整的路徑)。在編譯時用cmake獲得奇怪的鏈接錯誤後,我想先編譯一個非常簡單的boost-cmake示例來解決問題。

代碼如下。

#include <boost/program_options/options_description.hpp> 
#include <boost/program_options/option.hpp> 
using namespace std; 
#include <iostream> 

namespace po = boost::program_options; 

int main(int argc, char** argv) { 

po::options_description desc("Allowed options"); 
desc.add_options() 
    ("help", "produce help message") 
    ; 

return 0; 
} 

我正在使用以下CMakeLists.txt文件進行構建。

cmake_minimum_required(VERSION 2.8) 
set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib) 

find_package(Boost COMPONENTS program_options REQUIRED) 
include_directories(${Boost_INCLUDE_DIR}) 
link_directories(${Boost_LIBRARY_DIR}) 

message("Boost include dir is ${Boost_INCLUDE_DIR}") 
message("Boost library dir is ${Boost_LIBRARY_DIR}") 
message("Boost libraries are at ${Boost_LIBRARIES}") 

add_executable(main main.cpp) 
target_link_libraries(main ${Boost_LIBRARIES}) 

當我編譯使用cmake,我得到下面的輸出

[email protected] build]$ emacs ../CMakeLists.txt 
Display localhost:39.0 unavailable, simulating -nw 
[[email protected] build]$ rm -rf * 
[[email protected] build]$ cmake .. 
-- The C compiler identification is GNU 4.7.2 
-- The CXX compiler identification is GNU 4.7.2 
-- Check for working C compiler: /software/apps/comp_wrapper/gnu/gcc 
-- Check for working C compiler: /software/apps/comp_wrapper/gnu/gcc -- works 
-- Detecting C compiler ABI info 
-- Detecting C compiler ABI info - done 
-- Check for working CXX compiler: /software/apps/comp_wrapper/gnu/c++ 
-- Check for working CXX compiler: /software/apps/comp_wrapper/gnu/c++ -- works 
-- Detecting CXX compiler ABI info 
-- Detecting CXX compiler ABI info - done 
Boost found. 
Found Boost components: 
program_options 
Boost include dir is /usr/include 
Boost library dir is /software/apps/boost/1.55.0/build06/lib 
Boost libraries are at optimized;boost_program_options-mt-shared;debug;boost_program_options-mt-shared-debug 
-- Configuring done 
-- Generating done 
-- Build files have been written to: /home/x_ikrul/Downloads/boost_example/build 

問題是當我「作」的代碼如下。

[email protected] build]$make 
Scanning dependencies of target main 
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o 
make[2]: *** No rule to make target `/usr/lib64/lib64/libboost_program_options-mt.so.5', needed by `main'. Stop. 
make[1]: *** [CMakeFiles/main.dir/all] Error 2 
make: *** [all] Error 2 

正如你可以看到,雖然CMake的顯示提升的lib目錄中/software/apps/boost/1.55​​.0/build06/lib,奇怪的是在鏈接時,它指的是一個不同的非正在出現目錄。

有人遇到這樣的錯誤嗎?該集羣正在運行CentOS版本6.5,boost(我指向的地方)是1.55.0,我使用的cmake是2.8.8。

+0

您的提升包括目錄也沒有找到正確的? '提升包括目錄是/ usr/include' – fileoffset

+0

你是對的。事實上,當我在與cmake/boost版本相同的不同集羣上嘗試這個例子時,一切都很順利,但是對於當前的機器,它會給出這些奇怪的錯誤。 – Ikram

回答

1

stackoverflow answer建議在cmake命令行上添加-DBoost_NO_BOOST_CMAKE=ON

這似乎是由於某些CMake版本不適用於某些Boost版本而引起的。

我同意弗雷澤說的用戶。這些行沒有意義

set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib) 

由於CMake使用這些變量來存儲Boost搜索的結果。在他的回答中詳細瞭解它。

+0

你是對的,我現在已經刪除了該集(。)來自CMakeLists.txt的行,使其更透明。謝謝 – Ikram

3

您沒有正確設置提示路徑。

FindBoost module docs

此模塊讀取來自與變量的搜索位置的提示:

BOOST_ROOT - 首選安裝前綴 (或BOOSTROOT)

BOOST_INCLUDEDIR - 優選包括例如目錄<prefix>/include

BOOST_LIBRARYDIR - 首選庫目錄例如<prefix>/lib

Boost_NO_SYSTEM_PATHS - 設置爲ON禁止在未 這些提示變量指定的位置搜索。默認是OFF

...

和CMake的緩存條目持續保存的搜索結果:

Boost_INCLUDE_DIR - 目錄含Boost頭

Boost_LIBRARY_DIR - 目錄包含Boost庫

所以,你的臺詞:

set(Boost_INCLUDE_DIR /software/apps/boost/1.55.0/build06/include) 
set(Boost_LIBRARY_DIR /software/apps/boost/1.55.0/build06/lib) 

實際上不是提示提示變量 - 您想要設置BOOST_INCLUDEDIRBOOST_LIBRARYDIR;也可能是Boost_NO_SYSTEM_PATHS

這最好不要在你的CMakeLists.txt中硬編碼,因爲這不是可移植的。調用CMake的時候,而通過這些命令行:

cmake . -DBOOST_INCLUDEDIR=/software/apps/boost/1.55.0/build06/include -DBOOST_LIBRARYDIR=/software/apps/boost/1.55.0/build06/lib -DBoost_NO_SYSTEM_PATHS=ON 

您還可以得到什麼事情的一個更好的主意,如果你設置Boost_DEBUGON

順便說一句,你不應該需要link_directories調用,因爲在target_link_libraries調用中傳遞到Boost庫的完整路徑。

+0

我試過了,當我打印BOOST_INCLUDEDIR和BOOST_LIBRARYDIR時,它們不輸出這個路徑。我嘗試使用BOOST_LIBRARY_DIR/BOOST_LIBRARY_DIRS和BOOST_INCLUDE_DIR/BOOST_INCLUDE_DIRS,但無法完成。 我試過不同集羣上的代碼/腳本,並且他們在那裏編譯得很愉快。你認爲可能與其他加載的庫有衝突嗎? 感謝您的幫助:-) – Ikram

+0

在控制權到達FindCMake模塊之前,這些值*可能會在其他地方被設置/覆蓋。你可能會更新你的問題:你如何設置這些,你在哪裏打印CMakeLists.txt,以及cmake的輸出是什麼。 -DBoost_DEBUG = ON'? – Fraser

+0

我終於能夠使用BOOST_ROOT,BOOST_INCLUDEDIR和BOOST_LIBRARYDIR鏈接預期的路徑。我最初困惑是否使用BOOST_INCLUDEDIR或BOOST_INCLUDE_DIRS(輸入和輸出變量)。這個答案說得很清楚。非常感謝... – Ikram