Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Recreate static build packaging script #14459

Closed
ariya opened this issue Aug 8, 2016 · 20 comments
Closed

Recreate static build packaging script #14459

ariya opened this issue Aug 8, 2016 · 20 comments
Assignees

Comments

@ariya
Copy link
Owner

ariya commented Aug 8, 2016

Goal: a single script that produces a self-contained PhantomJS executable with virtually no dependency.

The script needs to do the following:

  • Verify the necessary requirements (compiler, Qt 5.6, etc)
  • Grab and build some dependencies from source (ICU, OpenSSL, etc)
  • Compile a QtWebKit release from annulen/webkit
  • Build PhantomJS with all the above

The script must run on macOS, Windows, and Linux (32-bit and 64-bit). The produced binaries will be made available from http://phantomjs.org/download.html.

NOTE: This is not intended for a distribution packager who wants to package PhantomJS for Debian/Fedora/Homebrew/etc. See #14458 for some additional context.

@ariya ariya self-assigned this Aug 8, 2016
@ariya ariya mentioned this issue Aug 8, 2016
4 tasks
@ariya ariya added this to the Release 2.5 milestone Aug 8, 2016
@ariya
Copy link
Owner Author

ariya commented Aug 8, 2016

This is also important to support installer wrapper such as:

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

So I got tired of waiting and figured out how to do this, mostly based on build.py. Here goes.

I did this on Ubuntu 16.10.

  1. First, I had to uninstall qmake and the qt development packages, because it was conflicting with the static qt I had to build.
  2. Clone https://github.com/qt/qtbase somewhere, check out 5.7.1 or whatever stable version you have
  3. symlink the phantom qt platform plugin into the qt source code (phantomjs 2.1.1 had the phantom plugin in its forked version of qtbase, so I duplicated that. I don't know if this is necessary, I don't know what I'm doing.)
  4. edit src/plugins/platforms/platforms.pro, add !win32:!winrt: SUBDIRS += phantom (again, the forked qtbase had this, to activate the platform plugin)
  5. build qt. The configure is based on build.py, but modified for 5.7, e.g. -no-mirclient is needed to disable the new mir client.
./configure -static -release -prefix . -opensource -confirm-license -qpa phantom -openssl -openssl-linked -no-openvg -no-eglfs -no-egl -no-glib -no-gtk -no-cups -no-sm -no-xkb -no-xcb -no-kms -no-linuxfb -no-directfb -no-mirclient -no-mtdev -no-libudev -no-evdev -no-pulseaudio -no-alsa -no-feature-PRINTPREVIEWWIDGET -fontconfig -icu -qt-zlib -qt-libpng -qt-libjpeg -qt-pcre -nomake examples -nomake tools -nomake tests -no-qml-debug -no-dbus -no-opengl -no-audio-backend -D QT_NO_GRAPHICSVIEW -D QT_NO_GRAPHICSEFFECT -D QT_NO_STYLESHEET -D QT_NO_STYLE_CDE -D QT_NO_STYLE_CLEANLOOKS -D QT_NO_STYLE_MOTIF -D QT_NO_STYLE_PLASTIQUE -D QT_NO_PRINTPREVIEWDIALOG -no-pkg-config
  1. build it (make -j4). No need to install it, but this directory will now act as the installation prefix.
  2. Add the bin subdirectory to your path to make your life easier. I think this also avoids some problems with cmake not finding qmake. I also had to delete /usr/bin/qmake, which is part of the qtchooser package on ubuntu (couldn't uninstall that because of dependencies, so it was pointing to a nonexistent qmake), to make sure it found my qmake, not that one.
  3. Clone https://github.com/qt/qtlocation and https://github.com/qt/qtsensors, check out same stable version as qtbase, then qmake && make && make install. It'll install to your qtbase directory.
  4. Clone https://github.com/annulen/webkit. The qtwebkit-stable branch should be checked out.
  5. You'll need to hack its makefiles to make it build correctly:
    1. Edit Source/cmake/OptionsQt.cmake, add add_definitions(-DQT_NO_GRAPHICSVIEW) under add_definitions(-DBUILDING_QT__=1) . I don't know why it's not picking this up from Qt, since it was built with QT_NO_GRAPHICSVIEW, but this was the only way to make it build.
    2. Edit Tools/PlatformQt.cmake, comment out add_subdirectory(QtTestBrowser). QTestBrowser won't build without GraphicsView, but we don't need it.
  6. Build webkit, using the linux instructions, but with some changes to the cmake command:
mkdir -p WebKitBuild/Release && cd WebKitBuild/Release
cmake -DPORT=Qt -DCMAKE_INSTALL_PREFIX="$WORKDIR"/qtbase -DCMAKE_BUILD_TYPE=Release -DQT_QMAKE_EXECUTABLE="$WORKDIR"/qtbase/bin/qmake -DCMAKE_PREFIX_PATH="$WORKDIR"/qtbase -DUSE_GSTREAMER=OFF -DENABLE_OPENGL=OFF -DENABLE_WEB_AUDIO=OFF -DENABLE_VIDEO=OFF -DENABLE_WEBKIT2=OFF -DENABLE_NETSCAPE_PLUGIN_API=OFF -DENABLE_TEST_SUPPORT=off -DQT_STATIC_BUILD=on -DENABLE_API_TESTS=off -DUSE_THIN_ARCHIVES=off  ../..
make -j4
make install

Replace $WORKDIR with the directory where qtbase is located.
I don't know if -DQT_STATIC_BUILD=on is needed, since webkit's Makefile should set that automatically, but I set it just in case. These options are mostly based on how build.py disabled features when building qtwebkit, I tried to find their equivalents here, but I couldn't find all of them. I also disabled the tests, since they failed to build because of missing graphicsview.
Make install will install it to your qtbase directory

  1. Finally, building phantomjs.
    1. export WEB_INSPECTOR_RESOURCES_DIR="$WORKDIR/webkit//WebKitBuild/Release/DerivedSources/WebInspectorUI/"
    2. qmake && make
    3. This will fail, but it will generate src/Makefile.phantomjs, and it won't overwrite it, so we're going to hack that. I don't know how to do these things properly, it was easier to just hack the generated Makefile to get it to build.
    4. Edit LFLAGS and add -static-libstdc++ -static-libgcc. This was needed to get the binary that I built on Ubuntu 16.10 to work on Debian Jessie. I think the old 2.1.1 build script got away with dynamically linking the standard libraries by building on Wheezy, so the standard libraries were old enough to work on most distros. That's also an option.
    5. Edit LIBS. I had to remove -lQt5DBus (qt was built without dbus, and I couldn't figure out why this was being added), add -lQt5Positioning, -lQt5Sensors (this can probably be added in the pro file, but I was lazy)
    6. Remove -lqtpng from LIBS. I built qtbase with -qt-libpng, based on build.py, but when I built phantomjs, I think it tried to use the system libpng as well, and ended up looking for a symbol that only exists in libpng 16, which was installed on my system. So I just replaced -lqtpng with -l:libpng.a (since I wanted to link it statically).
    7. Link a bunch of libraries statically by changing -lXXX to -l:libXXX.a: crypto, hyphen, webp, z, png, icui18n, icuuc icudata. In the end it looked like this:
LIBS          = $(SUBLIBS) -L/home/nkovacs/progs/phantomjs2/phantomjs/src/qt-qpa-platform-plugin/plugins/platforms -lqphantom -lgthread-2.0 -pthread -lglib-2.0 -lXrender -lXext -lX11 -linput -lxkbcommon -ludev -lmtdev -lEGL -lGL -L/home/nkovacs/progs/phantomjs2/qtbase/lib/x86_64-linux-gnu -lQt5WebKitWidgets -L/home/nkovacs/progs/phantomjs2/qtbase/lib -lQt5Sensors -lQt5PrintSupport -lQt5Widgets -lQt5WebKit -lQt5PlatformSupport -lQt5Positioning -lfontconfig -lfreetype -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/imageformats -lqico -lQt5Gui -lharfbuzz -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/bearer -lqgenericbearer -lQt5Network -lssl -l:libcrypto.a -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/sqldrivers -lqsqlite -lQt5Sql -lQt5Core -lqtpcre -lm -ldl -lrt -lpthread -lWebCore -lJavaScriptCore -lWTF -lxml2 -lbmalloc -lxslt -l:libhyphen.a -l:libwebp.a -lwoff2 -lbrotli -lfontconfig -l:libz.a -lfreetype -lQt5Sensors -l:libpng.a -l:libicui18n.a -l:libicuuc.a -l:libicudata.a

The binary seems to work fine, and it runs on Debian Jessie. However, the remote debugger can't find its resources. I've uploaded it here: https://github.com/nkovacs/selenium-standalone-phantomjs/tree/b5c20ef4eba3395bf23d5228d480810f3e4378f9

@vitallium
Copy link
Collaborator

@nkovacs thank you for this detailed instruction! I have some comments below:

First, I had to uninstall qmake and the qt development packages, because it was conflicting with the static qt I had to build.

You don't need to. You need to specify the correct qmake.

symlink the phantom qt platform plugin into the qt source code (phantomjs 2.1.1 had the phantom plugin in its forked version of qtbase, so I duplicated that. I don't know if this is necessary, I don't know what I'm doing.)

No needs to do that. Current master already includes the needed platform plugin that will be built on Linux.

-qt-zlib -qt-libpng -qt-libjpeg

This is dangerous and can lead to unpredicted behaviour. If you are building QtWebKitNG in-the-source (qt5.git), you can use bundled libraries, but not for out-of-the-source (like in your instruction), it's better to use system libraries.

Clone https://github.com/qt/qtlocation and https://github.com/qt/qtsensors,

These components are optional. Here is the list of Qt modules that you need for specific functionality:

Geolocation - qtlocation
Device Orientation - qtsensors
Multimedia (audio/video) - qtmultimedia

Clone https://github.com/annulen/webkit.

Instead of using this huge repo, I suggest to use qtwebkit-snapshots

10 and 11

Again, you don't need to hack CMake configuration, just use this command to build QtWebKitNG:

./Tools/Scripts/build-webkit --qt --release --no-device-orientation \
--no-web-audio --no-video --no-video-track --no-touch-events \
--no-touch-slider --no-geolocation --no-netscape-plugin-api --64-bit \
--cmakeargs="-Wno-dev -DCMAKE_PREFIX_PATH={PATH_TO_YOUR_QT_BUILD} -DUSE_GSTREAMER=OFF -DUSE_THIN_ARCHIVES=OFF -DENABLE_API_TESTS=OFF -DENABLE_TEST_SUPPORT=OFF -ENABLE_OPENGL=NO"

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

Thanks, I'll try your suggestions.

You don't need to. You need to specify the correct qmake.

I did that (-DQT_QMAKE_EXECUTABLE), but it wasn't working for some reason. Also, -DCMAKE_PREFIX_PATH didn't work, it was still picking up the system qt cmake files. When I uninstalled the ubuntu dev packages, it found the static qt's cmake files instead.

This is dangerous and can lead to unpredicted behaviour. If you are building QtWebKitNG in-the-source (qt5.git), you can use bundled libraries, but not for out-of-the-source (like in your instruction), it's better to use system libraries.

I took that from build.py: https://github.com/ariya/phantomjs/blob/2.1.1/build.py#L254

So I should leave that out and just statically link the system libraries to phantomjs? I think jpeg isn't used by phantomjs btw.

Instead of using this huge repo, I suggest to use qtwebkit-snapshots

Or just git clone --depth 1 to leave out the history.

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

Again, you don't need to hack CMake configuration, just use this command to build QtWebKitNG:

That won't work because of QtTestBrowser, and I can't get it to install the libraries to the qtbase directory. It's ninja install.
There's also a mistake, it should be -DENABLE_OPENGL=NO

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

No needs to do that. Current master already includes the needed platform plugin that will be built on Linux.

Doesn't work, the build fails with cannot find -lqphantom.
The Makefile in the qt-qpa-platform-plugin directory doesn't seem to be doing anything.

@vitallium
Copy link
Collaborator

Doesn't work, the build fails with cannot find -lqphantom.

@nkovacs you must use the latest version from the master branch.

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

I am using master.

@vitallium
Copy link
Collaborator

Could you please post the output of qmake -r on a clean tree?

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

Info: creating stash file /home/nkovacs/progs/phantomjs2/phantomjs3/.qmake.stash
Reading /home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin/phantom.pro
Info: creating stash file /home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin/.qmake.stash
Reading /home/nkovacs/progs/phantomjs2/phantomjs3/src/phantomjs.pro
Project MESSAGE: Using Web Inspector resources from /home/nkovacs/progs/phantomjs2/webkit2/WebKitBuild/Release/DerivedSources/WebInspectorUI
Project MESSAGE: This project is using private headers and will therefore be tied to this specific Qt module build version.
Project MESSAGE: Running this project against other versions of the Qt modules may crash at any arbitrary point.
Project MESSAGE: This is not a bug, but a result of using Qt internals. You have been warned!

@vitallium
Copy link
Collaborator

vitallium commented Mar 13, 2017

@nkovacs looks good. Now, can you post the output of make command? Thanks!

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

cd src/qt-qpa-platform-plugin/ && ( test -e Makefile.phantom || /home/nkovacs/progs/phantomjs2/qtbase2/bin/qmake /home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin/phantom.pro -o Makefile.phantom ) && make -f Makefile.phantom 
make[1]: Entering directory '/home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin'
/home/nkovacs/progs/phantomjs2/qtbase2/bin/moc -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_EVDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQ_FONTCONFIGDATABASE -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_STATICPLUGIN -DQT_PLUGIN -DQT_PLATFORMSUPPORT_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_GRAPHICSVIEW -DQT_NO_GRAPHICSEFFECT -DQT_NO_STYLESHEET -DQT_NO_STYLE_CDE -DQT_NO_STYLE_CLEANLOOKS -DQT_NO_STYLE_MOTIF -DQT_NO_STYLE_PLASTIQUE -DQT_NO_PRINTPREVIEWDIALOG -I/home/nkovacs/progs/phantomjs2/qtbase2/mkspecs/linux-g++ -I/home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin -I/home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin -I/home/nkovacs/progs/phantomjs2/qtbase2/include -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1/QtCore -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore -I/usr/include/c++/6 -I/usr/include/x86_64-linux-gnu/c++/6 -I/usr/include/c++/6/backward -I/usr/lib/gcc/x86_64-linux-gnu/6/include -I/usr/local/include -I/usr/lib/gcc/x86_64-linux-gnu/6/include-fixed -I/usr/include/x86_64-linux-gnu -I/usr/include main.cpp -o .moc/main.moc
g++ -c -pipe -O2 -fPIC -std=c++1z -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -Wvla -Wdate-time -D_REENTRANT -fPIC -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_EVDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQ_FONTCONFIGDATABASE -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_STATICPLUGIN -DQT_PLUGIN -DQT_PLATFORMSUPPORT_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_GRAPHICSVIEW -DQT_NO_GRAPHICSEFFECT -DQT_NO_STYLESHEET -DQT_NO_STYLE_CDE -DQT_NO_STYLE_CLEANLOOKS -DQT_NO_STYLE_MOTIF -DQT_NO_STYLE_PLASTIQUE -DQT_NO_PRINTPREVIEWDIALOG -I. -I. -I/home/nkovacs/progs/phantomjs2/qtbase2/include -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1/QtCore -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore -I.moc -I/home/nkovacs/progs/phantomjs2/qtbase2/mkspecs/linux-g++ -o .obj/main.o main.cpp
g++ -c -pipe -O2 -fPIC -std=c++1z -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -Wvla -Wdate-time -D_REENTRANT -fPIC -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_EVDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQ_FONTCONFIGDATABASE -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_STATICPLUGIN -DQT_PLUGIN -DQT_PLATFORMSUPPORT_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_GRAPHICSVIEW -DQT_NO_GRAPHICSEFFECT -DQT_NO_STYLESHEET -DQT_NO_STYLE_CDE -DQT_NO_STYLE_CLEANLOOKS -DQT_NO_STYLE_MOTIF -DQT_NO_STYLE_PLASTIQUE -DQT_NO_PRINTPREVIEWDIALOG -I. -I. -I/home/nkovacs/progs/phantomjs2/qtbase2/include -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1/QtCore -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore -I.moc -I/home/nkovacs/progs/phantomjs2/qtbase2/mkspecs/linux-g++ -o .obj/phantomintegration.o phantomintegration.cpp
g++ -c -pipe -O2 -fPIC -std=c++1z -fvisibility=hidden -fvisibility-inlines-hidden -fno-exceptions -Wall -W -Wvla -Wdate-time -D_REENTRANT -fPIC -DQT_NO_MTDEV -DQT_NO_LIBUDEV -DQT_NO_EVDEV -DQT_NO_TSLIB -DQT_NO_LIBINPUT -DQ_FONTCONFIGDATABASE -DQT_NO_EXCEPTIONS -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -DQT_NO_DEBUG -DQT_STATICPLUGIN -DQT_PLUGIN -DQT_PLATFORMSUPPORT_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_GRAPHICSVIEW -DQT_NO_GRAPHICSEFFECT -DQT_NO_STYLESHEET -DQT_NO_STYLE_CDE -DQT_NO_STYLE_CLEANLOOKS -DQT_NO_STYLE_MOTIF -DQT_NO_STYLE_PLASTIQUE -DQT_NO_PRINTPREVIEWDIALOG -I. -I. -I/home/nkovacs/progs/phantomjs2/qtbase2/include -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtPlatformSupport/5.7.1/QtPlatformSupport -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui/5.7.1/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtGui -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1 -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore/5.7.1/QtCore -I/home/nkovacs/progs/phantomjs2/qtbase2/include/QtCore -I.moc -I/home/nkovacs/progs/phantomjs2/qtbase2/mkspecs/linux-g++ -o .obj/phantombackingstore.o phantombackingstore.cpp
rm -f /home/nkovacs/progs/phantomjs2/qtbase2/plugins/platforms/libqphantom.a
ar cqs /home/nkovacs/progs/phantomjs2/qtbase2/plugins/platforms/libqphantom.a .obj/main.o .obj/phantomintegration.o .obj/phantombackingstore.o
make[1]: Leaving directory '/home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin'

It creates phantombackingstore.o, main.o and phantomintegration.o in .obj.

Edit: it does create libqphantom.a in /home/nkovacs/progs/phantomjs2/qtbase2/plugins/platforms/libqphantom.a, but ld can't find it when building phantomjs, because it's searching in the wrong place:

-L/home/nkovacs/progs/phantomjs2/phantomjs3/src/qt-qpa-platform-plugin/plugins/platforms

@nkovacs
Copy link

nkovacs commented Mar 13, 2017

Also, add_definitions(-DQT_NO_GRAPHICSVIEW) is still needed for webkit, otherwise it builds libQt5WebKitWidgets.a with graphicsview, and it won't link.

@vitallium
Copy link
Collaborator

No, I meant the full build log on a clean tree.

@nkovacs
Copy link

nkovacs commented Mar 14, 2017

@nkovacs
Copy link

nkovacs commented Mar 14, 2017

The previous binary had some problems, so I rebuilt it with some libraries built from sources.
Updated instructions:

  1. export WORKDIR=some directory where you'll be building phantomjs
  2. Build a static icu
    1. apt-get source icu
    2. cd icu*
    3. ./configure --prefix="$WORKDIR"/icu-install --enable-static --disable-shared
    4. make && make install
  3. Add $WORKDIR/icu-install to paths
    1. export C_INCLUDE_PATH="$WORKDIR"/icu-install/include/
    2. export CPLUS_INCLUDE_PATH="$WORKDIR"/icu-install/include/
    3. export LIBRARY_PATH="$WORKDIR"/icu-install/lib
  4. Build static libxml
    1. apt-get source libxml2
    2. cd libxml2-*
    3. ./configure --prefix="$WORKDIR"/icu-install --enable-static --disable-shared --without-python --with-libxml-prefix="$WORKDIR/icu-install/"
    4. make && make install
  5. Build static libxslt
    1. apt-get source libxslt
    2. Same as icu
  6. Build static liblzma
    1. apt-get source liblzma
    2. Same as icu
  7. Build static qtbase
    1. Clone qtbase, checkout v5.7.1
    2. edit src/3rdparty/icu_dependency.pri, add -ldl to the linker flags. See https://bugreports.qt.io/browse/QTBUG-58301
    3. ./configure -static -release -prefix . -opensource -confirm-license -qpa phantom -openssl -openssl-linked -no-openvg -no-eglfs -no-egl -no-glib -no-gtk -no-cups -no-sm -no-xkb -no-xcb -no-kms -no-linuxfb -no-directfb -no-mirclient -no-mtdev -no-libudev -no-evdev -no-pulseaudio -no-alsa -no-feature-PRINTPREVIEWWIDGET -fontconfig -icu -nomake examples -nomake tools -nomake tests -no-qml-debug -no-dbus -no-opengl -no-audio-backend -D QT_NO_GRAPHICSVIEW -D QT_NO_GRAPHICSEFFECT -D QT_NO_STYLESHEET -D QT_NO_STYLE_CDE -D QT_NO_STYLE_CLEANLOOKS -D QT_NO_STYLE_MOTIF -D QT_NO_STYLE_PLASTIQUE -D QT_NO_PRINTPREVIEWDIALOG -no-pkg-config
    4. make
  8. Build webkit
    1. clone annulen/webkit
    2. Edit Source/cmake/OptionsQt.cmake, add add_definitions(-DQT_NO_GRAPHICSVIEW) under add_definitions(-DBUILDING_QT__=1)
    3. Edit Tools/PlatformQt.cmake, comment out add_subdirectory(QtTestBrowser)
    4. ./Tools/Scripts/build-webkit --qt --release --no-device-orientation --no-web-audio --no-video --no-video-track --no-touch-events --no-touch-slider --no-geolocation --no-netscape-plugin-api --64-bit --cmakeargs="-Wno-dev -DCMAKE_PREFIX_PATH=$WORKDIR/qtbase -DUSE_GSTREAMER=OFF -DUSE_THIN_ARCHIVES=OFF -DENABLE_API_TESTS=OFF -DENABLE_TEST_SUPPORT=OFF -DENABLE_OPENGL=OFF -DCMAKE_INSTALL_PREFIX=$WORKDIR/qtbase"
    5. Install it: cd WebKitBuild/Release && ninja install
  9. Build phantomjs
    1. $WORKDIR/qtbase/bin/qmake && make
    2. This won't work because of the platform plugin. Fix it: mkdir -p src/qt-qpa-platform-plugin/plugins/platforms && cp $WORKDIR/qtbase/plugins/platforms/libphantom.* src/qt-qpa-plugin/plugins/platforms/
    3. Edit src/Makefile.phantom and add -static-libstdc++ -static-libgcc to LFLAGS
    4. Edit src/Makefile.phantom and make some libraries in LIBS static by changing -lXXX to -l:libXXX.a. The order will also be incorrect, static libraries must come after their dependants. E.g. this works:
LIBS          = $(SUBLIBS) -L/home/nkovacs/progs/phantomjs2/phantomjs/src/qt-qpa-platform-plugin/plugins/platforms -lqphantom -L/home/nkovacs/progs/phantomjs2/qtbase/lib -lQt5WebKitWidgets -lQt5PrintSupport -lQt5Widgets -lQt5WebKit -lQt5PlatformSupport -lfontconfig -lfreetype -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/imageformats -lqico -lQt5Gui -l:libjpeg.a -lqtharfbuzzng -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/bearer -lqgenericbearer -lQt5Network -lssl -l:libcrypto.a -L/home/nkovacs/progs/phantomjs2/qtbase/plugins/sqldrivers -lqsqlite -lQt5Sql -lQt5Core -lz -l:libpcre16.a -lm -ldl -lrt -lpthread -lWebCore -lJavaScriptCore -licui18n -licuuc -licudata -lWTF -lxml2 -lbmalloc -lxslt -l:libhyphen.a -l:libwebp.a -lwoff2 -lbrotli -lfontconfig -lfreetype -llzma -l:libpng.a

This one now works in my docker image (nkovacs/selenium-standalone-phantomjs) as well as Debian Jessie: https://github.com/nkovacs/selenium-standalone-phantomjs/tree/11420aaf2174428b56086673232365c820f98a42

@jefleponot
Copy link

@nkovacs

I saw that you success in compiling phantomJS 2.5.0
Do you have a simple script to do that ... for linux at least..

Thank by advance

@vitallium
I don't understand how it is so complex to compile source now... We aren't Qt and Webkit experts.

nkovacs referenced this issue in nkovacs/selenium-standalone-phantomjs Jun 26, 2017
@siddhi
Copy link

siddhi commented Jul 24, 2017

@nkovacs Thanks a ton for the detailed steps, I was able to get a static build working on SuSE linux by following your steps. The only change was in the Webkit compilation step where I had to pass -DCMAKE_PREFIX_PATH=$WORKDIR/icu-install instead of -DCMAKE_PREFIX_PATH=$WORKDIR/qtbase

A few places where I got tripped up:

  • If you have multiple versions of a library installed, then it is possible that Qt or webkit will build against one version of a library (libpng in my case) and link against another version which will cause a segfault when phantom is run. Check the configure output of the Qt and Webkit compilations steps carefully to ensure you are building against the version you intend to.
  • CMake caches detected library versions, so if you see the wrong library versions detected and make changes to include the right one, then delete the CMake cache files first (*Cache.txt) before re-running the build
  • Latest PhantomJS version doesn't enable local storage by default. See 2.5.0-development: missing window.localStorage #14740 for a fix

Other than that, everything seems to be working fine so far against a medium sized angular application. Fingers crossed that it stays that way.

@haroon-sheikh
Copy link
Contributor

@pixiuPL Are we continuing the development on phantomjs? I'm really glad to see some movement again. Thank you 👍

@ghost ghost removed the In progress label Jan 10, 2018
@ghost ghost removed this from the Release 2.5 milestone Jan 10, 2018
@ariya
Copy link
Owner Author

ariya commented Dec 25, 2019

Due to our very limited maintenance capacity (see #14541 for more details), we need to prioritize our development focus on other tasks. Therefore, this issue will be closed. In the future, if we see the need to attend to this issue again, then it will be reopened.
Thank you for your contribution!

@ariya ariya closed this as completed Dec 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants