Facebook Open Platform搭建

戈嘉慕
2023-12-01

研究一个open source project从编译它开始。像这个Facebook Open Platform这样编译起来过程这么烦琐,还真是头一次碰到。

 

要编译Facebook Open Platform,至少需要先安装Apache, MySQL, PHP。而且PHP至少包含下列PHP extensions:

ctype, curl, date, iconv, json, mysql, pcre, SimpleXML, standard, xmlwriter

 

在Facebook Open Platform的安装包里,其实还包含了Firefox的代码,最后这些代码会被编译成一个PHP extension,供apache和PHP使用。

 

 

 

环境:

OS: Fedora7 (kernel 2.6.21)

Shell: bash v3.2.9

GCC: v4.1.2

make: v3.81

 

---------------------------------------------------------------

第一部分,安装apache。

Apache 2.2.9  (httpd-2.2.9.tar.bz2)

 

假设安装路径为/home/tielei/opensrc/httpd-2.2.9-installed。

 

1, 将httpd-2.2.9.tar.bz2拷贝到/home/tielei/opensrc/目录下

2, tar xjf httpd-2.2.9.tar.bz2

3, mkdir httpd-2.2.9-installed

4, cd httpd-2.2.9

 

5, 执行configure脚本。顺便把常用的module都enable了,命令比较长。

 

./configure --prefix=/home/tielei/opensrc/httpd-2.2.9-installed --enable-so --enable-authz_groupfile=shared --enable-expires=shared --enable-alias=shared --enable-actions=shared --enable-auth_basic=shared --enable-auth_digest=shared --enable-authn_dbd=shared --enable-authn_dbm=shared --enable-authn_default=shared --enable-authn_file=shared --enable-authz_owner=shared --enable-authz_user=shared --enable-cgi=shared --enable-cgid=shared --enable-charset_lite=shared --enable-dbd=shared --enable-deflate=shared --enable-env=shared --enable-headers=shared --enable-imagemap=shared --enable-include=shared --enable-info=shared --enable-log_config=shared --enable-log_forensic=shared --enable-logio=shared --enable-mime=shared --enable-mime_magic=shared --enable-negotiation=shared --enable-speling=shared --enable-ssl=shared --enable-status=shared

 

6, make

7, make install

 

测试一下刚刚装好的apache server

8, cd /home/tielei/opensrc/httpd-2.2.9-installed

9, 检查和修改配置文件conf/httpd.conf,根据需要,可能需要修改DocumentRoot

10, su (切换到root)

11, 以root身份启动apache server

  ./bin/apachectl -f conf/httpd.conf

12, 保证DocumentRoot路径上的目录对other用户具有rx权限,DocumentRoot路径下的文件对other用户具有r权限

13, 可能需要关闭防火墙。在redhat/fedora系统中,执行

/etc/rc.d/init.d/iptables stop

14, 在另一台机器中访问http://192.168.1.102 (apache server所在机器的IP地址),如果httpd.conf没有被修改过,则访问的文件则是/home/tielei/opensrc/httpd- 2.2.9-installed/htdocs/index.html。它显示“It Works”!

15,关闭apache server

./bin/apachectl -k stop

16, 退出root身份:Ctrl+D

 

 

---------------------------------------------------------------

第二部分,安装Mysql (mysql-5.0.51a-linux-i686-icc-glibc23.tar.gz)

为简单起见,下载了一个已经编译好的package,下载链接是

http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.51a-linux-i686-icc-glibc23.tar.gz/from/http://mysql.cs.pu.edu.tw/

 

1, 将mysql-5.0.51a-linux-i686-icc-glibc23.tar.gz拷贝到/home/tielei/opensrc/目录下

2, tar xzf mysql-5.0.51a-linux-i686-icc-glibc23.tar.gz

 

拷贝完就算是已经安装好了。完成安装后的配置:

3, cd mysql-5.0.51a-linux-i686-icc-glibc23

4, 查看文档

info docs/mysql.info

进入文档目录installing/installing-cs/post-installation/unix-post-installation

文档中说明了初次安装后应该初始化grant tables,执行:

5, script s/mysql_install_db --user=mysql

6, 启动mysql server

bin/mysqld_safe --user=mysql &

 

测试一下刚配置好的mysql server

7, 连接mysql server

bin/mysql -u mysql

Welcome to MYSQL Monitor. Commands end with ; or /g.

...

mysql>quit

8, 关闭mysql server

bin/mysqladmin -u root shutdown

 

---------------------------------------------------------------

第三部分,安装PHP

PHP5 (php-5.2.6.tar.bz2)

 

假设安装路径为/home/tielei/opensrc/php-5.2.6-installed。

 

1, 将php-5.2.6.tar.bz2拷贝到/home/tielei/opensrc/目录下

2, tar xjf php-5.2.6.tar.bz2

3, mkdir php-5.2.6-installed

4, cd php-5.2.6

5, ./configure --prefix=/home/tielei/opensrc/php-5.2.6-installed --with-apxs2=/home/tielei/opensrc/httpd-2.2.9-installed/bin/apxs --with-mysql=/home/tielei/opensrc/mysql-5.0.51a-linux-i686-icc-glibc23 --with-curl

 

6, make

7, make install

8, 如果make install执行时出现如下错误

/home/tielei/opensrc/php-5.2.6/sapi/cli/php: error while loading shared libraries: /home/tielei/opensrc/mysql-5.0.51a-linux-i686-icc-glibc23/lib/libmysqlclient.so.15: cannot restore segment prot after reloc: Permission denied

则先执行

chcon -t texrel_shlib_t /home/tielei/opensrc/mysql-5.0.51a-linux-i686-icc-glibc23/lib/lib*

然后重新执行make install

 

9, 检查。

至此,在apache的ServerRoot/modules/目录下,即/home/tielei/opensrc/httpd-2.2.9-installed/modules/目录下,会出现libphp5.so

 

10, 设置配置文件

cp php.ini-dist ../php-5.2.6-installed/lib/php.ini

 

11, cd ../httpd-2.2.9-installed

12, 检查。

apache的配置文件中,即conf/httpd.conf中,有下面的一行:

LoadModule php5_module modules/libphp5.so

 

13,在配置文件conf/httpd.conf中,加入下面一行:

AddType application/x-httpd-php .php

 

测试一下刚配置好的PHP。

14, 以root身份启动apache server

./bin/apachectl -f conf/httpd.conf

15, 如果上面的命令出现如下错误提示:

httpd: Syntax error on line 85 of /home/tielei/opensrc/httpd-2.2.9-installed/conf/httpd.conf: Cannot load /home/tielei/opensrc/httpd-2.2.9-installed/modules/libphp5.so into server: /home/tielei/opensrc/httpd-2.2.9-installed/modules/libphp5.so: cannot restore segment prot after reloc: Permission denied

则需先执行chcon -t texrel_shlib_t modules/libphp5.so

16, 在htdocs目录下建一个.php文件,用浏览器访问,看是否能正常解析php脚本。

17, 测试完毕,关闭apache server

./bin/apachectl -k stop

 

18, cd ../php-5.2.6-installed

19, 检查。

运行 bin/php -m

检查打印出的module列表是否包含所有下列PHP extensions:

ctype, curl, date, iconv, json, mysql, pcre, SimpleXML, standard, xmlwriter

 

 

---------------------------------------------------------------

第四部分,安装和配置Facebook Open Platform (fb-open-platform.tar.gz)。

Facebook Open Platform软件包里面包含FBML的代码(libfbml.tar.gz,解压后libfbml-1.2.0),FBML的实现用到了 firefox,而firefox又依赖于一系列open source package(见下面第5步)。

 

1,将fb-open-platform.tar.gz拷贝到/home/tielei/opensrc/httpd-2.2.9-installed/htdocs/目录下

2,tar xzf fb-open-platform.tar.gz

3, tar xzf libfbml.tar.gz

4, cd libfbml-1.2.0

5, 下载firefox所依赖的代码。

在dependencies目录下,存放的是firefox的代码。由于firefox依赖下面列表所给出的project,所以需要先从括号中所示的URL下载所有这些软件包,并将它们都放入dependencies目录。

 

glib-2.14.6.tar.gz (http://ftp.acc.umu.se/pub/GNOME/sources/glib/2.14/glib-2.14.6.tar.gz)
pkg-config-0.20.tar.gz (ftp://ftp.gtk.org/pub/gtk/v2.10/dependencies/pkg-config-0.20.tar.gz)
atk-1.9.1.tar.bz2 (ftp://ftp.gtk.org/pub/gtk/v2.10/dependencies/atk-1.9.1.tar.bz2)
freetype-2.3.4.tar.gz (http://download.savannah.gnu.org/releases/freetype/freetype-2.3.4.tar.gz)
fontconfig-2.3.97.tar.gz (http://fontconfig.org/release/fontconfig-2.3.97.tar.gz)
libpng-1.2.25.tar.gz (http://internap.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.25.tar.gz)
cairo-1.2.6.tar.gz (ftp://ftp.gtk.org/pub/gtk/v2.10/dependencies/cairo-1.2.6.tar.gz)
tiff-3.7.4.tar.gz (ftp://ftp.gtk.org/pub/gtk/v2.10/dependencies/tiff-3.7.4.tar.gz)
pango-1.18.4.tar.bz2 (http://ftp.gnome.org/pub/gnome/sources/pango/1.18/pango-1.18.4.tar.bz2)
gtk+-2.10.13.tar.bz2 (ftp://ftp.gtk.org/pub/gtk/v2.10/gtk+-2.10.13.tar.bz2)
libIDL-0.8.8.tar.gz (http://ftp.gnome.org/pub/gnome/sources/libIDL/0.8/libIDL-0.8.8.tar.gz)
libXft-2.1.12.tar.gz (http://xorg.freedesktop.org/releases/individual/lib/libXft-2.1.12.tar.gz)
xproto-7.0.7.tar.gz (http://xorg.freedesktop.org/releases/individual/proto/xproto-7.0.7.tar.gz)
xrender-0.8.3.tar.bz2 (http://freeware.sgi.com/source/xrender/xrender-0.8.3.tar.bz2)

 

6, 修改/etc/sudoers文件。

将自己的用户名(tielei)加入到/etc/sudoers文件,使之允许以root身份执行make install和cp命令(在下面执行build-all.py脚本时会用到这两个命令)。具体做法是执行

/usr/sbin/visudo

在文件尾部加入两行:

tielei  localhost=NOPASSWD: /usr/bin/make install

tielei  localhost=NOPASSWD: /bin/cp pangocairo.pc /usr/local/lib/pkgconfig

 

7, export LD_LIBRARY_PATH=/usr/local/lib

保证连接的是刚装到/usr/local/lib/的库,而不是原来环境里就有的库(比如在/usr/lib/)。

 

8, 修改build-all.py脚本。

共三处修改:

(1)将第104行编译xrender-0.8.3.tar.bz2的命令改为:

'xrender-0.8.3.tar.bz2': ("./configure --x-includes=/usr/include/X11/extersions", "make", "sudo make install")

(2)将第82行到第85行packages变量中的'xrender-0.8.3.tar.bz2'换到'libIDL-0.8.8.tar.gz'和'libXft-2.1.12.tar.gz'之间的位置

(3)将第91行到第104行commands变量中的'xrender-0.8.3.tar.bz2'那一行换到'libIDL-0.8.8.tar.gz'一行和'libXft-2.1.12.tar.gz'一行中间的位置

 

否则编译xrender-0.8.3时提示找不到X11/extensions/Xrender.h和X11/extensions/render.h

修改脚本后会先编译xrender-0.8.3再编译libXft-2.1.12,会生成libXft-2.1.12需要的头文件Xrender.h

 

9, 修改源文件fbml.cpp的bug (libfbml-1.2.0/src/fbml.cpp)

将第1233行到第1330行的代码用{}括起来,代码片段:

  if (!chars) goto exit;
{ //line 1233
  // 3. Initialize tokenizer
  JSTokenStream *ts =
    js_NewTokenStream(cx, chars, length, NULL, line_number, NULL);
  if (!ts) goto exit;
...

...

  if (error) {
    *error = m(strdup(sError.c_str()));
  }
} //line 1330
 exit:
  if (chars) JS_free(cx, chars);

 

如果不在这里加上{},则编译时会提示如下错误:

fbml.cpp: In function ‘int fbml_sanitize_js(char*, int, int, int,
fbml_js_sanitizer*, char**, char**)’:
fbml.cpp:1331: error: jump to label ‘exit’
fbml.cpp:1237: error:   from here
fbml.cpp:1317: error:   crosses initialization of ‘char* deflated’
fbml.cpp:1254: error:   crosses initialization of ‘jschar* userbuf_pos’
fbml.cpp:1250: error:   crosses initialization of ‘jschar* this_rep’
fbml.cpp:1249: error:   crosses initialization of ‘size_t this_len’
fbml.cpp:1245: error:   crosses initialization of ‘char* this_replacement’
fbml.cpp:1241: error:   crosses initialization of ‘jschar* prefix’
fbml.cpp:1240: error:   crosses initialization of ‘size_t prefix_len’
fbml.cpp:1331: error: jump to label ‘exit’
fbml.cpp:1232: error:   from here
fbml.cpp:1317: error:   crosses initialization of ‘char* deflated’
fbml.cpp:1254: error:   crosses initialization of ‘jschar* userbuf_pos’
fbml.cpp:1250: error:   crosses initialization of ‘jschar* this_rep’
fbml.cpp:1249: error:   crosses initialization of ‘size_t this_len’
fbml.cpp:1245: error:   crosses initialization of ‘char* this_replacement’
fbml.cpp:1241: error:   crosses initialization of ‘jschar* prefix’
fbml.cpp:1240: error:   crosses initialization of ‘size_t prefix_len’
fbml.cpp:1235: error:   crosses initialization of ‘JSTokenStream* ts’
make[1]: *** [fbml.o] Error 1
make: *** [src] Error 2
Failed to make libfbml.... Aborting

 

错误的原因在于有些变量(如ts, prefix_len等)的生存期包含到1331行的"exit" label,如果在第1232或1237行直接跳到第1331行的"exit" label时,这些变量就没有机会被初始化。

 

10, 修改源文件jsbit.h的bug (libfbml-1.2.0/src/js/jsbit.h)

在第173行代码

JS_STATIC_ASSERT(sizeof(unsigned long long) == sizeof(JSUword));
中删掉一个"long"

否则编译时会提示以下错误:

In file included from js/jsarena.c:50:
js/jsbit.h:173: error: size of array ‘js_static_assert_line_173’ is negative
make[1]: *** [js/jsarena.o] Error 1
make: *** [src] Error 2

 

11, export LDFLAGS="-L/usr/local/lib -lX11 -lXrender"

否则编译firefox时很多符号(libX11.so/libXrender.so里的符号)找不到

 

12,export PATH=/home/tielei/opensrc/php-5.2.6-installed/bin:$PATH

是为了在编译fbml PHP extension时正确调用到刚刚安装好的PHP程序phpize (/home/tielei/opensrc/php-5.2.6-installed/bin/phpize)

 

13,编译libfbml-1.2.0。

./build-all.py

一个命令全部搞定!

这个脚本大概做了三件事:

(a) 将第5步中列出的firefox所依赖的库进行编译,并安装到/usr/local/lib/。

(b) 编译firefox-2.0.0.4 (但没有安装,因为编译libfbml的时候用不到)。

(c) 编译libfbml-1.2.0。将libfbml编译成一个新的PHP extension。

 

注 意要确保自己的主目录下(~/)没有一个叫做.mozconfig的文件,否则编译firefox-2.0.0.4时会去这个文件取回一些配置,造成混 乱。通常如果同时在编译或者编译过某一个firefox的版本,可能会在主目录下留下一个.mozconfig文件,这会对这里的编译造成影响。

 

脚本执行完毕后,会打印出:

Build complete.  You'll need to restart Apache before the new PHP extension can be used

 

14, 检查。

编 译完libfbml-1.2.0后,应该在php的安装目录下会产生一个.so库文件,即 /home/tielei/opensrc/php-5.2.6-installed/lib/php/extensions/no-debug-non-zts-20060613/fbml.so

 

15, 修改php.ini文件。

打开/home/tielei/opensrc/php-5.2.6-installed/lib/php.ini文件,做两个改动:

(a) 找到这一行

extension_dir = "./"

改为

extension_dir = "/home/tielei/opensrc/php-5.2.6-installed/lib/php/extensions/no-debug-non-zts-20060613/"
(b) 增加一行

extension=fbml.so

 

如果不修改php.ini,则apache/PHP找不到新安装好的PHP extension libfbml,调用facebook platform api时会出现如下类似的错误:

Fatal error : Call to undefined function fbml_complex_expand_tag_list_11() in /home/tielei/opensrc/httpd-2.2.9-installed/htdocs/lib/fbml/wrapper.php on line 62

 

16, 检查和修改源文件中所有出现"FBOPEN:SETUP"的地方。

先找到所有的文件:

cd /home/tielei/opensrc/httpd-2.2.9-installed/

grep -r "FBOPEN:SETUP" .

 

所有包含"FBOPEN:SETUP"的文件有:

(a) html/fbopentest/js_typeahead.php

app的名字"fbopentest",可以不做修改

(b) html/fbopentest/demo_libs/server_url.php

修改为:

$YOUR_PLATFORM_SERVER_URL = 'http://192.168.1.102/html';
$YOUR_APP_SERVER_URL = 'http://192.168.1.102/html';

(假定apache server所在机器的IP是192.168.1.102)

($YOUR_PLATFORM_SERVER_URL表示平台服务器的url;$YOUR_APP_SERVER_URL表示app server的url)

(c) html/fbopentest/demo_libs/config.php

这里指明了app fbopentest的api key 和 secret key,可以不做修改。

(d) html/fbopentest/ajax_typeahead.php

不用修改

(e) html/fbml/fbjs_ajax_proxy.php

user ID,可以不做修改

(f) fbopen_data_dump

将该文件里面出现的所有"YOUR_APP_SERVER_URL"都替换成"192.168.1.102/html"

(g) lib/core/init.php

这个文件中"FBOPEN:SETUP"共出现4次。第一次和第四次出现的地方必须要修改,其他两处可以不做修改。

第一次出现处,修改成

$DB_USERNAME = 'root'; // FBOPEN:NOTE - replace here with your own.
$DB_IP = 'localhost'; // FBOPEN:NOTE - replace here with your own.
$DB_PWD = ''; // FBOPEN:NOTE - replace here with your own.
(或者修改成其它任意配置好的用户名、密码)

第四次出现处,修改成

$YOUR_PLATFORM_SERVER_URL = 'http://192.168.1.102/html/';

(注意最后一定要有一个反斜杠)

 

17, 修改canvas.php/fbjs_ajax_proxy.php定义PHP_ROOT。

在html/canvas.php文件开头加入一行:

$_SERVER['PHP_ROOT'] = "/home/tielei/opensrc/httpd-2.2.9-installed/htdocs";

如果想运行ajax功能,则还需在html/fbml/fbjs_ajax_proxy.php文件开头也要加上这一行。

 

 

18, 创建数据表

如果mysql server没有启动,则先启动它

cd /home/tielei/opensrc/mysql-5.0.51a-linux-i686-icc-glibc23

bin/mysqld_safe --user=mysql &

 

执行fbopen_data_dump,创建数据表

cd /home/tielei/opensrc/httpd-2.2.9-installed

/home/tielei/opensrc/mysql-5.0.51a-linux-i686-icc-glibc23/bin/mysql -u root -h localhost < fbopen_data_dump

 

19,修改html/js/base.js

将该文件中的倒数第5行

document.domain = 'facebook.com';

改为

document.domain = '192.168.1.102';

 

否则会违反js的Same-Origin原则。

 

20,修改html/js/fbjs.js

找到这一行

fbjs_ajax.proxy_url = '/fbml/fbjs_ajax_proxy.php';
根据源码解压缩后存放的位置不同,这一行有可能不对。找到fbjs_ajax_proxy.php文件所在的正确位置,加以改正。

在我的环境中,该文件的路径为/home/tielei/opensrc/httpd-2.2.9-installed/htdocs/html/fbml/fbjs_ajax_proxy.php,因此将该行改为:

fbjs_ajax.proxy_url = '/html/fbml/fbjs_ajax_proxy.php';

 

 

21, 再次启动apache server

cd /home/tielei/opensrc/httpd-2.2.9-installed

bin/apachectl -f conf/httpd.conf 

 

22, 测试Facebook Platform API

在浏览器中键入:

http://192.168.1.102/html/canvas.php?fb_app_name=fbopentest&fb_user_id=1240077&fb_url_suffix=apitest.php%3Fparam1%3Dfoo%26param2%26param3%3Dbar

 

还会有simplexml_load_string函数打印出的一些warning message,暂时忽略。

 

23, 测试FBML

在浏览器中键入:

http://192.168.1.102/html/canvas.php?fb_app_name=fbopentest&fb_user_id=1240077&fb_url_suffix=fbml.php

 

24, 同时测试API, FBML和FBJS

在浏览器中键入:

http://192.168.1.102/html/fbopentest/testall.php

 类似资料: