From Fedora Project Wiki

steps taken to build phantomjs on ppc64le

The phantomjs project uses a docker container to perform the build. The instructions say:

$ git clean -xfd .
$ docker run -v $PWD:/src debian:wheezy /src/deploy/docker-build.sh

the script is here [1]

However, I could not build a wheezy container for Debian:

[hamzy@pkvmci853 phantomjs]$ sudo su -
[root@pkvmci853 ~]# mkdir /wheezy-root
[root@pkvmci853 ~]# debootstrap --arch=powerpc wheezy /wheezy-root/ http://ftp.debian.org/debian/
W: Cannot check Release signature; keyring file not available /usr/share/keyrings/debian-archive-keyring.gpg
I: Retrieving InRelease 
I: Retrieving Release 
I: Retrieving Packages 
I: Validating Packages 
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
...
I: Extracting zlib1g...
W: Failure trying to run: chroot /wheezy-root dpkg-deb -f /var/cache/apt/archives/dpkg_1.16.18_powerpc.deb Version
W: See /wheezy-root/debootstrap/debootstrap.log for details
W: Failure trying to run: chroot /wheezy-root mount -t proc proc /proc
W: See /wheezy-root/debootstrap/debootstrap.log for details
[root@pkvmci853 ~]# cat /wheezy-root/debootstrap/debootstrap.log
chroot: failed to run command 'dpkg-deb': Exec format error
chroot: failed to run command 'mount': Exec format error

Building a Jessie container did work:

[hamzy@pkvmci853 phantomjs]$ sudo su -
[root@pkvmci853 ~]# mkdir /jessie-root
[root@pkvmci853 ~]# debootstrap --arch=ppc64el jessie /jessie-root/ http://ftp.debian.org/debian/
W: Cannot check Release signature; keyring file not available /usr/share/keyrings/debian-archive-keyring.gpg
I: Retrieving InRelease
I: Retrieving Release
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
...
I: Configuring systemd...
I: Base system installed successfully.
[root@pkvmci853 ~]# tar -C /jessie-root/ -cJvf jessie-docker.tar.xz --xattrs .
[root@pkvmci853 ~]# cat jessie-docker.tar.xz | docker import - jessie-el
sha256:d0b376f5dd5397c6f5ded97293485043654a101ba77de54b9c926f974648724d

Running the commands in the above script ran into a problem:

[hamzy@pkvmci853 phantomjs]$ sudo docker run --rm -it --privileged jessie-el /bin/bash
root@8c186e049fe0:/# apt-get update -y
...
Reading package lists... Done
root@8c186e049fe0:/# apt-get install -y build-essential git flex bison gperf python ruby git libfontconfig1-dev
root@8c186e049fe0:/# echo "deb-src http://httpredir.debian.org/debian jessie main" >> /etc/apt/sources.list
root@8c186e049fe0:/# apt-get update -y
root@8c186e049fe0:/# apt-get source openssl
root@8c186e049fe0:/# cd openssl-1.0.1t/
root@8c186e049fe0:/openssl-1.0.1t# export OPENSSL_TARGET='linux-ppc64'
root@8c186e049fe0:/openssl-1.0.1t# export OPENSSL_FLAGS='no-idea no-mdc2 no-rc5 no-zlib enable-tlsext no-ssl2 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms'
root@8c186e049fe0:/openssl-1.0.1t# ./Configure --prefix=/usr --openssldir=/etc/ssl --libdir=lib ${OPENSSL_FLAGS} ${OPENSSL_TARGET}
root@8c186e049fe0:/openssl-1.0.1t# make depend && make && make install
...
make[2]: Entering directory '/openssl-1.0.1t/apps'
( :; LIBDEPS="${LIBDEPS:--L.. -lssl  -L.. -lcrypto -ldl}"; LDCMD="${LDCMD:-gcc}"; LDFLAGS="${LDFLAGS:--DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DB_ENDIAN -O3 -Wall -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM}"; LIBPATH=`for x in $LIBDEPS; do echo $x; done | sed -e 's/^ *-L//;t' -e d | uniq`; LIBPATH=`echo $LIBPATH | sed -e 's/ /:/g'`; LD_LIBRARY_PATH=$LIBPATH:$LD_LIBRARY_PATH ${LDCMD} ${LDFLAGS} -o ${APPNAME:=openssl} openssl.o verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o ca.o pkcs7.o crl2p7.o crl.o rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o s_time.o apps.o s_cb.o s_socket.o app_rand.o version.o sess_id.o ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o ${LIBDEPS} )
/usr/bin/ld: ../libcrypto.a(ppccpuid.o): ABI version 1 is not compatible with ABI version 2 output
/usr/bin/ld: failed to merge target specific data of file ../libcrypto.a(ppccpuid.o)
/usr/bin/ld: ../libcrypto.a(sha1-ppc.o): ABI version 1 is not compatible with ABI version 2 output
/usr/bin/ld: failed to merge target specific data of file ../libcrypto.a(sha1-ppc.o)
...
root@8c186e049fe0:/openssl-1.0.1t# exit

Okay, so much for self building! The docker images are located here [2].

Wheezy seems to be called oldstable-backports. This is probably not a good sign. The next revision, Jessie, also exists.

[hamzy@pkvmci853 phantomjs]$ sudo docker pull ppc64le/debian:oldstable-backports
...
55b804d0d9f8: Pull complete
d5724afd0b71: Pull complete
Digest: sha256:72e9f4110823ab427d964962371e2e003cb8e09e410018188d712968e6b44947
Status: Downloaded newer image for docker.io/ppc64le/debian:oldstable-backports
[hamzy@pkvmci853 phantomjs]$ sudo docker pull ppc64le/debian:jessie

The script to do a docker build here [3] does not work for ppc64el. I created a new version for testing:

[hamzy@pkvmci853 ~]$ cat << __EOF__ > ~/0001-hamzy-docker-build-ppc64el.patch
From a92b52908fb01e07cd7a38b029d8d158e9b88ac4 Mon Sep 17 00:00:00 2001
From: Mark Hamzy <hamzy@us.ibm.com>
Date: Tue, 20 Jun 2017 23:17:00 -0400
Subject: [PATCH] hamzy docker-build-ppc64el

---
 deploy/docker-build-ppc64el.sh | 65 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100755 deploy/docker-build-ppc64el.sh
diff --git a/deploy/docker-build-ppc64el.sh b/deploy/docker-build-ppc64el.sh
new file mode 100755
index 0000000..3b49ab8
--- /dev/null
+++ b/deploy/docker-build-ppc64el.sh
@@ -0,0 +1,66 @@
+#!/usr/bin/env bash
+
+set -e
+
+SOURCE_PATH=/src
+BUILD_PATH=$HOME/build
+
+echo "Installing packages for development tools..." && sleep 1
+apt-get -y update
+apt-get install -y build-essential g++-4.8 gcc-4.8 git flex bison gperf python ruby git libfontconfig1-dev
+echo
+
+echo "Preparing to download Debian source package..."
+echo "deb-src http://deb.debian.org/debian oldstable main" >> /etc/apt/sources.list
+apt-get -y update
+echo
+
+OPENSSL_TARGET='debian-ppc64el'
+if [ `getconf LONG_BIT` -eq 32 ]; then
+    OPENSSL_TARGET='linux-generic32'
+fi
+echo "Recompiling OpenSSL for ${OPENSSL_TARGET}..." && sleep 1
+apt-get source openssl
+
+cd openssl-1.0.1t/
+OPENSSL_FLAGS='no-idea no-mdc2 no-rc5 no-zlib enable-tlsext no-ssl2 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms'
+./Configure --prefix=/usr --openssldir=/etc/ssl --libdir=lib ${OPENSSL_FLAGS} ${OPENSSL_TARGET}
+make depend && make && make install
+cd ..
+echo
+
+echo "Building the static version of ICU library..." && sleep 1
+apt-get source icu
+cd icu-52.1/source/
+./configure --prefix=/usr --enable-static --disable-shared
+make && make install
+cd ..
+echo
+
+echo "Recreating the build directory $BUILD_PATH..."
+rm -rf $BUILD_PATH && mkdir -p $BUILD_PATH
+echo
+
+echo "Transferring the source: $SOURCE_PATH -> $BUILD_PATH. Please wait..."
+cd $BUILD_PATH && cp -rp $SOURCE_PATH . && cd src
+echo
+
+echo "Compiling PhantomJS..." && sleep 1
+python build.py --confirm --release --qt-config="-no-pkg-config" --git-clean-qtbase --git-clean-qtwebkit
+echo
+
+echo "Stripping the executable..." && sleep 1
+ls -l bin/phantomjs
+strip bin/phantomjs
+echo "Copying the executable..." && sleep 1
+ls -l bin/phantomjs
+cp bin/phantomjs $SOURCE_PATH
+echo
+
+echo "Finished."
--
1.8.3.1
__EOF__

The next problem is that the master version in git does not support the docker build anymore:

Note.png
We removed it because we no longer need bundled submodules (QtBase and QtWebKit). We are still working on the updated instruction how to build PhantomJS from master. But you always can checkout tag 2.1 and build it.

from here [4]

So, checking out the project like:

[hamzy@pkvmci853 ~]$ git clone https://github.com/ariya/phantomjs.git
[hamzy@pkvmci853 phantomjs]$ git checkout 2.1
Branch 2.1 set up to track remote branch 2.1 from origin.
Switched to a new branch '2.1'
[hamzy@pkvmci853 phantomjs]$ git am ~/0001-hamzy-docker-build-ppc64el.patch
Applying: hamzy docker-build-ppc64el

And running the build like:

[hamzy@pkvmci853 phantomjs]$ sudo docker run -v $PWD:/src -it --privileged --name phantomjs_ppc64el docker.io/ppc64le/debian:oldstable-backports /src/deploy/docker-build-ppc64el.sh
...
Copying the executable...
-rwxr-xr-x. 1 root root 78394384 Jun 21 04:04 bin/phantomjs

Finished.
...
[hamzy@pkvmci853 phantomjs]$ sudo docker cp phantomjs_ppc64el:/src/phantomjs .
[hamzy@pkvmci853 phantomjs]$ ./phantomjs
./phantomjs: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./phantomjs)
[hamzy@pkvmci853 phantomjs]$ ls -l /lib64/libstdc++.so.6
lrwxrwxrwx. 1 root root 19 May 30 17:21 /lib64/libstdc++.so.6 -> libstdc++.so.6.0.19
[hamzy@pkvmci853 phantomjs]$ rpm -qf /lib64/libstdc++.so.6
libstdc++-4.8.5-11.el7.ppc64le
[hamzy@pkvmci853 phantomjs]$ rpm -q libstdc++-4.8.5-11.el7.ppc64le --provides
...
libstdc++.so.6(CXXABI_1.3)(64bit)
libstdc++.so.6(CXXABI_1.3.1)(64bit)
libstdc++.so.6(CXXABI_1.3.2)(64bit)
libstdc++.so.6(CXXABI_1.3.3)(64bit)
libstdc++.so.6(CXXABI_1.3.4)(64bit)
libstdc++.so.6(CXXABI_1.3.5)(64bit)
libstdc++.so.6(CXXABI_1.3.6)(64bit)
libstdc++.so.6(CXXABI_1.3.7)(64bit)
...

Comes with the next two problems. 1) The program is not being built for 64-bit code and 2) The libstdc++ libraries are slightly newer than what exists on CentOS7.

Trying a backlevel gcc:

root@bdd8cc64c5ba:/# apt-get install -y build-essential g++-4.8 gcc-4.8 git flex bison gperf python ruby git libfontconfig1-dev
root@bdd8cc64c5ba:/# update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 10
update-alternatives: using /usr/bin/g++-4.9 to provide /usr/bin/g++ (g++) in auto mode
root@bdd8cc64c5ba:/# update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20
update-alternatives: using /usr/bin/g++-4.8 to provide /usr/bin/g++ (g++) in auto mode
root@bdd8cc64c5ba:/# update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 10
update-alternatives: using /usr/bin/gcc-4.9 to provide /usr/bin/gcc (gcc) in auto mode
root@bdd8cc64c5ba:/# update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20
update-alternatives: using /usr/bin/gcc-4.8 to provide /usr/bin/gcc (gcc) in auto mode
root@bdd8cc64c5ba:/# gcc --version
gcc (Debian 4.8.4-1) 4.8.4

Came with the following problem during the build:

...
gcc: error: unrecognized command line option '-fstack-protector-strong'
...
OpenSSL support cannot be enabled due to functionality tests!
 Turn on verbose messaging (-v) to /root/build/src/src/qt/qtbase/configure to see the final report.
 If you believe this message is in error you may use the continue
 switch (-continue) to /root/build/src/src/qt/qtbase/configure to continue.
ERROR: Failed to build PhantomJS! Configuration of Qt Base failed.
...

The fix is to remove that C flag from the defaults.

root@4fb1f5d4dc0b:/openssl-1.0.1t# dpkg-buildflags --get CFLAGS
-g -O2 -fstack-protector-strong -Wformat -Werror=format-security
root@4fb1f5d4dc0b:/openssl-1.0.1t# (export DEB_CFLAGS_SET=$(dpkg-buildflags --get CFLAGS | sed 's/-fstack-protector-strong//'); dpkg-buildflags --get CFLAGS)
-g -O2  -Wformat -Werror=format-security

Update the patch for the new script file.

[hamzy@pkvmci853 ~]$ cat << __EOF__ > ~/0001-hamzy-docker-build-ppc64el.patch
From 7fbffe473a1316bc7e1500d33fc3b24d5dc54247 Mon Sep 17 00:00:00 2001
From: Mark Hamzy <hamzy@us.ibm.com>
Date: Tue, 20 Jun 2017 23:17:00 -0400
Subject: [PATCH] hamzy docker-build-ppc64el

---
 deploy/docker-build-ppc64el.sh | 74 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100755 deploy/docker-build-ppc64el.sh

diff --git a/deploy/docker-build-ppc64el.sh b/deploy/docker-build-ppc64el.sh
new file mode 100755
index 0000000..12ddbfa
--- /dev/null
+++ b/deploy/docker-build-ppc64el.sh
@@ -0,0 +1,74 @@
+#!/usr/bin/env bash
+
+set -e
+
+SOURCE_PATH=/src
+BUILD_PATH=$HOME/build
+
+echo "Installing packages for development tools..." && sleep 1
+apt-get -y update
+apt-get install -y build-essential g++-4.8 gcc-4.8 git flex bison gperf python ruby git libfontconfig1-dev
+echo
+
+USE_GCC_49=/bin/false
+USE_GCC_48=/bin/true
+
+if ${USE_GCC_48}
+then
+    echo "Setting gcc version 4.8 to have priority against the auto installed 4.9"
+    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 10
+    update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20
+    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 10
+    update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20
+    # gcc-4.8 does not support -fstack-protector-strong
+    export DEB_CFLAGS_SET=$(dpkg-buildflags --get CFLAGS | sed 's/-fstack-protector-strong//')
+fi
+
+echo "Preparing to download Debian source package..."
+echo "deb-src http://deb.debian.org/debian oldstable main" >> /etc/apt/sources.list
+apt-get -y update
+echo
+
+OPENSSL_TARGET='debian-ppc64el'
+if [ `getconf LONG_BIT` -eq 32 ]; then
+    OPENSSL_TARGET='linux-generic32'
+fi
+echo "Recompiling OpenSSL for ${OPENSSL_TARGET}..." && sleep 1
+apt-get source openssl
+
+cd openssl-1.0.1t/
+OPENSSL_FLAGS='no-idea no-mdc2 no-rc5 no-zlib enable-tlsext no-ssl2 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms'
+./Configure --prefix=/usr --openssldir=/etc/ssl --libdir=lib ${OPENSSL_FLAGS} ${OPENSSL_TARGET}
+make depend && make && make install
+cd ..
+echo
+
+echo "Building the static version of ICU library..." && sleep 1
+apt-get source icu
+cd icu-52.1/source/
+./configure --prefix=/usr --enable-static --disable-shared
+make && make install
+cd ..
+echo
+
+echo "Recreating the build directory $BUILD_PATH..."
+rm -rf $BUILD_PATH && mkdir -p $BUILD_PATH
+echo
+
+echo "Transferring the source: $SOURCE_PATH -> $BUILD_PATH. Please wait..."
+cd $BUILD_PATH && cp -rp $SOURCE_PATH . && cd src
+echo
+
+echo "Compiling PhantomJS..." && sleep 1
+python build.py --confirm --release --qt-config="-no-pkg-config" --git-clean-qtbase --git-clean-qtwebkit
+echo
+
+echo "Stripping the executable..." && sleep 1
+ls -l bin/phantomjs
+strip bin/phantomjs
+echo "Copying the executable..." && sleep 1
+ls -l bin/phantomjs
+cp bin/phantomjs $SOURCE_PATH
+echo
+
+echo "Finished."
--
1.8.3.1
__EOF__

And run the script:

[hamzy@pkvmci853 phantomjs]$ sudo docker run -v $PWD:/src -it --privileged --name phantomjs_ppc64el docker.io/ppc64le/debian:jessie /src/deploy/docker-build-ppc64el.sh
...
Copying the executable...
-rwxr-xr-x. 1 root root 77959272 Jun 21 23:10 bin/phantomjs
Finished.
[hamzy@pkvmci853 phantomjs]$ sudo docker cp phantomjs_ppc64el:/src/phantomjs /home/hamzy/bin/
[hamzy@pkvmci853 phantomjs]$ phantomjs
phantomjs>

The next step was to build a source tarball for tripleo-ui-deps:

[hamzy@pkvmci853 tripleo-ui]$ rm -rf node_modules/
[hamzy@pkvmci853 tripleo-ui]$ npm cache clean
[hamzy@pkvmci853 tripleo-ui]$ npm install
...
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"ppc64"})
npm WARN eslint-config-prettier@1.7.0 requires a peer of eslint@>=3.14.1 but none was installed.
[hamzy@pkvmci853 tripleo-ui]$ npm shrinkwrap
...
wrote npm-shrinkwrap.json
[hamzy@pkvmci853 tripleo-ui]$ tar czf tripleo-ui-deps-hamzy.tar.gz node_modules/
[hamzy@pkvmci853 tripleo-ui]$ sudo cp tripleo-ui-deps-hamzy.tar.gz /var/lib/mock/mockchain2-ppc64le/root/builddir/build/SOURCES/

And then build the private srpm for tripleo-ui-deps:

<mock-chroot> bash-4.2# vi ~/build/SPECS/openstack-tripleo-ui-deps.spec 
...
#%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global shortcommit hamzy
...
<mock-chroot> bash-4.2# (cd build/; rpmbuild -ba SPECS/openstack-tripleo-ui-deps.spec 2>&1 | tee errors.openstack-tripleo-ui-deps)
...
Wrote: /builddir/build/SRPMS/openstack-tripleo-ui-deps-7-5.mh.el7.centos.src.rpm
Wrote: /builddir/build/RPMS/openstack-tripleo-ui-deps-7-5.mh.el7.centos.ppc64le.rpm
Wrote: /builddir/build/RPMS/openstack-tripleo-ui-deps-babel-7-5.mh.el7.centos.ppc64le.rpm
Wrote: /builddir/build/RPMS/openstack-tripleo-ui-deps-webpack-7-5.mh.el7.centos.ppc64le.rpm
Wrote: /builddir/build/RPMS/openstack-tripleo-ui-deps-debuginfo-7-5.mh.el7.centos.ppc64le.rpm
...

Apparently, phantomjs has been broken out of tripleo-ui-deps tarball into its own package phantomjs-1.9.7-3.el7 and of course it does not build on ppc64le.

[hamzy@pkvmci853 mockchain2]$ wget http://cbs.centos.org/kojifiles/packages/phantomjs/1.9.7/3.el7/src/phantomjs-1.9.7-3.el7.src.rpm
[hamzy@pkvmci853 mockchain2]$ mockchain -r epel-7-ppc64le --tmp_prefix=mockbuild --localrepo=mock-repo ${ADDREPO} --log=mockchain.log --recurse phantomjs-1.9.7-3.el7.src.rpm
...
../../JavaScriptCore/runtime/Error.cpp:151:5: error: 'ReturnAddressPtr' was not declared in this scope
     ReturnAddressPtr pc;
...
breakpad/src/client/linux/handler/exception_handler.h:178:26: error: field 'float_state' has incomplete type
     struct _libc_fpstate float_state;
...

One of the sub-packages of phantomjs is breakpad which is located here.

Trying to build it locally results in:

[hamzy@pkvmci853 ~]$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
[hamzy@pkvmci853 ~]$ (export PATH=${PATH}:/home/hamzy/depot_tools/; mkdir breakpad; cd breakpad; fetch breakpad)
[hamzy@pkvmci853 ~]$ cd breakpad/src/
[hamzy@pkvmci853 src]$ ./configure
[hamzy@pkvmci853 src]$ make
...
src/client/linux/crash_generation/crash_generation_client.cc: In member function ‘virtual bool google_breakpad::{anonymous}::CrashGe
nerationClientImpl::RequestDump(const void*, size_t)’:
src/client/linux/crash_generation/crash_generation_client.cc:53:21: error: ‘sys_pipe’ was not declared in this scope
     if (sys_pipe(fds) < 0)
                     ^
src/client/linux/crash_generation/crash_generation_client.cc:57:25: error: aggregate ‘google_breakpad::{anonymous}::CrashGenerationC
lientImpl::RequestDump(const void*, size_t)::kernel_iovec iov’ has incomplete type and cannot be defined
     struct kernel_iovec iov;
...

There already are two bugs written against breakpad to support PowerPC.

powerpc-linux not currently supported

Porting google-breakpad on ppc64le