2016-11-08 2 views
1

私は自分のライブラリ内でArmadilloを使用する際にいくつか問題があります。私はArmadilloをインストールしました。私はsvd_econメソッドを呼び出す独自のライブラリを作成しました。これは、ヘッダファイルであるArmadilloのリンクエラーは、自分のライブラリで使用する場合にのみ発生します。

cmake_minimum_required (VERSION 2.8.9) 
set(PROJECTNAME training_library) 
project(${PROJECTNAME}) 

if (NOT DEFINED ENV{EIGEN_ROOT}) 
message(FATAL_ERROR "Could not find EIGEN_ROOT environment variable") 
endif() 

find_package(Armadillo REQUIRED) 

include_directories("$ENV{EIGEN_ROOT}") 

add_definitions(-g) 
add_definitions(-O3) 
add_definitions(-DNDEBUG) 

include_directories(${ARMADILLO_INCLUDE_DIRS}) 
include_directories(${PROJECT_SOURCE_DIR}/include) 

file(GLOB header include/*.h) 
file(GLOB source src/*.cpp) 

source_group("Source Files" FILES ${source}) 
source_group("Header Files" FILES ${header}) 

add_library(${PROJECTNAME} ${source} ${header}) 
target_link_libraries(${PROJECTNAME} ${ARMADILLO_LIBRARIES}) 

::これはCMakeList.txtファイルです

#include <algorithm> 
#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <vector> 
#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <armadillo> 
#include <Eigen/Dense> 
#include <Eigen/SVD> 

namespace statistics 
{ 
    bool findPCS(const Eigen::MatrixXd &data, Eigen::VectorXd &eigenvalues, Eigen::MatrixXd &eigenvectors); 
} 

#endif 

と、これは.CPPです:今

#include "statistics.h" 

namespace statistics 
{ 

Eigen::MatrixXd convert(const arma::mat &data) 
{ 
    Eigen::MatrixXd res(data.n_rows,data.n_cols); 
    for (int i = 0; i < data.n_rows; i++) 
    { 
    for (int j = 0; j < data.n_cols; j++) 
    { 
     res(i,j) = data(i,j); 
    } 
    } 
    return res; 
} 

arma::mat convert(const Eigen::MatrixXd &data) 
{ 
    arma::mat res(data.rows(),data.cols()); 
    for (int i = 0; i < data.rows(); i++) 
    { 
    for (int j = 0; j < data.cols(); j++) 
    { 
     res(i,j) = data(i,j); 
    } 
    } 
    return res; 
} 

Eigen::VectorXd convert(const arma::vec &data) 
{ 
    Eigen::VectorXd res(data.size()); 
    for (int i = 0; i < data.size(); i++) 
    { 
    res(i) = data(i); 
    } 
    return res; 
} 

arma::vec convert(const Eigen::VectorXd &data) 
{ 
    arma::vec res(data.size()); 
    for (int i = 0; i < data.size(); i++) 
    { 
    res(i) = data(i); 
    } 
    return res; 
} 

bool findPCS(const Eigen::MatrixXd &data, Eigen::VectorXd &eigenvalues, Eigen::MatrixXd &eigenvectors) 
{ 
    arma::mat arma_mat = convert(data); 
    arma::mat U; arma::vec S; arma::mat V; 
    arma::svd_econ(U,S,V,arma_mat);  
    eigenvalues = convert(S)/sqrt((double)(data.rows()));  
    eigenvectors = convert(V); 

    return true; 
} 

} 

、このライブラリは問題なくコンパイル。次に、clean_dataという別のモジュールからfindPCSメソッドを呼び出す必要があります。そのためCMakeLists.txtファイルは以下の通りです:

cmake_minimum_required (VERSION 2.8.9) 
set(PROJECTNAME clean_data) 
project(${PROJECTNAME}) 

find_package(OpenCV REQUIRED) 
find_package(Armadillo REQUIRED) 

if (NOT DEFINED ENV{EIGEN_ROOT}) 
message(FATAL_ERROR "Could not find EIGEN_ROOT environment variable") 
endif() 

include_directories("$ENV{EIGEN_ROOT}") 
include_directories("$ENV{training_INCLUDE}") 
link_directories("$ENV{training_LIBS}") 

add_definitions(-g) 
add_definitions(-O3) 
add_definitions(-DNDEBUG) 

file(GLOB SOURCES *.c *.cpp) 

add_executable(${PROJECTNAME} ${SOURCES}) 
target_link_libraries(${PROJECTNAME} ${OpenCV_LIBS} ${ARMADILLO_LIBRARIES} training_library) 

次のようにfindPCSメソッドを呼び出すmain.cppには、次のとおりです。

#include <armadillo> 
#include <string> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <vector> 
#include <iostream> 
#include <fstream> 
#include <ctime> 
#include <algorithm> 
#include <numeric> 
#include <list> 
#include <statistics.h> 
#include <opencv2/opencv.hpp> 
#include <Eigen/Dense> 

int main() { 

    Eigen::MatrixXd matrix(4,10); 
    matrix << 1, 2, 2, 1, 5, 5, 4, 12, 32, 1, 
     44, 34, 12, 11, 21, 5, 54, 1, 12, 3, 
     33, 128, 112, 126, 3, 3, 2, 12, 1, 54, 
     66, 34, 1, 54, 2, 2, 1, 43, 4, 12; 
    Eigen::VectorXd eigenval; Eigen::MatrixXd eigenvec; 
    statistics::findPCS(matrix,eigenval,eigenvec); 

    //arma::mat x = arma::randu<arma::mat>(3,4); 
    //arma::mat U; arma::vec S; arma::mat V; 
    //arma::svd(U,S,V,x); 

    return 0; 
} 

このコード、私がコンパイルしようとすると、私にこれを提供しますリンクエラー:私は私のmain.cppににコメントしているラインをdecomment場合

しかし
/home/ilaria/Dev/training_library/build/libtraining_library.a(statistics.cpp.o):  In function `gesdd<double>': 
/usr/local/include/armadillo_bits/wrapper_lapack.hpp:571: undefined  reference to `wrapper_dgesdd_' 
/home/ilaria/Dev/training_library/build/libtraining_library.a(statistics.cpp.o):  In function `gesvd<double>': 
/usr/local/include/armadillo_bits/wrapper_lapack.hpp:506: undefined  reference to `wrapper_dgesvd_' 
/usr/local/include/armadillo_bits/wrapper_lapack.hpp:506: undefined reference to `wrapper_dgesvd_' 
collect2: error: ld returned 1 exit status 
make[2]: *** [clean_data] Error 1 
make[1]: *** [CMakeFiles/clean_data.dir/all] Error 2 
make: *** [all] Error 2 

、コードは問題なくコンパイル、それが正常に動作し、それは私に右の結果が得られます!私はインターネットを見て、役に立つ答えは見つけられませんでした。私はUbuntu 14.04を使用しています。私はソースからアルマジロをインストールし、シナプスからラパック、ブラス、オープンブラスをインストールしました。誰でもどこでも問題を見つけることができますか?どんな助けでも大歓迎です。

おかげで、 イラリア

+0

は、リンク順序の問題のようですね。作成されたリンカコマンドラインを共有できますか? – Smeeheey

答えて

1

あなたの問題は、ライブラリのリンク順に沸きます。私はあなたの完全なリンクラインを知っているが、ここで問題を説明するための単純化されていない:

gcc -o myOutput main.o -l someLibrary -l training_library 

training_library.aは、外部シンボルへの参照が含まれています:wrapper_dgesvd_特にとりわけ。これらは実際にsomeLibrary.aで定義されています(実際のライブラリ名はわかりませんので、私の要点を説明するためにこのモニカを使用してください)。ただし、上記の-lオーダのため、解決できません(リンカ行の未解決のシンボルは左から右に処理され、未解決のシンボルが導入されたポイントの右側に表示される-lのエントリのみが処理できます)。それを解決する)。

なぜ、main.cppの行のコメントを解除すると役立ちますか?コメントされた行のコールをおそらく(フードの下で)呼び出すと、それらの未解決のシンボルが参照される(たとえば、wrapper_dgesvd_)。これらは今では-l someLibraryの左側に導入されているので、これを解決するために使用できるようになりました。引き込まれると、後でコマンドラインで表示されるもの、つまりtraining_libraryあなたの以前の問題は消え去る。

これを解決するにはどうすればよいですか?ただの推測ではなく、あなたからCMakeラインを変更してみてください:

target_link_libraries(${PROJECTNAME} ${OpenCV_LIBS} ${ARMADILLO_LIBRARIES} training_library) 

へ:

target_link_libraries(${PROJECTNAME} training_library ${OpenCV_LIBS} ${ARMADILLO_LIBRARIES}) 
+0

はい!それはそれを解決しました!本当にありがとう、私はそれで夢中になっていた!ありがとう。 – Ilaria

関連する問題