Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Portability #54

Open
stephenheron opened this issue Jun 1, 2018 · 24 comments
Open

Portability #54

stephenheron opened this issue Jun 1, 2018 · 24 comments
Assignees

Comments

@stephenheron
Copy link

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.

#39 (comment)

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

and
#52 (comment)

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
Copy link
Owner

deuill commented Jun 1, 2018

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
Copy link
Author

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
Copy link

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
Copy link
Author

@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
Copy link

adamlc commented Jun 4, 2018

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

@deuill
Copy link
Owner

deuill commented Jun 4, 2018

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:

  • Building go-php inside the Docker container will place build artefacts (i.e. the go-php.a library) inside the .build/env/GOPATH directory, which means this needs to be moved to your normal GOPATH if subsequent build commands are to pick it up.
  • It appears that you need to pass the static build tag for any build command you make against code that imports go-php, not just go-php itself. This is due to the fact that Go will try to build packages that aren't already built, and build tags play into the final output.

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
Copy link

adamlc commented Jun 4, 2018

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
Copy link
Owner

deuill commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

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

@deuill
Copy link
Owner

deuill commented Jun 4, 2018

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

@adamlc
Copy link

adamlc commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

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
Copy link
Author

stephenheron commented Jun 4, 2018

@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
Copy link
Owner

deuill commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

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
Copy link
Owner

deuill commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

@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
Copy link
Owner

deuill commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

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
Copy link
Owner

deuill commented Jun 4, 2018

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
Copy link

adamlc commented Jun 4, 2018

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

@deuill deuill self-assigned this Jun 4, 2018
@stephenheron
Copy link
Author

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
Copy link
Owner

deuill commented Jun 5, 2018

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
Copy link

@deuill that was where I got stuck also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants