deuill / go-php

PHP bindings for the Go programming language (Golang)
MIT License
922 stars 105 forks source link

Portability #54

Open stephenheron opened 6 years ago

stephenheron commented 6 years ago

Hi,

I am thinking about using this library for a project however I need to build a portable binary which I can easily move between different systems

I had a look at the issue queue and I noticed two items that are interesting.

https://github.com/deuill/go-php/issues/39#issuecomment-279719970

you can, however, build PHP as a static binary yourself and try to build with.....

and https://github.com/deuill/go-php/issues/52#issuecomment-374189561

Distributing static libraries built against static PHP builds may also be useful, but their use might be a bit more narrow, depending on which modules we include.

So it looks like it's possible however I am struggling to work out how to actually do it! Can anyone point me in a direction of how implement this?

Thanks, Stephen

deuill commented 6 years ago

Hi, the easiest way would be to use the Dockerfile provided here and build PHP there as a static library, then build your project that uses go-php with the static tag.

I've opened a PR with relevant fixes on #55, but this needs some extra work for linking go-php against the various dynamic libraries (libxml2, etc). You can use this as a starting point.

stephenheron commented 6 years ago

Hi @deuill

Thanks for the help!

After a bit of mucking around I got the Dockerfile to build a go-php.a file located in build/env/GOPATH/pkg/linux_amd64/github.com/deuill.

Apologies for my naivety but this is my first Go project. Now that I have the go-php.a file what do I do next? You mention "then build your project that uses go-php with the static tag.".

I placed that go-php.a file at $GOPATH/pkg/linux_amd64/github.com/deuill/go-php.a and ran go build -tags "static" however I get the error:

# github.com/deuill/go-php
../github.com/deuill/go-php/context.go:11:23: fatal error: main/php.h: No such file or directory
 // #include <main/php.h

Any ideas?

richardjennings commented 6 years ago

I am looking at if there are any performance advantages to using gophp in aws lambda. I appreciate how to compile php statically and also how to use gophp to execute php. I have not had any success however compiling my gophp program into a static binary. I am missing a bit of cgo understanding i think. Any pointers?

stephenheron commented 6 years ago

@richardjennings That is exactly what I am trying to do as well. I am currently launching php from node but looking at gophp to see if we can get extra performance.

If you managed to crack it please let me know!

adamlc commented 6 years ago

This would be interesting if we could do this, especially in lambda!

deuill commented 6 years ago

Apologies for the late reply, I've pushed some fixes to #55 which should allow building go-php against a static version of the PHP library, inside the Docker container provided here. There's a number of things to keep in mind:

Your best bet would be to build a Docker image with PHP built statically (with make docker-image STATIC=true), mount your GOPATH in there and run any build commands you need. For instance, this is how I might build a binary for my project that depends on go-php, having built the Docker image:

docker run --rm -e GOPATH="/tmp/go" -v "$GOPATH:/tmp/go" deuill/go-php:7.0.30 "go install -tags 'php7 static' github.com/deuill/go-php-example"

Obviously not ideal, but I haven't been able to build a shared library (with -buildmode=shared) due to the fact we use cgo and there's some strange errors I need to fix.

adamlc commented 6 years ago

I did have a go trying the example above after building a new docker image against your pull request but it wouldn't compile my code, something related to linker errors with curl. I'll be honest I'm terrible at these sort of things.

I think it would be awesome if we could get the hello world example compiling statically and an example in the README. 💃

deuill commented 6 years ago

Those issues were fixed in recent commits to the branch, try pulling and re-compiling. Agreed that there should be examples. I'll get something running.

adamlc commented 6 years ago

I've literally just pulled that feature branch in #55 to try it. Is that the right branch?

deuill commented 6 years ago

Correct, that's the branch. What error are you getting (I probably missed something)?

adamlc commented 6 years ago

I'm getting the following errors, also had to install libreadline-dev to get this far:

/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zm_info_curl':
interface.c:(.text+0x1aa): undefined reference to `curl_version_info'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zm_startup_curl':
interface.c:(.text+0x3ba4): undefined reference to `curl_global_init'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zm_shutdown_curl':
interface.c:(.text+0x3bd4): undefined reference to `curl_global_cleanup'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_version':
interface.c:(.text+0x3c36): undefined reference to `curl_version_info'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_set_default_options':
interface.c:(.text+0x3f24): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x3f35): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x3f48): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x3f5e): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x3f70): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o):interface.c:(.text+0x3f86): more undefined references to `curl_easy_setopt' follow
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_copy_handle':
interface.c:(.text+0x4371): undefined reference to `curl_easy_duphandle'
interface.c:(.text+0x44ab): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x44bd): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x44cf): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x44e1): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x454e): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o):interface.c:(.text+0x45ba): more undefined references to `curl_easy_setopt' follow
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_setopt':
interface.c:(.text+0x5527): undefined reference to `curl_formadd'
interface.c:(.text+0x5702): undefined reference to `curl_formadd'
interface.c:(.text+0x580c): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x5967): undefined reference to `curl_slist_append'
interface.c:(.text+0x5a1f): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x5a3a): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_getinfo':
interface.c:(.text+0x673f): undefined reference to `curl_easy_getinfo'
interface.c:(.text+0x6779): undefined reference to `curl_slist_free_all'
interface.c:(.text+0x67d0): undefined reference to `curl_easy_getinfo'
interface.c:(.text+0x6836): undefined reference to `curl_easy_getinfo'
interface.c:(.text+0x6873): undefined reference to `curl_easy_getinfo'
interface.c:(.text+0x68b0): undefined reference to `curl_easy_getinfo'
interface.c:(.text+0x68ca): undefined reference to `curl_easy_getinfo'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o):interface.c:(.text+0x68e4): more undefined references to `curl_easy_getinfo' follow
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_strerror':
interface.c:(.text+0x70d8): undefined reference to `curl_easy_strerror'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_escape':
interface.c:(.text+0x7200): undefined reference to `curl_easy_escape'
interface.c:(.text+0x7264): undefined reference to `curl_free'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_unescape':
interface.c:(.text+0x7339): undefined reference to `curl_easy_unescape'
interface.c:(.text+0x7398): undefined reference to `curl_free'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_pause':
interface.c:(.text+0x742d): undefined reference to `curl_easy_pause'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_reset':
interface.c:(.text+0x758a): undefined reference to `curl_easy_reset'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_verify_handlers':
interface.c:(.text+0x78ea): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x793e): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x7991): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_close_ex':
interface.c:(.text+0x7a22): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x7a38): undefined reference to `curl_easy_setopt'
interface.c:(.text+0x7a40): undefined reference to `curl_easy_cleanup'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_init':
interface.c:(.text+0x7cc0): undefined reference to `curl_easy_init'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zif_curl_exec':
interface.c:(.text+0x8a40): undefined reference to `curl_easy_perform'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `curl_free_slist':
interface.c:(.text+0x3ef4): undefined reference to `curl_slist_free_all'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `curl_free_post':
interface.c:(.text+0x3f04): undefined reference to `curl_formfree'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_set_default_options':
interface.c:(.text+0x404f): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `_php_curl_verify_handlers':
interface.c:(.text+0x7800): undefined reference to `curl_easy_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_init':
multi.c:(.text+0x93): undefined reference to `curl_multi_init'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_add_handle':
multi.c:(.text+0x1b5): undefined reference to `curl_multi_add_handle'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_remove_handle':
multi.c:(.text+0x290): undefined reference to `curl_multi_remove_handle'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_select':
multi.c:(.text+0x3f3): undefined reference to `curl_multi_fdset'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_exec':
multi.c:(.text+0x58e): undefined reference to `curl_multi_perform'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_info_read':
multi.c:(.text+0x71c): undefined reference to `curl_multi_info_read'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `_php_curl_multi_close':
multi.c:(.text+0x95c): undefined reference to `curl_multi_cleanup'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_strerror':
multi.c:(.text+0x9d8): undefined reference to `curl_multi_strerror'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(multi.o): In function `zif_curl_multi_setopt':
multi.c:(.text+0xb00): undefined reference to `curl_multi_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(share.o): In function `zif_curl_share_init':
share.c:(.text+0x23): undefined reference to `curl_share_init'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(share.o): In function `zif_curl_share_setopt':
share.c:(.text+0x175): undefined reference to `curl_share_setopt'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(share.o): In function `_php_curl_share_close':
share.c:(.text+0x1f7): undefined reference to `curl_share_cleanup'
collect2: error: ld returned 1 exit status
adamlc commented 6 years ago

I'll be honest I have no experience with cgo at all, heres what I'm trying to compile :)

package main

import (
    "fmt"

    php "github.com/deuill/go-php"
)

func main() {
    engine, _ := php.New()
    context, _ := engine.NewContext()

    val, _ := context.Eval("return 'Hello World';")
    fmt.Printf("%s", val.Interface())
    // Prints 'Hello World' back to the user.

    engine.Destroy()
}
stephenheron commented 6 years ago

@adamlc I had the same problem, luckily I did not need curl so in the Dockerfile I removed the --with-curl line on the configure.

Not perfect but it got me got me a bit further along in the process.

deuill commented 6 years ago

Assuming a folder containing a single file, test.go, containing the lines posted by @adamlc above, the following works for me:

docker run --rm -e GOPATH="/tmp/go" -v "$GOPATH:/tmp/go" -v "$(pwd):/tmp/test" deuill/go-php:7.0.30 "cd /tmp/test; go build -tags 'php7 static' test.go"

You get a binary test which is statically linked against PHP (but not the underlying libraries, which might be a problem):

$ ldd test
./test: /usr/lib/libcurl.so.4: version `CURL_OPENSSL_3' not found (required by ./test)
    linux-vdso.so.1 (0x00007fff538a6000)
    libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f46b684a000)
    libm.so.6 => /usr/lib/libm.so.6 (0x00007f46b64b5000)
    libcurl.so.4 => /usr/lib/libcurl.so.4 (0x00007f46b6235000)
    libpcre.so.3 => not found
    libssl.so.1.0.2 => not found
    libcrypto.so.1.0.2 => not found
    libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007f46b601e000)
    libedit.so.2 => not found
    libz.so.1 => /usr/lib/libz.so.1 (0x00007f46b5e07000)
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f46b5aa1000)
    libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f46b5883000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007f46b54c7000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f46b6a4e000)
    libnghttp2.so.14 => /usr/lib/libnghttp2.so.14 (0x00007f46b52a2000)
    libidn2.so.0 => /usr/lib/libidn2.so.0 (0x00007f46b5085000)
    libpsl.so.5 => /usr/lib/libpsl.so.5 (0x00007f46b4e75000)
    libssl.so.1.1 => /usr/lib/libssl.so.1.1 (0x00007f46b4c0b000)
    libcrypto.so.1.1 => /usr/lib/libcrypto.so.1.1 (0x00007f46b478e000)
    libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x00007f46b4540000)
    libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x00007f46b4257000)
    libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x00007f46b4024000)
    libcom_err.so.2 => /usr/lib/libcom_err.so.2 (0x00007f46b3e20000)
    libicuuc.so.61 => /usr/lib/libicuuc.so.61 (0x00007f46b3a66000)
    liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007f46b3840000)
    libunistring.so.2 => /usr/lib/libunistring.so.2 (0x00007f46b34bf000)
    libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x00007f46b32b2000)
    libkeyutils.so.1 => /usr/lib/libkeyutils.so.1 (0x00007f46b30ae000)
    libicudata.so.61 => /usr/lib/libicudata.so.61 (0x00007f46b1509000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f46b1180000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f46b0f68000)

I'll see about getting these linked statically as well, since the host system might not provide them.

adamlc commented 6 years ago

Not sure if if anything to go with the host OS (macOS here). But building the container from #55 and running as above I get the following:

$ cat main.go
package main

import (
    "fmt"

    php "github.com/deuill/go-php"
)

func main() {
    engine, _ := php.New()
    context, _ := engine.NewContext()

    val, _ := context.Eval("return 'Hello World';")
    fmt.Printf("%s", val.Interface())
    // Prints 'Hello World' back to the user.

    engine.Destroy()
}
$ docker run --rm -e GOPATH="/tmp/go" -v "$GOPATH:/tmp/go" -v "$(pwd):/tmp/test" deuill/go-php:7.0.30 "cd /tmp/test; go build -tags 'php7 static' main.go"
# github.com/deuill/go-php
/usr/bin/ld: cannot find -lreadline
collect2: error: ld returned 1 exit status

If I install libreadline-dev before then I get the curl error again:

$ docker run --rm -e GOPATH="/tmp/go" -v "$GOPATH:/tmp/go" -v "$(pwd):/tmp/test" deuill/go-php:7.0.30 "apt-get update && apt-get -y install libreadline-dev && cd /tmp/test; go build -tags 'php7 static' main.go"
Hit:1 http://security.debian.org/debian-security stretch/updates InRelease
Ign:2 http://deb.debian.org/debian stretch InRelease
Hit:3 http://deb.debian.org/debian stretch-updates InRelease
Hit:4 http://deb.debian.org/debian stretch Release
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
Suggested packages:
  readline-doc
The following NEW packages will be installed:
  libreadline-dev
0 upgraded, 1 newly installed, 0 to remove and 6 not upgraded.
Need to get 132 kB of archives.
After this operation, 726 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian stretch/main amd64 libreadline-dev amd64 7.0-3 [132 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 132 kB in 0s (1242 kB/s)
Selecting previously unselected package libreadline-dev:amd64.
(Reading database ... 15863 files and directories currently installed.)
Preparing to unpack .../libreadline-dev_7.0-3_amd64.deb ...
Unpacking libreadline-dev:amd64 (7.0-3) ...
Setting up libreadline-dev:amd64 (7.0-3) ...
# github.com/deuill/go-php
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zm_info_curl':
interface.c:(.text+0x1aa): undefined reference to `curl_version_info'
/usr/lib/gcc/x86_64-linux-gnu/6/../../../../lib/libphp7.a(interface.o): In function `zm_startup_curl':
...
deuill commented 6 years ago

That's strange, was the deuill/go-php:7.0.30 image built using make docker-image STATIC=true while on the feature/build-static-php branch?

I'll need to have different tags for static and non-static images, and push those to the Docker registry, to avoid confusion. The Go build system makes this unnecessarily complex, but I'll try and get a one-command solution here.

adamlc commented 6 years ago

@deuill yep!

$ git branch
* feature/build-static-php
  master

$ make docker-image STATIC=true
Error response from daemon: manifest for deuill/go-php:7.0.30 not found
Sending build context to Docker daemon  438.3kB
Step 1/16 : FROM golang:1.10-stretch
 ---> 6b369f7eed80
Step 2/16 : ARG PHP_VERSION
 ---> Using cache
 ---> 260493529e5e
Step 3/16 : ARG STATIC=false
 ---> Using cache
 ---> a5b51a3daf4c
Step 4/16 : ENV PHP_URL="https://secure.php.net/get/php-${PHP_VERSION}.tar.xz/from/this/mirror"
 ---> Using cache
 ---> 0e0bc57b150b
Step 5/16 : ENV PHP_BASE_DIR="/tmp/php"
 ---> Using cache
 ---> cd1259d5589e
Step 6/16 : ENV PHP_SRC_DIR="${PHP_BASE_DIR}/src"
 ---> Using cache
 ---> b01f2a33c395
Step 7/16 : ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
 ---> Using cache
 ---> 546bcf8073a4
Step 8/16 : ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
 ---> Using cache
 ---> 3c6bbb02e022
Step 9/16 : ENV PHP_CPPFLAGS="${PHP_CFLAGS}"
 ---> Using cache
 ---> a51ef7dd26df
Step 10/16 : ENV FETCH_DEPS="ca-certificates wget"
 ---> Using cache
 ---> 3062e2c1c812
Step 11/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${FETCH_DEPS} &&     mkdir -p ${PHP_BASE_DIR} && cd ${PHP_BASE_DIR} &&     wget -O php.tar.xz ${PHP_URL} &&     apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${FETCH_DEPS}
 ---> Using cache
 ---> cae8062511fc
Step 12/16 : ENV BUILD_DEPS="build-essential file libpcre3-dev dpkg-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libssl1.0-dev libxml2-dev zlib1g-dev"
 ---> Using cache
 ---> 911a9211574d
Step 13/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${BUILD_DEPS};     export CFLAGS="${PHP_CFLAGS}" CPPFLAGS="${PHP_CPPFLAGS}" LDFLAGS="${PHP_LDFLAGS}";     arch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" && multiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)";     [ "x$STATIC" = "xfalse" ]         && options="--enable-embed"         || options="--enable-embed=static --enable-static";     [ ! -d /usr/include/curl ] && ln -sT "/usr/include/$multiarch/curl" /usr/local/include/curl;     mkdir -p ${PHP_SRC_DIR} && cd ${PHP_SRC_DIR} &&     tar -xJf ${PHP_BASE_DIR}/php.tar.xz -C . --strip-components=1 &&     ./configure         --prefix=/usr --build="$arch"         --with-libdir="lib/$multiarch"         --with-pcre-regex=/usr         --disable-cgi --disable-fpm         --enable-ftp --enable-mbstring         --with-curl --with-libedit --with-openssl --with-zlib         $options         &&     make -j "$(nproc)" &&     apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${BUILD_DEPS}
 ---> Using cache
 ---> 75d4c1cbd87d
Step 14/16 : ENV RUNTIME_DEPS="build-essential git curl libssl1.0 libpcre3-dev libcurl4-openssl-dev libedit-dev libxml2-dev zlib1g-dev"
 ---> Using cache
 ---> 3b7863dafd45
Step 15/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${RUNTIME_DEPS} &&     cd ${PHP_SRC_DIR} && make -j "$(nproc)" PHP_SAPI=embed install-sapi install-headers &&     cd / && rm -Rf ${PHP_BASE_DIR} ${PHP_SRC_DIR}
 ---> Using cache
 ---> 691fb9e3e09e
Step 16/16 : ENTRYPOINT ["/bin/sh", "-c"]
 ---> Using cache
 ---> 7979e54499e5
Successfully built 7979e54499e5
Successfully tagged deuill/go-php:7.0.30
deuill commented 6 years ago

Thanks for the info, it might be a Mac OS thing, but I can't imagine how (Docker-on-Mac is known to do weird stuff, however). AFAICT you don't need readline, that's what libedit is for.

Does make docker-test STATIC=true work, or does that throw the same errors too?

adamlc commented 6 years ago

Here the output (had to specify the path to make)

$ MAKE="/usr/bin/make" make docker-test STATIC=true
Error response from daemon: manifest for deuill/go-php:7.0.30 not found
Sending build context to Docker daemon  438.3kB
Step 1/16 : FROM golang:1.10-stretch
 ---> 6b369f7eed80
Step 2/16 : ARG PHP_VERSION
 ---> Using cache
 ---> 260493529e5e
Step 3/16 : ARG STATIC=false
 ---> Using cache
 ---> a5b51a3daf4c
Step 4/16 : ENV PHP_URL="https://secure.php.net/get/php-${PHP_VERSION}.tar.xz/from/this/mirror"
 ---> Using cache
 ---> 0e0bc57b150b
Step 5/16 : ENV PHP_BASE_DIR="/tmp/php"
 ---> Using cache
 ---> cd1259d5589e
Step 6/16 : ENV PHP_SRC_DIR="${PHP_BASE_DIR}/src"
 ---> Using cache
 ---> b01f2a33c395
Step 7/16 : ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
 ---> Using cache
 ---> 546bcf8073a4
Step 8/16 : ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
 ---> Using cache
 ---> 3c6bbb02e022
Step 9/16 : ENV PHP_CPPFLAGS="${PHP_CFLAGS}"
 ---> Using cache
 ---> a51ef7dd26df
Step 10/16 : ENV FETCH_DEPS="ca-certificates wget"
 ---> Using cache
 ---> 3062e2c1c812
Step 11/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${FETCH_DEPS} &&     mkdir -p ${PHP_BASE_DIR} && cd ${PHP_BASE_DIR} &&     wget -O php.tar.xz ${PHP_URL} &&     apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${FETCH_DEPS}
 ---> Using cache
 ---> cae8062511fc
Step 12/16 : ENV BUILD_DEPS="build-essential file libpcre3-dev dpkg-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libssl1.0-dev libxml2-dev zlib1g-dev"
 ---> Using cache
 ---> 911a9211574d
Step 13/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${BUILD_DEPS};     export CFLAGS="${PHP_CFLAGS}" CPPFLAGS="${PHP_CPPFLAGS}" LDFLAGS="${PHP_LDFLAGS}";     arch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" && multiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)";     [ "x$STATIC" = "xfalse" ]         && options="--enable-embed"         || options="--enable-embed=static --enable-static";     [ ! -d /usr/include/curl ] && ln -sT "/usr/include/$multiarch/curl" /usr/local/include/curl;     mkdir -p ${PHP_SRC_DIR} && cd ${PHP_SRC_DIR} &&     tar -xJf ${PHP_BASE_DIR}/php.tar.xz -C . --strip-components=1 &&     ./configure         --prefix=/usr --build="$arch"         --with-libdir="lib/$multiarch"         --with-pcre-regex=/usr         --disable-cgi --disable-fpm         --enable-ftp --enable-mbstring         --with-curl --with-libedit --with-openssl --with-zlib         $options         &&     make -j "$(nproc)" &&     apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false ${BUILD_DEPS}
 ---> Using cache
 ---> 75d4c1cbd87d
Step 14/16 : ENV RUNTIME_DEPS="build-essential git curl libssl1.0 libpcre3-dev libcurl4-openssl-dev libedit-dev libxml2-dev zlib1g-dev"
 ---> Using cache
 ---> 3b7863dafd45
Step 15/16 : RUN set -xe &&     apt-get update && apt-get install -y --no-install-recommends ${RUNTIME_DEPS} &&     cd ${PHP_SRC_DIR} && make -j "$(nproc)" PHP_SAPI=embed install-sapi install-headers &&     cd / && rm -Rf ${PHP_BASE_DIR} ${PHP_SRC_DIR}
 ---> Using cache
 ---> 691fb9e3e09e
Step 16/16 : ENTRYPOINT ["/bin/sh", "-c"]
 ---> Using cache
 ---> 7979e54499e5
Successfully built 7979e54499e5
Successfully tagged deuill/go-php:7.0.30
make: Entering directory '/tmp/go/src/github.com/deuill/go-php'
Running tests for 'go-php'...
--- FAIL: TestContextLog (0.00s)
    context_test.go:204: Context.Eval('$a = 10; $a + $b;'): expected 'Undefined variable: b in gophp-engine on line 1', actual ''
    context_test.go:204: Context.Eval('strlen();'): expected 'strlen() expects exactly 1 parameter, 0 given in gophp-engine on line 1', actual ''
    context_test.go:204: Context.Eval('trigger_error('Test Error');'): expected 'Test Error in gophp-engine on line 1', actual ''
--- FAIL: TestContextBind (0.00s)
    context_test.go:279: Context.Bind('3.14159'): expected 'd:3.14159;', actual 'd:3.1415899999999999;'
FAIL
FAIL    github.com/deuill/go-php    0.086s
Makefile:32: recipe for target 'test' failed
make: Leaving directory '/tmp/go/src/github.com/deuill/go-php'
make: *** [test] Error 1
make: *** [docker-test] Error 2
deuill commented 6 years ago

Seems to work (failed tests are known issues ATM). Not sure why your binary is failing, but I'll try and get to the bottom of it.

adamlc commented 6 years ago

No worries, if you need anything from me give me a shout :)

stephenheron commented 6 years ago

Nice one @deuill I followed your instructions and got a successful binary to be built. (I am using a Ubuntu VM). However I ran into the issue that you mentioned about missing underlying libraries.

Thanks for the help so far. I had a look to see if I could find anything around bringing those libraries but I am out of my depth to be honest.

deuill commented 6 years ago

It appears that PHP has issues with building statically against its own dependencies, and I'll have to follow up on their mailing lists and see what can be done there. I assume there's some license issues that prevent them from doing so.

Until then, I'm afraid you'll have to provide the libraries (libedit, libpcre, libssl, libcurl, etc) on the host system that runs the final Go binary. I'll work at getting the build process easier, though, and get some examples in the repo.

richardjennings commented 6 years ago

@deuill that was where I got stuck also