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 <module>
		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<char>]':
	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

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