2016-11-08 11 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 

이는 통화 당입니다 : 이제

#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 

, 코드가 문제없이 컴파일, 그것을 잘 실행하고 그것은 나에게 올바른 결과를 제공합니다! 나는 인터넷에서 보았고 어떤 유용한 대답도 찾을 수 없었다. 우분투 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