Не могу слинковаться из С++ под Windows (x64, MSYS2) с POCO
Господа.
я уже неделю занимаюсь этим, перепробовал всё, что только можно, на нескольких компьютерах, но прогресса - пока никакого.
Специально пишу подробно, пожалуйста, проверьте ход моих рассуждений, возможно, я где то "схожу с тропы".
Смотрите, что я делаю.
Система - Windows 10, 64bit, установлены MSYS2, притащивший в систему g++ и gdb, и Visual Studio 2019.
g++ --version выдает инфу g++ (Rev2, Built by MSYS2 project) 9.2.0
Всё 64-битное.
Беру проект https://github.com/spot62/PocoAngularTodo - простое приложение, которое запускает http - сервер из POCO и начинает слушать порт.
Хочу скомпилировать его для своей системы (из командной строки, потому что потом я эту конфигурацию засуну в VSC и буду в ней дебажиться).
Заглядываю в Makefile, вижу флаги линковщика, которые говорят мне, что на этапе линковки нужны такие библиотеки: -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoUtil -lPocoXML
Ставлю чистенький, cвеженький vcpkg из репозитория https://github.com/microsoft/vcpkg и собираю его, запустив bootstrap-vcpkg.bat - это рекомендованный способ. Пока всё нормально.
Теперь у меня есть пакетный менеджер, могу попросить у него собрать библиотеки. Они мне, для 64битного проекта, нужны 64 битные. Поэтому я собираю их вызовом vcpkg install poco:x64-windows
Теперь у меня есть следующее:
include - файлы, котроые лежат в D:\Programs\vcpkg\installed\x64-windows\include
Библиотеки, котроые лежат в D:\Programs\vcpkg\installed\x64-windows\debug\lib
Глазами смтотрю - вроде всё на месте.
Делаю из всей вышеприведенной информации команду для g++: включаю туда путь к инклудам, путь к либам (не забыв перевернуть слеши в другую сторону), и список библиотек, с которыми я собственно линкуюсь. Для очистки совести еще раз говорю, что у меня всё 64-битное ключем -m64.
Теперь мне - по моей логике - команда g++ -m64 -std=c++17 -lstdc++ -ID:\Programs\vcpkg\installed\x64-windows\include -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoUtil -lPocoXML -LD:/Programs/vcpkg/installed/x64-windows/debug/lib main.cpp TodoServerApp.cpp -o TodoServerApp, вызванная из директории проекта, должна всё собрать.
Но нет. Получаю ВСЕГДА, при любых попытках как то повлиять на стуацию, ошибки линковки. В этом кокретном случае - линкер просто не видит библиотек:
g++ -m64 -std=c++17 -lstdc++ -ID:\Programs\vcpkg\installed\x64-windows\include -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoUtil -lPocoXML -LD:/Programs/vcpkg/installed/x64-windows/debug/lib main.cpp TodoServerApp.cpp -o TodoServerApp
In file included from D:\Programs\vcpkg\installed\x64-windows\include/Poco/String.h:22,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/NameValueCollection.h:22,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/MessageHeader.h:22,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/HTTPMessage.h:22,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/HTTPRequest.h:22,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/HTTPServerRequest.h:22,
from TodoServerApp.h:4,
from TodoServerApp.cpp:4:
D:\Programs\vcpkg\installed\x64-windows\include/Poco/Ascii.h:133:13: warning: 'static bool Poco::Ascii::isAscii(int)' redeclared without dllimport attribute after being referenced with dll linkage
133 | inline bool Ascii::isAscii(int ch)
| ^~~~~
In file included from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/HTTPResponse.h:24,
from D:\Programs\vcpkg\installed\x64-windows\include/Poco/Net/HTTPServerResponse.h:22,
from TodoServerApp.h:6,
from TodoServerApp.cpp:4:
D:\Programs\vcpkg\installed\x64-windows\include/Poco/Timestamp.h:256:28: warning: 'static Poco::Timestamp::TimeDiff Poco::Timestamp::resolution()' redeclared without dllimport attribute after being referenced with dll linkage
256 | inline Timestamp::TimeDiff Timestamp::resolution()
| ^~~~~~~~~
C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lPocoFoundation
C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lPocoNet
C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lPocoNetSSL
C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lPocoUtil
C:/Programs/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lPocoXML
collect2.exe: error: ld returned 1 exit status
Что еще я пробовал:
0) До объектных файллов процесс доходит без ошибок, я получаю командой g++ -m64 -std=c++17 -lstdc++ -ID:\Programs\vcpkg\installed\x64-windows\include -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoUtil -lPocoXML -LD:/Programs/vcpkg/installed/x64-windows/debug/lib main.cpp TodoServerApp.cpp -c хорошие, жирные TodoServerApp.o и main.o
1) пробовал собрать библиотеки при помощи команды
vcpkg install poco: x64-mingw - но это так называемый 'community triplets', про который пишут, что он не гарантировано работоспособен - и действительно, он не завершает работу. Повисает где то в середине. я конечно послал логи в составе iisues для vcpkg, но не думаю, что они будут этим особо заниматься.
2) попробовал принудительно выставить статическую линковку. результат примерно такой же.
3) я уже начинаю впадать в паранойю, и думать, не может ли ошибка быть связана с тем, что у меня вызывается линкер "не той системы"? например, 32-битный? Но как это проверить? Вторая параноидальная идея - не может проблем быть из аз того, что компилятор установлен на диск C:\, а проекты и библиотеки лежат на диске D:?
Может быть, есть какой то простой метод диагностики, который мне не приходит в голову и который покажет, что не так с библиотеками? Может, я в силу своей неопытности, просто неправильно формирую команду на линковку с ними?
Спасибо заранее за советы.
Ответы (1 шт):
Господа, большое спасибо, замечание HolyBlackCat было решающим.
Благодаря ему я вышел на дискуссию дискуссию.
После этого я смог набрать пару команд:
первая pacman -Ss poco нашла пакеты, на её основе я сделал вторую - pacman -S mingw-w64-x86_64-poco - и она поставила пакеты в систему.
Но это была еще не окончательная победа. Поискав нужные файлы среди скачанных, я нашел две версии библиотеки: libPocoFoundation.dll.a и PocoFoundationd.dll
После этого, попробовав команду
g++ -m64 -std=c++17 -lstdc++ -IC:\Programs\msys64\mingw64\include -lPocoFoundation -lPocoNet -lPocoNetSSL -lPocoUtil -lPocoXML -LC:/Programs/msys64/mingw64/bin main.cpp TodoServerApp.cpp -o TodoServerApp - я, наконец, получил нужный результат!
Выводы:
1) Нельзя в одном проекте C++ совмещать код, собранный разными компиляторами
2) "учите матчасть": если бы я сразу знал, что poco есть в msys2 - мне бы пришлось гораздо меньше возиться.
Спасибо большое всем и HolyBlackCat в особенности!
И, пока "суп не остыл в горшке", еще один вопрос: а как быть со статической линковкой? я так понял, что для этого нужно не просто добавить ключ -static в команду сборки проекта, а еще и запастись статическими версиями библиотек.
Я попробовал вариант с тем, что возможно в директории msys2 лежит в msys64\mingw64\bin динамический вариант, а в msys64\mingw64\lib - статический, но так не работает... При попытке линковаться статически по прежнему появляется ошибка линкера о том, что не найдена библиотека. Какие нибудь советы на эту тему есть?