QA Fest — конференция №1 по тестированию и автоматизации. Финальная программа уже на сайте >>
×Закрыть

Как выбирать в линухе нужную версию либы?

В линухе установлен matlab. Он с собой тянет opencv 2.4.
Я ручками собрал и установил OpenCV 3.2 (make, make install).

Один добрый человек сделал биндинг к матлабу mexopencv.
Это я тоже собрал. И почти работает, но столкнулся со следующей проблемой:
в точности ее описание здесь есть github.com/…​magu/mexopencv/issues/195 (это не от меня а от кого-то другого, неважно).

Кратко, в матлабе всегда подтягиваются версии opencv 2.4, а не 3.2, как мне надо.
Точнее мне нужно, чтобы сам матлаб мог использовать opencv 2.4 там, где ему нужно, а мои скрипты, что используют биндинги использовали 3.2.

Вот там ответ собственно автора mexopencv:
kyamagu commented on Oct 9, 2015

@chenfisher I think the best solution in this scenario is to use the v2.4 branch of mexopencv and link against Matlab’s own shared object in the build script. I have never tried that, but probably you cannot load two versions at the same time. Static linking could remedy some issue, but that will require huge amount of dependent libs linked to OpenCV.

Т.е. он видит решение в статической линковке, но сам с этим возиться не хочет. И матлаб использует mex для компиляции и линковке, который внутри уже дергает настроенный компилятор и предпочитает so вариант (то есть прмого и явного пути для статической линковки не предлагается).

В Винде такой проблемы нет, потому как версия OpenCV есть в имени файла dll и все прекрасно разруливается само. Главное, чтобы путь в переменной PATH был прописан.

Вопрос, как разруливают такие ситуации в Линуксе?
И второй вопрос:
Как в линуксе явно заставить прилиноквать статические либы?
pkg-config —static —libs opencv возвращает ровно тоже, что и pkg-config —libs opencv

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

хм. а не проще ли поставить octave и дергать mexopencv оттуда?

Как в линуксе явно заставить прилиноквать статические либы?
... -Wl,-Bstatic, -lblabla, -Wl,-Bdynamic ...

Но ты бы лучше собрал все с чем то одним.

короче сделай две вещи:
1. strace -e open -o out.txt matlab -r „cd /home/viktor/Work/experimental/Visual/ImgProc/mat; runtests uts.m” -nodisplay -noFigureWindows -nosplash
2.1 ulimit -c unlimited
2.2 gdb coredump
2.3 (в gdb) bt
Результаты расшарь.

strace -binary- | grep open
и смотри куда и в каком порядке бинарь ходит за библиотеками, скорее всего он находит 2.4 раньше чем 3.2

Да именно так. В матлабе так жестко сделано, сначала в свою папку с либами, а потом уже к системе.

Если в исполнимом файле прошит realsoname (objdump -x покажет), то он будет искать именно то, что указано, но там может быть ещё такая вещь, как множественная зависимость. Например при подгрузке одна из либ использует 3.2, они загрузятся первыми, а прописанная 2.4 не загрузится никогда, потому что все имена динамический линер уже разрешил.

Так, это хреновенько. А как тогда разруливают такую ситуацию?
Куча имен пересекаются в opencv 2 и 3, причем многое работает и сделано по разному.
Т.е. получается, что в одном приложении я не могу использовать две разных версии OpenCV другим способом, как через dlopen?

Перелинковывают от и до.

Сделай то, что я сказал — станут ясны причины, а по ним можно будет и решение найти.

Я попробовал

 strace /home/viktor/MATLAB/R2016b/bin/matlab -r "cd /home/viktor/Work/experimental/Visual/ImgProc/mat; runtests uts.m" -nodisplay -noFigureWindows -nosplash 2>&1 | tee re.txt
и в re.txt c opencv только такие строчки:
Stack Trace (from fault):
[  0] 0x00007fe9bc421ac2 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01411778 _ZNK2cv3Mat6copyToERKNS_12_OutputArrayE+00000034
[  1] 0x00007fe9bc3dc744 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01128260 _ZNK2cv3Mat9convertToERKNS_12_OutputArrayEidd+00000964
[  2] 0x00007fe993dd17a7 /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64+00137127
[  3] 0x00007fe993dbbb93 /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64+00048019 mexFunction+00004001

В тоже время

viktor@VIK-MINT18 ~/OpenCV $ objdump -x /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64 | grep opencv
/home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64:     file format elf64-x86-64
/home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64
  NEEDED               libopencv_xfeatures2d.so.3.2
  NEEDED               libopencv_features2d.so.3.2
  NEEDED               libopencv_flann.so.3.2
  NEEDED               libopencv_imgproc.so.3.2
  NEEDED               libopencv_core.so.3.2
0000000000000000 l    df *ABS*	0000000000000000              mexopencv_features2d.cpp
000000000001af64 l     F .text	0000000000000015              _GLOBAL__sub_I_mexopencv_features2d.cpp

Если я ручками удалю opencv либы из /home/viktor/MATLAB/R2016b/bin/glnxa64/ то биндинг работает, но не работают матлабовские функции, что oт opencv зависят.

Блин, в Винде я близко такой проблемы не словил. Это реально dll-hell в сравнении с виндой.
Но хотелось в Линухе иметь возможно одновременно из матлаба использовать и opencv2 и opencv3 и собственные аналогичные функции матлаба. В винде это у меня без проблем работало.

А можешь просто — strace matlab
или сказать, где скачать 2016-й и твою либу?

Могу, но там простыня еще та. Матлаб на рутреккере, но он большой (7G) и без опыта заманаешься его ставить, еще и с таблеткой.
Мне не понятно, если objdump четко указывает на версию so, то какого черта используется другая

/home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4
Я ставлю его в хомяка, потому как в этом случае меньше гемора с поправкой прав ему после исталляции.
Вот ссылка drive.google.com/…​aMzlFVG8/view?usp=sharing

strace -e open -o out.txt matlab 
Прости завтыкал

Получишь что-то подобное:
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libuuid.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libssl.so.1.0.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libcrypto.so.1.0.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/usr/lib/x86_64-linux-gnu/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 open("/etc/wgetrc", O_RDONLY)           = 3 open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3 open("/usr/share/locale/en_US/LC_MESSAGES/wget.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/wget.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale-langpack/en_US/LC_MESSAGES/wget.mo", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale-langpack/en/LC_MESSAGES/wget.mo", O_RDONLY) = -1 ENOENT (No such file or directory) +++ exited with 1 +++

Не вижу либы. Попробуй еще со скриптом.

Так да, я тоже не вижу. Вот так запускал
strace -e open -o out.txt /home/viktor/MATLAB/R2016b/bin/matlab -r „cd /home/viktor/Work/experimental/Visual/ImgProc/mat; runtests uts.m” -nodisplay -noFigureWindows -nosplash
и в консоли матлабовской вижу:

                                                                                            < M A T L A B (R) >
                                                                                   Copyright 1984-2016 The MathWorks, Inc.
                                                                                   R2016b (9.1.0.441655) 64-bit (glnxa64)
                                                                                              September 7, 2016

 
To get started, type one of these: helpwin, helpdesk, or demo.
For product information, visit www.mathworks.com.
 
Running uts
.Attempt to restart MATLAB? [y or n]>>y
------------------------------------------------------------------------
       Segmentation violation detected at Wed Apr 12 17:37:43 2017
------------------------------------------------------------------------

Configuration:
  Crash Decoding      : Disabled - No sandbox or build area path
  Crash Mode          : continue (default)
  Current Graphics Driver: Unknown software 
  Current Visual      : None
  Default Encoding    : UTF-8
  Deployed            : false
  GNU C Library       : 2.23 stable
  Host Name           : VIK-MINT18
  MATLAB Architecture : glnxa64
  MATLAB Entitlement ID: Unknown
  MATLAB Root         : /home/viktor/MATLAB/R2016b
  MATLAB Version      : 9.1.0.441655 (R2016b)
  OpenGL              : software
  Operating System    : Linux 4.8.0-42-generic #45~16.04.1-Ubuntu SMP Thu Mar 9 14:10:58 UTC 2017 x86_64
  Processor ID        : x86 Family 31 Model 10 Stepping 0, AuthenticAMD
  Virtual Machine     : Java 1.7.0_60-b19 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
  Window System       : No active display

Fault Count: 1


Abnormal termination:
Segmentation violation

Register State (from fault):
  RAX = 00007f3402010000  RBX = 00007f34bf4af9e0
  RCX = 00007f344b2a1fac  RDX = 0000000000000000
  RSP = 00007f34bf4af570  RBP = 00007f34bf4afa60
  RSI = 00000000ffffffff  RDI = 00007f34bf4af9e0

   R8 = 0000000042ff4000   R9 = 0000000000000000
  R10 = 00007f34bf4afa68  R11 = 0000000000000004
  R12 = 0000000000000000  R13 = 00007f34bf4af9e0
  R14 = 0000000000000000  R15 = 0000000000000001

  RIP = 00007f341461fac2  EFL = 0000000000010202

   CS = 0033   FS = 0000   GS = 0000

Stack Trace (from fault):
[  0] 0x00007f341461fac2 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01411778 _ZNK2cv3Mat6copyToERKNS_12_OutputArrayE+00000034
[  1] 0x00007f34145da744 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01128260 _ZNK2cv3Mat9convertToERKNS_12_OutputArrayEidd+00000964
[  2] 0x00007f33d02f57a7 /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64+00137127
[  3] 0x00007f33d02dfb93 /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64+00048019 mexFunction+00004001
[  4] 0x00007f34d0623caa   /home/viktor/MATLAB/R2016b/bin/glnxa64/libmex.so+00175274 mexRunMexFile+00000106
...

Добавить -f для strace. Потому что не видно загрузки библиотек, но виден fork (в виде clone) — скорее всего, часть действий выполняется в потомке.

Блин, в Винде я близко такой проблемы не словил. Это реально dll-hell в сравнении с виндой.
Да, винда немного умнее. Есть приложение, которое использует либу версии X, есть плагин к приложению, который использует либу версии Y, даже несмотря на то, что имена функций могут быть одинаковые, винда использует прямые ссылки на прилинкованную DLL, а линуксе динамический линкер пытается разрешить именно имена функций, что позволяет вступить в гуано по самые уши. Просто винда, как десктопная ОС с этим столкнулась гораздо раньше:
en.wikipedia.org/…​iki/Side-by-side_assembly

А линукс всегда был непригодный для самокомпиляции приложений, только хорошо работает установка из пакетов, собранных централизовано с использованием одной-двух версий библиотек и всё. Во всех остальных случаях, нужна либо анальная изоляция в виде chroot, где полностью лежит копия системы, но с либами тех версий, что тебе нужны, либо статическая линковка (предпочтительнее), но там тоже своих граблей хватает. Например, не все линуксы хорошо работают с миксом POS (-fPIC опция к gcc) и non-POS кода (который обычно присутствует в статических библиотеках). Например, -fPIC запрещала в том числе портить EBX регистр, который использовался для хранения Global Offset Table, а в обычных статических либах был код, который портил EBX. В результате, если к .so прилинковать .a, то можно было наблюдать феерические факапы приложения в разных местах и кучу другого фана. en.wikipedia.org/…​Position-independent_code

Есть приложение, которое использует либу версии X, есть плагин к приложению, который использует либу версии Y, даже несмотря на то, что имена функций могут быть одинаковые, винда использует прямые ссылки на прилинкованную DLL, а линуксе динамический линкер пытается разрешить именно имена функций, что позволяет вступить в гуано по самые уши.
И что, другого пути в виде виртуалки полноценной или не очень нет?
А есть возможно в линуксе как-то прибить гвоздями, что должна юзаться в этой либе исключительно нужная мне сторонняя либа, а не то, что хочет динамический линкер?

Написать свой динамический линкер. С нужной логикой разрешения символов.

Вернуться на Винду, где эта проблема не существует уже хер знает сколько лет.

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

Если бы не было конфликта по символам в общем пространстве (вторая библиотека загружена с RTLD_LOCAL), думаю, установка RPATH использующему — помогла бы.

Но при общем пространстве — поможет только версионирование символов.

Можно попробовать собрать либу с -Bsymbolic, есть некоторые шансы что будет работать

Я уже написал, что с помощью одного знакомого, сумел статически opencv3 вкомпилить в mexa64 файлы.
Оказалось не так страшно, как напугал kyamagu.
Для экспериментов и исследований мне достаточно.

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

Ну, просто обычно люди не понимают как это все работает. Типа разбираться лень, УМВР, вот вам мой говнокод — пользуйтесь дорогие.

винда использует прямые ссылки на прилинкованную DLL
Я как-то так давно виндой не пользовался видать, что вообще не понимаю что это может значить. Это оно как-то магически понимает, что вот эту MegaFunction1 надо брать из DLL1, а MegaFunction2 из DLL2 еще до этапа динамической линковки?
Например, не все линуксы хорошо работают с миксом POS (-fPIC опция к gcc) и non-POS кода (который обычно присутствует в статических библиотеках).

Это как в анекдоте про крестик

Это как в анекдоте про крестик
Ану :)
Я как-то так давно виндой не пользовался видать, что вообще не понимаю что это может значить.
Я там вверху приводил ссылку на педивикию про Side-by-side_assembly

Ну а можно как-нибудь привязать ее контент к сложивщейся трагедии топикстартера?

В линаксе в общем случае нет проблем подгрузить в один процесс пару либ разных версий. Гнушному линкеру конечно далеко до энтерпрайза с XML, но symbolic-functions есть, soname есть, symver есть. Нужно только что бы быдлокодящие либы инвалиды были об этом в курсе.

Ну а можно как-нибудь привязать ее контент к сложивщейся трагедии топикстартера?
Если перейдёт на винду — несомненно.
В линаксе в общем случае нет проблем подгрузить в один процесс пару либ разных версий.
И тут на арену выходит горбатый С++ (OpenCV, етить) и разносит в пух и прах все эти пластыри, подорожники, и прочие бинты с костылями из палочек из под мороженого. Когда часть кода компилируется в виде темплейтов в основное приложение, а часть остаётся в либе. Только подсунешь либу другой версии и вся память в корке. «С» тоже этим грешит с любителями в хедерах использовать static inline functions, в которых, например используется sizeof() какой-то структуры, которая имеет другой размер в другой версии.

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

Да все есть, просто читать никто не хочет. У того же Ульриха есть отличная статья, как правильно писать библиотеки.

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

Он описывает техническую часть, а не архитектурную. Например, никогда не светить структурами для пользователя, а выставлять наружу только opaque типы. Как поддерживать обратную и прямую совместимость, например, многие ли из либо-писателей делают проверку при передаче каких-нибудь флагов на то, что был передан неподдерживаемый флаг? И таких ньюансов вагон и маленькая тележка, каждые подобные грабли обильно окроплены кофем и смазаны многочасовыми овертаймами.

ELF DSO практически полностью определяются одним документом 1995 года выпуска:

refspecs.linuxbase.org/elf/elf.pdf

Там интересный список авторов на 2й странице. Писалось это для System V UNIX, Линукса в современном понимании тогда ещё не было. По этому же документу работают все *BSD и ещё много чего:

en.wikipedia.org/…​kable_Format#Applications

Когда часть кода компилируется в виде темплейтов в основное приложение, а часть остаётся в либе. Только подсунешь либу другой версии и вся память в корке.

Не, ну обождите. Чудес не бывает. Если код A и Б имеют одинаковый ABI, а код A и C не имеют одинаковый ABI, чудо не произойдет ни в одной операционной системе ни с одной реализацией линкера.

Обычно имеет быть ситуация иного характера, когда есть код X и Y, и ни коим образом не возможно определить, где Б и где С. Получается бум.

Вот WinSxS про это вот разделение, равно как и symver/soname.

Я не спец в системном программировании, но матлаб в винде как-то без проблем мог одновременно и opencv2 и opencv3 юзать. Правда в винде opencv присобачивает номер версии к имени файла, а загрузчик либ как то разбирается от какой либы заюзать функцию, хоть и с одинаковой сигнатурой.
И симлинки в винде ну очень редко юзаются.

Правда в винде opencv присобачивает номер версии к имени файла,

Линкер при линковке с динамической библиотекой пихает в секцию результирующего объекта т.н. soname этой самой динамической библиотеки. Т.е. если автор либы почесался и собрал свое творение как-нибудь так -Wl,-soname,blabla.so.100500, то при ld.so при загрузке твоего объекта будет поищет (а если не найдет — то завалится) либу с таким-же soname (или по крайней мере именем файла). Но твоему коду в целом нужна не либа, а функции из этой либы.

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

Если ты свою либу грузишь не руками (что кстати было бы прямее), а отдаешься на откуп ld.so, ему нужно как-то понять, как разрешать объекты, которых у тебя в в бинаре нет. И там есть несколько стратегий. Типа пихать все символы в один большой котел (что обычно и делается), или же строить иерархию (blog.flameeyes.eu/…​r-what-does-bsymbolic-do) (что обычно не делается).
Хорошо описано как правильно поступать в статье Ульриха.

И симлинки в винде ну очень редко юзаются.

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

В SxS как раз юзаются в полный рост, только в виде хардлинков.

Disk Space

In practice, nearly every file in the WinSxS directory is a „hard link” to the physical files elsewhere on the system—meaning that the files are not actually in this directory. For instance in the WinSxS there might be a file called advapi32.dll that takes up >700K however what’s being reported is a hard link to the actual file that lives in the Windows\System32, and it will be counted twice (or more) when simply looking at the individual directories from Windows Explorer.
Я как-то так давно виндой не пользовался видать, что вообще не понимаю что это может значить. Это оно как-то магически понимает, что вот эту MegaFunction1 надо брать из DLL1, а MegaFunction2 из DLL2 еще до этапа динамической линковки?

Там двухфазная реализация. Есть сама dll и есть к ней lib для компиляции («import library»). lib всегда линкуется статически и представляет собой для каждой функции простой переходник типа «искать функцию с именем X в библиотеке Y.dll» (хотя можно извратиться и засунуть туда более сложный код), так что линкер вообще ничего про динамическую линковку не знает.
(Особые извращенцы могут перенести эту же схему на Unix, это тривиально, но они подтвердят своё звание;))

При совпадении имён библиотек в Windows в одном процессе была бы такая же ситуация, как у ТС. Но вот если при статической линковке имена dll разные, но символы компиляции совпадают, то в Windows каждый линкуемый компонент видит своё пространство имён, которые затем превращаются в вызовы разных dll. Например, основная программа знает foo, которое buka.dll!foo, а нечто подгружаемое — foo, которое zuka.dll!foo — рантайм про конфликт вокруг foo ничего не узнает.

Как прямое следствие — если каждый компонент с libc (который зовётся crt${номер}.lib или как-то похоже), эти libc будут по экземпляру в каждой dllʼке и в главном бинаре, и могут передраться за функциональность — поэтому есть масса ограничений, в первую очередь жёсткое правило полученное по malloc в некоторой dll освобождать в ней же. Кому нужно без ограничений — должен использовать всякие VirtualAlloc из уже виндового рантайма. Ну и другие подобные фишки.

readelf -d, а не objdump, на будущее.

Блин, в Винде я близко такой проблемы не словил. Это реально dll-hell в сравнении с виндой.

В либах написаных нормальными людьми есть обратная совместимость, так что ты бы подсунул своему матлабу новенький блестящий opencv, и все бы поехало. Проблема в том, что в основном код пишут какие-то инвалиды. Особенный ад в околонаучном и академическом софте. Тебе это конечно не поможет, но тем не менее :D

readelf -d, а не objdump, на будущее.
Я против. objdump я посоветовал :), т.к. он идёт с gcc toolchain’ом, ему пофиг — elf, не elf, он реально знает все бинарные форматы, в этом его и удобство.
он реально знает все бинарные форматы

Ну, это безусловно полезное качество когда нужно посмотреть .dynsym матлаба. Наверняка он закодирован в ihex, и objdump’ом это сделать проще простого

Да, а еще матлаб тянет с собой даже java и с другой конкретно глючит, я проверял когда-то.
Но мне один знакомый уже помог, мы сумели статически влинковать OpenCV на линухе.
Тот же OpenCV делает кривой opencv.pc файл.
А кривость и недоделанность pkg-config меня уже впечатлила.

А кривость и недоделанность pkg-config меня уже впечатлила.
Тихо шёпотом в сторону. Вот и меня в один прекрасный день всё это настолько достало, что я встал, сказал «епись оно всё конём!» и ушёл из линукса (это я так думаю, что ушёл, уйти от туда можно только вперёд ногами).

Винда сейчас не лучше. Она меня настолько достала, что я в линух решил уйти.
Теперь привыкаю к его кривости. Где-то он менее крив Винды, где-то более.
Винда стала напрягать собственной жизнью, не зависящей от моих желаний. Линух хоть и крив и не доделан, но не делает того, что от него не просят, пока.
В линухе, надо мне помучиться и привыкнуть к его кривизне и знать где и как ее обходить. Как там «сначала было тяжело, а потом привык».

Первый ответ вот тут:
stackoverflow.com/…​s-with-different-versions
sourceware.org/…​8/ld/VERSION.html#VERSION

Идея в том, чтобы в готовой библиотеке получить немного другие имена для функций. Вместо foo::bar чтобы было foo::bar@3.2. И слинковать mex на вот эти новые имена.
То же самое касается зависимостей с разными версиями.

Проблема уходит корнями глубоко в недра GNUшного линкера. Простых решений не будет.
Правильное с точки зрения GNU решение ­— пересобрать Matlab под системные библиотеки.

Поэтому я и советую strace — он покажет что происходит в динамике.
А то бывали ситуации, когда загрузчик ходил где-то в lib, a где-то в lib64.

Поэтому я и советую strace — он покажет что происходит в динамике.

Если хочется посмотреть, что действительно /происходит/, лучше использовать не strace, а LD_DEBUG=all

Во время рантайма или во время компиляции? В ELF может может быть (а скорее всего так и есть) зашит realsoname во время линковки и там будет не libxxxx.so, а libxxxx.so.1.2.3.4.5.

Как в линуксе явно заставить прилиноквать статические либы?
pkg-config —static —libs opencv возвращает ровно тоже, что и pkg-config —libs opencv
LDFLAGS="-static `pkg-config —static`" make
Вопрос, как разруливают такие ситуации в Линуксе?
При линковке можно указать вместо -lopencv -l:libopencv.so.x.y.z , если линкёр не очень древний.

А здесь так влоб попробовал. mex выдает, что не в курсе про ключ —static. Т.е. либо как-то хитро его прокинуть через mex к gcc (наверное как-то можно, но до такого уровня не лазил пока).
Под виндой этих трюков не надо было.

При линковке можно указать вместо -lopencv -l:libopencv.so.x.y.z , если линкёр не очень древний.
И он явно именно эти версии прилинкует? Т.е я могу сделать линки с другим именами (типа opencv3.2_лялялля.so) на нужные мне либы и указать их при линковке? и по линкам он заюзает именно то, что мне нужно?
Т.е я могу сделать линки с другим именами (типа opencv3.2_лялялля.so) на нужные мне либы и указать их при линковке? и по линкам он заюзает именно то, что мне нужно?
Да, но зачем создавать линки? Укажи где лежат либы через -L и через -l: укажи имя либы — линкёр сам её найдёт.

Либ там дофига в OpenCV
А в одну все в opencv_world пока не получается собрать.
Оно же, блин еще дофига времени собирает.
Просто этот

kyamagu
написал makefile, а я в них не очень, я уже давно cmake предпочитаю, ибо он проще.
Он делает так:
# OpenCV flags
ifneq ($(shell pkg-config --exists --atleast-version=3 $(PKG_CONFIG_OPENCV); echo $$?), 0)
    $(error "OpenCV 3 package was not found in pkg-config search path")
endif
CV_CFLAGS  := $(shell pkg-config --static --cflags $(PKG_CONFIG_OPENCV))
CV_LDFLAGS := $(shell pkg-config --static(этот статик ничего не дает, я его добавил) --libs $(PKG_CONFIG_OPENCV))
ifndef NO_CV_PKGCONFIG_HACK
#LIB_SUFFIX := %.so %.dylib %.a %.la %.dll.a %.dll
LIB_SUFFIX := %.a %.la
CV_LDFLAGS := $(filter-out $(LIB_SUFFIX),$(CV_LDFLAGS)) \
              $(addprefix -L, \
                  $(sort $(dir $(filter $(LIB_SUFFIX),$(CV_LDFLAGS))))) \
              $(patsubst lib%, -l%, \
                  $(basename $(notdir $(filter $(LIB_SUFFIX),$(CV_LDFLAGS)))))
endif
я попробовал дописать такую строчку
CV_LDFLAGS := --static $(CV_LDFLAGS)
Меня mex послал лесом со «—static»

Один дефис, а не два.

Именно во время рантайма.
ldd показывает всё, как мне надо.
Причем !ldd в матлабе (есть такая там функция) тоже показывает правильные пути к либам.
А вот в рантайме все время тянет 2.4.

 !ldd /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64
	linux-vdso.so.1 =>  (0x00007ffcff7cb000)
	libopencv_xfeatures2d.so.3.2 => /usr/local/lib/libopencv_xfeatures2d.so.3.2 (0x00007f44bc4e3000)
	libopencv_features2d.so.3.2 => /usr/local/lib/libopencv_features2d.so.3.2 (0x00007f44bc219000)
	libopencv_flann.so.3.2 => /usr/local/lib/libopencv_flann.so.3.2 (0x00007f44bbfc0000)
	libopencv_imgproc.so.3.2 => /usr/local/lib/libopencv_imgproc.so.3.2 (0x00007f44ba770000)
	libopencv_core.so.3.2 => /usr/local/lib/libopencv_core.so.3.2 (0x00007f44b99f3000)
а при выполнении крэш:
[  0] 0x00007f9962ddcac2 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01411778 _ZNK2cv3Mat6copyToERKNS_12_OutputArrayE+00000034
[  1] 0x00007f9962d97744 /home/viktor/MATLAB/R2016b/bin/glnxa64/libopencv_core.so.2.4+01128260 _ZNK2cv3Mat9convertToERKNS_12_OutputArrayEidd+00000964
[  2] 0x00007f9957de67a7 /home/viktor/OpenCV/mexopencv/+cv/private/FeatureDetector_.mexa64+00137127
что логично.

ldd показывает то, что якобы увидит динамический линкёр, часто это не соответствует действительности. Реальность обычно показывается вот так:

objdump -x exe_name | grep NEEDED

export LD_LIBRARY_PATH не пробовали?

Матлав ее добавляет после своей. И соответсвенно дергает версию 2.4, но биндинг для 3.2 и облом.
С LD_PRELOAD тоже в посте попробовали, всё тоже самое.

Подписаться на комментарии