仅当我在自己的库中使用犰狳链接错误
Posted
技术标签:
【中文标题】仅当我在自己的库中使用犰狳链接错误【英文标题】:Armadillo linking error only if I use it in my own library 【发布时间】:2016-11-08 10:07:16 【问题描述】:我在自己的库中使用犰狳时遇到了一些问题。我安装了 Armadillo,并创建了自己的库,它调用 svd_econ 方法。这是 CMakeList.txt 文件:
cmake_minimum_required (VERSION 2.8.9)
set(PROJECTNAME training_library)
project($PROJECTNAME)
if (NOT DEFINED ENVEIGEN_ROOT)
message(FATAL_ERROR "Could not find EIGEN_ROOT environment variable")
endif()
find_package(Armadillo REQUIRED)
include_directories("$ENVEIGEN_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)
这是头文件:
#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 ENVEIGEN_ROOT)
message(FATAL_ERROR "Could not find EIGEN_ROOT environment variable")
endif()
include_directories("$ENVEIGEN_ROOT")
include_directories("$ENVtraining_INCLUDE")
link_directories("$ENVtraining_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;
当我尝试编译时,这段代码给出了这个链接错误:
/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
但是,如果我将 main.cpp 中注释的行取消注释,则代码编译时不会出现任何问题,它运行良好并且给了我正确的结果!我在互联网上查找,我找不到任何有用的答案。我正在使用 Ubuntu 14.04。我从源代码安装了犰狳,从突触安装了 lapack、blas 和 openblas。任何人都可以在任何地方发现问题吗?任何帮助将不胜感激。
谢谢, 伊拉利亚
【问题讨论】:
听起来像是链接顺序问题。你能分享一下生成的链接器命令行吗? 【参考方案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
的左侧,所以现在可以使用它来解决它们,因此它们被拉入。一旦被拉入,它们现在也可用于稍后在命令行中出现的东西,即@ 987654330@,这样你之前的问题就解决了。
如何解决这个问题?只是猜测,但请尝试将您的 CMake
行更改为:
target_link_libraries($PROJECTNAME $OpenCV_LIBS $ARMADILLO_LIBRARIES training_library)
收件人:
target_link_libraries($PROJECTNAME training_library $OpenCV_LIBS $ARMADILLO_LIBRARIES)
【讨论】:
是的!那解决了!非常感谢,我快疯了!谢谢。以上是关于仅当我在自己的库中使用犰狳链接错误的主要内容,如果未能解决你的问题,请参考以下文章
链接器错误、Xcode 5 和 Armadillo:“找不到 -larmadillo.4.0.2 的库”
c ++犰狳库中的sort_index()函数给出错误的结果