Проблема с привязкой броненосца к фреймворку для модульного тестирования Boost

Я пытаюсь связать класс, определенный в myclass.hpp и myclass.cpp, который использует броненосец, с файлом Boost_utf.cpp Boost UTF. У меня нет проблем с компиляцией boost_utf.cpp, если я не включаю внешние классы, т.е. только определяю функции для тестирования в boost_utf.cpp выше модульных тестов. РЕДАКТИРОВАТЬ: я также должен упомянуть, что myclass.cpp компилируется и работает просто отлично, если я включу main() в myclass.cpp и протестирую там функцию dp.

Но когда я пытаюсь включить myclass.cpp, я получаю сообщение об ошибке

myclass.o: в функции myclass::dp(arma::Col<double>, arma::Col<double>)': myclass.cpp:(.text+0x1ae): undefined reference towrapper_ddot_' collect2: ошибка: ld вернул 1 статус выхода

Процедура компиляции, которую я использую,

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

Мои файлы

//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);
};

person user155225    schedule 19.12.2014    source источник


Ответы (1)


При компиляции с ключом -c компоновка не выполняется. g++ просто создает myclass.o без привязки к библиотеке времени выполнения Armadillo.

Решение состоит в том, чтобы выполнить связывание, когда создается окончательный исполняемый файл:

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

Вы также можете сначала заставить все работать без переключателя -static.

Все параметры и переключатели описаны в руководстве по GCC.

В качестве примечания: по соображениям производительности не передавайте векторы (или матрицы) по значению в функции. Вместо этого объявите функции для приема ссылок. Например:

double myclass::dp(vec& x, vec& y){
  return (as_scalar(x.t()*y));
}

Обратите внимание на использование & в объявлении функции. Это предотвращает создание копии. Функция по-прежнему используется, как и раньше: dp(a,b).

Если векторы не нужно изменять, используйте константные ссылки:

double myclass::dp(const vec& x, const vec& y){
  return (as_scalar(x.t()*y));
}

Ссылки const позволяют компилятору выполнять более агрессивную оптимизацию.

person mtall    schedule 19.12.2014