holzschu / a-shell

A terminal for iOS, with multiple windows
BSD 3-Clause "New" or "Revised" License
2.59k stars 116 forks source link

Help wanted for compiling PHP for a-shell #265

Open bummoblizard opened 3 years ago

bummoblizard commented 3 years ago

I was attempting to compile PHP for a-shell using the following script.

#!/bin/bash
make clean

PLATFORM=iPhoneOS # iPhoneSimulator # iPhoneOS
HOST=arm-apple-darwin # i386-apple-darwin10 # arm-apple-darwin10
ARCH=arm64 # i386 # armv7s #armv7
SDK_VERSION=14.5

XCODE_ROOT=`xcode-select -print-path`
PLATFORM_PATH=$XCODE_ROOT/Platforms/$PLATFORM.platform/Developer
SDK_PATH=$PLATFORM_PATH/SDKs/$PLATFORM$SDK_VERSION.sdk
FLAGS="-isysroot $SDK_PATH -arch $ARCH -miphoneos-version-min=$SDK_VERSION"
PLATFORM_BIN_PATH=$XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin
CFLAGS="$FLAGS -std=gnu99"
CXXFLAGS="$FLAGS -std=gnu++11 -stdlib=libc++"
LDFLAGS="$FLAGS -lresolv -nostartfiles"

export CFLAGS CXXFLAGS LDFLAGS # PCRE2_CFLAGS PCRE2_LIBS

CONFIGURE_FLAGS="--host=$HOST --enable-embed=static --enable-cli --disable-phpdbg --disable-phar --enable-static --without-pear --disable-opcache --disable-opcache-jit --without-iconv --disable-cgi --disable-shared --enable-mysqlnd --with-pdo-mysql --with-mysqli --with-tsrm-pthreads --without-pcre-jit"
./configure $CONFIGURE_FLAGS
make

cp sapi/cli/php iOS/php
cd iOS
mkdir php.framework
mv php php.framework/php
cp Info.plist php.framework/Info.plist
xcodebuild -create-xcframework -framework php.framework -output php.xcframework

It worked fine and produced a php cli executable to be used in a-shell. However, when I called the command from the app, the following error shows:

Failed loading php from php.framework/php, cause = dlopen(php.framework/php, 9): no suitable image found.  Did find:
    /private/var/containers/Bundle/Application/CE45D906-0B67-4AF8-824D-1643D66BABFE/WKConsole.app/Frameworks/php.framework/php: out of address space

So I renamed main() function in sapi/cli/php_cli.c to command_main().

Then I have the following error during the build:

Undefined symbols for architecture arm64:
  "_main", referenced from:
     implicit entry/start for main executable
     (maybe you meant: _virtual_cwd_main_cwd_init, _command_main )
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [sapi/cli/php] Error 1

I suspect the linker expects a main function when creating an executable. How can I overcome this limitation?

holzschu commented 3 years ago

Hi, Impressive work so far. From the first error message, I take it that you also edited commandDictionary.plist and added php.xcframework to the list of embedded frameworks.

There are few things to check and then it should work:

bummoblizard commented 3 years ago

Yes, I did modified commandDictionary.plist.

It created a Mach-O 64-bit arm64 executable unfortunately. Adding -dylib to LDFLAGS doesn't work either. I'll investigate how I can create a dynamic library instead. Thanks for the help :)

bummoblizard commented 3 years ago

I have made a progress! I added -dynamiclib to LDFLAGS and it successfully produced a Mach-O 64-bit dynamically linked shared library arm64.

Now I'm getting this: Failed loading php from php.framework/php, cause = dlsym(0x2835580d0, command_main): symbol not found

Is this somehow related to my config in commandDictionary.plist? I'm unsure what to put in the third field.

<key>php</key>
<array>
    <string>php.framework/php</string>
    <string>command_main</string>
    <string></string>
    <string>file</string>
</array>
bummoblizard commented 3 years ago

I edited one of the header files and it seems to be working now :) No output though, I'm now going to link it to ios_system.

holzschu commented 3 years ago

You should see the program output in the Xcode console. In order to see it in a-Shell, you will need:

Once you see output in the terminal, there will be the question of variable initialization and freeing up memory.

bummoblizard commented 3 years ago

Yes, I am seeing output in Xcode console and program exit is redirected to ios_system. Fixing the printf's now.

You should see the program output in the Xcode console. In order to see it in a-Shell, you will need:

  • include ios_error.h at the beginning of every C file that reads or write the standard input/output.
  • link with ios_system.xcframework.
  • redefine printf with fprintf(thread_stdout, ...). If you're lucky, this can be done with #define printf(args...) fprintf(thread_stdout, args), but that does not always work.

Once you see output in the terminal, there will be the question of variable initialization and freeing up memory.

holzschu commented 3 years ago

Awesome!

bummoblizard commented 3 years ago

PHP executions are also working fine!

bummoblizard commented 3 years ago

Good news: Just by #define printf(args...) fprintf(thread_stdout, args), both cli commands and outputs from php files are redirected to the terminal.

Here's a screenshot from my app called Code App that uses ios_system: IMG_D4F42561F2C7-1

I will probably create a fork of php and upload the XCFrameworks as releases, and also build for simulators. Would you be interested in putting it to a-Shell? :)

holzschu commented 3 years ago

Congratulations! (and yes, I would absolutely be interested in adding PHP to a-Shell) Once the App is in the AppStore, remind me to add it to the list of Applications that use ios_system at: https://github.com/holzschu/ios_system/

bummoblizard commented 3 years ago

It's actually on App Store already! https://apple.co/2ItI3ub

I have forked PHP: https://github.com/bummoblizard/php-src/tree/PHP-8.0.8. In the release page, you can download the XCFramework for a quick test.

So far I have noticed that only the output of the first php execution is redirected to the terminal. After the first run, the code still executes but the output is not redirecting to terminal.

bummoblizard commented 3 years ago

It's actually on App Store already! https://apple.co/2ItI3ub

I have forked PHP: https://github.com/bummoblizard/php-src/tree/PHP-8.0.8. In the release page, you can download the XCFramework for a quick test.

So far I have noticed that only the output of the first php execution is redirected to the terminal. After the first run, the code still executes but the output is not redirecting to terminal.

Good news! I got around this by preventing PHP from closing stdout or stderr after exit.

Regarding freeing up memory, PHP seems to do a pretty good job already. After running a simple PHP script, the memory usage only goes up by 1MB, sometimes less, which is pretty darn impressive!

I have also tested the built in sqlite3 and web-server. They works fine as far as I have tested. Maybe it's even ready for TestFlight builds. Although I'm not sure how ios_system would handle multiple calls to php.

Line 1858 in main.c:

/* Reset memory limit, as the reset during INI_STAGE_DEACTIVATE may have failed.
* At this point, no memory beyond a single chunk should be in use. */
zend_set_memory_limit(PG(memory_limit));
bummoblizard commented 3 years ago

TODOs:

bummoblizard commented 3 years ago

I also noticed Python produces bus error after I ran any php command. Not sure what's happening there.

TODOs:

holzschu commented 3 years ago

Good news! I got around this by preventing PHP from closing stdout or stderr after exit.

You probably need to check what stdout and stderr are. If they are equal to thread_stdout/thread_stderr (I check this by looking at fileno(stdout)==fileno(thread_stdout)), then you don't want to close them. But if they are different, then the output has been redirected (for example to a file or piped into a command), and then you need to close them.

TechnagyDev commented 2 years ago

Out of curiosity, are there some instructions on getting PHP to work within a-Shell?

bummoblizard commented 2 years ago

Out of curiosity, are there some instructions on getting PHP to work within a-Shell?

If you have access to Xcode, you can link this xcframework and add the entry in commandDictionary.

https://github.com/bummoblizard/php-src/releases/download/v0.2/php.xcframework.zip

lukasbestle commented 1 year ago

What's the current state of this? I'm also interested in PHP support for a-Shell.