October 04, 2019
On Friday, 4 October 2019 at 14:14:33 UTC, Jacob Carlborg wrote:
> I can give some answers related to iOS, although I'm not that guy working on the iOS project.

oh i thought it was you :S

> For interfacing between the Swift/Objective-C code either the `extern(C)` or `extern(Objective-C)` can be used. DStep [1] can generate bindings to Objective-C code.

So it isn't that different than doing a Mac cocoa program?

I don't have a mac nor an apple developer license though, just a vm. So I probably couldn't do it even if I tried. (the android thing is painful enough, I don't even know how to do it and most the work is already done for me by others!)
October 04, 2019
On Friday, 4 October 2019 at 15:02:36 UTC, H. S. Teoh wrote:
> On Fri, Oct 04, 2019 at 02:14:33PM +0000, Jacob Carlborg via Digitalmars-d wrote: [...]
>> The simplest would probably be to add an external build step in Xcode to compile the D code, which should produce a static library. Then just link with that static library. It's a bit simpler on iOS since everything is native code and there are nothin like JNI that needs to be handled.
> [...]
>
> FYI, on Android there *is* a C API in the NDK that you can use to interface with the OS. IIRC Java/JNI is not strictly necessary, though it's certainly more convenient since a large number of built-in resources are only accessible to Java (esp. the various GUI components).
>
> I chose the mixed Java/D route mainly so that I can just leverage off the Java stuff that's already built-in, instead of homebrewing everything from scratch in D.
>
>
> T

JNI is pretty much a requirement for anything that isn't OpenGL, Vulkan, Audio, ISO C or ISO C++ standard libraries, even accessing files outside the APK install directory requires Java due to SAF.

Additionally since Android 7 Google has been clamping down the NDK APIs to minimize exploits via native code.
October 04, 2019
On Friday, 4 October 2019 at 15:34:32 UTC, Paulo Pinto wrote:
> JNI is pretty much a requirement for anything that isn't OpenGL, Vulkan, Audio, ISO C or ISO C++ standard libraries, even accessing files outside the APK install directory requires Java due to SAF.
>
> Additionally since Android 7 Google has been clamping down the NDK APIs to minimize exploits via native code.

But Flutter is made by Google, so they clearly have a path to a Java-free environment? Or does Flutter depend on Java?

October 04, 2019
On Friday, 4 October 2019 at 15:56:28 UTC, Ola Fosheim Grøstad wrote:
> On Friday, 4 October 2019 at 15:34:32 UTC, Paulo Pinto wrote:
>> JNI is pretty much a requirement for anything that isn't OpenGL, Vulkan, Audio, ISO C or ISO C++ standard libraries, even accessing files outside the APK install directory requires Java due to SAF.
>>
>> Additionally since Android 7 Google has been clamping down the NDK APIs to minimize exploits via native code.
>
> But Flutter is made by Google, so they clearly have a path to a Java-free environment? Or does Flutter depend on Java?

We're using Flutter at work for one of our applications, so I can answer that.

The Flutter project is divided in two parts: engine and framework. The engine is written in a mix of C++, Java and Objective-C where Java and Objective-C are respectively used to access the platform APIs. The framework (what Flutter apps are directly using) is written in pure Dart.
Flutter is using a technique called system channels which is basically an RPC-like thing that marshals method calls to/from C/C++/Java/Objective-C from/to C++ and Dart. It's slower than calling the method from the same language.

I believe Flutter will be framework of choice for their upcoming Fuchsia OS, but currently Dart is very much a second class citizen on Android (unlike Kotlin), just like it is on iOS. Fortunately, Google have done a stellar job of creating good dev experience by providing a solid CLI and editor plugins that abstract the platform differences.


October 04, 2019
On Fri, Oct 04, 2019 at 03:19:48PM +0000, Adam D. Ruppe via Digitalmars-d wrote: [...]
> (the android thing is painful enough, I don't even know how to do it and most the work is already done for me by others!)

Just in case this is helpful, here's an overview of I get from sources to .apk in my mixed Java/D project:

1) Generate R.java from Java sources by running `aapt` (from the
   SDK/NDK; some Linux distros ship it separately as well -- be aware
   that the version must match the rest of your environment or you might
   get strange errors / compatibility issues).

2) Build Java sources by invoking `javac`.

3) Run the `dx` tool to transform the resulting .class files to
   the classes.dex format required by Android.

4) Cross-compile D sources to the target architecture using LDC (in my
   case, I target cortex-a8 / armv7 androideabi). In my case, I found
   that I need to compile to object files first, and link separately
   (see following step).

5) Link .o files to .so file using the clang compiler from the Android
   NDK. This is to ensure that you get the right native libs linked to
   your D code, otherwise you'll end up with link errors and/or runtime
   problems. Be sure to specify -shared and the right -soname.

   EXTRA NOTE: In order to optimize the resulting binary size, I also
   specify -Wl,--gc-sections and -Wl,--version-script=libmyapp.version,
   where libmyapp.version contains the following:

	LIBGAME_1.0 {
		global:
			Java_*;
		local:
			*;
	};

   This is to ensure that --gc-sections deletes all sections not
   reachable from a symbol that matches the name Java_* (i.e., a JNI
   entry point). Without this, tons of unused symbols from druntime and
   Phobos get included in the .so, significantly bloating the APK size.

   If you're generating a Java-free native app, you'll have to customize
   the global: line to point to your app's entry point so that it
   doesn't get GC'd. :-D

6) Create the initial (unaligned) APK file using the following commands:

	aapt package -f -m -M$manifest_file -S$resource_dir -I$sdkjar -F $target-unaligned.apk
	aapt add $target-unaligned.apk classes.dex
	aapt add $target-unaligned.apk path/to/libmyapp.so

	where:
		$manifest_file
			is the Android manifest file for your project;
		$sdkjar
			points to platforms/android-$version/android.jar
			where $version is the Android API version number
			you're targeting;
		$resource_dir
			Points to the subdir (generally called `res`)
			containing various XML resources and other
			media.

7) Sign the APK:

	apksigner sign --ks-pass file:path/to/passwordfile -ks path/to/keystore $target-unaligned.apk

   (Note: apksigner expects a keystore in the proprietary Java format;
   if you want to use a different keystore format you'll have to
   manually do the signing -- google for instructions on how to do
   this. Be warned that it will not be pretty.)

8) Align the APK:

	zipalign -f 4 $target-unaligned.apk $target.apk

Now $target.apk should be ready for installation.

Most of the above steps are customarily hidden from view when you use an IDE like Android Studio, and it's mostly automated by Gradle.  Ideally, to make the above more accessible to D users, you'd probably want to create a Gradle plugin that integrates the LDC cross-compilation and linking step into Gradle, or whatever IDE / build system you want to target, so that users can just add the plugin to their build config and build away.

I did all of the above manually primarily because I have auxiliary code generators in my project (small D programs running on the host PC that read in a bunch of data files and process them into a form suitable for inclusion into the APK, along the way also generating D wrapper code for working with said data). Doing it manually is also more direct, and has less external dependencies, which makes it faster (using SCons, I can already finish building the darned thing from start to finish in the time it takes just for Gradle to *start up* -- and this, in a fraction of the RAM required to even run Gradle in the first place).

Generally, I don't recommend doing all of this manually. :-D  So for your general D user who's uncomfortable with writing build scripts manually you probably want to look into Gradle integration of some sort, or whatever IDE or build system you want to target.  Note that the current version of dub is unable to handle some of the above steps without heavy hackery / hard-coding of stuff / external scripting.  (The cross-compilation step and the need to compile Java are big show-stoppers when it comes to dub.) It would be *very* nice if you could somehow coax dub to do the Right Thing(tm), but I honestly have my doubts about it.  You *should* be able to do the cross-compilation and linking step as a Gradle plugin, though, and Gradle will take care of the rest of the APK heavy-lifting for you, so perhaps this could be a first target: get D cross-compilation working in Android Studio.

(Unfortunately, I have not bothered to use Gradle to any meaningful degree, so I'm unable to help you on that front.)


T

-- 
The best way to destroy a cause is to defend it poorly.
October 04, 2019
On Friday, 4 October 2019 at 16:28:31 UTC, Petar Kirov [ZombineDev] wrote:
> The Flutter project is divided in two parts: engine and framework. The engine is written in a mix of C++, Java and Objective-C where Java and Objective-C are respectively used to access the platform APIs. The framework (what Flutter apps are directly using) is written in pure Dart.
> Flutter is using a technique called system channels which is basically an RPC-like thing that marshals method calls to/from C/C++/Java/Objective-C from/to C++ and Dart. It's slower than calling the method from the same language.

Ok, it was not apparent from their system overview chart that they go through Java, it basically says that the engine is C/C++ and sits on top of a system specific "embedder" layer. So I guess then that Java is called from the "embedder" layer where the API isn't available otherwise? But rendering is done straight from C/C++? It does use its own renderer, right?

> I believe Flutter will be framework of choice for their upcoming Fuchsia OS, but currently Dart is very much a second class citizen on Android (unlike Kotlin), just like it is on iOS. Fortunately, Google have done a stellar job of creating good dev experience by providing a solid CLI and editor plugins that abstract the platform differences.

Thanks for sharing your experience with Flutter! Being able to do cross-platform apps for iOS, Android and web did peak my curiosity, so downloading now to see how it all works.

October 04, 2019
On Friday, 4 October 2019 at 15:18:03 UTC, Ola Fosheim Grøstad wrote:
>
> I wonder how hard it would be to port Flutter to D and bypass Java/Swift entirely. I don't think "modern" Dart is all that different.
>
> https://flutter.dev/docs/resources/technical-overview

The guy is obviously biased, but he has a point. Kotlin devs will not want to move to Dart, and who knows how long Flutter will last, till the next cool framework comes along? Personally, it's too React-ish and Angular-ish for my liking.

https://blog.kotlin-academy.com/flutter-and-kotlin-multiplatform-relationship-890616005f57
October 04, 2019
On Friday, 4 October 2019 at 17:41:15 UTC, Chris wrote:
> The guy is obviously biased, but he has a point. Kotlin devs will not want to move to Dart, and who knows how long Flutter will last, till the next cool framework comes along? Personally, it's too React-ish and Angular-ish for my liking.

I don't know, but Google is using Dart internally and also control Android, so it might currently be the best option for cross platform. Anyway, if it all is open source, then the code will be there even if they drop it.

So, I have no experience with Flutter, but it seems to be more mature than it was a few years ago.

It doesn't really matter all that much whether people want to transition or not. If Google don't drop Flutter then the business-cost-savings will be more important than what programmers want or don't want...

Anyway, since the layer under Dart is C/C++, then it should be possible to port Flutter to other languages.

October 04, 2019
On 2019-10-04 17:19, Adam D. Ruppe wrote:

> oh i thought it was you :S

Unfortunately no. It doesn't look like anyone is working on it [1].

> So it isn't that different than doing a Mac cocoa program?

No, it's the same idea. The underlying operating systems are the same (or very similar). They share many of the non-UI frameworks and other libraries.

[1] https://dlang.org/blog/2019/10/04/d-language-foundation-funding-new-platforms-new-bounties/

-- 
/Jacob Carlborg
October 04, 2019
On 2019-10-04 16:14, Jacob Carlborg wrote:

> I can give some answers related to iOS, although I'm not that guy working on the iOS project.
> 
> The simplest would probably be to add an external build step in Xcode to compile the D code, which should produce a static library. Then just link with that static library. It's a bit simpler on iOS since everything is native code and there are nothin like JNI that needs to be handled.
> 
> For interfacing between the Swift/Objective-C code either the `extern(C)` or `extern(Objective-C)` can be used. DStep [1] can generate bindings to Objective-C code.
> 
> I think it should be possible to implement an application completely in D as well.
> 
> [1] http://github.com/jacob-carlborg/dstep

I can also add that it's not possible to create plugins for Xcode. It does support extensions but so far it's only possible to access and manipulate the source code. Can't add support for new languages, can't add new build types or similar.

It's probably possible to build an iOS project without the help of Xcode, just look at the commands Xcode is invoking and replicate those. Can probably use Dub as well with the help of pre and post actions.

-- 
/Jacob Carlborg