Open ghost opened 3 years ago
Hi I have exactly the same question, that's the reason I am exploring the build process of a-shell. Are there any deep dependencies of a-shell to python? I would rather like explore to have a-shell only to have the shell commands, clang, vim and cargo/ rust targeted to WASM . (i.e. remove python and tex ), leaving in clang and adding rust and its supporting commands. (python, tex and rust communities are not that much overlapping).
Any recommendations where to start ?
Hi, these are very good questions. a-Shell does not have any deep dependency to python, python is just treated like one of the many commands available.
To compile a command, you will need to:
ios_system.framework
(use the binary release at https://github.com/holzschu/ios_system)CC = clang
, CFLAGS="-arch arm64 -miphoneos-version-min=14.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.3.sdk
, LDFLAGS
is like CFLAGS
, plus -F ...Frameworks -framework ios_system
.Resources/commandDictionary.plist
. It's an array of arrays, indexed by the name of the command, with 4 entries for each command:
std::cout
will have to be replaced by fprintf(thread_stdout, ...)
, I haven't yet found a way to redirect C++ standard streams.The first step can be difficult if the package or command insists on guessing the compiler and flags rather than letting you set them.
If your command is simple and fast (so, not rust or cargo) you can also compile it to webAssembly, which makes things a lot easier.
If the command uses fork
and exec
, you will need to edit the source code a bit more, as fork()
is a no-op in iOS
. iOS_system
has a fake fork, but we go through both branches in the same thread.
Thanks for the detailled instructions.
But... rust is a llvm based compiler, cargo it's packaging and build system :=) Challenge is to support a different compiler. My proposal for a seperate app is not to enlarge the bulky and ressource heavy a-shell by adding the resource intensive rust compiler on top. If I understood correctly, the App Group Feature would make it possible to interact a "rust shell" with "a-Shell" , right?
You probably want to have a look at https://github.com/holzschu/llvm-project, then. But compilers are just like other commands, only larger. For a compiler to create something that can be executed, it has to produce webAssembly, which should be feasible for rust.
Hi, these are very good questions. a-Shell does not have any deep dependency to python, python is just treated like one of the many commands available.
To compile a command, you will need to:
- download the
ios_system.framework
(use the binary release at https://github.com/holzschu/ios_system)- compile the command for the iOS architecture:
CC = clang
,CFLAGS="-arch arm64 -miphoneos-version-min=14.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.3.sdk
,LDFLAGS
is likeCFLAGS
, plus-F ...Frameworks -framework ios_system
.- (once it compiles) make the system create a dynamic library rather than an executable
- embed that dynamic library inside the executable ("Embed Frameworks", in "Build Phases")
add the command to
Resources/commandDictionary.plist
. It's an array of arrays, indexed by the name of the command, with 4 entries for each command:
- name of dynamic library
- function to be called inside the library (usually main)
- options (the string that is passed to get_options, can be left empty)
- whether the command operates on files, directories or not (file for a compiler).
- (once all this is done) start the command and observe what happens, debug any crash.
(once it is done) edit the source files for:
- output to stdout/stderr should be replaced by output to thread_stout/thread_stderr
- reading from stdin should be replaced by reading from thread_stdin
- make sure all memory is released when leaving the program
- make sure all variables are initialized when we restart the program
- (these two are related to a fundamental issue: we never actually exit from a program on iOS, so the system will never reclaim the memory we allocated and reinitialize the variables. It is up to us to do the cleaning).
- lines using
std::cout
will have to be replaced byfprintf(thread_stdout, ...)
, I haven't yet found a way to redirect C++ standard streams.- (once all this is done): for AppStore release, convert the dynamic library into a framework (see examples in https://github.com/holzschu/python-aux/)
- (once all this is done): submit a pull request, if you want the command to become part of the main application. I see your idea about having a third, separate app for a-Shell, targetting rust more than python and TeX.
The first step can be difficult if the package or command insists on guessing the compiler and flags rather than letting you set them.
If your command is simple and fast (so, not rust or cargo) you can also compile it to webAssembly, which makes things a lot easier.
If the command uses
fork
andexec
, you will need to edit the source code a bit more, asfork()
is a no-op iniOS
.iOS_system
has a fake fork, but we go through both branches in the same thread.
That’s very interesting, and I think I’ll have a look at that just for the learning experience. I think it might become handy down the road in my studies!
I know there’s already a fair share of rust compatability with wasm, so I guess it should be somewhat possible to have something working. No idea about cargo though.
I should probably have added a step 0 for compilers: first compile the compiler on your usual computer, and check that it can produce webAssembly programs that are compatible with the wasi-sdk: https://github.com/holzschu/wasi-sdk and https://github.com/holzschu/wasi-libc. (with this modified wasi-libc, you get access to local files).
I’ll look into this! Thank you so much, it’s very interesting and nice to get some more hands-on experience
rust target wasm32-wasi works out of the box. That's really great.
Thanks for the detailled instructions.
But... rust is a llvm based compiler, cargo it's packaging and build system :=) Challenge is to support a different compiler. My proposal for a seperate app is not to enlarge the bulky and ressource heavy a-shell by adding the resource intensive rust compiler on top. If I understood correctly, the App Group Feature would make it possible to interact a "rust shell" with "a-Shell" , right?
AFAIK, a-Shell already support clang and it is gcc that is not supported by a-Shell.
So maybe it’s not that hard to support cargo, but you probably need to configure cargo to use existing llvm toolchain dynamically instead of compiling another one.
IMHO, one of the problem for supporting rust is that it uses custom lang_start function (called by _start) that initialize argv, heap, unwinding, backtraces and etc, so instead of calling main, one would need to invoke _start direcrly.
It seems that lang_start
is actually called in main
, so that shouldn’t be any problem at all.
This comment about compiling miri (and I think also rustc) to WASM is interesting: https://github.com/rust-lang/miri/issues/722#issuecomment-795763551
This comment about compiling miri (and I think also rustc) to WASM is interesting: rust-lang/miri#722 (comment)
wasmer v2.1.0 can now compile wasm to native dynamic library.
pip3 install nb-cli
I have this problem too
You probably want to have a look at https://github.com/holzschu/llvm-project, then. But compilers are just like other commands, only larger. For a compiler to create something that can be executed, it has to produce webAssembly, which should be feasible for rust.
Replying here because it's the most relevant place regarding adding LLVM based languages. .I want to know if this seems possible to you?
I've been trying to get Julia in a-shell. There was some work compiling (an older version) to wasm , but it's pretty limited if you want to use any real functionality.
Compiling Julia natively would never be allowed, because it uses a JIT which as far as I know is a non-starter for Apple.
Julia is LLVM based, though, and we have a version of LLVM running. The other option then is to compile Julia minus LLVM natively. And use it with our existing version of LLVM (well, Julia requires some patches to LLVM that the upstream hasn't fixed, but maybe those can be added).There are problems with this too, there's a long list of dependencies. Not sure which would pose issues, but certainly seems more feasible. It does compile to Arm64 just fine on my Mac M1.
I honestly have no idea. It's worth trying, though. I would suggest starting with merging https://github.com/holzschu/llvm-project with the Julia patches and compiling. Also start with side-loading (placing the modified a-Shell with Julia on your own devices). Apple allows JIT with side-loading, just not for distribution on the AppStore... for now.
@rquinn2 Think this might be relevant https://github.com/Keno/julia-wasm ?
About Rust: the easiest path right now is to compile on another computer, then execute in a-Shell:
Notes for myself:
Hi!
Would it be possible to include Rust and Cargo in a-shell? As far as I know Rust has a lot of interoperability with C/C++, so I have no idea if it would be possible to include in a future version.
Thanks in advance!