Использование одновременно 2 версий Boost - PullRequest
12 голосов
/ 25 мая 2010

Я использую RHEL 5.3, который поставляется с gcc 4.1.2 и boost 1.33.Есть некоторые функции, которые я хочу, которые отсутствуют в надстройке 1.33.Поэтому мысль была обновить до свежего буст-релиза 1.43.

  1. Можно ли одновременно использовать некоторые библиотеки только для заголовков из Boost 1.43, а остальные из 1.33?Например, я хочу использовать unorded_map, который отсутствует в boost 1.33.

  2. Можно ли использовать одновременно двоичные библиотеки boost из разных выпусков?

Ответы [ 3 ]

14 голосов
/ 25 мая 2010

НЕТ - никогда не делай этого!

Это невозможно, вы можете получить случайные сбои.

Единственный способ сделать это правильно - использовать переименование пространства имен: создать альтернативу буст-версия помещена в другое пространство имен.

В последней версии BCP предусмотрена эта опция. Таким образом, вы будете использовать что-то вроде boost_1_43 вместо boost. Но это будет довольно прозрачно для вас. Но вы все равно должны знать из этого вы не можете использовать две версии boost в одном файле cpp.

Также посмотрите на это обсуждение: Создание библиотеки с обратно совместимым ABI, использующим Boost

Любимый скрипт переименовывает пространство имен, определяет и включает в себя, так что вы можете включить два версии boost как

#include <boost/foo.hpp>
#include <myboost/bar.hpp>

boost::foo f;
myboost::bar b;

Повышение ППГ не позволяет этого.

Но все же вы должны быть осторожны, так как некоторые библиотеки экспортируют внешние символы "C" без префикс boost, boost :: thread и boost :: regex, C API (regexec, regcomp)

Редактировать

В качестве примера такой проблемы создайте следующие файлы:

a.cpp:

template<typename Foo>
Foo add(Foo a, Foo b)
{
        return a+b;
}


int foo(int x,int y)
{
        return add(x,y);
}

b.cpp:

template<typename Foo>
Foo add(Foo a, Foo b)
{
        return a-b;
}


int bar(int x,int y)
{
        return add(x,y);
}

test.cpp:

#include <iostream>

int foo(int,int);
int bar(int,int);

int main()
{
        std::cout<< foo(10,20) <<" " <<bar(10,20) << std::endl;
}

Скомпилируйте их:

g++ a.cpp b.cpp test.cpp

Вы ожидаете:

30 -10

Но вы получите

30 30

или

-10 -10

В зависимости от порядка связывания.

Таким образом, используя две версии буста, вы можете случайно использовать символы других бустов и сбоев так же, как в этой программе символ int add<int>(int,int) преобразуется в тот же символ даже если он размещен в разных единицах компиляции.

3 голосов
/ 25 мая 2010

С небольшой удачей (и большой осторожностью) вы можете , вероятно, избежать использования совершенно новых заголовков. Практически для всего остального это может стать уродливым в спешке, потому что некоторые части Boost ссылаются на другие части, и если какой-то код v. 1.33 случайно загружает заголовок v. 1.43 для своей зависимости, есть очень хороший шанс, что вы собираетесь чтобы получить некоторые проблемы в результате - самое лучшее, на что вы можете надеяться, - это быстрая, чистая смерть (сбой) на этом этапе, но вы можете легко стать намного хуже (например, повреждение данных без вывода сообщений).

1 голос
/ 26 мая 2010

Обновление

Я думаю, что в моем первоначальном ответе слишком много предположений о возможностях компоновщика и используемых параметрах, и он может быть совершенно неверным. Обычно я бы его удалил, но есть некоторые моменты в обсуждении, которые не включены в другие ответы.

Я считаю, что последствия для создания библиотеки с закрытым исходным кодом с хорошим исходным кодом просто поразительны.

Оригинальный ответ

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

Я предполагаю, что Boost по-прежнему является библиотекой шаблонов без связанных библиотек. Если это не так, то вы все в порядке, если не ссылаетесь на более чем одну версию библиотеки.

Я могу ошибаться, но это может означать, что вы не можете использовать любую стороннюю библиотеку, созданную для другой версии Boost, отличной от версии, определенной для вашего приложения. Ничто из того, что я прочитал или услышал, даже не намекает на то, что применяется это ограничение.

Если вы создаете собственное приложение, я бы остановился на одной версии Boost для всего вашего собственного кода. Это не обязательно должна быть та же версия, что и RHEL.

Обновление

По сравнению с примером Артема сценарий, о котором я говорю, выглядит примерно так:

g++ -c -I/usr/include/boost_1.31 a.cpp
g++ -c -I/usr/include/boost_1.39 b.cpp
ar rcs liba.a a.o
ar rcs libb.a b.o
g++ -I/usr/include/boost_1.41 test.cpp liba.a libb.a -o test

... и теперь я понимаю точку зрения Артема, потому что это зависит от того, предпочитает ли компоновщик символы в одном и том же библиотечном файле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...