Reputation: 13
I'm trying to link a class defined in myclass.hpp and myclass.cpp which uses armadillo to a Boost UTF file boost_utf.cpp. I have no trouble compiling boost_utf.cpp if I include no external classes, ie only define the functions to test in boost_utf.cpp, above the unit tests. EDIT: I should also mentioned that myclass.cpp compiles and runs just fine if I include a main() in myclass.cpp and test out the dp function there.
But when I try to include myclass.cpp I get the error
myclass.o: In function
myclass::dp(arma::Col<double>, arma::Col<double>)': myclass.cpp:(.text+0x1ae): undefined reference to
wrapper_ddot_' collect2: error: ld returned 1 exit status
The compiling procedure I'm using is
g++ -c myclass.cpp -O1 -larmadillo
g++ myclass.o boost_utf.cpp -L/home/me/bin/boost_libs/lib -lboost_unit_test_framework -static -std=c++11
My files are
//FILE boost_utf.cpp
#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>
#include "myclass.hpp"
int add( int i, int j ) { return i+j; }
BOOST_AUTO_TEST_CASE( my_test )
{
BOOST_CHECK_EQUAL( add( 2,2 ), 4 );
myclass me = myclass();
BOOST_CHECK_EQUAL(me.add(3,2),5);
BOOST_CHECK_EQUAL(me.add(3,2),1);
vec y = ones<vec>(3);
BOOST_CHECK_EQUAL(me.dp(y,y),14);
}
\\FILE myclass.cpp
#include "myclass.hpp"
int myclass::add(int x, int y){
return x + y;
}
double myclass::dp(vec x, vec y){
return (as_scalar(x.t()*y));
}
\\FILE myclass.hpp
#include<stdlib.h>
#include<armadillo>
using namespace arma;
class myclass{
public:
int add(int x, int y);
double dp(vec x, vec y);
};
Upvotes: 1
Views: 77
Reputation: 3620
When compiling with the -c
switch, no linking is done. g++ simply produces myclass.o, without linking to the armadillo run-time library.
The solution is to do the linking when the final executable is being produced:
g++ -c myclass.cpp -O2
g++ myclass.o boost_utf.cpp -O2 -larmadillo -L/home/me/bin/boost_libs/lib -lboost_unit_test_framework -static -std=c++11
You may also want to first get things working without the -static
switch.
The options and switches are all explained in the GCC manual.
As a side note, for performance reasons do not pass vectors (or matrices) by value to functions. Instead, declare the functions to accept references. For example:
double myclass::dp(vec& x, vec& y){
return (as_scalar(x.t()*y));
}
Note the use of &
in the function declaration. This prevents a copy being made. The function is still used as before: dp(a,b)
.
If the vectors do not need to be modified, use const references:
double myclass::dp(const vec& x, const vec& y){
return (as_scalar(x.t()*y));
}
const references allow the compiler to optimise more aggressively.
Upvotes: 2