diff --git a/nix/plugin.nix b/nix/plugin.nix index 9483077..762c385 100644 --- a/nix/plugin.nix +++ b/nix/plugin.nix @@ -7,11 +7,14 @@ runCommand, }: let - # nixpkgs splits Qt tools across packages: moc/rcc/qtpaths live in qtbase, - # qmltyperegistrar and qmlcachegen live in qtdeclarative. qt-build-utils - # finds tools via `qmake -query QT_INSTALL_LIBEXECS`, which only returns - # qtbase paths, so those two tools are invisible. Fix: combine them into a - # single symlink tree and point a qmake wrapper at it. + # nixpkgs splits Qt: tools (moc/rcc/qtpaths in qtbase, qmltyperegistrar/qmlcachegen + # in qtdeclarative) and headers (qtbase has Qt6Core etc., qtdeclarative has Qt6Qml + # incl. qqmlregistration.h). qt-build-utils derives both from `qmake -query`, which + # only knows about qtbase. Symptom of missing headers: moc warns "Potential QML + # registration macro was found, but no header containing it was included", silently + # strips QML_NAMED_ELEMENT/QML_SINGLETON from the JSON, qmltyperegistrar emits an + # empty qml_register_types_*, and the QML import resolves to no types. Fix: combine + # tools and headers into symlink trees and point a qmake wrapper at them. qtBuildTools = runCommand "qt6-build-tools" { } '' mkdir -p $out/libexec $out/bin for f in ${qt6.qtbase}/libexec/* ${qt6.qtbase}/bin/*; do @@ -22,6 +25,12 @@ let [ -f "$src" ] && ln -sf "$src" "$out/libexec/$tool" done ''; + qtIncludeRoots = runCommand "qt6-include-roots" { } '' + mkdir -p $out/include + for src in ${qt6.qtbase.dev}/include/* ${qt6.qtdeclarative.dev}/include/*; do + ln -sfn "$src" "$out/include/$(basename "$src")" + done + ''; qmakeWrapper = writeShellScript "qmake6" '' if [ "$1" = "-query" ]; then case "$2" in @@ -29,6 +38,8 @@ let echo "${qtBuildTools}/libexec"; exit 0;; QT_HOST_BINS|QT_HOST_BINS/get|QT_INSTALL_BINS|QT_INSTALL_BINS/get) echo "${qtBuildTools}/bin"; exit 0;; + QT_HOST_INCLUDES|QT_HOST_INCLUDES/get|QT_INSTALL_HEADERS|QT_INSTALL_HEADERS/get) + echo "${qtIncludeRoots}/include"; exit 0;; esac fi exec ${qt6.qtbase}/bin/qmake6 "$@" diff --git a/plugin/build.rs b/plugin/build.rs index 0f10623..064e486 100644 --- a/plugin/build.rs +++ b/plugin/build.rs @@ -26,17 +26,9 @@ fn main() { // Crane's deps-only build stubs out lib.rs and removes our bridge sources to // build a dummy crate that only compiles dependencies. Skip cxx-qt codegen in // that case - we just want cxx-qt-lib (the heavy dep) cached, not our own glue. - // Use CARGO_MANIFEST_DIR for a robust path that doesn't depend on cargo's CWD. let manifest = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); let bridge_files = ["src/system_stats.rs", "src/cpu_service.rs"]; - let present: Vec = bridge_files - .iter() - .map(|p| manifest.join(p).exists()) - .collect(); - println!("cargo:warning=build.rs manifest_dir={}", manifest.display()); - println!("cargo:warning=build.rs bridge_files present: {present:?}"); - if !present.iter().all(|b| *b) { - println!("cargo:warning=build.rs bailing: bridge files missing (deps-only build?)"); + if !bridge_files.iter().all(|p| manifest.join(p).exists()) { return; } diff --git a/plugin/src/lib.rs b/plugin/src/lib.rs index eca2e48..6c837e5 100644 --- a/plugin/src/lib.rs +++ b/plugin/src/lib.rs @@ -2,21 +2,7 @@ pub mod cpu_service; pub mod stats; pub mod system_stats; -// cxx-qt 0.8.1's PluginType::Dynamic emits a QQmlEngineExtensionPlugin whose -// constructor only anchors qml_register_types_NovaStats with `volatile auto X = &X` -// (linker-keep, not a call), and the qmltyperegistrar static init doesn't call it -// either. Net effect: types never register, NS.* stays undefined in QML. Workaround: -// call it ourselves at .so load time. The function is mangled (returns void, no -// extern "C"), so go through #[link_name] using the itanium-mangled symbol seen in -// `nm libNovaStats.so | grep qml_register_types`. -unsafe extern "C" { - #[link_name = "_Z28qml_register_types_NovaStatsv"] - fn qml_register_types_nova_stats(); -} - #[ctor::ctor(unsafe)] fn on_dylib_load() { eprintln!("[nova-plugin] dylib loaded (libNovaStats.so)"); - unsafe { qml_register_types_nova_stats() }; - eprintln!("[nova-plugin] qml_register_types_NovaStats called"); }