a-shell icon indicating copy to clipboard operation
a-shell copied to clipboard

Help wanted for compiling PHP for a-shell

Open bummoblizard opened this issue 4 years ago • 17 comments

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?

bummoblizard avatar Jun 19 '21 12:06 bummoblizard

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:

  • did the compilation step produce an executable or a dynamic library? They look very much the same, but when you call file php, you want the answer to be Mach-O 64-bit arm64 dynamically linked shared library and not Mach-O 64-bit arm64 executable.
  • to trick the make file into creating a dynamic library instead of an executable, I add -dylib to the LDFLAGS. Sometimes I have to prevent configure from adding -execute.

holzschu avatar Jun 19 '21 13:06 holzschu

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 avatar Jun 19 '21 13:06 bummoblizard

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 avatar Jun 19 '21 17:06 bummoblizard

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.

bummoblizard avatar Jun 19 '21 18:06 bummoblizard

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 avatar Jun 19 '21 18:06 holzschu

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.

bummoblizard avatar Jun 19 '21 18:06 bummoblizard

Awesome!

holzschu avatar Jun 19 '21 18:06 holzschu

PHP executions are also working fine!

bummoblizard avatar Jun 19 '21 18:06 bummoblizard

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

bummoblizard avatar Jun 19 '21 18:06 bummoblizard

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/

holzschu avatar Jun 19 '21 18:06 holzschu

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 avatar Jun 19 '21 20:06 bummoblizard

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));
  • See https://github.com/bummoblizard/php-src/blob/2c4fe7e666b846fbaee867e42c7af7c48c721e20/main/main.c#L1752-L1871 for the related clean-up functions.

  • Download a ready-to-use PHP 8.0.8 XCFramework (arm64 only) here: https://github.com/bummoblizard/php-src/releases/tag/v0.2

  • Forked repository with build guide in README.md: https://github.com/bummoblizard/php-src/tree/PHP-8.0.8

  • The entry I have added to commandDictionary.plist:

 <key>php</key>
 <array>
     <string>php.framework/php</string>
     <string>main</string>
     <string></string>
     <string>file</string>
 </array>

bummoblizard avatar Jun 20 '21 16:06 bummoblizard

TODOs:

  • Support for OpenSSL, using configure option --with-openssl[=DIR] (https://www.php.net/manual/en/openssl.installation.php)
  • Support for stdin from terminal
  • Set the path of configuration file php.ini in PHPRC environment variable (https://www.php.net/configuration.file)
  • Composer support (a package manager for PHP)

bummoblizard avatar Jun 20 '21 18:06 bummoblizard

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

TODOs:

  • Support for OpenSSL, using configure option --with-openssl[=DIR] (https://www.php.net/manual/en/openssl.installation.php)
  • Support for stdin from terminal
  • Set the path of configuration file php.ini in PHPRC environment variable (https://www.php.net/configuration.file)
  • Composer support (a package manager for PHP)

bummoblizard avatar Jun 24 '21 19:06 bummoblizard

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.

holzschu avatar Jun 25 '21 09:06 holzschu

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

TechnagyDev avatar Mar 16 '22 19:03 TechnagyDev

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

bummoblizard avatar Mar 19 '22 00:03 bummoblizard

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

lukasbestle avatar Oct 23 '22 20:10 lukasbestle