Fork me on GitHub
#graalvm-mobile
<
2022-04-07
>
phronmophobic03:04:21

@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.

phronmophobic04:04:01

The TestSkia project now builds on github as well.

phronmophobic04:04:36

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

👀 1
borkdude08:04:37

Pretty cool

borkdude08:04:43

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

phronmophobic16:04:16

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

borkdude17:04:24

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

phronmophobic17:04:05

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.

phronmophobic17:04:20

I've only tested with this specific version.

phronmophobic18:04:21

"_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.

borkdude18:04:43

build succeeded!±±

🎉 1
clojure-spin 1
phronmophobic18:04:37

does it load on your phone?

phronmophobic18:04:49

there might be some signing issues

borkdude18:04:01

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

phronmophobic18:04:13

> Settings -> General -> Device Management this?

borkdude18:04:39

yep, retrying now

borkdude18:04:27

Aw yeah :)

bananadance 1
borkdude18:04:04

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

phronmophobic18:04:29

the Mobiletest project is pretty minimal

borkdude18:04:51

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

phronmophobic18:04:44

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

phronmophobic18:04:25

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

phronmophobic18:04:47

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

borkdude18:04:15

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

borkdude18:04:46

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

phronmophobic18:04:32

what do you mean by not using?

borkdude18:04:44

avoiding the usage of requiring-resolve

👍 1
borkdude18:04:18

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

phronmophobic18:04:45

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

borkdude18:04:47

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

borkdude18:04:38

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}))

borkdude18:04:48

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

phronmophobic18:04:06

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

👍 1
borkdude18:04:02

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

phronmophobic18:04:25

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

borkdude18:04:02

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

👍 1
phronmophobic18:04:35

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

borkdude18:04:58

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

borkdude18:04:04

Even (System/exit 0) worked ;)

1
phronmophobic18:04:06

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

borkdude18:04:33

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

borkdude18:04:59

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

phronmophobic18:04:19

Like the apps on your phone?

phronmophobic18:04:47

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

borkdude18:04:13

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

borkdude18:04:31

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

phronmophobic18:04:37

If there's an API, you can

borkdude18:04:54

can't I just use babashka fs?

phronmophobic18:04:03

I think you can access data like photos, address book

borkdude18:04:14

I mostly want to delete photos

👍 1
phronmophobic18:04:29

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

phronmophobic18:04:26

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

phronmophobic18:04:48

But cleaning up photos seems totally possible

borkdude19:04:04

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

phronmophobic19:04:37

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

borkdude19:04:41

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

borkdude19:04:01

perhaps with this new Panama stuff it becomes a different story

phronmophobic19:04:17

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.

borkdude19:04:44

true yes. so dtype.next also uses insn?

phronmophobic19:04:07

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

phronmophobic19:04:44

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

borkdude19:04:45

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

borkdude19:04:18

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

borkdude19:04:38

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

phronmophobic19:04:19

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

borkdude19:04:38

that's true

phronmophobic19:04:45

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.

borkdude19:04:41

worth some investigation

phronmophobic19:04:38

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

borkdude19:04:34

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))

borkdude19:04:48

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

borkdude19:04:02

then I could maybe use that at build time instead

phronmophobic19:04:18

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.

borkdude19:04:18

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

phronmophobic19:04:23

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

phronmophobic17:04:29

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

phronmophobic17:04:39

I also had to add NSPhotoLibraryUsageDescription to the Info.plist

phronmophobic17:04:52

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

borkdude18:04:12

That's quite some impressive dynamic native interop ;)

phronmophobic18:04:24

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.

phronmophobic18:04:19

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