KDAB / cxx-qt

Safe interop between Rust and Qt
https://kdab.github.io/cxx-qt/book/
1.02k stars 67 forks source link

Linkage error on Linux when including *.qrc.cpp #826

Closed wolfseifert closed 7 months ago

wolfseifert commented 7 months ago

I followed the instructions here:

    /// Generate C++ files from [Qt resource .qrc files](https://doc.qt.io/qt-6/resources.html).
    /// The generated file needs to be `#include`d in another .cpp file. For example:
    /// ```no_run
    /// # use cxx_qt_build::CxxQtBuilder;
    /// CxxQtBuilder::new()
    ///     .file("src/cxxqt_module.rs")
    ///     .qrc("src/my_resources.qrc")
    ///     .cc_builder(|cc| {
    ///         cc.file("file_with_include.cpp");
    ///     })
    ///     .build();
    /// ```
    ///
    /// In `file_with_include.cpp`:
    /// ```C++
    /// #include "my_resources.qrc.cpp"
    /// ```
    ///
    /// You also need to [explicitly load](https://doc.qt.io/qt-6/resources.html#explicit-loading-and-unloading-of-embedded-resources)
    /// the resources in your .cpp file by calling `qInitResources()` once before starting your application.
    pub fn qrc(mut self, qrc_file: impl AsRef) -> Self {

and got a linkage error on Linux:

error: linking with `cc` failed: exit status: 1
  |
  = note: ld.lld: error: duplicate symbol: qInitResources_resources_qrc()
          >>> defined at resources.qrc.cpp:232 (/home/wolfgang/tmp/cxx-qt-issue/target/debug/build/cxxqt-65f02becf5f1daac/out/resources.qrc.cpp:232)
          >>>            resources.o:(qInitResources_resources_qrc()) in archive /home/wolfgang/tmp/cxx-qt-issue/target/debug/deps/libcxxqt-36f2a5c0ea9d991a.rlib
          >>> defined at resources.qrc.cpp:232 (/home/wolfgang/tmp/cxx-qt-issue/target/debug/build/cxxqt-65f02becf5f1daac/out/resources.qrc.cpp:232)
          >>>            93a1f1269bf6ec12-resources.qrc.o:(.text._Z28qInitResources_resources_qrcv+0x0) in archive /tmp/rustckvUNyy/libqt-static-initializers.a

          ld.lld: error: duplicate symbol: qCleanupResources_resources_qrc()
          >>> defined at resources.qrc.cpp:241 (/home/wolfgang/tmp/cxx-qt-issue/target/debug/build/cxxqt-65f02becf5f1daac/out/resources.qrc.cpp:241)
          >>>            resources.o:(qCleanupResources_resources_qrc()) in archive /home/wolfgang/tmp/cxx-qt-issue/target/debug/deps/libcxxqt-36f2a5c0ea9d991a.rlib
          >>> defined at resources.qrc.cpp:241 (/home/wolfgang/tmp/cxx-qt-issue/target/debug/build/cxxqt-65f02becf5f1daac/out/resources.qrc.cpp:241)
          >>>            93a1f1269bf6ec12-resources.qrc.o:(.text._Z31qCleanupResources_resources_qrcv+0x0) in archive /tmp/rustckvUNyy/libqt-static-initializers.a
          collect2: error: ld returned 1 exit status

error: could not compile `cxxqt-helloworld` (bin "cxxqt-helloworld") due to previous error

It turned out that removing cc.file("file_with_include.cpp") (and the file "file_with_include.cpp" itself) resolved the issue!!!

It seems that the instruction above is not only obsolete, but also harmful (in the case of Linux). It makes no difference on Windows. Please remove it if I am right.

Here is a short reproducer which works as it is, but fails to link on Linux if you activate cc.file("src/resources.cpp") in build.rs:

cxx-qt-issue.zip

ahayzen-kdab commented 7 months ago

Right, i think that qrc files are now automatically sorted for you since the move to QML modules etc, so you don't need manually include the cpp file any more. Looks like that has been missed in this part of the docs :-)

The cc.file("foo.cpp") is still useful for including custom C++ classes however.

Be-ing commented 7 months ago

Right, i think that qrc files are now automatically sorted for you since the move to QML modules etc, so you don't need manually include the cpp file any more. Looks like that has been missed in this part of the docs :-)

That was implemented as part of implementing QML module support, but it's orthogonal. The cc.file("src/resources.cpp") is obsolete now that cxx-qt-build builds the C++ file generated by qrc and links it with +whole-archive.