@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.
The TestSkia project now builds on github as well.
In theory, we could offer a github action to allow anyone to build a mobile app even without a macbook.
Pretty cool
@smith.adriane Thanks. I don't know what I did wrong, but I'm getting this now:
@borkdude, progress! I can't tell what the cause might be. Can you send the full build log?
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
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
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.
I've only tested with this specific version.
"_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.build succeeded!±±
does it load on your phone?
there might be some signing issues
indeed, signing issue. I need to allow something on my phone... but where
not sure.
> Settings -> General -> Device Management this?
yep, retrying now
Aw yeah :)
it works!
hell yeah!
What can I eval again? I'll look it up
the Mobiletest project is pretty minimal
let's see what is the ip of my phone again ...
you can get that from Settings > Wifi . tap on Info button for your connected network
got it now
the main namespace for the mobiletest project is com.phronemophobic.grease if you want to see the nrepl setup.
the membrane example project prints out the local address. I can have the mobiletest do the same.
That's be useful. Maybe along with some things you can do in the REPL
btw not using (requiring-resolve 'tech.v3.datatype.ffi.graalvm/expose-clojure-functions) will likely have a positive effect on the bundle size
what do you mean by not using?
avoiding the usage of requiring-resolve
at compile time it's fine, but at runtime it will make graalvm suspicious and hold on to a lot of stuff
cool. I'll file an issue so I can remember to fix that.
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
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}))Is there a reason why clj_eval does not share the sci-ctx?
The mobiletest project was basically an attempt at the most minimal example. The membrane example has a lot more comforts and features.
are the reflection configs generated or can I add a class to it?
I used the configs that gluon used as an example. My understanding of reflection configs is pretty minimal
ok. I just want to add java.lang.System so I can poke in the REPL to see what it does there :)
I'm sure you know more about the reflection config than I do, so whatever you recommend.
Do you accept PRs? I could add it so you can do:
Even (System/exit 0) worked ;)
PRs welcome!
if you include the clj-objc stuff, you can call arbitrary objective-c code.
Maybe it will be nice to make a 4clojure app or so
Yea, I'd like to make something like https://apps.apple.com/us/app/pyto-python-3/id1436650069
I think I'd also find it pretty useful to clean up my phone using a script
Like the apps on your phone?
I'm not sure that's possible with an app.
it is possible if I just hook it up like this right?
or do you mean, the app needs specific access to things?
If there's an API, you can
can't I just use babashka fs?
I think you can access data like photos, address book
I mostly want to delete photos
by default, the app can only access its own files.
I'm not sure deleting photos will be as straightforward as using babaska.fs. You may need to use a specific photos API.
But cleaning up photos seems totally possible
right
can't say that removing the requiring-resolve helped much ;)
It only needs to be available at compile time, so it would be easy to wrap in a macro regardless
it requires you to initialize ASM at built time too since I guess dtype.next uses that at the top level somewhere
perhaps with this new Panama stuff it becomes a different story
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.
true yes. so dtype.next also uses insn?
yea
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
I believe the insn stuff is only needed at compile time.
If graalvm 17+ supports the Panama stuff perhaps we could just write some of that stuff in java
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
supposedly insn should help with that, but just writing Java seems less daunting to me
For me, being able to expose a clojure function just by providing its name is a big time saver
that's true
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.
true :)
worth some investigation
for sure. I'm not opposed to writing java.
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))it's not possible in clojure itself, ghadi told me (and I tried hard using reflection)
then I could maybe use that at build time instead
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.
hmm right
it's either that or generate Java code via some hacks :/
I think https://github.com/gtrak/no.disassemble/ comes pretty close to datafying the instructions for you
you're right about the permissions: https://twitter.com/borkdude/status/1512429405347397641/photo/1
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
nilUsing PhotoKit, https://developer.apple.com/documentation/photokit?language=objc
I also had to add NSPhotoLibraryUsageDescription to the Info.plist
The calls fail the first time until you allow permissions to the app.
That's quite some impressive dynamic native interop ;)
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.
There's also a json API for the Apple docs that could be used to generate a more clojure friendly interface with docstrings.
https://developer.apple.com/tutorials/data/documentation/technologies.json?language=objc