user155225
user155225

Reputation: 13

Trouble linking armadillo with boost unit testing framework

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 towrapper_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

Answers (1)

mtall
mtall

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

Related Questions