Qt QBS 和 android
Qt QBS and android
我正在寻找一个简单的教程:如何使用 gbps 为 android 制作一个简单的应用程序。找到以下链接:
- Stack oferflow。这个问题的答案一直没有
收到了,虽然cbs的版本已经更新了
到 1.11 并包括 android 的支持。
- AndroidApk Item in QBS Documentation。在这种情况下,我收到警告:
'../Application/src/main/AndroidManifest.xml' does not exist.
很遗憾,我找不到任何新信息。我寻求帮助。
更新:
对于 Qmake,我只是像这样创建标准的小部件项目:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = androidtest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
CONFIG += mobility
MOBILITY =
这可以正常工作并且构建良好。 QtCreator 会自动创建所有必要的文件,然后在我的 phone
上创建 运行 应用程序
在 Qbs 中,我尝试制作相同的应用程序。出于这个原因,我有 QBS 文件:
import qbs
Project {
CppApplication {
name: "helloworld"
Depends {
name: "Qt"
submodules: [
"core",
"widgets"
]
}
Depends { name: "Android.ndk" }
Android.ndk.appStl: "gnustl_shared"
Group {
name: "src"
files: [
"main*.*"
]
}
}
AndroidApk {
name: "helloworld_android"
Depends {name: "helloworld" }
packageName: "com.example.android.helloworld"
}
}
最后我完成了 HelloWorld 产品 (libhelloworld.so)。但是 "helloworld_android" 的第一个错误是 android 清单中的失败。该文件未定义。接下来我应该做什么?
qmake 在为 Android 构建时具有一些内置的魔力,例如使用 Qt 提供的资源(包括清单模板)和 运行 android-deployqt 工具。 None 目前由 qbs 完成。
好的,我想我做到了。这不是一个好的解决方案,但这是可行的。您可以在 "\install-root\$productName$\build\outputs\apk\$productName$-debug.apk
中找到生成的 APK
import qbs
import qbs.TextFile
import qbs.Process
import qbs.File
Project {
//Main Application
CppApplication {
name: "helloworld";
Depends {
name: "Qt"
submodules: [
"core",
"widgets"
]
}
Depends { name: "Android.ndk" }
Android.ndk.appStl: "gnustl_shared"
Group {
name: "src"
files: [
"main*.*"
]
}
Group {
qbs.install: true
fileTagsFilter: "dynamiclibrary"
qbs.installPrefix : product.name+"/libs/"+Android.ndk.abi+"/"
}
}
//Preparation
Product {
name: "Prepared2Deploy"
type: "prepared2deploy"
Depends { name: "helloworld" }
Depends { name: "Qt.core" }
Depends { name: "Android.ndk" }
Depends { name: "Android.sdk" }
Rule {
inputsFromDependencies: "installable"
Artifact {
filePath: input.fileName+".json"
fileTags: "prepared2deploy"
}
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "prepare for androidDeployQt";
cmd.highlight = "install";
cmd.sourceCode = function() {
var outputFile = new TextFile(output.filePath, TextFile.WriteOnly);
outputFile.writeLine("{");
outputFile.writeLine(" \"qt\": \"" + product.Qt.core.binPath.replace(/\/bin$/,"") + "\",");
outputFile.writeLine(" \"sdk\": \"" + product.Android.sdk.sdkDir + "\",");
outputFile.writeLine(" \"sdkBuildToolsRevision\": \"" + product.Android.sdk.buildToolsVersion + "\",");
var ndkDir = product.Android.ndk.ndkDir.replace(/\/g,"/"); //why sdk ndk get wrong slashes?
outputFile.writeLine(" \"ndk\": \""+ndkDir+"\",");
var toolchain = product.cpp.toolchainPrefix.replace(/-$/,"");
outputFile.writeLine(" \"toolchain-prefix\": \"" + toolchain + "\",");
outputFile.writeLine(" \"tool-prefix\": \"" + toolchain + "\",");
outputFile.writeLine(" \"toolchain-version\": \"4.9\","); //how I can get it ???
outputFile.writeLine(" \"ndk-host\": \"windows-x86_64\","); //how I can get it ???
var abi = product.Android.ndk.abi
outputFile.writeLine(" \"target-architecture\": \""+abi+"\",");
outputFile.writeLine(" \"stdcpp-path\": \""+ndkDir+"/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + //how I can get it ???
abi+"/lib"+product.Android.ndk.appStl+".so\",");
outputFile.writeLine(" \"application-binary\": \""+ input.filePath+"\"");
outputFile.writeLine("}");
outputFile.close();
}
return cmd;
}
}
}
//Deployer
Product {
name: "AndroidDeployQt"
Depends { name: "helloworld" }
id: androidDeployQt
type: "androidDeployQt"
Depends {name: "Qt.core" }
Rule {
inputsFromDependencies: "prepared2deploy"
alwaysRun: true
Artifact {
filePath: "log.txt"
fileTags: "androidDeployQt"
}
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "androidDeployQt";
cmd.highlight = "install";
cmd.sourceCode = function() {
var logFile = new TextFile(output.filePath, TextFile.WriteOnly);
logFile.writeLine(input.fileName);
var productName = input.fileName.replace(/.so.json$/,"").replace(/^(lib)/,"");
var androidDeployProcess = new Process();
var exitCode = androidDeployProcess.exec(product.Qt.core.binPath+"/androiddeployqt.exe",
[
"--input", input.filePath,
"--output", project.buildDirectory+"/install-root/"+productName,
"--android-platform", "android-25", //???
"--gradle"
])
if (exitCode) {
console.error("Error at androidDeployProcess. Error code: "+exitCode);
console.error(androidDeployProcess.readStdErr());
console.error("FULL_LOG: ");
console.error(androidDeployProcess.readStdOut());
}
logFile.close();
}
return cmd;
}
}
}
}
QBS 1.13,于今年 2 月 (2019) 发布,使得部署 Android 应用程序与使用 qmake 一样简单。实际上,您不需要做任何特别的事情。例如,我使用了 contactlist application from the Qt examples 并添加了这个 QBS 文件:
import qbs 1.0
Project {
QtGuiApplication {
name: "contactlist"
install: true
files: [
"contactmodel.h",
"contactmodel.cpp",
"main.cpp",
]
Group {
files: [
"*.qml",
"designer/Backend/*.qml",
"designer/Backend/qmldir",
]
fileTags: ["qt.core.resource_data"]
}
Depends { name: "Qt.quick" }
}
}
如您所见,Android 没有任何特定内容。我使用的唯一技巧是将标签 qt.core.resource_data
分配给 QML 文件,以便将它们编译为资源文件——但这甚至不是必需的。
使用 qbs run
,应用程序将 运行 在您连接的 Android 设备中。
我正在寻找一个简单的教程:如何使用 gbps 为 android 制作一个简单的应用程序。找到以下链接:
- Stack oferflow。这个问题的答案一直没有 收到了,虽然cbs的版本已经更新了 到 1.11 并包括 android 的支持。
- AndroidApk Item in QBS Documentation。在这种情况下,我收到警告:
'../Application/src/main/AndroidManifest.xml' does not exist.
很遗憾,我找不到任何新信息。我寻求帮助。
更新: 对于 Qmake,我只是像这样创建标准的小部件项目:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = androidtest
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
CONFIG += mobility
MOBILITY =
这可以正常工作并且构建良好。 QtCreator 会自动创建所有必要的文件,然后在我的 phone
上创建 运行 应用程序在 Qbs 中,我尝试制作相同的应用程序。出于这个原因,我有 QBS 文件:
import qbs
Project {
CppApplication {
name: "helloworld"
Depends {
name: "Qt"
submodules: [
"core",
"widgets"
]
}
Depends { name: "Android.ndk" }
Android.ndk.appStl: "gnustl_shared"
Group {
name: "src"
files: [
"main*.*"
]
}
}
AndroidApk {
name: "helloworld_android"
Depends {name: "helloworld" }
packageName: "com.example.android.helloworld"
}
}
最后我完成了 HelloWorld 产品 (libhelloworld.so)。但是 "helloworld_android" 的第一个错误是 android 清单中的失败。该文件未定义。接下来我应该做什么?
qmake 在为 Android 构建时具有一些内置的魔力,例如使用 Qt 提供的资源(包括清单模板)和 运行 android-deployqt 工具。 None 目前由 qbs 完成。
好的,我想我做到了。这不是一个好的解决方案,但这是可行的。您可以在 "\install-root\$productName$\build\outputs\apk\$productName$-debug.apk
中找到生成的 APKimport qbs
import qbs.TextFile
import qbs.Process
import qbs.File
Project {
//Main Application
CppApplication {
name: "helloworld";
Depends {
name: "Qt"
submodules: [
"core",
"widgets"
]
}
Depends { name: "Android.ndk" }
Android.ndk.appStl: "gnustl_shared"
Group {
name: "src"
files: [
"main*.*"
]
}
Group {
qbs.install: true
fileTagsFilter: "dynamiclibrary"
qbs.installPrefix : product.name+"/libs/"+Android.ndk.abi+"/"
}
}
//Preparation
Product {
name: "Prepared2Deploy"
type: "prepared2deploy"
Depends { name: "helloworld" }
Depends { name: "Qt.core" }
Depends { name: "Android.ndk" }
Depends { name: "Android.sdk" }
Rule {
inputsFromDependencies: "installable"
Artifact {
filePath: input.fileName+".json"
fileTags: "prepared2deploy"
}
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "prepare for androidDeployQt";
cmd.highlight = "install";
cmd.sourceCode = function() {
var outputFile = new TextFile(output.filePath, TextFile.WriteOnly);
outputFile.writeLine("{");
outputFile.writeLine(" \"qt\": \"" + product.Qt.core.binPath.replace(/\/bin$/,"") + "\",");
outputFile.writeLine(" \"sdk\": \"" + product.Android.sdk.sdkDir + "\",");
outputFile.writeLine(" \"sdkBuildToolsRevision\": \"" + product.Android.sdk.buildToolsVersion + "\",");
var ndkDir = product.Android.ndk.ndkDir.replace(/\/g,"/"); //why sdk ndk get wrong slashes?
outputFile.writeLine(" \"ndk\": \""+ndkDir+"\",");
var toolchain = product.cpp.toolchainPrefix.replace(/-$/,"");
outputFile.writeLine(" \"toolchain-prefix\": \"" + toolchain + "\",");
outputFile.writeLine(" \"tool-prefix\": \"" + toolchain + "\",");
outputFile.writeLine(" \"toolchain-version\": \"4.9\","); //how I can get it ???
outputFile.writeLine(" \"ndk-host\": \"windows-x86_64\","); //how I can get it ???
var abi = product.Android.ndk.abi
outputFile.writeLine(" \"target-architecture\": \""+abi+"\",");
outputFile.writeLine(" \"stdcpp-path\": \""+ndkDir+"/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + //how I can get it ???
abi+"/lib"+product.Android.ndk.appStl+".so\",");
outputFile.writeLine(" \"application-binary\": \""+ input.filePath+"\"");
outputFile.writeLine("}");
outputFile.close();
}
return cmd;
}
}
}
//Deployer
Product {
name: "AndroidDeployQt"
Depends { name: "helloworld" }
id: androidDeployQt
type: "androidDeployQt"
Depends {name: "Qt.core" }
Rule {
inputsFromDependencies: "prepared2deploy"
alwaysRun: true
Artifact {
filePath: "log.txt"
fileTags: "androidDeployQt"
}
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "androidDeployQt";
cmd.highlight = "install";
cmd.sourceCode = function() {
var logFile = new TextFile(output.filePath, TextFile.WriteOnly);
logFile.writeLine(input.fileName);
var productName = input.fileName.replace(/.so.json$/,"").replace(/^(lib)/,"");
var androidDeployProcess = new Process();
var exitCode = androidDeployProcess.exec(product.Qt.core.binPath+"/androiddeployqt.exe",
[
"--input", input.filePath,
"--output", project.buildDirectory+"/install-root/"+productName,
"--android-platform", "android-25", //???
"--gradle"
])
if (exitCode) {
console.error("Error at androidDeployProcess. Error code: "+exitCode);
console.error(androidDeployProcess.readStdErr());
console.error("FULL_LOG: ");
console.error(androidDeployProcess.readStdOut());
}
logFile.close();
}
return cmd;
}
}
}
}
QBS 1.13,于今年 2 月 (2019) 发布,使得部署 Android 应用程序与使用 qmake 一样简单。实际上,您不需要做任何特别的事情。例如,我使用了 contactlist application from the Qt examples 并添加了这个 QBS 文件:
import qbs 1.0
Project {
QtGuiApplication {
name: "contactlist"
install: true
files: [
"contactmodel.h",
"contactmodel.cpp",
"main.cpp",
]
Group {
files: [
"*.qml",
"designer/Backend/*.qml",
"designer/Backend/qmldir",
]
fileTags: ["qt.core.resource_data"]
}
Depends { name: "Qt.quick" }
}
}
如您所见,Android 没有任何特定内容。我使用的唯一技巧是将标签 qt.core.resource_data
分配给 QML 文件,以便将它们编译为资源文件——但这甚至不是必需的。
使用 qbs run
,应用程序将 运行 在您连接的 Android 设备中。