Can a Gluon Mobile project automatically download and include libCharm.a? - gluon-mobile

I have written a small sample that makes use of com.gluonhq.charm.down.common.ScanService. It works as expected on a real iOS device, if I manually include the native library libCharm.a in src/ios/jniLibs. This is explained in the Gluon documentation of their GoNative app. If I am not mistaken, the library is built in the build.gradle file of Charm Down IOS.
Here is the build.gradle of my sample. As I have said, this leads to a fully working app if I copy libCharm.a manually to src/ios/jniLibs.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.0.8'
}
}
apply plugin: 'org.javafxports.jfxmobile'
repositories {
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'com.thomaskuenneth.scanservicedemo.ScanserviceDemo'
dependencies {
compile 'com.gluonhq:charm:3.0.0'
androidRuntime 'com.gluonhq:charm-android:3.0.0'
androidRuntime 'com.google.zxing:core:3.2.1'
iosRuntime 'com.gluonhq:charm-ios:3.0.0'
desktopRuntime 'com.gluonhq:charm-desktop:3.0.0'
}
jfxmobile {
apply plugin: 'idea'
idea.module.downloadJavadoc = true
android {
manifest = 'src/android/AndroidManifest.xml'
androidSdk = '/Users/thomas/Library/Android/sdk'
compileSdkVersion = 23
}
ios {
infoPList = file('src/ios/Default-Info.plist')
forceLinkClasses = [
'com.google.zxing.**.*',
'com.gluonhq.**.*',
'io.datafx.**.*',
'javax.annotations.**.*',
'javax.inject.**.*',
'javax.json.**.*',
'org.glassfish.json.**.*'
]
}
}
I tried to add a iosRuntime dependency to the latest version of charm-down-ios, but this seemed to have no effect. So, the question: is there a way to automatically get a libCharm.a that matches my specified dependencies or is the manual way (which, again, does work) the only one possible? Thank you very much in advance.

As of now there is no automatic tool for this included in the plugin that manages the proper installation of the native library, extracting it from the charm-down-ios.jar and moving it to the jniLibs library of the project. But it should be available in a future version of the plugin.
For now, you have to do it manually, as you mentioned, extracting the libCharm.a file from the charm-ios-3.0.0.jar that will be located on your local .m2 repository, and copying it into your project under src/ios/jniLibs.
I've come up with this task that will help you do it:
task extractNativeLib(type: Sync) {
def iosNativeDir = project.file(project.jfxmobile.ios.nativeDirectory)
if (!iosNativeDir.exists()) {
iosNativeDir.mkdirs()
}
setIncludeEmptyDirs(false)
from {
configurations.iosRuntime.collect { zipTree(it).matching { include 'native/**' } }
}
into iosNativeDir
eachFile {details -> details.path = details.name }
}
Run this task before calling launchIOSDevice, and it will extract the library and copy it into your native folder.
EDIT
Since the release of the javafxmobile plugin 1.1.0 (October 2016) there is no need for using this task, as the plugin will manage it.
For the Charm Down 3.0.0+ plugins included in the project, their native libraries will be automatically added to the build, as well as any other third party native library included in src/ios/jniLibs.

Related

Aar containing string resources aren't visible in a jetpack compose project

I'm having an issue with an aar in a jetpack compose project.
I've created a library which contains all the string resources I'm using in multiple projects. In my old java/kotlin projects there is no issue and I can implement the library and reach the strings. But when I do this in my new jetpack compose project it loads the aar but when in code I do R.string. I don't see the specific strings.
Also when I add some kotlin classes with functions in the library, these functions can be accessed. This way I'm 100% sure the library is loaded.
Is there a way to solve this?
The android manifest for the library looks like:
<manifest package="com.test.library"/>
The build.gradle:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdk 31
defaultConfig {
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
android.libraryVariants.all { variant ->
def debug = ""
if (variant.name == "debug") {
debug = "-debug"
}
variant.outputs.all {
outputFileName = "TestLibrary" + debug + ".aar"
}
}
}
}
}
dependencies {
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
In my jetpack compose project I implement it with the following call:
implementation files('libs/TestLibrary.aar')
How can I solve this? Is there somebody with the same issue (and a solution)?
Kind regards,
Jeroen
I also have been struggling with this for a while and I believe I found what causes this issue.
Your jetpack compose project should have a new entry in its gradle.properties file. The entry should look like this:
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
If you change this value to false your project should be able to find the string resources declared in your library. As the description shows.
So your new entry will look like this:
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=false
Hope this helps!

TrustWalletCore/WalletCore pod in Kotlin Multiplatform - almost no classes

In our Kotlin Mobile Multiplatform project for iOS and Android, we're trying to access TrustWalletCore cocoapod from Kotlin.
// build.gradle.kts (:shared)
cocoapods {
version = "1.0"
podfile = project.file("../iosApp/Podfile")
pod("WalletCore")
}
And the Podfile is
target 'iosApp' do
pod 'TrustWalletCore'
end
This successfully enables import cocoapods.WalletCore.* in shared/iosMain - without the above cocoapods {...} the import is unavailable.
However, only a Crypto class is available from this package (and CryptoMeta which doesn't look too different).
By the looks of it, it's generated from the Pod/library by commonizer in 0_WalletCore.knm (about 15 expect functions in total - a couple here for illustration):
#kotlin.commonizer.ObjCCallable public open external expect fun base58Encode(data: platform.Foundation.NSData): kotlin.String { /* compiled code */ }
#kotlin.commonizer.ObjCCallable public open external expect fun generateMnemonicFromSeed(seed: platform.Foundation.NSData): kotlin.String { /* compiled code */ }
It has mnemonic-related functionality, as well as signHash/verifySignature but not much else.
I was hoping to see - available to import in Kotlin - classes like HDWallet, EthereumSigningInput etc.
I can use these library classes in Swift, via pod TrustWalletCore in Xcode (import WalletCore).
WHY can I not get a similar/full set of classes via native.cocoapods plugin?
Try to declare dependency with moduleName parameter:
kotlin {
cocoapods {
...
pod(name = "TrustWalletCore", version = "3.1.0", moduleName = "WalletCore")
}
}

Xcode shows swift compiler errors when importing cocoapods generated by gradle plugin

I am trying to use shared code in my iOS project from cocoapods that i created with cocoapods gradle plugin.
Podspec is created without problems.
My shared build.gradle:
plugins {
id("org.jetbrains.kotlin.multiplatform")
id("com.android.library")
id ("org.jetbrains.kotlin.native.cocoapods")
}
android {
compileSdkVersion 29
buildToolsVersion '30.0.0'
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
version = "1.0"
kotlin {
ios()
android()
cocoapods {
// Configure fields required by CocoaPods.
summary = "Some description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
// The name of the produced framework can be changed.
// The name of the Gradle project is used here by default.
frameworkName = "toshlShared"
}
sourceSets {
commonMain.dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib-common'
}
androidMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
}
iosMain.dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlin_version"
}
}
}
When i run pod install all looks good, but when i run ios app i see this error:
EDIT: Added my project folder structure with my single .kt file (it is accessible from android code)
As far as I can see, the problem here is caused by the project structure. In the Gradle script, there are three targets declared: an Android one, and iosX64+iosArm64 shortcut(see details here) providing the other two. For this layout, there would be two compilations per iOS target(iosX64Main, iosX64Test, iosArm64Main, iosArm64Test) and
a compilation per Android build variant, for Android targets;
according to the documentation.In this particular case, only source file SharedUtils.kt is being located in a directory located on an Android main compilation's source set. This means it does not get into any iOS compilation. To make this source file shared, it should be relocated to the common code. There are two default source sets for common code in Kotlin Multiplatform: commonMain and commonTest. Therefore, source code should be placed under src/<sourceSetName>/kotlin directory(commonMain for this case).

Including OpenCV native library headers in Android Studio

I can't get my C code using native OpenCV to work in Android Studio. OpenCV through the Java wrappers work, but I have been banging my head against this for the last couple of days trying to get it to work with the native libraries. (I have some C code that depends on OpenCV that I need to use in my project)
To pin down the problem I'm trying to get the tutorial-2-mixedprocessing OpenCV sample project to build in AS.
OpenCV is in a separate module in the project, with the shared libraries (.so, .a files) in jniLibs, and the headers are in jni. The application module has a dependency on it. See the image below for the sample code and result when building.
Apparently the headers are not found?
I have tried adding the -I flag to CFlags in android.ndk in the gradle file with no success:
CFlags.add("-I${file("path/to/opencv-android-sdk/native/jni/include/")}".toString())
I have also tried placing the headers in the app module jni folder, as well as using different versions of Android Studio and Gradle.
I keep finding outdated solutions and conflicting information online, it seems like the build system in Android Studio is still changing a lot between versions. I'm also new to both Android development and NDK, so apologies if this is a stupid question. All I really need is a working sample that I can adapt to my project.
What am I missing?
Project structure:
Project gradle:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.7.2'
}
}
allprojects {
repositories {
jcenter()
}
}
OpenCV library module gradle:
apply plugin: 'com.android.model.library'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig {
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 23
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
}
Application module gradle:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig {
applicationId = "org.opencv.samples.tutorial2"
minSdkVersion.apiLevel = 21
targetSdkVersion.apiLevel = 23
}
ndk {
moduleName = "mixed_sample"
//CFlags.add("-I${file("path/to/opencv-android-sdk/native/jni/include/")}".toString())
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
}
dependencies {
compile project(':openCVLibrary2411')
}

How build Vaadin project with gradle?

I have gradle project (backend) and I want to add Vaadin-based frontend. But I haven't find any gradle-plugins for Vaadin.
While, as was already mentioned above, Vaadin app is a simple web application and does not require any additional plugins but "java" and "war" (and maybe "jetty" to run the app), currently there seems to be the first vaadin-specific gradle plugin available:
https://github.com/johndevs/gradle-vaadin-plugin
It will help you with Vaadin-specific task like building widgetsets, creating components skeletons, etc.
I think there is no a Vaadin plugin for Gradle but I have used Gradle in one of my Vaadin add-on projects: SplitButton. It's a project with sub-projects, widgetset compilation and it writes necessary jar manifest entries neebed by Vaadin Directory.
EDIT
Actually there is Gradle Vaadin plugin now - it allows you to easily build Vaadin projects with Gradle. It helps with the most tedious tasks when building a Vaadin project like building the widgetset and running development mode. It also helps you to quickly get started by providing tasks for project, component and theme creation:
https://github.com/johndevs/gradle-vaadin-plugin
You don't need a Vaadin plugin. A Vaadin application is simply a web application.The war plugin will suffice. If you want support for automatically creating the folder layout that Vaadin wants however, you might look into using the vaadin eclipse plugin found here:
http://vaadin.com/eclipse
If you are looking for deployment support, you can simply use the jetty plugin that comes with gradle or the tomcat plugin found here
https://github.com/bmuschko/gradle-tomcat-plugin
If you need to create custom widgets and compile them into a widgetset that's a GWT compile
https://vaadin.com/book/vaadin6/-/page/gwt.development.html#gwt.development.compiler
Note: The Vaadin7 Book no longer has the section on developing Gwt widgets.
There is a gradle plugin for GWT that could help with that. However, I've not needed a custom widget yet, so I haven't actually tried it.
https://github.com/markuskobler/gwt-gradle-plugin
This post:
Using Gradle with Vaadin
looks very comprehensive as far as Gradle+Vaadin setup goes. I'm also including a link to another Vaadin-based 'build.gradle' file I found on my travels, using Google's very useful 'filetype' search (see also the associated gradle.properties file).
JFYI that Google file search is:
filetype:<extension> <your search phrases>
Gradle can also be used to configure Eclipse and IntelliJ's project files by using a fragment such as the following (Eclipse natures can be 'found' by using the above Google file search for "project" extension and "natures" search, etc.):
//Template plugin - Great for project-layout setup - See http://tellurianring.com/wiki/gradle/templates
apply from: 'http://launchpad.net/gradle-templates/trunk/latest/+download/apply.groovy'
apply plugin: 'eclipse'
apply plugin: 'idea'
// if you want to distribute the gradle with your code
task('wrapper', type: Wrapper).configure {
gradleVersion = '1.0-milestone-8a'
}
def versionCompatibility = 1.6
//configurations.providedDependencies.extendsFrom configurations.gwt
eclipse {
project {
comment = ""
buildCommand "org.eclipse.jdt.core.javabuilder"
buildCommand "org.eclipse.wst.jsdt.core.javascriptValidator"
buildCommand "org.eclipse.wst.common.project.facet.core.builder"
buildCommand "org.eclipse.wst.validation.validationbuilder"
buildCommand "com.vaadin.integration.eclipse.widgetsetBuilder"
//buildCommand "org.eclipse.m2e.core.maven2Builder"
//buildCommand "org.maven.ide.eclipse.maven2Builder"
//buildCommand "com.google.gdt.eclipse.core.webAppProjectValidator"
//buildCommand "com.google.gwt.eclipse.core.gwtProjectValidator"
//buildCommand "com.google.gdt.eclipse.designer.GWTBuilder"
//Don't forget commas - no trailing
natures "org.eclipse.jdt.core.javanature",
"com.vaadin.integration.eclipse.widgetsetNature",
"org.eclipse.wst.jsdt.core.jsNature",
"org.eclipse.wst.common.project.facet.core.nature",
"org.eclipse.wst.common.modulecore.ModuleCoreNature",
"org.eclipse.jem.workbench.JavaEMFNature"
//"org.eclipse.m2e.core.maven2Nature",
//"org.maven.ide.eclipse.maven2Nature",
//"com.google.gwt.eclipse.core.gwtNature"
//"com.google.gdt.eclipse.designer.GWTNature",
//"ch.epfl.lamp.sdt.core.scalanature",
//"com.springsource.sts.grails.core.nature",
//"org.eclipse.jdt.groovy.core.groovyNature"
}
classpath {
containers "com.google.gwt.eclipse.core.GWT_CONTAINER"
//"com.springsource.sts.gradle.classpathcontainer"
//minusConfigurations=[configurations.gwt]
}
}
idea {
project {
jdkName = versionCompatibility
ipr {
withXml { provider ->
def node = provider.asNode()
// Set Gradle home
def gradleSettings = node.appendNode('component', [name: 'GradleSettings'])
gradleSettings.appendNode('option', [name: 'SDK_HOME', value: gradle.gradleHomeDir])
}
}
}
}
Cheers
Rich

Resources