graalvm-mobile

phronmophobic 2022-04-07T03:32:21.154419Z

@borkdude ok, I think the configuration issues should be fixed now. I was able to build the MobileTest xcode project on a second computer within a https://github.com/phronmophobic/grease/runs/5861890606?check_suite_focus=true which means there's at least a 50% chance it will work on third computer 😄. You'll need to rerun ./scripts/download-deps and ./scripts/compile-shared. Also, I'd be happy to do a video call at some point if that would help get you up and running. One last note is that I've only tested with https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.0.0.2/graalvm-ce-java17-darwin-amd64-22.0.0.2.tar.gz, so you may want to start with that specific version of graalvm.

phronmophobic 2022-04-07T04:05:01.111789Z

The TestSkia project now builds on github as well.

phronmophobic 2022-04-07T04:05:36.138129Z

In theory, we could offer a github action to allow anyone to build a mobile app even without a macbook.

👀 1
borkdude 2022-04-07T08:44:37.800229Z

Pretty cool

borkdude 2022-04-07T08:39:43.483149Z

@smith.adriane Thanks. I don't know what I did wrong, but I'm getting this now:

phronmophobic 2022-04-07T16:57:16.314689Z

@borkdude, progress! I can't tell what the cause might be. Can you send the full build log?

phronmophobic 2022-04-07T17:01:37.670479Z

Also, can you confirm you built your jar and native image with this version of graalvm? https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.0.0.2/graalvm-ce-java17-darwin-amd64-22.0.0.2.tar.gz

borkdude 2022-04-07T17:50:24.520949Z

I'm using export GRAALVM_HOME=~/Downloads/graalvm-ce-java11-22.0.0.2/Contents/Home by default... is that a problem? I'll try with 17

phronmophobic 2022-04-07T17:57:05.791849Z

I'm not sure if using java11 is a problem, but since it's not working, I think it makes sense to try and narrow down the list of possible issues.

phronmophobic 2022-04-07T17:57:20.223009Z

I've only tested with this specific version.

phronmophobic 2022-04-07T18:03:21.360899Z

"_Java_java_net_SocketOutputStream_init", referenced from:
      ___svm_vm_target_platform in bb.o
Ok, the missing symbols are from bb.o and I don't see those symbols show up in my bb.o when I build. I think the different graalvm version might be the cause.

borkdude 2022-04-07T18:04:43.365339Z

build succeeded!±±

1
🎉 1
phronmophobic 2022-04-07T18:05:37.101929Z

does it load on your phone?

phronmophobic 2022-04-07T18:05:49.047419Z

there might be some signing issues

borkdude 2022-04-07T18:07:01.982359Z

indeed, signing issue. I need to allow something on my phone... but where

phronmophobic 2022-04-07T18:07:55.847349Z

not sure.

borkdude 2022-04-07T18:08:24.087009Z

> https://developer.apple.com/forums/thread/666097

phronmophobic 2022-04-07T18:09:13.929649Z

> Settings -> General -> Device Management this?

borkdude 2022-04-07T18:11:39.364199Z

yep, retrying now

borkdude 2022-04-07T18:12:27.561239Z

Aw yeah :)

1
phronmophobic 2022-04-07T18:12:44.113379Z

it works!

borkdude 2022-04-07T18:12:54.043739Z

hell yeah!

borkdude 2022-04-07T18:13:04.005289Z

What can I eval again? I'll look it up

phronmophobic 2022-04-07T18:13:29.699349Z

the Mobiletest project is pretty minimal

borkdude 2022-04-07T18:13:51.826049Z

let's see what is the ip of my phone again ...

phronmophobic 2022-04-07T18:14:44.705849Z

you can get that from Settings > Wifi . tap on Info button for your connected network

borkdude 2022-04-07T18:15:25.311439Z

got it now

phronmophobic 2022-04-07T18:15:25.938079Z

the main namespace for the mobiletest project is com.phronemophobic.grease if you want to see the nrepl setup.

phronmophobic 2022-04-07T18:16:47.486319Z

the membrane example project prints out the local address. I can have the mobiletest do the same.

borkdude 2022-04-07T18:17:15.206599Z

That's be useful. Maybe along with some things you can do in the REPL

borkdude 2022-04-07T18:17:46.227419Z

btw not using (requiring-resolve 'tech.v3.datatype.ffi.graalvm/expose-clojure-functions) will likely have a positive effect on the bundle size

phronmophobic 2022-04-07T18:19:32.010809Z

what do you mean by not using?

borkdude 2022-04-07T18:19:44.740829Z

avoiding the usage of requiring-resolve

👍 1
borkdude 2022-04-07T18:20:18.503939Z

at compile time it's fine, but at runtime it will make graalvm suspicious and hold on to a lot of stuff

phronmophobic 2022-04-07T18:21:45.722609Z

cool. I'll file an issue so I can remember to fix that.

borkdude 2022-04-07T18:24:47.646759Z

thanks for helping me with this. perhaps I can make a fun little app. I've always stayed away from this stuff because it's so hard to get going and the "closed" app store stuff

borkdude 2022-04-07T18:25:38.878189Z

I'm seeing this:

(defn clj_eval [bs]
  (add-result (sci/eval-string (dt-ffi/c->string bs))))

(defn clj_print_hi []
  (println "hi"))


(def opts (-> {:namespaces {'foo.bar {'x 1}}}
              addons/future))
(def sci-ctx (sci/init opts))

(defn clj_start_server []
  (babashka.nrepl.server/start-server! sci-ctx {:host "0.0.0.0" :port 23456}))

borkdude 2022-04-07T18:25:48.928859Z

Is there a reason why clj_eval does not share the sci-ctx?

phronmophobic 2022-04-07T18:27:06.239299Z

The mobiletest project was basically an attempt at the most minimal example. The membrane example has a lot more comforts and features.

👍 1
borkdude 2022-04-07T18:29:02.088809Z

are the reflection configs generated or can I add a class to it?

phronmophobic 2022-04-07T18:30:25.115959Z

I used the configs that gluon used as an example. My understanding of reflection configs is pretty minimal

borkdude 2022-04-07T18:31:02.955509Z

ok. I just want to add java.lang.System so I can poke in the REPL to see what it does there :)

👍 1
phronmophobic 2022-04-07T18:31:35.614879Z

I'm sure you know more about the reflection config than I do, so whatever you recommend.

borkdude 2022-04-07T18:39:58.705959Z

Do you accept PRs? I could add it so you can do:

borkdude 2022-04-07T18:40:04.501429Z

Even (System/exit 0) worked ;)

🤣 1
phronmophobic 2022-04-07T18:41:05.377789Z

PRs welcome!

phronmophobic 2022-04-07T18:43:06.656139Z

if you include the clj-objc stuff, you can call arbitrary objective-c code.

borkdude 2022-04-07T18:48:19.103299Z

First PR up: https://github.com/phronmophobic/grease/pull/2

🎉 1
borkdude 2022-04-07T18:48:33.802629Z

Maybe it will be nice to make a 4clojure app or so

phronmophobic 2022-04-07T18:49:05.883029Z

Yea, I'd like to make something like https://apps.apple.com/us/app/pyto-python-3/id1436650069

borkdude 2022-04-07T18:49:59.850199Z

I think I'd also find it pretty useful to clean up my phone using a script

phronmophobic 2022-04-07T18:50:19.567319Z

Like the apps on your phone?

phronmophobic 2022-04-07T18:50:47.793019Z

I'm not sure that's possible with an app.

borkdude 2022-04-07T18:51:13.627179Z

it is possible if I just hook it up like this right?

borkdude 2022-04-07T18:51:31.754279Z

or do you mean, the app needs specific access to things?

phronmophobic 2022-04-07T18:51:37.812259Z

If there's an API, you can

borkdude 2022-04-07T18:51:54.015989Z

can't I just use babashka fs?

phronmophobic 2022-04-07T18:52:03.562319Z

I think you can access data like photos, address book

borkdude 2022-04-07T18:52:14.484379Z

I mostly want to delete photos

👍 1
phronmophobic 2022-04-07T18:52:29.921519Z

by default, the app can only access its own files.

phronmophobic 2022-04-07T18:53:26.948719Z

I'm not sure deleting photos will be as straightforward as using babaska.fs. You may need to use a specific photos API.

phronmophobic 2022-04-07T18:53:48.378439Z

But cleaning up photos seems totally possible

borkdude 2022-04-07T18:54:02.432759Z

right

borkdude 2022-04-07T19:01:04.964079Z

can't say that removing the requiring-resolve helped much ;)

phronmophobic 2022-04-07T19:02:37.549979Z

It only needs to be available at compile time, so it would be easy to wrap in a macro regardless

borkdude 2022-04-07T19:03:41.524779Z

it requires you to initialize ASM at built time too since I guess dtype.next uses that at the top level somewhere

borkdude 2022-04-07T19:04:01.037369Z

perhaps with this new Panama stuff it becomes a different story

phronmophobic 2022-04-07T19:07:17.204469Z

Perhaps. I thought the ASM stuff was to generate classes that would otherwise be awkward to generate from clojure. I thought coffi also used insn which uses asm under the hood.

borkdude 2022-04-07T19:07:44.043459Z

true yes. so dtype.next also uses insn?

phronmophobic 2022-04-07T19:08:00.489309Z

yea

phronmophobic 2022-04-07T19:09:07.601469Z

it's possible that we could submit a pull request to avoid loading insn at build time if it's not needed and has a negative impact

phronmophobic 2022-04-07T19:09:44.307919Z

I believe the insn stuff is only needed at compile time.

borkdude 2022-04-07T19:10:45.869079Z

If graalvm 17+ supports the Panama stuff perhaps we could just write some of that stuff in java

borkdude 2022-04-07T19:11:18.186629Z

I'm also considering writing some Java for bb: I can't easily get to the default method of an interface without invoking the virtual method

borkdude 2022-04-07T19:11:38.149029Z

supposedly insn should help with that, but just writing Java seems less daunting to me

phronmophobic 2022-04-07T19:12:19.909609Z

For me, being able to expose a clojure function just by providing its name is a big time saver

borkdude 2022-04-07T19:12:38.645039Z

that's true

phronmophobic 2022-04-07T19:13:45.032249Z

Especially if we can mitigate any downside by just loading insn at compile time, then I'd be happier to improve dtype.next/coffi than write all my ffi in java.

borkdude 2022-04-07T19:14:34.676439Z

true :)

borkdude 2022-04-07T19:14:41.277319Z

worth some investigation

phronmophobic 2022-04-07T19:23:38.343539Z

for sure. I'm not opposed to writing java.

borkdude 2022-04-07T19:25:34.384839Z

perhaps you know how to express this in isns?

(def method-map {'remove ....})
(reify java.util.Iterator (remove [this] (if-let [m (get method-map 'remove)] (m this) (super-remove this))

borkdude 2022-04-07T19:25:48.162689Z

it's not possible in clojure itself, ghadi told me (and I tried hard using reflection)

borkdude 2022-04-07T19:26:02.102389Z

then I could maybe use that at build time instead

phronmophobic 2022-04-07T19:41:18.684889Z

I don't know how to express that off the top of my head. I think that would be a good fit for insn. I would just write the Java class, compile it. There are tools that will print out the instructions which should be fairly straightforward to parameterize and output via insn.

borkdude 2022-04-07T19:42:58.834899Z

hmm right

borkdude 2022-04-07T19:43:18.611269Z

it's either that or generate Java code via some hacks :/

phronmophobic 2022-04-07T19:56:23.178639Z

I think https://github.com/gtrak/no.disassemble/ comes pretty close to datafying the instructions for you

borkdude 2022-04-08T13:58:17.316629Z

you're right about the permissions: https://twitter.com/borkdude/status/1512429405347397641/photo/1

phronmophobic 2022-04-08T17:08:29.015839Z

The objective-c API is a little clunky, but you I've been at least able to grab image meta-data:

objc> (def PHFetchOptions (objc/string->class "PHFetchOptions"))
#<SciVar@1f6eaa07: 
  #object[tech.v3.datatype.ffi.Pointer 0x105ee349 "{:address 0x00000001DACA9988 }"]>
objc> (def fetch-options (-> PHFetchOptions
                       (objc/call-objc "alloc" :pointer)
                       (objc/call-objc "init" :pointer)))
#<SciVar@68b17ebd: 
  #object[tech.v3.datatype.ffi.Pointer 0xd86e8fb "{:address 0x000000010B40BA80 }"]>
objc> (def PHAsset (objc/string->class "PHAsset"))
#<SciVar@7cb89932: 
  #object[tech.v3.datatype.ffi.Pointer 0x25c0cb71 "{:address 0x00000001DACA9A78 }"]>
objc> (def result (objc/call-objc PHAsset "fetchAssetsWithOptions:" :pointer :pointer fetch-options))
#<SciVar@5feadd9e: 
  #object[tech.v3.datatype.ffi.Pointer 0x4e5b6c "{:address 0x000000028318C3C0 }"]>
objc> (def num-photos (objc/call-objc result "count" :int64))
#<SciVar@6b732bd0: 1753>
objc> (def photo (objc/call-objc result "firstObject" :pointer))
#<SciVar@2d3064ab: 
  #object[tech.v3.datatype.ffi.Pointer 0x796f4d7 "{:address 0x000000010B40F100 }"]>
objc> (println (objc/objc->str photo))
<PHAsset: 0x10b40f100> 6C5434F5-8DEF-4AA0-A1FD-FB3F4C3CABB6/L0/001 mediaType=2/0, sourceType=1, (720x1280), creationDate=2015-11-15 21:27:11 +0000, location=0, hidden=0, favorite=0, adjusted=0 
nil

phronmophobic 2022-04-08T17:09:16.378079Z

Using PhotoKit, https://developer.apple.com/documentation/photokit?language=objc

phronmophobic 2022-04-08T17:09:39.570289Z

I also had to add NSPhotoLibraryUsageDescription to the Info.plist

phronmophobic 2022-04-08T17:09:52.881309Z

The calls fail the first time until you allow permissions to the app.

borkdude 2022-04-08T18:16:12.099689Z

That's quite some impressive dynamic native interop ;)

phronmophobic 2022-04-08T18:19:24.684459Z

Even so, it could be much better! It wouldn't that hard to create a DSL that makes it much more straightforward. Objective-c is actually very dynamic.

phronmophobic 2022-04-08T18:27:19.384859Z

There's also a json API for the Apple docs that could be used to generate a more clojure friendly interface with docstrings.