Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
version.<latest>.<latest>.so.$ objdump -x chrome|grep NEEDED|grep nss3
NEEDED libnss3.so
$ ./chrome
./chrome: /usr/lib64/seamonkey/libnss3.so: version 'NSS_3.14.3' not found (required by ./chrome)
$ objdump -x /usr/lib64/seamonkey/libnss3.so |grep SONAME
SONAME libnss3.so
$ objdump -x chrome|egrep 'R(\|UN)PATH'
$
-lx. Новый gcc & ld умеет прямо компоновать с нужным файлом: -l:x.so.3.2.1. Разве что на Маке я не нашёл такой возможности. (Дурацкий префикс 'lib' тоже не нужен).
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib64
includedir=${prefix}/include/nss
Name: NSS
Description: Network Security Services
Version: 3.13.5
Requires: nspr >= 4.9.1 sqlite3
Libs: -L${libdir} -lnss3 -lsmime3 -lssl3 -lsoftokn3 -lnssutil3
Cflags: -I${includedir}
inline namespace. Если приходится разрабатывать проект без поддержки C++11, то к вашим услугам (на MacOS и Linux) strong using появившийся в GCC 3.4 (не 4.4, а именно 3.4) — собственно он явился прототипом для inline namespace.// ...
typedef version::list<version::window> windows_list;
// ...
version::list. Если он – хедер-онли, то всё плохо:version::list<version::window>;version::list<version::window>. Он будет скомпилирован, в лучшем случае бинарно совместим с классом в version.dll, и все ссылки на него будут не undefined (что заставило бы загрузчик искать эти символы во время загрузки), а определены и указывать на сущности внутри а (в терминах nm – T либо t).version::list<version::window> и был версионирован в version.dll, он окажется в непонятном состоянии в liba. (Тут, кстати, стоит отметить, что именно по этой причине некоторые люди используют AddRef/Release семантику для экспортируемых классов, а также, не экспортируют stl-классы: нагенерреные классы внутри самой либе и её пользователе отличаются бинарно даже в случае Debug/Release )) ).#include "version_windows_list.hpp"
// подключаем тело шаблона
#include "version_list_impl.h"
// явно инстанцируем шаблон
template class version::list<version::window>;
vesion::list<version::window> внутри самой библиотеки. liba и другие при компиляции не получат тело шаблона version::list, что заставит компоновщик требовать его при связывании. Таким образом, все получат в зависимостях версионированный шаблонный класс. Эта техника разделения шаблона описана тут: http://www.parashift.com/c++-faq/templates-defn-vs-decl.html.extern. Например, для std::unique_ptr:// MyTypePtr.hpp
#include <memory>
namespace mylib
{
class MyType;
} // namespace mylib
extern template class std::unique_ptr<mylib::MyType>;
namespace mylib
{
using MyTypePtr = std::unique_ptr<mylib::MyType>;
} // namespace mylib
// MyTypePtr.cpp
#include "MyTypePtr.hpp"
#include "MyType.hpp"
template class std::unique_ptr<mylib::MyType>;
extern уже давно использовался как расширение Си++ в msvc: http://support.microsoft.com/kb/168958/en-us.Теперь, при сборке самой version.dll будет использован version.script для символов vesion::list<version::window> внутри самой библиотеки. liba и другие при компиляции не получат тело шаблона version::list, что заставит компоновщик требовать его при связывании.Флаг вам в руки и барабан на шею. Поробуйте проделать это с Boost'ом или каким-нибудь Eigen'ом, потом возвращайтесь расскажете про результаты.С точки зрения version, это проблема других, как они используют эти шаблоны.Почему тогда не считать что проблемы версионированных символов, SONAME и прочего — это тоже «проблема других»? Наши тестовые программы работают — и ладно. Пусть всё через dlopen грузят, им жалко, что ли?
Даже если класс version::list<version::window> и был версионирован в version.dll, он окажется в непонятном состоянии в liba. Вот собственно тут вы и ошибаетесь. Если version::list<version::window> был версионирован в version.dll с использованием inline namespace<code> (или <code>string using), то в liba он тоже будет версионирован.Вы даже выделить объект в одной библиотеке, а потом удалить в другой не можете, какие уж тут шаблоны.
c++filt входит в состав системы, стандартный ABI вполне себе существует и всё, в общем, вполне себе работает. Есть, конечно, проблемы свяанные с тем, что программисты соответствующие инструменты неправильно используют, ну так от этого и COM не защищает.Т.е. все намного проще и удобнее, чем в других ОС, на самом деле.
Про компоновку, dependency hell и обратную совместимость