May 12

杂记两则

很久没有发文了。。。于是记一下最近捣鼓项目的经验。。。

1、缩小Mplayer体积

Mplayer默认编译版有10MB之巨。。。其实有很多功能是不需要的,特别是我这个项目定死了视频的编码,更是可以把没用的编码全部禁用。要点有两个:

(1) FFMpeg单独编译

Mplayer虽然内置了FFmpeg,但是配置非常不方便,而且没用的功能禁用不干净。。。单独编译的时候,只需要几行参数就可以禁掉所有东西,在后面再启用需要的功能就可以了。

编译的时候要注意,光禁用_a结尾启用_so结尾的参数还不够,要手动指定库路径才能正常链接(也可能是我这的MinGW有问题。。。)。如:

--disable-libavutil_a   \
--disable-libavcodec_a   \
--disable-libavformat_a  \
--disable-libpostproc_a   \
--disable-libswscale_a    \
--enable-libavutil_so   \
--enable-libavcodec_so   \
--enable-libavformat_so  \
--enable-libpostproc_so   \
--enable-libswscale_so    \
--extra-libs-mplayer="/local/lib/libavformat.a /local/lib/libavcodec.a /local/lib/libswscale.a /local/lib/libpostproc.a /local/lib/libavutil.a" \

另外库的顺序非常重要,错了链接就会不成功。(想当初我试了N次才试出这个顺序。。。

(2) 编译后删除所有内嵌符号

这个是我最近才发现的,原来gcc会在输出文件中内嵌调试符号。。。直接导致程序大幅膨胀。这些符号基本是没有用处的(很少会有人在Windows用gdb调试吧。。。),完全是浪费空间。

还好删除符号也很简单,在Cygwin或MinGW环境下运行以下命令就可以了:

strip --strip-all <输出文件名>

弄完这些之后,MPlayer就只剩下5MB左右了,足足缩小了50%,而且基本的功能也不会缺少。

 

 

2、使Mono支持加载路径包含非ASCII字符的程序集

于是这个应该是很老的bug了,但是修复起来很简单。。。patch已经发到mono开发组了,希望下个版本可以包含吧。

2.4的Patch:

--- E:/image-2.4.c	四 四月 30 15:39:45 2009
+++ E:/image.c	四 四月 30 15:46:49 2009
@@ -878,11 +878,23 @@
 	MonoImage *image;
 	FILE *filed;
 	struct stat stat_buf;
-
+#ifdef PLATFORM_WIN32
+	gsize bytes_written;
+	gchar *fname_ansi = g_locale_from_utf8 (fname, -1, NULL, &bytes_written, NULL);
+	filed = fopen (fname_ansi, "rb");
+	g_free (fname_ansi);
+	if (filed == NULL){
+#else
 	if ((filed = fopen (fname, "rb")) == NULL){
+#endif // PLATFORM_WIN32
 		if (IS_PORTABILITY_SET) {
 			gchar *ffname = mono_portability_find_file (fname, TRUE);
 			if (ffname) {
+#ifdef PLATFORM_WIN32
+				gchar *ffname_utf8 = ffname;
+				ffname = g_locale_from_utf8 (ffname_utf8, -1, NULL, &bytes_written, NULL);
+				g_free (ffname_utf8);
+#endif // PLATFORM_WIN32
 				filed = fopen (ffname, "rb");
 				g_free (ffname);
 			}

 

由于在SVN的代码中fopen的调用改到另一个地方了,所以需要另一个patch:

--- E:/mono-filemap.c	三 四月 29 20:05:26 2009

+++ E:/mono-filemap-2.c	三 四月 29 20:11:35 2009

@@ -25,7 +25,17 @@

 MonoFileMap *
 mono_file_map_open (const char* name)
 {
-	return (MonoFileMap *)fopen (name, "rb");
+#ifdef PLATFORM_WIN32
+	// fopen in msvcrt.dll accepts ANSI string, but name is UTF-8 encoded
+	gsize bytes_written;
+	gchar *name_utf8 = name;
+	name = g_locale_from_utf8 (name_utf8, -1, NULL, &bytes_written, NULL);
+#endif // PLATFORM_WIN32
+	MonoFileMap *map = (MonoFileMap *)fopen (name, "rb");
+#ifdef PLATFORM_WIN32
+	g_free (name);
+#endif // PLATFORM_WIN32
+	return map;
 }
 
 guint64 

 

应用之后参照Mono主页的教程在Cygwin编译就可以了。(编译好要记得删符号。。。不然mono.dll会比发布版大N倍。。。