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