summaryrefslogtreecommitdiff
path: root/xmake/modules
diff options
context:
space:
mode:
authorChan Lee <[email protected]>2025-01-22 17:25:06 +0800
committerChan Lee <[email protected]>2025-01-22 17:25:06 +0800
commitbb89dfcc8a32c401b2208ce9c1f8a1862bb5a574 (patch)
tree82f71a4c2cfc0343660297ac199fd2b7bc2e61a6 /xmake/modules
parentc61d7bb40353b161da913bdcbc6fa399e36164a1 (diff)
Add `qt_host` option to enable cross-platform Qt Builds using host SDK tools
Diffstat (limited to 'xmake/modules')
-rw-r--r--xmake/modules/detect/sdks/find_qt.lua65
1 files changed, 56 insertions, 9 deletions
diff --git a/xmake/modules/detect/sdks/find_qt.lua b/xmake/modules/detect/sdks/find_qt.lua
index 1a9e79f76..d720ac8b8 100644
--- a/xmake/modules/detect/sdks/find_qt.lua
+++ b/xmake/modules/detect/sdks/find_qt.lua
@@ -190,11 +190,21 @@ function _find_qmake(sdkdir, sdkver)
end
-- get qt environment
-function _get_qtenvs(qmake)
+function _get_qtenvs(qmake, sdkdir)
local envs = {}
+ local run_args = {"-query"}
+ if sdkdir then
+ local conf_paths = {path.join(sdkdir, "bin", "target_qt.conf"), path.join(sdkdir, "bin", "qt.conf")}
+ for _, conf_path in ipairs(conf_paths) do
+ if os.isfile(conf_path) then
+ table.join2(run_args, {"-qtconf", conf_path})
+ break
+ end
+ end
+ end
local results = try {
function ()
- return os.iorunv(qmake, {"-query"})
+ return os.iorunv(qmake, run_args)
end,
catch {
function (errors)
@@ -215,24 +225,44 @@ function _get_qtenvs(qmake)
end
end
+-- Verify and correct the Qt SDK version for cross-compiling.
+-- qmake reports its own version (QT_VERSION), not the version specified in the SDK's configuration files.
+function _tryfix_sdkver_for_cross(sdkdir, sdkver)
+ local qconfig_path = sdkdir and path.join(sdkdir, "mkspecs", "qconfig.pri")
+ if not sdkver or not os.isfile(qconfig_path) then
+ return sdkver
+ end
+ -- Extract the actual SDK version from qconfig.pri
+ local qconfig = io.readfile(qconfig_path)
+ local actual_sdkver = qconfig and qconfig:match("QT_VERSION%s*=%s*(%S+)") -- Expected format: QT_VERSION = x.y.z
+ if not actual_sdkver then
+ return sdkver
+ end
+ if sdkver ~= actual_sdkver then
+ wprint("Host Qt SDK version (%s) differs from Target Qt SDK version (%s). To prevent build issues, please ensure both use the same version.", sdkver, actual_sdkver);
+ end
+ return actual_sdkver
+end
+
-- find qt sdk toolchains
-function _find_qt(sdkdir, sdkver)
+function _find_qt(sdkdir, sdkver, sdkdir_host)
-- find qmake
- local qmake = _find_qmake(sdkdir, sdkver)
+ local qmake = _find_qmake(sdkdir_host or sdkdir, sdkver)
if not qmake then
return
end
-- get qt environments
- local qtenvs = _get_qtenvs(qmake)
+ local located_sdkdir = sdkdir and _find_sdkdir(sdkdir, sdkver)
+ local qtenvs = _get_qtenvs(qmake, located_sdkdir or sdkdir)
if not qtenvs then
return
end
-- get qt toolchains
sdkdir = qtenvs.QT_INSTALL_PREFIX
- local sdkver = qtenvs.QT_VERSION
+ local sdkver = _tryfix_sdkver_for_cross(sdkdir, qtenvs.QT_VERSION)
local bindir = qtenvs.QT_INSTALL_BINS
local libexecdir = qtenvs.QT_INSTALL_LIBEXECS
local qmldir = qtenvs.QT_INSTALL_QML
@@ -259,6 +289,16 @@ function _find_qt(sdkdir, sdkver)
-- TODO
end
end
+
+ if sdkdir_host then
+ local located_sdkdir_host = _find_sdkdir(sdkdir_host, sdkver)
+ local qtenvs_host = _get_qtenvs(qmake, located_sdkdir_host or sdkdir_host)
+ if qtenvs_host then
+ bindir_host = qtenvs_host.QT_HOST_BINS or qtenvs_host.QT_INSTALL_BINS or bindir_host
+ libexecdir_host = qtenvs_host.QT_HOST_LIBEXECS or qtenvs_host.QT_INSTALL_LIBEXECS or libexecdir_host
+ end
+ end
+
return {sdkdir = sdkdir, bindir = bindir, bindir_host = bindir_host, libexecdir = libexecdir, libexecdir_host = libexecdir_host, libdir = libdir, includedir = includedir, qmldir = qmldir, pluginsdir = pluginsdir, mkspecsdir = mkspecsdir, sdkver = sdkver}
end
@@ -282,13 +322,16 @@ function main(sdkdir, opt)
-- attempt to load cache first
local key = "detect.sdks.find_qt"
- local cacheinfo = detectcache:get(key) or {}
+ local cacheinfo = (sdkdir and detectcache:get2(key, sdkdir)) or detectcache:get(key) or {}
if not opt.force and cacheinfo.qt and cacheinfo.qt.sdkdir and os.isdir(cacheinfo.qt.sdkdir) then
return cacheinfo.qt
end
-- find qt
- local qt = _find_qt(sdkdir or config.get("qt") or global.get("qt") or config.get("sdk"), opt.version or config.get("qt_sdkver"))
+ local sdkdir = sdkdir or config.get("qt") or global.get("qt") or config.get("sdk")
+ local sdkver = opt.version or config.get("qt_sdkver")
+ local sdkdir_host = opt.sdkdir_host or config.get("qt_host") or global.get("qt_host")
+ local qt = _find_qt(sdkdir, sdkver, sdkdir_host)
if qt then
-- save to config
@@ -314,7 +357,11 @@ function main(sdkdir, opt)
-- save to cache
cacheinfo.qt = qt or false
- detectcache:set(key, cacheinfo)
+ if sdkdir then
+ detectcache:set2(key, sdkdir, cacheinfo)
+ else
+ detectcache:set(key, cacheinfo)
+ end
detectcache:save()
return qt
end