Install & configure google’s mod_pagespeed for apache

#See https://adrhc.go.ro/blog/common-commands-when-building/ for building environment, x.sh script and other things not defined here.
#Before starting do declare the environment variables specified to the link above.

#mod_pagespeed (see depot_tools and modpagespeed-patch.sh below)
rm -r ~/compile/mod_pagespeed
mkdir ~/compile/mod_pagespeed
cd ~/compile/mod_pagespeed
#export PATH=/ffp/sbin:/usr/sbin:/sbin:/ffp/bin:/usr/bin:/bin:/ffp/opt/ejre1.7.0_60/bin:/ffp/home/root/compile/depot_tools/
export PATH=$PATH:/ffp/home/root/compile/depot_tools/
export GIT_SSL_NO_VERIFY=true
gclient config http://modpagespeed.googlecode.com/svn/trunk/src
#Ignore the warning: Running depot tools as root is sad; this means that depot tools won't update itself.
#gclient config http://modpagespeed.googlecode.com/svn/branches/latest-beta/src
gclient sync --force --jobs=1
renice -14 `pidof python` -p `pidof svn` -p `pidof git`

#ERROR1
    ________ running '/ffp/bin/python src/tools/clang/scripts/update.py --mac-only' in '/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed'
    Traceback (most recent call last):
      File "src/tools/clang/scripts/update.py", line 193, in 
        sys.exit(main())
      File "src/tools/clang/scripts/update.py", line 183, in main
        stderr=os.fdopen(os.dup(sys.stdin.fileno())))
      File "/ffp/lib/python2.7/subprocess.py", line 522, in call
        return Popen(*popenargs, **kwargs).wait()
      File "/ffp/lib/python2.7/subprocess.py", line 710, in __init__
        errread, errwrite)
      File "/ffp/lib/python2.7/subprocess.py", line 1335, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory
    Error: Command /ffp/bin/python src/tools/clang/scripts/update.py --mac-only returned non-zero exit status 1 in /usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed
#SOLUTION1
    find . -type f -name "DEPS" -exec sed -i s/"https"/"http"/ {} \;
    find . -type f -name "DEPS" -exec sed -i s/"http:\/\/boringssl"/"https:\/\/boringssl"/ {} \;
    sed -i s/"256281"/"262880"/ ~/compile/mod_pagespeed/src/DEPS
    sed -i s#,\ \"\\--mac-only\"## ~/compile/mod_pagespeed/src/DEPS
    gclient sync --force --jobs=1

#ERROR2
    ________ running '/ffp/bin/python src/tools/clang/scripts/update.py' in '/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed'
    Traceback (most recent call last):
      File "src/tools/clang/scripts/update.py", line 197, in 
        sys.exit(main())
      File "src/tools/clang/scripts/update.py", line 183, in main
        stderr=os.fdopen(os.dup(sys.stdin.fileno())))
      File "/ffp/lib/python2.7/subprocess.py", line 522, in call
        return Popen(*popenargs, **kwargs).wait()
      File "/ffp/lib/python2.7/subprocess.py", line 710, in __init__
        errread, errwrite)
      File "/ffp/lib/python2.7/subprocess.py", line 1335, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory
    Error: Command /ffp/bin/python src/tools/clang/scripts/update.py returned non-zero exit status 1 in /usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed
#SOLUTION2
    sed -i s/"https"/"http"/ ~/compile/mod_pagespeed/src/tools/clang/scripts/update.*
    sed -i s/"\/usr\/bin\/env"/"\/ffp\/bin\/env"/ ~/compile/mod_pagespeed/src/tools/clang/scripts/update.*
    #also do solutions for errors listed till TO DO BEFORE "make AR.host ..." section
    gclient sync --force --jobs=1

#ERROR3:
    gyp: Undefined variable deb_arch in /usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed/src/build/install.gyp
    Error: Command /ffp/bin/python src/build/gyp_chromium -Dchromium_revision=256281 returned non-zero exit status 1 in /usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed
#SOLUTION3:
    Modify manually ~/compile/mod_pagespeed/src/build/install.gyp:
        'conditions': [             -> existing line
          ['target_arch=="ia32"', { -> existing line
            'deb_arch': 'i386',     -> existing line
            'rpm_arch': 'i386',     -> existing line
          }],                       -> existing line
          ['target_arch=="arm"', {
            'deb_arch': 'arm',
            'rpm_arch': 'arm',
          }],
    or simply run this:
    sed -i s/"target_arch==\"x64"/"target_arch==\"arm"/ ~/compile/mod_pagespeed/src/build/install.gyp        
    sed -i s/"deb_arch':\s'amd64"/"deb_arch': 'arm"/ ~/compile/mod_pagespeed/src/build/install.gyp       
    sed -i s/"rpm_arch':\s'x86_64"/"rpm_arch': 'arm"/ ~/compile/mod_pagespeed/src/build/install.gyp
    #continue to ERROR4 (step 1) without running 'gclient sync'

#ERROR4 (step 1):
    Hook '/ffp/bin/python src/build/gyp_chromium -Dchromium_revision=262880' took 301.05 secs
    ________ running 'src/third_party/closure/download.sh' in '/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed'
    find: 'src/tools/closure': No such file or directory
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 5522k  100 5522k    0     0  1709k      0  0:00:03  0:00:03 --:--:-- 1709k
    Archive:  src/tools/closure/compiler-latest.zip
#SOLUTION4:
    sed -i s/"curl\s-"/"curl -k -"/ src/tools/clang/scripts/update.sh
    sed -i s/"curl\shttp"/"curl -k http"/ src/third_party/closure/download.sh
    sed -i s/"\/bin\/bash"/"\/ffp\/bin\/sh"/ src/third_party/closure/download.sh
    gclient sync --force --jobs=1

#ERROR4 (step 2):
    Hook '/ffp/bin/python src/build/gyp_chromium -Dchromium_revision=262880' took 301.05 secs
    ________ running 'src/third_party/closure/download.sh' in '/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed'
    Traceback (most recent call last):
      File "/ffp/home/root/compile/depot_tools/gclient.py", line 2264, in 
        sys.exit(Main(sys.argv[1:]))
      File "/ffp/home/root/compile/depot_tools/gclient.py", line 2252, in Main
        return dispatcher.execute(OptionParser(), argv)
      File "/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/depot_tools/subcommand.py", line 245, in execute
        return command(parser, args[1:])
      File "/ffp/home/root/compile/depot_tools/gclient.py", line 2009, in CMDsync
        ret = client.RunOnDeps('update', args)
      File "/ffp/home/root/compile/depot_tools/gclient.py", line 1528, in RunOnDeps
        self.RunHooksRecursively(self._options)
      File "/ffp/home/root/compile/depot_tools/gclient.py", line 983, in RunHooksRecursively
        hook, cwd=self.root.root_dir, always=True)
      File "/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/depot_tools/gclient_utils.py", line 293, in CheckCallAndFilterAndHeader
        return CheckCallAndFilter(args, **kwargs)
      File "/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/depot_tools/gclient_utils.py", line 488, in CheckCallAndFilter
        **kwargs)
      File "/usr/local/zy-pkgs/ffproot/ffp/home/root/compile/depot_tools/subprocess2.py", line 253, in __init__
        % (str(e), kwargs.get('cwd'), args[0]))
    OSError: Execution failed with error: [Errno 2] No such file or directory.
    Check that /usr/local/zy-pkgs/ffproot/ffp/home/root/compile/mod_pagespeed or src/third_party/closure/download.sh exist and have execution permission.
#SOLUTION4 (it's same solution applied second time):
    sed -i s/"curl\s-"/"curl -k -"/ src/tools/clang/scripts/update.sh
    sed -i s/"curl\shttp"/"curl -k http"/ src/third_party/closure/download.sh
    sed -i s/"\/bin\/bash"/"\/ffp\/bin\/sh"/ src/third_party/closure/download.sh
    gclient sync --force --jobs=1

#TO DO BEFORE "make AR.host ...":
    cd ~/compile/mod_pagespeed
    /ffp/opt/apache-htdocs/public/modpagespeed-patch.sh
    #BUG1 (~/compile/mod_pagespeed/src/pagespeed/kernel/base/stdio_file_system.cc):
        bug: https://bugs.uclibc.org/2089
        patch: https://github.com/mat-c/uClibc/commit/328d392c54aa5dc2b8e7f398a419087de497de2b
        grep -r -I "hidden_\w.*errno_" .
    #SOLUTION-BUG1:
        grep -i -I -r --include=*.cc "set_error()" ~/compile/mod_pagespeed/src
        Modify ~/compile/mod_pagespeed/src/pagespeed/kernel/base/stdio_file_system.cc:
        1) BoolOrError StdioFileSystem::Exists(const char* path, MessageHandler* handler) {
            //if (ret.is_false() && errno != ENOENT) {  // Not error if file doesn't exist.
            if (ret.is_false()) {
                handler->Message(kError, "[adr, Exists] Failed to stat %s: %s", path, strerror(errno));
                // ret.set_error();
        2) BoolOrError StdioFileSystem::IsDir(const char* path, MessageHandler* handler) {
            if (stat(path, &statbuf) == 0) {
                ret.set(S_ISDIR(statbuf.st_mode));
            //} else if (errno != ENOENT) {  // Not an error if file doesn't exist.
            } else {
                handler->Message(kError, "[adr, IsDir] Failed to stat %s: %s", path, strerror(errno));
                // ret.set_error();
        Modify (optional) ~/compile/mod_pagespeed/src/pagespeed/apache/apr_file_system.cc:
        See ~/compile/mod_pagespeed/src/third_party/apr/src/include/apr_file_info.h for definition of apr_stat(...).
        1) BoolOrError AprFileSystem::Exists(const char* path, MessageHandler* handler) {
            //if (ret != APR_SUCCESS && ret != APR_ENOENT) {
            if (ret != APR_SUCCESS) {
                AprReportError(handler, path, 0, "[adr:Exists:apr_stat] failed to stat", ret);
                //exists.set_error();
        2) BoolOrError AprFileSystem::IsDir(const char* path, MessageHandler* handler) {
            //if (ret != APR_SUCCESS && ret != APR_ENOENT) {
            if (ret != APR_SUCCESS) {
                AprReportError(handler, path, 0, "[adr:IsDir:apr_stat] failed to stat", ret);
                //is_dir.set_error();
#ERROR5:
    missing ContainsOnlyWhitespaceASCII
#SOLUTION5:
    I modified mod_pagespeed/src/pagespeed/kernel/base/string_util.cc and added:
        bool ContainsOnlyWhitespaceASCII(const std::string& str) {
          for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) {
            if (!IsAsciiWhitespace(*i))
              return false;
          }
          return true;
        }
        insert it before the line below (last line in string_util.cc):
        }  // namespace net_instaweb            -> this line already existed the rest above I added
    I modified mod_pagespeed/src/pagespeed/kernel/base/string_util.h and added:
        void LowerString(GoogleString* str);    -> this line already existed the rest below I added
        bool ContainsOnlyWhitespaceASCII(const std::string& str);
#ERROR21 (not always):
    out/Release/obj.target/pagespeed_automatic_test/net/instaweb/rewriter/split_html_filter_test.o: In function `net_instaweb::(anonymous namespace)::SplitHtmlFilterTest_SplitHtmlWithDriverHavingCriticalLineInfo_Test::TestBody()':
    split_html_filter_test.cc:(.text._ZN12net_instaweb12_GLOBAL__N_166SplitHtmlFilterTest_SplitHtmlWithDriverHavingCriticalLineInfo_Test8TestBodyEv+0x364): relocation truncated to fit: R_ARM_THM_CALL against symbol `operator delete(void*)@@GLIBCXX_3.4' defined in .plt section in /ffp/bin/../lib/gcc/arm-ffp-linux-uclibcgnueabi/4.6.2/../../../crt1.o
    collect2: ld returned 1 exit status
    make: *** [out/Release/pagespeed_automatic_test] Error 1
#SOLUTION21:
    Modify ~/compile/mod_pagespeed/src/build/All.target.mk:
    $(obj).target/build/All.stamp: $(obj).target/build/mod_pagespeed.stamp $(obj).target/build/test.stamp $(obj).target/build/js_minify.stamp FORCE_DO_CMD
    Modify ~/compile/mod_pagespeed/src/Makefile:
    comment any ifeq using *pagespeed_automatic*.mk
#ERROR22 (not always):
    In file included from ./pagespeed/kernel/base/string_util.h:28:0,
                     from ./net/instaweb/rewriter/public/js_replacer.h:30,
                     from net/instaweb/rewriter/js_replacer.cc:17:
    third_party/chromium/src/base/logging.h: In function 'std::string* logging::CheckGEImpl(const t1&, const t2&, const char*) [with t1 = unsigned int, t2 = int, std::string = std::basic_string]':
    net/instaweb/rewriter/js_replacer.cc:157:3:   instantiated from here
    third_party/chromium/src/base/logging.h:560:1: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
    cc1plus: all warnings being treated as errors
#SOLUTION22:
    Compile again the line producing the error modifying -Werror with -Wsign-compare (below is the corrected g++ command):
    g++ '-DCHROMIUM_REVISION=262880' '-DV8_DEPRECATION_WARNINGS' '-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' '-D_FILE_OFFSET_BITS=64' '-DPAGESPEED_SUPPORT_POSIX_SHARED_MEM' '-DGTEST_HAS_RTTI=1' '-DCHROMIUM_BUILD' '-DTOOLKIT_VIEWS=1' '-DUI_COMPOSITOR_IMAGE_TRANSPORT' '-DUSE_AURA=1' '-DUSE_CAIRO=1' '-DUSE_GLIB=1' '-DUSE_DEFAULT_RENDER_THEME=1' '-DUSE_LIBJPEG_TURBO=1' '-DUSE_X11=0' '-DUSE_CLIPBOARD_AURAX11=1' '-DENABLE_ONE_CLICK_SIGNIN' '-DUSE_XI2_MT=2' '-DENABLE_REMOTING=1' '-DENABLE_WEBRTC=1' '-DENABLE_PEPPER_CDMS' '-DENABLE_CONFIGURATION_POLICY' '-DENABLE_INPUT_SPEECH' '-DENABLE_NOTIFICATIONS' '-DUSE_UDEV' '-DENABLE_EGLIMAGE=1' '-DENABLE_TASK_MANAGER=1' '-DENABLE_EXTENSIONS=1' '-DENABLE_PLUGIN_INSTALLATION=1' '-DENABLE_PLUGINS=1' '-DENABLE_SESSION_SERVICE=1' '-DENABLE_THEMES=1' '-DENABLE_AUTOFILL_DIALOG=1' '-DENABLE_BACKGROUND=1' '-DENABLE_GOOGLE_NOW=1' '-DCLD_VERSION=2' '-DENABLE_FULL_PRINTING=1' '-DENABLE_PRINTING=1' '-DENABLE_SPELLCHECK=1' '-DENABLE_CAPTIVE_PORTAL_DETECTION=1' '-DENABLE_APP_LIST=1' '-DENABLE_SETTINGS_APP=1' '-DENABLE_MANAGED_USERS=1' '-DENABLE_MDNS=1' '-DENABLE_SERVICE_DISCOVERY=1' '-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER' '-DUSE_NSS=1' '-D__STDC_CONSTANT_MACROS' '-D__STDC_FORMAT_MACROS' '-DNDEBUG' '-DNVALGRIND' '-DDYNAMIC_ANNOTATIONS_ENABLED=0' '-D_FORTIFY_SOURCE=2' -Ithird_party/chromium/src -I. -Ithird_party/css_parser/src -Ithird_party/google-sparsehash/gen/arch/linux/ia32/include -Ithird_party/google-sparsehash/src -Iout/Release/obj/gen/protoc_out/instaweb -Ithird_party/protobuf/src -Ithird_party/re2/src -Ithird_party/protobuf  -fno-stack-protector -march=armv5te -mtune=xscale -mfloat-abi=soft -mabi=aapcs-linux -mthumb -O2 --param=ssp-buffer-size=4 -Wsign-compare -pthread -fno-exceptions -fno-strict-aliasing -Wall -Wno-unused-parameter -Wno-missing-field-initializers -fvisibility=hidden -pipe -fPIC -fexceptions -fasynchronous-unwind-tables -Wno-unused-but-set-variable -march=armv5te -mtune=xscale -mfloat-abi=soft -mabi=aapcs-linux -mthumb -O2 -mfpu=vfp -mfloat-abi=soft -mthumb -O2 -fno-ident -fdata-sections -ffunction-sections -funwind-tables -fno-threadsafe-statics -fvisibility-inlines-hidden -frtti -Wno-abi -MMD -MF out/Release/.deps/out/Release/obj.target/instaweb_rewriter/net/instaweb/rewriter/js_replacer.o.d.raw -march=armv5te -mfloat-abi=soft -mabi=aapcs-linux -pthread -O2 -lintl -Wall -I/ffp/include -c -o out/Release/obj.target/instaweb_rewriter/net/instaweb/rewriter/js_replacer.o net/instaweb/rewriter/js_replacer.cc
    Find the *.mk: 
    grep -I -r "js_replacer.o" .
    sed -i s/"-Werror"/""/ ./net/instaweb/instaweb_rewriter.target.mk
    sed -i s/"-Werror"/""/ ./third_party/css_parser/css_parser.target.mk

#START BULDING (check error and apply patch before make):
    cd ~/compile/mod_pagespeed/src
    rm -r ~/compile/mod_pagespeed/src/out
    rm nohup.out
    echo -e "X-Mod-Pagespeed:\n`cat ~/compile/mod_pagespeed/src/net/instaweb/public/VERSION`" > nohup.out
    #nohup /ffp/bin/make AR.host=`pwd`/build/wrappers/ar.sh AR.target=`pwd`/build/wrappers/ar.sh BUILDTYPE=Release V=1 &
    nohup /ffp/bin/make AR.host=`pwd`/build/wrappers/ar.sh AR.target=`pwd`/build/wrappers/ar.sh APACHE_ROOT=/ffp/opt/apache-2.2.29-worker APACHE_MODULES=/ffp/opt/apache-2.2.29-worker/modules APACHE_DOC_ROOT=/ffp/opt/apache-htdocs APACHE_USER=nobody APACHE_GROUP=nobody BINDIR=/ffp/bin BUILDTYPE=Release V=1 &
    renice -11 `pidof cc1plus` -p `pidof make` -p `pidof as` -p `pidof ld` -p `pidof configure` -p `pidof cc1` -p `pidof ccmake`
    tail -f nohup.out
    MPSB="2015-03-12 pagespeed trunk"
    cd ~/NSA310-backups && mkdir "$MPSB"
    cd "$MPSB"
    mv -v ~/compile/mod_pagespeed/src/nohup.out build.log

#TESTS:
    #Is the mozilla for python certificate:
    wget -nv http://curl.haxx.se/ca/cacert.pem -O /ffp/etc/ssl/cert.pem
    export SSL_CERT_FILE=/ffp/etc/ssl/cert.pem
    #./out/Release/mod_pagespeed_test
    #./out/Release/pagespeed_automatic_test
    cd ~/compile/mod_pagespeed/src
    rm nohup.out
    nohup ./out/Release/pagespeed_automatic_test &
    tail -f nohup.out
    cd ~/NSA310-backups && cd "$MPSB"
    mv -v ~/compile/mod_pagespeed/src/nohup.out tests.log

#INSTALLATION:
    Modify /ffp/opt/apache-2.2.29-worker/conf/httpd.conf for User and Group to be like in /etc/service_config/httpd.conf.
    sed -i s/"User daemon"/"User nobody"/ /ffp/opt/apache-2.2.29-worker/conf/httpd.conf
    sed -i s/"Group daemon"/"Group nobody"/ /ffp/opt/apache-2.2.29-worker/conf/httpd.conf
    cd ~ && ./x.sh xstop
    rm -v /ffp/opt/apache-2.2.29-worker/modules/*pagespeed*.*
    rm -v /ffp/opt/apache-2.2.29-worker/conf/*pagespeed*.*
    rm -v /ffp/bin/pagespeed_js_minify
    chmod +x ~/compile/mod_pagespeed/src/install/install_apxs.sh
    cd ~/compile/mod_pagespeed/src/install
    NO_SUDO=1 APXS_BIN=/ffp/opt/apache-2.2.29-worker/bin/apxs ~/compile/mod_pagespeed/src/install/install_apxs.sh
    cp -v /ffp/opt/apache-2.2.29-worker/modules/*pagespeed*.so /ffp/opt/apache-htdocs/ffp_0.7_armv5/packages/
    cp -v /ffp/bin/pagespeed_js_minify /ffp/opt/apache-htdocs/ffp_0.7_armv5/packages/
    mkdir -p /ffp/var/cache/mod_pagespeed
    rm -r /ffp/var/cache/mod_pagespeed/*
    mkdir -p /ffp/var/log/pagespeed
    chown nobody:nobody /ffp/var/cache/mod_pagespeed
    chmod 777 -R /ffp/var/cache/mod_pagespeed
    chown nobody:nobody /ffp/var/log/pagespeed
    chmod 777 -R /ffp/var/log/pagespeed
    cd ~/NSA310-backups && cd "$MPSB"
    cp -v /ffp/opt/apache-2.2.29-worker/modules/*pagespeed*.* .
    cp -v /ffp/opt/apache-2.2.29-worker/conf/*pagespeed*.* .
    cp -v /ffp/bin/pagespeed_js_minify .
    #rm -r /ffp/var/cache/mod_pagespeed/*
    cd ~ && ./x.sh hstart
    du -sh --apparent-size /ffp/var/cache/mod_pagespeed

click to get modpagespeed-patch.sh

#depot_tools
cd ~/compile
rm -r depot_tools
svn co http://src.chromium.org/svn/trunk/tools/depot_tools
cd ~/compile/depot_tools/
~/x.sh ffpg
#Run this in order to allow depot_tools to auto-update (only when you're logged with root):
#sed -i s#\"\$USER\"\ ==\ \"root\"#\"\$USER\"\ ==\ \"dont-let-me-run-as-root\"# ~/compile/depot_tools/update_depot_tools
#otherwise you'll get the message: Running depot tools as root is sad.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.