From 8397fd257b60325f2439188902c4d1a7fd599c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Wed, 28 Jul 2021 16:13:22 +0200 Subject: [PATCH] XMake: Qt as packages, proof of concept --- tools/xmake.lua | 102 +++++++++++++++--- .../n/nodeeditor/patches/2.1.3/fix_qt.patch | 2 +- xmake-repo/packages/n/nodeeditor/xmake.lua | 11 +- xmake-repo/packages/q/qt5base/xmake.lua | 35 ++++++ xmake-repo/packages/q/qt5core/xmake.lua | 19 ++++ xmake-repo/packages/q/qt5gui/xmake.lua | 18 ++++ xmake-repo/packages/q/qt5widgets/xmake.lua | 19 ++++ 7 files changed, 185 insertions(+), 21 deletions(-) create mode 100644 xmake-repo/packages/q/qt5base/xmake.lua create mode 100644 xmake-repo/packages/q/qt5core/xmake.lua create mode 100644 xmake-repo/packages/q/qt5gui/xmake.lua create mode 100644 xmake-repo/packages/q/qt5widgets/xmake.lua diff --git a/tools/xmake.lua b/tools/xmake.lua index 402101d41..22b3f54f7 100644 --- a/tools/xmake.lua +++ b/tools/xmake.lua @@ -1,24 +1,102 @@ -add_requires("nodeeditor", {debug = is_mode("debug"), optional = true}) +add_requires("nodeeditor", "qt5core", "qt5gui", "qt5widgets", {debug = is_mode("debug"), optional = true}) + +rule("qt5.env") + after_load(function (target) + -- retrieve qtbase + local qtdir + + local qtbase = target:pkg("qt5base") + if qtbase then + qtdir = assert(qtbase:get("qtdir")) + else + local qtcore = assert(target:pkg("qt5core"), "target does not use qt5") + qtdir = assert(qtcore:get("qtdir")) + end + + target:data_set("qt", qtdir) + end) + + +rule("qt5.moc") + add_deps("qt5.env") + set_extensions(".h", ".hpp") + before_buildcmd_file(function (target, batchcmds, sourcefile, opt) + local qtbase = target:dep("qt5core") + local qt = assert(qtbase:data("qtdir"), "qt not found!") + + -- imports + import("core.tool.compiler") + + -- get moc + local moc = path.join(qt.bindir, is_host("windows") and "moc.exe" or "moc") + if not os.isexec(moc) and qt.libexecdir then + moc = path.join(qt.libexecdir, is_host("windows") and "moc.exe" or "moc") + end + assert(moc and os.isexec(moc), "moc not found!") + + -- get c++ source file for moc + -- + -- add_files("mainwindow.h") -> moc_MainWindow.cpp + -- add_files("mainwindow.cpp", {rules = "qt.moc"}) -> mainwindow.moc, @see https://github.com/xmake-io/xmake/issues/750 + -- + local basename = path.basename(sourcefile) + local filename_moc = "moc_" .. basename .. ".cpp" + if sourcefile:endswith(".cpp") then + filename_moc = basename .. ".moc" + end + local sourcefile_moc = path.join(target:autogendir(), "rules", "qt", "moc", filename_moc) + + -- add objectfile + local objectfile = target:objectfile(sourcefile_moc) + table.insert(target:objectfiles(), objectfile) + + -- add commands + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.qt.moc %s", sourcefile) + + -- generate c++ source file for moc + local flags = {} + table.join2(flags, compiler.map_flags("cxx", "define", target:get("defines"))) + table.join2(flags, compiler.map_flags("cxx", "includedir", target:get("includedirs"))) + table.join2(flags, compiler.map_flags("cxx", "includedir", target:get("sysincludedirs"))) -- for now, moc process doesn't support MSVC external includes flags and will fail + table.join2(flags, compiler.map_flags("cxx", "frameworkdir", target:get("frameworkdirs"))) + batchcmds:mkdir(path.directory(sourcefile_moc)) + batchcmds:vrunv(moc, table.join(flags, sourcefile, "-o", sourcefile_moc)) + + -- we need compile this moc_xxx.cpp file if exists Q_PRIVATE_SLOT, @see https://github.com/xmake-io/xmake/issues/750 + local mocdata = io.readfile(sourcefile) + if mocdata and mocdata:find("Q_PRIVATE_SLOT") or sourcefile_moc:endswith(".moc") then + -- add includedirs of sourcefile_moc + target:add("includedirs", path.directory(sourcefile_moc)) + + -- remove the object file of sourcefile_moc + local objectfiles = target:objectfiles() + for idx, objectfile in ipairs(objectfiles) do + if objectfile == target:objectfile(sourcefile_moc) then + table.remove(objectfiles, idx) + break + end + end + else + -- compile c++ source file for moc + batchcmds:compile(sourcefile_moc, objectfile) + end + + -- add deps + batchcmds:add_depfiles(sourcefile) + batchcmds:set_depmtime(os.mtime(objectfile)) + batchcmds:set_depcache(target:dependfile(objectfile)) + end) target("NazaraShaderNodes") set_group("Tools") set_kind("binary") - add_rules("qt.console", "qt.moc") + add_rules("qt5.moc") add_deps("NazaraShader") - add_frameworks("QtCore", "QtGui", "QtWidgets") add_packages("nodeeditor") + add_packages("qt5core", "qt5gui", "qt5widgets") add_includedirs("../src") add_headerfiles("../src/ShaderNode/**.hpp", "../src/ShaderNode/**.inl") add_files("../src/ShaderNode/**.cpp") - - on_load(function (target) - import("detect.sdks.find_qt") - - if (not has_package("nodeeditor") or not find_qt()) then - -- Disable building by default if nodeeditor or Qt is not found - target:set("default", false) - end - end) diff --git a/xmake-repo/packages/n/nodeeditor/patches/2.1.3/fix_qt.patch b/xmake-repo/packages/n/nodeeditor/patches/2.1.3/fix_qt.patch index 943f9612d..ce1dd3560 100644 --- a/xmake-repo/packages/n/nodeeditor/patches/2.1.3/fix_qt.patch +++ b/xmake-repo/packages/n/nodeeditor/patches/2.1.3/fix_qt.patch @@ -17,7 +17,7 @@ index 3d47a3f..cc5eb68 100644 @@ -1,5 +1,11 @@ #pragma once -+#include ++#include + +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + diff --git a/xmake-repo/packages/n/nodeeditor/xmake.lua b/xmake-repo/packages/n/nodeeditor/xmake.lua index 07c447faa..758274571 100644 --- a/xmake-repo/packages/n/nodeeditor/xmake.lua +++ b/xmake-repo/packages/n/nodeeditor/xmake.lua @@ -7,9 +7,9 @@ package("nodeeditor") set_urls("https://github.com/paceholder/nodeeditor/archive/refs/tags/$(version).tar.gz", "https://github.com/paceholder/nodeeditor.git") add_versions("2.1.3", "4e3194a04ac4a2a2bf4bc8eb6cc27d5cc154923143c1ecf579ce7f0115a90585") - add_patches("2.1.3", path.join(os.scriptdir(), "patches", "2.1.3", "fix_qt.patch"), "804ee98d47b675c578981414ed25a745f1b12d0cd8b03ea7d7b079c7e1ce1ea9") + add_patches("2.1.3", path.join(os.scriptdir(), "patches", "2.1.3", "fix_qt.patch"), "3192c66fe711ad4bbfba96348601655396bc32465e2807f5be252cde6e2a3d59") - add_deps("cmake") + add_deps("cmake", "qt5core", "qt5gui", "qt5widgets") on_load(function (package) if package:config("shared") then @@ -20,8 +20,7 @@ package("nodeeditor") end) on_install("windows", "linux", "mingw", "macosx", function (package) - import("detect.sdks.find_qt") - local qt = find_qt() + local qt = package:dep("qt5core"):fetch().qtdir local configs = {"-DBUILD_EXAMPLES=OFF", "-DBUILD_TESTING=OFF"} table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF")) @@ -33,10 +32,6 @@ package("nodeeditor") end) on_test(function (package) - do - -- Disable test until I can test with Qt - return - end assert(package:check_cxxsnippets({test = [[ void test() { QtNodes::FlowScene scene(std::make_shared()); diff --git a/xmake-repo/packages/q/qt5base/xmake.lua b/xmake-repo/packages/q/qt5base/xmake.lua new file mode 100644 index 000000000..0b2253576 --- /dev/null +++ b/xmake-repo/packages/q/qt5base/xmake.lua @@ -0,0 +1,35 @@ +package("qt5base") + + set_kind("binary") + set_homepage("https://www.qt.io") + set_description("Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.") + set_license("LGPL-3") + + on_load(function (package) + -- I think find_qt could be moved here + import("detect.sdks.find_qt") + local qt = find_qt() + if qt then + package:data_set("qtdir", qt) + end + end) + + on_fetch(function (package) + local qt = package:data("qtdir") + if not qt then + return + end + + return { + qtdir = qt, + } + end) + + -- TODO: on_install using aqtinstall + + on_test(function (package) + local qt = package:data("qtdir") + os.vrun(path.join(qt.bindir, "moc", " -v")) + os.vrun(path.join(qt.bindir, "rcc", " -v")) + os.vrun(path.join(qt.bindir, "uic", " -v")) + end) diff --git a/xmake-repo/packages/q/qt5core/xmake.lua b/xmake-repo/packages/q/qt5core/xmake.lua new file mode 100644 index 000000000..079d15d7b --- /dev/null +++ b/xmake-repo/packages/q/qt5core/xmake.lua @@ -0,0 +1,19 @@ +package("qt5core") + + set_homepage("https://www.qt.io") + set_description("Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.") + set_license("LGPL-3") + + add_deps("qt5base", {public=true}) + + on_fetch(function (package) + local base = package:dep("qt5base") + local qt = base:data("qtdir") + + return { + qtdir = qt, + links = table.wrap("Qt5Core" .. (package:is_debug() and "d" or "")), + linkdirs = table.wrap(qt.libdir), + includedirs = table.wrap(qt.includedir) + } + end) diff --git a/xmake-repo/packages/q/qt5gui/xmake.lua b/xmake-repo/packages/q/qt5gui/xmake.lua new file mode 100644 index 000000000..cee573442 --- /dev/null +++ b/xmake-repo/packages/q/qt5gui/xmake.lua @@ -0,0 +1,18 @@ +package("qt5gui") + + set_homepage("https://www.qt.io") + set_description("Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.") + set_license("LGPL-3") + + add_deps("qt5base", "qt5core", "qt5core") + + on_fetch(function (package) + local base = package:dep("qt5base") + local qt = base:data("qtdir") + + return { + links = table.wrap("Qt5Gui" .. (package:is_debug() and "d" or "")), + linkdirs = table.wrap(qt.libdir), + includedirs = table.wrap(qt.includedir) + } + end) diff --git a/xmake-repo/packages/q/qt5widgets/xmake.lua b/xmake-repo/packages/q/qt5widgets/xmake.lua new file mode 100644 index 000000000..9013494cf --- /dev/null +++ b/xmake-repo/packages/q/qt5widgets/xmake.lua @@ -0,0 +1,19 @@ +package("qt5widgets") + + set_homepage("https://www.qt.io") + set_description("Qt is the faster, smarter way to create innovative devices, modern UIs & applications for multiple screens. Cross-platform software development at its best.") + set_license("LGPL-3") + + add_deps("qt5base", "qt5core", "qt5gui") + + on_fetch(function (package) + local base = package:dep("qt5base") + local qt = base:data("qtdir") + print(qt) + + return { + links = table.wrap("Qt5Widgets" .. (package:is_debug() and "d" or "")), + linkdirs = table.wrap(qt.libdir), + includedirs = table.wrap(qt.includedir) + } + end)