У меня есть библиотека (технически расширение Ruby) под названием NMatrix, написанная на C и C ++. Он использует шаблоны C ++ для управления различными типами, например, Rational128
против Rational64
, Он также имеет RubyObject
а также Complex64
а также Complex128
, Я заставляю эти версии шаблонов создавать, создавая некоторые из них внутри объектного файла — в функции, которая вызывается из точки входа в библиотеку.
Работает просто отлично в GCC 4.7, но когда я компилирую на Travis-CI, он сталкивается с неопределенной ошибкой символа во время выполнения:
exposes cblas rot /home/travis/.rvm/rubies/ruby-2.0.0-p247/bin/ruby: symbol lookup error: /home/travis/build/SciRuby/nmatrix/lib/nmatrix.so: undefined symbol: _ZN2nm7ComplexIfEC1ERKNS_10RubyObjectE
Неопределенный символ nm::Complex::Complex(nm::RubyObject const&)
, который явно определен и создан (см. ниже).
Вот урезанная версия data.cpp
:
#include "data.h"
void nm_init_data() { // called from library entry point
// These force the compiler to build these versions of the typedef'd templates.
// I think this is a gross way to do it, but can't find a better idea.
nm::RubyObject obj(INT2FIX(1));
nm::Rational32 x(obj);
nm::Rational64 y(obj);
nm::Rational128 z(obj);
nm::Complex64 a(obj); // Clear instantiation of the undefined symbol
nm::Complex128 b(obj);
}
а также data.h
вот так:
#include "nmatrix.h"
#include "complex.h" // classes are all declared in headers
#include "rational.h"#include "ruby_object.h"
void nm_init_data();
nmatrix.cpp
где точка входа библиотеки объявлена. Соответствующие части выглядят так:
void Init_nmatrix() {
// declarations of Ruby-exposed functions here, e.g.,
rb_define_method(cNMatrix, "initialize", (METHOD)nmatrix_constructor, -1);
nm_init_data();
}
Так что я делаю не так? Почему это работает на GCC 4.7.1 (все спецификации проходят), а не на 4.6.3? Это ошибка? (Если это ошибка, есть ли обходной путь?)
Если вам интересно, полные версии соответствующих файлов Вот.
Задача ещё не решена.
Других решений пока нет …