Résolution de l'erreur d'absence de ui_xxx.h lors de la compilation de Qt avec Xmake

Origine du problème : gestion des fichiers générés

L'outil uic de Qt transforme les fichiers .ui en en-têtes C++ (comme ui_xxx.h). Xmake stocke ces fichiers intermédiaires dans un répertoire de compilation spécifique. Si le copmilateur ne trouve pas ce chemin d'inclusion, la build échoue avec l'erreur fatal error: ui_xxx.h: No such file or directory.

Le chemin par défaut défini par les règles Xmake pour ces en-têtes est généralement : build/.gens/[cible]/rules/qt/ui

Méthodes de résolution

1. Validation de la configuration de base

La majorité des erreurs provient d'une déclaration incomplète dans le fichier de configuration. Assurez-vous d'appliquer les règles Qt dédiées et d'inclure explicitement les fichiers d'interface :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/*.cpp")
    add_files("interfaces/*.ui")
    add_headerfiles("app_sources/*.h")

2. Spécification manuelle du chemin de l'outil UIC

Si Xmake ne parvient pas à localiser l'exécutable uic sur votre système, indiquez le répertoire bin de Qt manuellement :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/*.cpp", "interfaces/*.ui")
    set_toolchains("qt", {bin = "/opt/Qt/6.5.1/gcc_64/bin"})

Alternativement, via la ligne de commande lors de la configuration :

xmake f --qt_bin=/opt/Qt/6.5.1/gcc_64/bin && xmake

3. Ajustement des chemins d'inclusion

En cas de remplacement accidentel des chemins d'inclusion automatiques, forcez l'ajout du répertoire de génération pour la cible :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/*.cpp", "interfaces/*.ui")
    add_includedirs("$(buildir)/.gens/application_qt/rules/qt/ui")

4. Purge du cache de compilation

Un cache corromu peut empêcher la génération correcte des en-têtes. Nettoyez l'espace de travail et forcez la reconstruction :

xmake clean -a
xmake -r

5. Surveillance de la génération UIC

Affichez les journaux détaillés pour vérifier si uic est bien invoqué par le système de build :

xmake -vD | grep uic

Une sortie correcte devrait afficher la commande de compilation de l'interface, similaire à :

[  2%]: compiling.qt.ui interfaces/mainwindow.ui
/opt/Qt/6.5.1/gcc_64/bin/uic interfaces/mainwindow.ui -o build/.gens/application_qt/rules/qt/ui/ui_mainwindow.h

6. Redéfinition du répertoire de sortie (Avancé)

Si le répertoire par défaut ne convient pas à votre architecture, créez une règle personnalisée pour rediriger les fichiers générés :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/*.cpp")
    add_files("interfaces/*.ui", {rule = "qt.uic_custom"})
    
rule("qt.uic_custom")
    after_buildcmd_file(function (project_target, cmd_batch, src_file)
        local uic_path = project_target:data("qt.uic")
        local custom_dir = path.join(os.projectdir(), "app_generated")
        local output_file = path.join(custom_dir, "ui_" .. path.basename(src_file) .. ".h")
        cmd_batch:mkdir(custom_dir)
        cmd_batch:vrunv(uic_path, {src_file, "-o", output_file})
        project_target:add("includedirs", custom_dir)
    end)

7. Réorganisation de l'arborescence du projet

Une structure de fichiers non conventionnelle peut nécessiter des déclarations explicites pour localiser les interfaces :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/**.cpp")
    add_files("ui_forms/*.ui")
    add_includedirs("ui_forms")

8. Mise à jour de l'environnement

Les anciennes versoins de Xmake contiennent des bugs connus concernant la gestion des règles Qt. Mettez à jour vers la dernière version stable ou de développement :

xmake update -s dev

Mécanisme interne de Xmake pour Qt

Xmake crée dynamiquement le répertoire cible et l'ajoute aux chemins d'inclusion du compilateur avant d'appeler uic. Le comportement interne ressemble à ceci :

local gen_dir = path.join(target:autogendir(), "rules", "qt", "ui")
if not os.isdir(gen_dir) then
    os.mkdir(gen_dir)
end
target:add("includedirs", path.absolute(gen_dir, os.projectdir()))

batchcmds:vrunv(uic, {path(ui_file), "-o", path(gen_header)})

Étude de cas : interfaces réparties dans plusieurs sous-dossiers

Pour un projet structuré avec des interfaces dispersées dans divers répertoires, une configuration récursive garantit que tous les fichiers sont traités et que le chemin d'inclusion global est正确ement défini :

target("application_qt")
    add_rules("qt.application")
    add_files("app_sources/**.cpp")
    add_files("app_sources/**.ui")
    
    on_config(function(proj_target)
        local ui_gen_dir = path.join(proj_target:autogendir(), "rules", "qt", "ui")
        proj_target:add("includedirs", ui_gen_dir)
    end)

Bonnes pratiques d'intégration

Pour éviter les conflits dans le contrôle de version, excluez les répertoires de build et les fichiers générés automatiquement en ajoutant ces lignes à votre fichier .gitignore :

/build/
/.xmake/
**/ui_*.h

Étiquettes: Xmake Qt uic C++ Lua

Publié le 29 juin à 06h53