simulton / QSchematic

A library that allows creating diagrams such as flowcharts or even proper engineering schematics within a Qt application.
https://simulton.com
MIT License
231 stars 60 forks source link

Visual Studio linker error #40

Closed Galileo53 closed 9 months ago

Galileo53 commented 1 year ago

I am using Cmake 3.26.4 and Visual Studio 16.11.11 with C++ 2019. Everything compiles fine, but the linker issues the following error:

LNK2019 unresolved external symbol "public: void __cdecl wire_system::manager::detach_wire(struct wire_system::connectable const *)" (?detach_wire@manager@wire_system@@QEAAXPEBUconnectable@2@@Z) referenced in function "private: void __cdecl QSchematic::Items::Connector::disconnect_all_wires(void)" (?disconnect_all_wires@Connector@Items@QSchematic@@AEAAXXZ) qschematic-shared D:\qschematic\build\qschematic\connector.obj 1

and a lot of more similar errors, all related to the Connector class and the connectable struct.

While the "detach_wire(const connectable* connector)" seems to defined and implemented well, the "detach_wire(this);" reference is not solved by the linker.

I have tried for hours to find the problem, but did not succeed. Can anybody please help me to fix this error?

Tectu commented 1 year ago

I'll be having a look. Could you please provide the entire build output of a clean build for referencing?

Galileo53 commented 1 year ago

Build started... 1>------ Build started: Project: ZERO_CHECK, Configuration: Debug x64 ------ 1>Checking Build System 2>------ Build started: Project: gpds-static, Configuration: Debug x64 ------ 3>------ Build started: Project: gpds-shared, Configuration: Debug x64 ------ 2>Building Custom Rule D:/qschematic/build/_deps/gpds-src/lib/CMakeLists.txt 2>archiver_xml.cpp 3>Building Custom Rule D:/qschematic/build/_deps/gpds-src/lib/CMakeLists.txt 3>archiver_xml.cpp 2>container.cpp 3>container.cpp 2>value.cpp 3>value.cpp 2>serialize.cpp 3>serialize.cpp 2>tinyxml2.cpp 2>Generating Code... 3>tinyxml2.cpp 3>Generating Code... 2>gpds-static.vcxproj -> D:\qschematic\build_deps\gpds-build\lib\Debug\gpdsd.lib 4>------ Build started: Project: qschematic-static, Configuration: Debug x64 ------ 5>------ Build started: Project: qschematic-shared, Configuration: Debug x64 ------ 5>Automatic MOC for target qschematic-shared 4>Automatic MOC for target qschematic-static 4>Building Custom Rule D:/qschematic/qschematic/CMakeLists.txt 5>Building Custom Rule D:/qschematic/qschematic/CMakeLists.txt 3>gpds-shared.vcxproj -> D:\qschematic\build_deps\gpds-build\lib\Debug\gpdsd.dll 5>mocs_compilation_Debug.cpp 4>mocs_compilation_Debug.cpp 5>base.cpp 4>base.cpp 5>item_add.cpp 4>item_add.cpp 5>item_move.cpp 4>item_move.cpp 5>item_remove.cpp 4>item_remove.cpp 4>item_visibility.cpp 5>item_visibility.cpp 4>label_rename.cpp 5>label_rename.cpp 4>rectitem_resize.cpp 5>rectitem_resize.cpp 4>rectitem_rotate.cpp 5>rectitem_rotate.cpp 4>wirenet_rename.cpp 5>wirenet_rename.cpp 4>wirepoint_move.cpp 5>wirepoint_move.cpp 4>connector.cpp 5>connector.cpp 4>item.cpp 5>item.cpp 4>itemfactory.cpp 5>itemfactory.cpp 4>itemmimedata.cpp 5>itemmimedata.cpp 4>label.cpp 5>label.cpp 4>node.cpp 5>node.cpp 4>rectitem.cpp 5>rectitem.cpp 4>splinewire.cpp 5>splinewire.cpp 4>widget.cpp 5>widget.cpp 4>Generating Code... 5>Generating Code... 4>Compiling... 4>wirenet.cpp 5>Compiling... 5>wirenet.cpp 4>wireroundedcorners.cpp 5>wireroundedcorners.cpp 4>line.cpp 5>line.cpp 4>manager.cpp 5>manager.cpp 4>point.cpp 5>point.cpp 4>net.cpp 5>net.cpp 4>scene.cpp 5>scene.cpp 4>settings.cpp 5>settings.cpp 4>utils.cpp 5>utils.cpp 4>view.cpp 5>view.cpp 4>Generating Code... 5>Generating Code... 4>wire.cpp 5>wire.cpp 4>wire.cpp 5>wire.cpp 4>qschematic-static.vcxproj -> D:\qschematic\build\qschematic\Debug\qschematicd.lib 6>------ Build started: Project: qschematic-demo, Configuration: Debug x64 ------ 7>------ Build started: Project: wire_system-tests, Configuration: Debug x64 ------ 6>Automatic MOC for target qschematic-demo 7>Building Custom Rule D:/qschematic/qschematic/wire_system/test/CMakeLists.txt 5>Auto build dll exports 6>Automatic RCC for resources/examples/examples.qrc 5> Creating library D:/qschematic/build/qschematic/Debug/qschematicd.lib and object D:/qschematic/build/qschematic/Debug/qschematicd.exp 5>connector.obj : error LNK2019: unresolved external symbol "public: void cdecl wire_system::manager::detach_wire(struct wire_system::connectable const )" (?detach_wire@manager@wire_system@@QEAAXPEBUconnectable@2@@Z) referenced in function "private: void cdecl QSchematic::Items::Connector::disconnect_all_wires(void)" (?disconnect_all_wires@Connector@Items@QSchematic@@AEAAXXZ) 5>connector.obj : error LNK2019: unresolved external symbol "public: void cdecl wire_system::manager::connector_moved(struct wire_system::connectable const )" (?connector_moved@manager@wire_system@@QEAAXPEBUconnectable@2@@Z) referenced in function "private: void cdecl QSchematic::Items::Connector::notify_wire_manager(void)" (?notify_wire_manager@Connector@Items@QSchematic@@AEAAXXZ) 5>wire.cpp.obj : error LNK2019: unresolved external symbol "public: class wire_system::wire __cdecl wire_system::manager::attached_wire(struct wire_system::connectable const )" (?attached_wire@manager@wire_system@@QEAAPEAVwire@2@PEBUconnectable@2@@Z) referenced in function "protected: virtual class QVariant cdecl QSchematic::Items::Wire::itemChange(enum QGraphicsItem::GraphicsItemChange,class QVariant const &)" (?itemChange@Wire@Items@QSchematic@@MEAA?AVQVariant@@W4GraphicsItemChange@QGraphicsItem@@AEBV4@@Z) 5>wire.cpp.obj : error LNK2019: unresolved external symbol "public: int cdecl wire_system::manager::attached_point(struct wire_system::connectable const )" (?attached_point@manager@wire_system@@QEAAHPEBUconnectable@2@@Z) referenced in function "protected: virtual class QVariant __cdecl QSchematic::Items::Wire::itemChange(enum QGraphicsItem::GraphicsItemChange,class QVariant const &)" (?itemChange@Wire@Items@QSchematic@@MEAA?AVQVariant@@W4GraphicsItemChange@QGraphicsItem@@AEBV4@@Z) 5>D:\qschematic\build\qschematic\Debug\qschematicd.dll : fatal error LNK1120: 4 unresolved externals 6>Automatic RCC for resources/icons/icons.qrc 5>Done building project "qschematic-shared.vcxproj" -- FAILED. 6>Building Custom Rule D:/qschematic/demo/CMakeLists.txt 7>test_main.cpp 6>mocs_compilation_Debug.cpp 7>net.cpp 7>point.cpp 6>node_add_connector.cpp 7>utils.cpp 7>settings.cpp 6>treeitem.cpp 7>nets.cpp 6>treemodel.cpp 7>Generating Code... 7>line.cpp 6>popup.cpp 7>manager.cpp 6>customitemfactory.cpp 7>wire.cpp 6>fancywire.cpp 7>manager.cpp 7>wire.cpp 6>flowend.cpp 7>line.cpp 7>manager.cpp.obj : error LNK2019: unresolved external symbol "public: void __cdecl wire_system::manager::attach_wire_to_connector(class wire_system::wire ,struct wire_system::connectable const )" (?attach_wire_to_connector@manager@wire_system@@QEAAXPEAVwire@2@PEBUconnectable@2@@Z) referenced in function "void __cdecl _DOCTEST_ANON_SUITE_2::_DOCTEST_ANON_FUNC_11(void)" (?_DOCTEST_ANON_FUNC_11@_DOCTEST_ANON_SUITE_2@@YAXXZ) 7>manager.cpp.obj : error LNK2019: unresolved external symbol "public: class wire_system::wire cdecl wire_system::manager::attached_wire(struct wire_system::connectable const )" (?attached_wire@manager@wire_system@@QEAAPEAVwire@2@PEBUconnectable@2@@Z) referenced in function "void cdecl _DOCTEST_ANON_SUITE_2::_DOCTEST_ANON_FUNC_11(void)" (?_DOCTEST_ANON_FUNC_11@_DOCTEST_ANON_SUITE_2@@YAXXZ) 7>manager.cpp.obj : error LNK2019: unresolved external symbol "public: int cdecl wire_system::manager::attached_point(struct wire_system::connectable const )" (?attached_point@manager@wire_system@@QEAAHPEBUconnectable@2@@Z) referenced in function "void cdecl _DOCTEST_ANON_SUITE_2::_DOCTEST_ANON_FUNC_19(void)" (?_DOCTEST_ANON_FUNC_19@_DOCTEST_ANON_SUITE_2@@YAXXZ) 7>manager.cpp.obj : error LNK2019: unresolved external symbol "public: void __cdecl wire_system::manager::connector_moved(struct wire_system::connectable const *)" (?connector_moved@manager@wire_system@@QEAAXPEBUconnectable@2@@Z) referenced in function "void __cdecl _DOCTEST_ANON_SUITE_2::_DOCTEST_ANON_FUNC_15(void)" (?_DOCTEST_ANON_FUNC_15@_DOCTEST_ANON_SUITE_2@@YAXXZ) 7>D:\qschematic\build\qschematic\wire_system\test\Debug\wire_system-tests.exe : fatal error LNK1120: 4 unresolved externals 7>Done building project "wire_system-tests.vcxproj" -- FAILED. 6>flowstart.cpp 6>operation.cpp 6>operationconnector.cpp 6>operationdemo1.cpp 6>viewer.cpp 6>main.cpp 6>mainwindow.cpp 6>D:\qschematic\demo\mainwindow.cpp(40,1): fatal error C1021: invalid preprocessor command 'warning' 6>qrc_examples.cpp 6>qrc_icons.cpp 6>Generating Code... 6>Done building project "qschematic-demo.vcxproj" -- FAILED. 8>------ Build started: Project: ALL_BUILD, Configuration: Debug x64 ------ 8>Building Custom Rule D:/qschematic/CMakeLists.txt 9>------ Skipped Build: Project: INSTALL, Configuration: Debug x64 ------ 9>Project not selected to build for this solution configuration 10>------ Skipped Build: Project: PACKAGE, Configuration: Debug x64 ------ 10>Project not selected to build for this solution configuration ========== Build: 5 succeeded, 3 failed, 0 up-to-date, 2 skipped ==========

Tectu commented 1 year ago

I won't be able to test this on an actual Windows machine until next week. Could you try to the newly pushed features/msvc_fix and tell me whether that that resolves the issue?

It certainly seems like the issue you're experiencing is only centered around symbol exporting on Windows.

Galileo53 commented 1 year ago

Unfortunately this did not change anything. Again, we tried to find out what the reason for this error is. But the only finding was that the error already occurs when creating the libraries, i.e. within a closed area where no "export" should actually occur. Maybe you can tell me some exact versions of qt, cmake, vs, where it works so I can cross-check if it is related to a special version or not.

Tectu commented 1 year ago

Maybe you can tell me some exact versions of qt, cmake, vs, where it works so I can cross-check if it is related to a special version or not.

The actual "supported scenarios" list is fairly huge but as of today I can safely say that we're using this library out-of-the-box successfully under Windows with Qt 5.15 and Qt 6.5 using CMake 3.26. However, we're building on Windows via MSYS2 (MinGW). That being said, there can't be much missing here. I have been using this library also on Windows with MSVC in the past.

Right now I am still struggling to reproduce the issue you're reporting (as in: I am even struggling getting the CMake project to load properly in VisualStudio but that's just a knowledge gap on my end).

Again, we tried to find out what the reason for this error is. But the only finding was that the error already occurs when creating the libraries, i.e. within a closed area where no "export" should actually occur.

Based on the build output you provided I'd argue that something is wrong with the wire_system test target. This target builds a test case to ensure that the wire system is behaving as expected. It is mainly needed for development & QA. You won't need this in your consuming application. Are you able to "disable" or "remove" this? I have no idea what the correct lingo for this is in the world of MSVC. i.e. try not to build the wire_system-tests target.

Galileo53 commented 1 year ago

Finally I have found the problem:

In manager.h, line 24, "class connectable" is declared, while on any other file "connectable" is a "struct". Changing this declaration to "struct connectable" solves the problem.

There is a second thing that Visual Studio does not like: In mainwindow.cpp, line 40, "#warning TEMPORARY" throws an unknown preprocessor command error. I have commented that out (although I don't know what it is worth for)

There are now some more linker errors, probably related to the test target. I did not analyze this but just removed any compile target except gpds-static, qschematic-demo, and qschematic-static and now it works perfectly.

Thank you for all, for me you may close this Issue :-)

Tectu commented 1 year ago

In manager.h, line 24, "class connectable" is declared, while on any other file "connectable" is a "struct". Changing this declaration to "struct connectable" solves the problem.

Glad to hear that you managed to get it working! Would you like to provide a patch / pull request for these fixes or do you prefer if I handle this?

In mainwindow.cpp, line 40, "#warning TEMPORARY" throws an unknown preprocessor command error. I have commented that out (although I don't know what it is worth for)

Ah that is just to indicate that the part of the demo app showing how to embedd a QWidget into the QSchematic::Scene is not really finalized. I agree that a #warning is a bit over the top for that. I'll get that one handled.

Galileo53 commented 1 year ago

Since I am not so fit with Git and pull requests :-) I would prefer if you handle this by your own. Thank you again.

Tectu commented 1 year ago

Done - Credits in the commit message.

Would you be able to do a fresh clone of the current master branch and check whether both issues are now gone out-of-the-box? I'd initiate the v1.5.0 release in the next few days.

Galileo53 commented 1 year ago

I compiled a fresh clone of the master and it works as expected :-)

But as I mentioned before, this is only true for "gpds-static, qschematic-demo, and qschematic-static". There is still an issue with the shared library. Just for your information, this is the output if it fails:

Build started... 1>------ Build started: Project: ZERO_CHECK, Configuration: Debug x64 ------ 1>Checking Build System 2>------ Build started: Project: gpds-static, Configuration: Debug x64 ------ 3>------ Build started: Project: gpds-shared, Configuration: Debug x64 ------ 2>Building Custom Rule D:/QSchematic/build/_deps/gpds-src/lib/CMakeLists.txt 2>archiver_xml.cpp 3>Building Custom Rule D:/QSchematic/build/_deps/gpds-src/lib/CMakeLists.txt 3>archiver_xml.cpp 2>archiver_yaml.cpp 3>archiver_yaml.cpp 2>value.cpp 3>value.cpp 2>serialize.cpp 3>serialize.cpp 2>tinyxml2.cpp 3>tinyxml2.cpp 2>yaml.cpp 3>yaml.cpp 2>Generating Code... 3>Generating Code... 3>Auto build dll exports 2>gpds-static.vcxproj -> D:\QSchematic\build_deps\gpds-build\lib\Debug\gpdsd.lib 4>------ Build started: Project: qschematic-static, Configuration: Debug x64 ------ 5>------ Build started: Project: qschematic-shared, Configuration: Debug x64 ------ 4>Automatic MOC for target qschematic-static 3> Creating library D:/QSchematic/build/_deps/gpds-build/lib/Debug/gpdsd.lib and object D:/QSchematic/build/_deps/gpds-build/lib/Debug/gpdsd.exp 3>gpds-shared.vcxproj -> D:\QSchematic\build_deps\gpds-build\lib\Debug\gpdsd.dll 5>Automatic MOC for target qschematic-shared 4>Building Custom Rule D:/QSchematic/qschematic/CMakeLists.txt 5>Building Custom Rule D:/QSchematic/qschematic/CMakeLists.txt 4>mocs_compilation_Debug.cpp 5>mocs_compilation_Debug.cpp 4>base.cpp 5>base.cpp 5>item_add.cpp 4>item_add.cpp 5>item_move.cpp 4>item_move.cpp 5>item_remove.cpp 4>item_remove.cpp 4>item_visibility.cpp 5>item_visibility.cpp 5>label_rename.cpp 4>label_rename.cpp 4>rectitem_resize.cpp 5>rectitem_resize.cpp 5>rectitem_rotate.cpp 4>rectitem_rotate.cpp 5>wirenet_rename.cpp 4>wirenet_rename.cpp 4>wirepoint_move.cpp 5>wirepoint_move.cpp 4>connector.cpp 5>connector.cpp 5>item.cpp 4>item.cpp 4>itemfactory.cpp 5>itemfactory.cpp 4>itemmimedata.cpp 5>itemmimedata.cpp 5>label.cpp 4>label.cpp 5>node.cpp 4>node.cpp 5>rectitem.cpp 4>rectitem.cpp 4>splinewire.cpp 5>splinewire.cpp 4>widget.cpp 5>widget.cpp 4>Generating Code... 5>Generating Code... 4>Compiling... 4>wirenet.cpp 5>Compiling... 5>wirenet.cpp 4>wireroundedcorners.cpp 5>wireroundedcorners.cpp 4>line.cpp 5>line.cpp 4>manager.cpp 5>manager.cpp 4>point.cpp 5>point.cpp 4>net.cpp 5>net.cpp 4>scene.cpp 5>scene.cpp 4>settings.cpp 5>settings.cpp 4>utils.cpp 5>utils.cpp 4>view.cpp 5>view.cpp 4>Generating Code... 5>Generating Code... 4>wire.cpp 5>wire.cpp 4>wire.cpp 5>wire.cpp 4>qschematic-static.vcxproj -> D:\QSchematic\build\qschematic\Debug\qschematicd.lib 6>------ Build started: Project: qschematic-demo, Configuration: Debug x64 ------ 7>------ Build started: Project: qschematic-wiresystem-tests, Configuration: Debug x64 ------ 6>Automatic MOC for target qschematic-demo 5>Auto build dll exports 5> Creating library D:/QSchematic/build/qschematic/Debug/qschematicd.lib and object D:/QSchematic/build/qschematic/Debug/qschematicd.exp 6>Automatic RCC for resources/examples/examples.qrc 5>qschematic-shared.vcxproj -> D:\QSchematic\build\qschematic\Debug\qschematicd.dll 7>Building Custom Rule D:/QSchematic/qschematic/wire_system/test/CMakeLists.txt 6>Automatic RCC for resources/icons/icons.qrc 7>test_main.cpp 6>Building Custom Rule D:/QSchematic/demo/CMakeLists.txt 6>mocs_compilation_Debug.cpp 7>net.cpp 7>point.cpp 7>utils.cpp 6>node_add_connector.cpp 7>settings.cpp 6>treeitem.cpp 7>nets.cpp 7>Generating Code... 6>treemodel.cpp 7>line.cpp 6>popup.cpp 7>manager.cpp 6>customitemfactory.cpp 7>wire.cpp 7>manager.cpp 6>fancywire.cpp 7>wire.cpp 6>flowend.cpp 7>line.cpp 7>qschematic-wiresystem-tests.vcxproj -> D:\QSchematic\build\qschematic\wire_system\test\Debug\qschematic-wiresystem-tests.exe 6>flowstart.cpp 6>operation.cpp 6>operationconnector.cpp 6>operationdemo1.cpp 6>viewer.cpp 6>main.cpp 6>mainwindow.cpp 6>qrc_examples.cpp 6>qrc_icons.cpp 6>Generating Code... 6>model.cpp 6>view.cpp 6>widget.cpp 6>model.cpp 6>view.cpp 6>widget.cpp 6>mocs_compilation_Debug.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::Item::staticMetaObject" (?staticMetaObject@Item@Items@QSchematic@@2UQMetaObject@@B) 6>operation.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::Item::staticMetaObject" (?staticMetaObject@Item@Items@QSchematic@@2UQMetaObject@@B) 6>mocs_compilation_Debug.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::WireRoundedCorners::staticMetaObject" (?staticMetaObject@WireRoundedCorners@Items@QSchematic@@2UQMetaObject@@B) 6>mocs_compilation_Debug.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::Connector::staticMetaObject" (?staticMetaObject@Connector@Items@QSchematic@@2UQMetaObject@@B) 6>mocs_compilation_Debug.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::Node::staticMetaObject" (?staticMetaObject@Node@Items@QSchematic@@2UQMetaObject@@B) 6>operation.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::RectItem::staticMetaObject" (?staticMetaObject@RectItem@Items@QSchematic@@2UQMetaObject@@B) 6>mainwindow.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::Wire::staticMetaObject" (?staticMetaObject@Wire@Items@QSchematic@@2UQMetaObject@@B) 6>mainwindow.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Scene::staticMetaObject" (?staticMetaObject@Scene@QSchematic@@2UQMetaObject@@B) 6>mainwindow.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::View::staticMetaObject" (?staticMetaObject@View@QSchematic@@2UQMetaObject@@B) 6>view.cpp.obj : error LNK2001: unresolved external symbol "public: static struct QMetaObject const QSchematic::Items::MimeData::staticMetaObject" (?staticMetaObject@MimeData@Items@QSchematic@@2UQMetaObject@@B) 6>D:\QSchematic\build\demo\Debug\qschematic-demo.exe : fatal error LNK1120: 9 unresolved externals 6>Done building project "qschematic-demo.vcxproj" -- FAILED. 8>------ Build started: Project: ALL_BUILD, Configuration: Debug x64 ------ 8>Building Custom Rule D:/QSchematic/CMakeLists.txt 9>------ Skipped Build: Project: INSTALL, Configuration: Debug x64 ------ 9>Project not selected to build for this solution configuration 10>------ Skipped Build: Project: PACKAGE, Configuration: Debug x64 ------ 10>Project not selected to build for this solution configuration ========== Build: 7 succeeded, 1 failed, 0 up-to-date, 2 skipped ==========

Tectu commented 9 months ago

@Galileo53 is this still a problem as of v1.5.0?