Экспортированные символы в .o файле не экспортируются в .dylib

Недавно я столкнулся с ошибкой при создании общих библиотек (файлы .dylib) из скомпилированного кода C ++ (файлы .o) на Mavericks (OS X 10.9.4, Xcode 5.1). Кажется, что ключевые символы из одного конкретного класса реализации экспортируются в файл .o, но не из файла .dylib, включающего .o.

Наша кодовая база разбита на модули. Мы интенсивно используем шаблон шаблона CURLY CURRURRING CRIF. Эскиз кода показан здесь:

#include <string>
class ExprVec;

class Operator
{
public:
virtual bool operator()(bool &result, ExprVec const &args) const = 0;
virtual bool operator()(int32_t &result, ExprVec const &args) const = 0;
virtual bool operator()(double &result, ExprVec const &args) const = 0;
virtual bool operator()(std::string &result, ExprVec const &args) const = 0;
};

template <class IMPL>
class OperatorShim : public Operator
{
public:
bool operator()(bool &result, ExprVec const &args) const
{
return static_cast<IMPL const *>(this)->calc(result, args);
}
bool operator()(int32_t &result, ExprVec const &args) const
{
return static_cast<IMPL const *>(this)->calc(result, args);
}
bool operator()(double &result, ExprVec const &args) const
{
return static_cast<IMPL const *>(this)->calc(result, args);
}
bool operator()(std::string &result, ExprVec const &args) const
{
return static_cast<IMPL const *>(this)->calc(result, args);
}
};

template <typename T>
class OperatorImpl : public OperatorShim<OperatorImpl<T> >
{
public:
// implemented by derived classes
virtual bool calc(T &result, ExprVec const &args) const = 0;

// default methods
template <typename U>
bool calc <U &result, ExprVec const &args) const
{
// throw wrong-type exception
return false;
}
};

template class OperatorImpl<bool>;
template class OperatorImpl<int32_t>;
template class OperatorImpl<double>;
template class OperatorImpl<std::string>;

В нашей фактической базе кода объявления находятся в файле .hh, а определения в файле .cc. Файл .o из .cc экспортирует все шаблонные методы calc () по умолчанию, но .dylib — нет. Эти символы находятся в .dylib, но только как символы отладки. Я проверил это с помощью nm и c ++ Filter для проверки файлов.

Это приводит к ошибке связывания любого приложения, использующего эту библиотеку, поскольку методы OperatorShim вызывают неэкспортированные методы OperatorImpl.

Это происходит только при сборке в Mac OS X 10.9.x с помощью инструментов командной строки Xcode 5.1.x. 10.8.x и Xcode 5.0.x не имеют проблем с подключением этой библиотеки, равно как и инструменты GNU в Linux.

В качестве обходного пути я переместил реализации метода обратно в файл .hh. Поскольку они требуют нескольких других включаемых файлов, я бы предпочел хранить реализации отдельно от объявлений.

Вы можете воспроизвести актуальную проблему на OS X 10.9.x следующим образом:

export PLEXIL_HOME=$PWD
svn checkout -r3785 svn+ssh://svn.code.sf.net/p/plexil/code/branches/plexil-3-new-exp/src
cd src
./configure --disable-static --enable-module-tests --prefix=$PLEXIL_HOME
make

Этими файлами являются … / src / expr / OperatorImpl. {Hh, cc, o} и … / src / expr / .libs / libPlexilExpr.0.dylib. Команда, которая создала файл dylib:

libtool: link: g++ -dynamiclib -Wl,-undefined -Wl,dynamic_lookup -o .libs/libPlexilExpr.0.dylib  .libs/libPlexilExpr_la-Alias.o .libs/libPlexilExpr_la-Array.o .libs/libPlexilExpr_la-ArrayImpl.o .libs/libPlexilExpr_la-ArithmeticFunctionFactory.o .libs/libPlexilExpr_la-ArithmeticOperators.o .libs/libPlexilExpr_la-ArrayOperators.o .libs/libPlexilExpr_la-ArrayReference.o .libs/libPlexilExpr_la-ArrayVariable.o .libs/libPlexilExpr_la-Assignable.o .libs/libPlexilExpr_la-AssignableImpl.o .libs/libPlexilExpr_la-BooleanOperators.o .libs/libPlexilExpr_la-CommandHandle.o .libs/libPlexilExpr_la-Comparisons.o .libs/libPlexilExpr_la-ConcreteExpressionFactory.o .libs/libPlexilExpr_la-Constant.o .libs/libPlexilExpr_la-Expression.o .libs/libPlexilExpr_la-ExpressionConstants.o .libs/libPlexilExpr_la-ExpressionFactories.o .libs/libPlexilExpr_la-ExpressionFactory.o .libs/libPlexilExpr_la-ExpressionImpl.o .libs/libPlexilExpr_la-ExpressionListener.o .libs/libPlexilExpr_la-ExprVec.o .libs/libPlexilExpr_la-Function.o .libs/libPlexilExpr_la-FunctionFactory.o .libs/libPlexilExpr_la-NodeConstants.o .libs/libPlexilExpr_la-NodeConstantExpressions.o .libs/libPlexilExpr_la-NotifierImpl.o .libs/libPlexilExpr_la-OperatorImpl.o .libs/libPlexilExpr_la-PlexilExpr.o .libs/libPlexilExpr_la-StringOperators.o .libs/libPlexilExpr_la-UserVariable.o .libs/libPlexilExpr_la-Value.o .libs/libPlexilExpr_la-ValueType.o   -lm -lpthread -ldl  -O2   -install_name  /Users/chucko/src/plexil-3-new-exp/lib/libPlexilExpr.0.dylib -compatibility_version 1 -current_version 1.0 -Wl,-single_module

Это результат ошибки кодирования с моей стороны? Я попробовал несколько разных подходов, но не смог решить проблему.

1

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]