summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-06-11 08:56:52 +0800
committerGitHub <[email protected]>2022-06-11 08:56:52 +0800
commit5b718c4f9ac86a13edc1ac5e7c135ac2a3022b4a (patch)
tree14edb1035f4a49028c0969b7c14e7ad15ae0bbd6
parent6228b34ad91719e309bef698f7c611887040b825 (diff)
parent4331ffcbbb032102f16b0a7516c690b64516e824 (diff)
Merge pull request #2447 from Arthapz/qtquick-plugins
Add qt.qmlplugin rule and support of qmltypesregistrar
-rw-r--r--tests/projects/qt/quickplugin/src/Foo.cpp16
-rw-r--r--tests/projects/qt/quickplugin/src/Foo.h22
-rw-r--r--tests/projects/qt/quickplugin/src/Plugin.cpp10
-rw-r--r--tests/projects/qt/quickplugin/src/Plugin.h10
-rw-r--r--tests/projects/qt/quickplugin/xmake.lua8
-rw-r--r--xmake/rules/qt/env/xmake.lua4
-rw-r--r--xmake/rules/qt/moc/xmake.lua3
-rw-r--r--xmake/rules/qt/qmltyperegistrar/xmake.lua125
-rw-r--r--xmake/rules/qt/xmake.lua7
9 files changed, 204 insertions, 1 deletions
diff --git a/tests/projects/qt/quickplugin/src/Foo.cpp b/tests/projects/qt/quickplugin/src/Foo.cpp
new file mode 100644
index 000000000..d4065cb52
--- /dev/null
+++ b/tests/projects/qt/quickplugin/src/Foo.cpp
@@ -0,0 +1,16 @@
+#include "Foo.h"
+
+Foo::Foo(QObject *parent) : QObject { parent }, m_bar{ 0 } {
+}
+
+int Foo::bar() const noexcept {
+ return m_bar;
+}
+
+void Foo::setBar(int bar) noexcept {
+ if (bar == m_bar) return;
+
+ m_bar = bar;
+
+ Q_EMIT barChanged(m_bar);
+} \ No newline at end of file
diff --git a/tests/projects/qt/quickplugin/src/Foo.h b/tests/projects/qt/quickplugin/src/Foo.h
new file mode 100644
index 000000000..71e2b0e23
--- /dev/null
+++ b/tests/projects/qt/quickplugin/src/Foo.h
@@ -0,0 +1,22 @@
+#include <QtCore/QObject>
+#include <QtQml/qqml.h>
+
+class Foo: public QObject {
+ Q_OBJECT
+ Q_PROPERTY(int bar READ bar WRITE setBar NOTIFY barChanged)
+ QML_NAMED_ELEMENT(Foo)
+
+ public:
+ explicit Foo(QObject *parent = nullptr);
+
+ int bar() const noexcept;
+ void setBar(int bar) noexcept;
+
+ Q_SIGNALS:
+ void barChanged(int bar);
+
+ private:
+ int m_bar;
+};
+
+QML_DECLARE_TYPE(Foo)
diff --git a/tests/projects/qt/quickplugin/src/Plugin.cpp b/tests/projects/qt/quickplugin/src/Plugin.cpp
new file mode 100644
index 000000000..9138c68b0
--- /dev/null
+++ b/tests/projects/qt/quickplugin/src/Plugin.cpp
@@ -0,0 +1,10 @@
+#include "Plugin.h"
+
+void qml_register_types_My_Plugin();
+
+/////////////////////////////////////
+/////////////////////////////////////
+Plugin::Plugin(QObject *parent) : QQmlEngineExtensionPlugin { parent } {
+ volatile auto registration = &qml_register_types_My_Plugin;
+ Q_UNUSED(registration);
+}
diff --git a/tests/projects/qt/quickplugin/src/Plugin.h b/tests/projects/qt/quickplugin/src/Plugin.h
new file mode 100644
index 000000000..72f7b6466
--- /dev/null
+++ b/tests/projects/qt/quickplugin/src/Plugin.h
@@ -0,0 +1,10 @@
+#include <QtCore/QObject>
+#include <QtQml/QQmlEngineExtensionPlugin>
+
+class Plugin: public QQmlEngineExtensionPlugin {
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid)
+
+ public:
+ explicit Plugin(QObject *parent = nullptr);
+};
diff --git a/tests/projects/qt/quickplugin/xmake.lua b/tests/projects/qt/quickplugin/xmake.lua
new file mode 100644
index 000000000..afd4cc59b
--- /dev/null
+++ b/tests/projects/qt/quickplugin/xmake.lua
@@ -0,0 +1,8 @@
+add_rules("mode.debug", "mode.release")
+
+target("demo")
+ add_rules("qt.qmlplugin")
+ add_headerfiles("src/*.h")
+ add_files("src/*.cpp")
+
+ set_values("qt.qmlplugin.import_name", "My.Plugin") \ No newline at end of file
diff --git a/xmake/rules/qt/env/xmake.lua b/xmake/rules/qt/env/xmake.lua
index 4cc39794c..47bc0760c 100644
--- a/xmake/rules/qt/env/xmake.lua
+++ b/xmake/rules/qt/env/xmake.lua
@@ -34,6 +34,10 @@ rule("qt.env")
target:add("runenvs", "PATH", qt.bindir)
target:set("runenv", "QML2_IMPORT_PATH", qt.qmldir)
target:set("runenv", "QML_IMPORT_TRACE", "1")
+
+ if not target:is_plat("mingw") then
+ target:add("cxxflags", "/permissive-")
+ end
elseif target:is_plat("msys", "cygwin") then
raise("please run `xmake f -p mingw --mingw=/mingw64` to support Qt/Mingw64 on Msys!")
end
diff --git a/xmake/rules/qt/moc/xmake.lua b/xmake/rules/qt/moc/xmake.lua
index 5a10f73f8..2092ebe71 100644
--- a/xmake/rules/qt/moc/xmake.lua
+++ b/xmake/rules/qt/moc/xmake.lua
@@ -78,8 +78,9 @@ rule("qt.moc")
table.insert(flags, pathitem)
end
end
+ local user_flags = target:get("qt.moc.flags") or {}
batchcmds:mkdir(path.directory(sourcefile_moc))
- batchcmds:vrunv(moc, table.join(flags, path(sourcefile), "-o", path(sourcefile_moc)))
+ batchcmds:vrunv(moc, table.join(user_flags, flags, path(sourcefile), "-o", path(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)
diff --git a/xmake/rules/qt/qmltyperegistrar/xmake.lua b/xmake/rules/qt/qmltyperegistrar/xmake.lua
new file mode 100644
index 000000000..38a04bbc4
--- /dev/null
+++ b/xmake/rules/qt/qmltyperegistrar/xmake.lua
@@ -0,0 +1,125 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author arthapz
+-- @file xmake.lua
+--
+
+rule("qt.qmltyperegistrar")
+ add_deps("qt.env")
+ set_extensions(".h", ".hpp")
+
+ on_load(function(target)
+ -- get qt
+ local qt = assert(target:data("qt"), "qt not found!")
+
+ -- get qmltyperegistrar
+ local qmltyperegistrar = path.join(qt.bindir, is_host("windows") and "qmltyperegistrar.exe" or "qmltyperegistrar")
+ if not os.isexec(qmltyperegistrar) and qt.libexecdir then
+ qmltyperegistrar = path.join(qt.libexecdir, is_host("windows") and "qmltyperegistrar.exe" or "qmltyperegistrar")
+ end
+ if not os.isexec(qmltyperegistrar) and qt.libexecdir_host then
+ qmltyperegistrar = path.join(qt.libexecdir_host, is_host("windows") and "qmltyperegistrar.exe" or "qmltyperegistrar")
+ end
+ assert(qmltyperegistrar and os.isexec(qmltyperegistrar), "qmltyperegistrar not found!")
+
+ -- set targetdir
+ local importname = target:values("qt.qmlplugin.import_name")
+ assert(importname, "QML plugin import name not set")
+
+ local targetdir = path.join(target:targetdir(), "imports")
+ for _, dir in pairs(importname:split(".", { plain = true })) do
+ targetdir = path.join(targetdir, dir)
+ end
+ os.mkdir(targetdir)
+ target:set("targetdir", targetdir)
+
+ -- add qmldir
+ local qmldir = target:values("qt.qmlplugin.qmldirfile")
+ if qmldir then
+ target:add("installfiles", qmldir)
+ end
+
+ -- add qmltypes
+ target:add("installfiles", target:get("targetdir") .. "/plugin.qmltypes")
+
+ local sourcefile = path.join(target:autogendir(), "rules", "qt", "qmltyperegistrar", target:name() .. "_qmltyperegistrations.cpp")
+ local sourcefile_dir = path.directory(sourcefile)
+ os.mkdir(sourcefile_dir)
+ target:data_set("qt.qmlplugin.sourcefile", sourcefile)
+
+ -- add moc arguments
+ target:add("qt.moc.flags", "--output-json")
+
+ -- save qmltyperegistrar
+ target:data_set("qt.qmltyperegistrar", qmltyperegistrar)
+ -- save qmltyperegistrar
+ target:data_set("qt.qmlplugin.qmltyperegistrar", qmltyperegistrar)
+ end)
+
+ on_buildcmd_files(function(target, batchcmds, sourcebatch, opt)
+
+ -- setup qmltyperegistrar arguments
+ local qmltyperegistrar = target:data("qt.qmltyperegistrar")
+ local sourcefile = target:data("qt.qmlplugin.sourcefile")
+
+ local importname = target:values("qt.qmlplugin.import_name")
+ local majorversion = target:values("qt.qmlplugin.majorversion") or 1
+ local minorversion = target:values("qt.qmlplugin.minorversion") or 0
+
+ local metatypefiles = {}
+ for _, mocedfile in ipairs(sourcebatch.sourcefiles) do
+ target:add("includedirs", path.directory(mocedfile))
+ local basename = path.basename(mocedfile)
+ local filename_moc = "moc_" .. basename .. ".cpp"
+ if mocedfile:endswith(".cpp") then
+ filename_moc = basename .. ".moc"
+ end
+ local sourcefile_moc = target:autogenfile(path.join(path.directory(mocedfile), filename_moc))
+ table.insert(metatypefiles, path(sourcefile_moc .. ".json"))
+ end
+
+ local args = {
+ "--generate-qmltypes=" .. target:get("targetdir") .. "/plugin.qmltypes",
+ "--import-name=" .. importname,
+ "--major-version=" .. majorversion,
+ "--minor-version=" .. minorversion,
+ "-o", sourcefile
+ }
+
+ -- gen sourcefile
+ batchcmds:show_progress(opt.progress, "${color.build.object}generate.qt.qmltyperegistrar %s", path.filename(sourcefile))
+ qmltype_source = os.vrunv(qmltyperegistrar, table.join(args, metatypefiles))
+
+ -- add objectfile
+ local objectfile = target:objectfile(sourcefile)
+ table.insert(target:objectfiles(), objectfile)
+
+ -- compile sourcefile
+ batchcmds:show_progress(opt.progress, "${color.build.object}compile.qt.qmltyperegistrar %s", path.filename(sourcefile))
+ batchcmds:compile(sourcefile, objectfile)
+
+ batchcmds:add_depfiles(sourcefile)
+ batchcmds:set_depmtime(os.mtime(objectfile))
+ batchcmds:set_depcache(target:dependfile(objectfile))
+ end)
+
+ after_build(function(target)
+ local qmldir = target:values("qml.plugin.qmldirfile")
+ if qmldir then
+ os.cp(qmldir, target:targetdir())
+ end
+ end) \ No newline at end of file
diff --git a/xmake/rules/qt/xmake.lua b/xmake/rules/qt/xmake.lua
index b26a458a5..b8cc59cfd 100644
--- a/xmake/rules/qt/xmake.lua
+++ b/xmake/rules/qt/xmake.lua
@@ -235,6 +235,13 @@ rule("qt.quickapp_static")
on_install("android", "install.android")
after_install("windows", "install.windows")
+-- define rule: qt qmlplugin
+rule("qt.qmlplugin")
+ add_deps("qt.shared", "qt.qmltyperegistrar")
+ on_load(function(target)
+ import("load")(target, {frameworks = { "QtCore", "QtGui", "QtQuick", "QtQml", "QtNetwork" }})
+ end)
+
-- define rule: qt application (deprecated)
rule("qt.application")
add_deps("qt.quickapp", "qt.ui")