LINUX.ORG.RU

Раздвоение личности std::string под minGW (сборка openCV)

 


0

3

Собственно openCV в итоге собрать удалось, но вот дальше началось непонятное. При сборке тестового проекта (стандартная шняга с открытием картинки) вылетает куча undefined reference. Опытным путём было обнаружено, что у всех функций, которые параметром имеют std::string (алиас cv::String) не совпадает сигнатура и линкёр их не видит. Поиск навёл на подобную проблему со сборкой под мак clang-ом. Там, вроде как, 2 версии разных библиотек с реализацийе std::*, причём сигнатуры как раз совпадают с моими. Вот только никакой информации о подобном раздвоении у minGW не нашлось. При сборке openCV, вроде, никаких подозрительных флагов не нашел и почему такая разница - непонятно. Может кто в курсе, где копать?

Ответ на: комментарий от TripleGluk

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

Iron_Bug ★★★★ ()
Ответ на: комментарий от pon4ik

Я не очень помню чё там как под виндой, но, вроде бы бинари собранные с дебажным рантаймом и с релизным не совместимы. Так же как и бинари собранные со статическим и динамическим рантаймом.

Это только с MSVC, у которого есть несовместимые между собой MD/MDd (динамические) и MT/MTd (статические), у MinGW этого маразма нет

annulen ★★★★★ ()
Ответ на: комментарий от zamazan4ik

набери в гугле. я их тебе не назову по причине, описанной выше: графика меня не интересует. я занимаюсь системой и сетями. но я математик и все эти алгоритмы настолько тривиальны и очень давно используются, так что задолго до OpenCV всё это было. и написано не по разу.

Iron_Bug ★★★★ ()
Ответ на: комментарий от annulen

А чего же тогда бинарники кутишных семплов под mingw не пускаются с дебажными версиями либ?

Как минимум в 4.x ветке (Qt 4.6) я точно помню такой маразм именно с mingw32.

pon4ik ★★★★★ ()
Ответ на: комментарий от TripleGluk

которые в дебаге никто (в здравом уме)

Скажи это trolltech/nokia/digia since 2006 как минимум. А так же бусту и остальным одекватным инструментам не из разряда допили меня напильником :)

pon4ik ★★★★★ ()
Ответ на: комментарий от zamazan4ik

Лога не нашел, а в CMakeCache не нашел выбранных значений. Там везде всё подряд в кучу. И дебаг, и релиз... Ну т.е. кое что (вроде) понятно, но как вычленить из этой свалки настройки - нет. :( Вроде в cmakeVars что-то похожее, но там тоже их многовато (IMHO).

TripleGluk ()
Ответ на: комментарий от pon4ik

Скажи это trolltech/nokia/digia since 2006 как минимум. А так же бусту и остальным одекватным инструментам не из разряда допили меня напильником :)

Внезапно! А буст разве не в сырцах идёт? Там же вроде по большей части всё на темплейтах, из-за чего всё компилится по сто лет.

TripleGluk ()
Ответ на: комментарий от TripleGluk

Не считая кучи включённых варнингов там (вроде) ничего интересного.: -fdiagnostics-show-option -march=i686 -fomit-frame-pointer -ffunction-section -fdata-section -msse -msse2 -mfpmath=sse -fvisibility=hidden -DNDEBUG -shared

В списке линковки помимо его собственных модулей только всякие user32, kernel32 и т.д.

TripleGluk ()
Ответ на: комментарий от pon4ik

Статический рантайм в mingw тоже есть однако, как и в любом нормальном компиле :)

Это понятно. Но тут либа и он в качестве параметров принимает объекты этого рантайма. Не посыпется?

TripleGluk ()
Ответ на: комментарий от TripleGluk

Какая разница, если под пиндой одна фигня все зависимости распостраняются рядом с бинарём.

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

pon4ik ★★★★★ ()
Ответ на: комментарий от TripleGluk

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

Смотри разницу в флагах компиляции и линковки, делай у себя так же как в open(что ты там собираешь).

Или вот тебе идея - собери свою поделку с помощью CMake, я почти уверен, что в собираемом тобой поделии дефолт дефолтный по флагам.

А ещё такой вопрос - не статическую ли ты либу часом линкуешь?

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Ну это были дополнения к тому ответу, так что пофиг. Про cmake была мысль, но очень неохота с ним разбираться. Либы в списке указаны как .dll, так что вряд-ли. Да и статических просто нет. Есть мелкие .dll.a

TripleGluk ()
Ответ на: комментарий от TripleGluk

Ну тогда просто интереса для поставь у себя все те же флаги компилятора (линковщик по идее пока пофик), и попробуй ещё раз.

Если ты точно собираешь одной и той же версией компиля(тоже лучше проверить, cmake при начальной конфигурации пишет версию), у меня нет идей почему оно не слинкуется при одних и тех же флагах компиляции.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

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

:'(

TripleGluk ()
Ответ на: комментарий от pon4ik

Не учёл ни того, ни другого, т.к. не в курсе, о чём вообще речь. С dll я мало имел дел, и (обычно) с помощью loadLib/getProcAdr, там на тонкости пофиг. И тем более никогда с объектами, только с примитивными типами. Я правильно понимаю, что он мог собрать статический рантайм и он не совпадает с внешним?

TripleGluk ()
Ответ на: комментарий от TripleGluk

Врят ли. Возможно, что, по каким то причинам, у тебя неверно определён макрос CV_EXPORTS, я пока не нашёл в сорцах где он дифайнится.

Выведи его значение.

pon4ik ★★★★★ ()
Ответ на: комментарий от TripleGluk

В двух словах:

По умолчанию в винде dll ничего не экспортирует. Экспортируются только символы с флагом dllexport. В клиентском коде символы явно надо дополнить аттрибутом dllimport иначе, в противном случае линкер будет искать такие символы только в обьектниках и в статических либах.

По умолчанию в линуксе so всё экспортирует. Можно поменять поведение выставив флаг -fvisibillity=hidden (или как то так, на память пишу). Тогда, символы, которые надо экспортировать, надо явно пометить аттрибутом visibility(«default»). Для использования символов никаких доп телодвижений не нужно.

Начиная с какой то версии, mingw32-gcc тоже научили в visibility=hidden. А вот как оно там работает - не знаю. Для старого варианта с __declspec надо было разработчикам api делать примерно так, только с плясками ещё под сигвин, борланд, интел, и чего они там ещё хотят поддерживать.

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

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Ну можно ткнуть импорт ради прикола и посмотреть, что будет. Но вряд-ли там всё так плохо, что они так накосячили. Вроде там не в видимости проблема. Функции, в которых нет std::string вполне нормально видятся т.к. имеют одинаковые сигнатуры.

TripleGluk ()
Ответ на: комментарий от pon4ik

В чём отличия в названии я и так вижу. Собственно тема с этого началась ;) Я не понимаю, почему они есть.

Сигнатур там две. Обе они гуглом ищутся на раз. Одна обычная, как я понимаю. Та, которая в либе. Вторая (у меня в проекте) такая, как у людей с аналогичной проблемой на маках с clang. У которых цепляется не та stdc++ Но в mingv я не нашел инфы про две версии этой либы и возможность её выбора. Она либо есть, либо нет.

TripleGluk ()
Ответ на: комментарий от TripleGluk

В общем если там будет что-то в духе std::cxx11::basic_string, что мне подсказывает интуёвина, то делай так:

cd <opencv-build-dir>
rm -fr *
cmake -DCMAKE_CXX_STANDARD=11 <other options>
mingw32-make
pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Первая без стринга. Дальше сверху из моего проекта, снизу из либы

__ZN2cv7waitKeyEi

__ZN2cv6imshowERKSsRKNS_11_InputArrayE

__ZN2cv6imshowERKNS_6StringERKNS_11_InputArrayE

__ZN2cv6imreadERKSsi

__ZN2cv6imreadERKNS_6StringEi

Хз как тут одиночный перенос строки сделать.

TripleGluk ()
Ответ на: комментарий от zamazan4ik

Из чего такой вывод? Сигнатуры должны совпадать до линковки, в этом их смысл. Без этого слинковать не сможет. Для первой функции (у которой они совпадают) ошибки НЕ выдаётся (о чём писал уже)

TripleGluk ()
Ответ на: комментарий от pon4ik

Кажется нашел. Очень странная хрень. Попытался объявить у себя функцию с параметром cv::String (алиас std::string) но сделал это немного криво и он выдал сообщение про std::basic_string. Т.е. 1. Собирается неправильно мой проект. 2... !?

TripleGluk ()
Ответ на: комментарий от Iron_Bug

Ты почитай исходники OpenCV! Я и сам подумывал было это говно использовать, но как глянул, что там внутри за быдлокод, понял, что лучше самому с нуля писать! Там вообще никакой оптимизацией и не пахнет. И CUDA они никак не осилят...

anonymous ()