Monday, November 12, 2007

Be aware that both cscope and make honor $SOURCEDIRS

Emerging media-sound/cdparanoia failed lately on my box when I was running "sudo emerge...".
The error was that an archive file was missing.
However, I didn't find any bug report related to that on bug.g.o.
So, I decided to take a look myself. I found that if I emerged it using root user, then everything was ok. So, I suspected this might have something to do with my environment setting, coz I don't reset env for users in wheel group(so that I can "USE=... sudo emerge").
I ran ebuild unpack/install/compile/install separately using normal user and root to determine which stage caused the difference. Finally, I found the difference happened when "make"ing in the paranoia directory. An target called "lib" defines the rule to build that archive file. The lib is not a real file, however it is not labeled as PHONY. Apparently, the target is not run. But why?
I straced make as normal user. I found something strange. The strange thing was make looked in /usr/src/linux for "lib" and found it - everyone has it. So make believed that lib was already there, no need to make. That's why the archive file was missing. But why looking for lib under /usr/src/linux?
I ran "env | grep '/usr/src/linux'", and found SOURCEDIRS is defined to that value. It is intended to be used by cscope.
Up till this moment, everthing is clear.
The lessons we can learn from this incident:
1. Not resetting env for sudo may cause problems
2. If a target is not a real file, lable it as .PHONY in makefile
3. Be aware that both cscope and make honor SOURCEDIRS.

the myths about stardict-3.0.1's text-to-speech feature

stardict-3 is now available via gentoo-china overlay. (I wish I could pass ebuild quiz soon and become stardict's maintainer in gentoo...)
stardict-3 has got tts feature. It could use festival or espeak to play an arbitrary sequence of characters.
There are two ways to use this feature. One way is via tts plugin, one for each tts engine. In fact, tts plugin does more than that - it could set the voice of its corresponding tts engine as well. The other way is to specify the command to play yourself, and there are two options which you can choose from, "echo %s | festival --tts" and "espeak %s".
My experience is the first way has priority over the latter one.
My suggestion is to use the latter one. Because tts plugin's functionality is redundant. You can choose tts engine's voices anyway. And you can use tts engine without them. Moreover, the festival plugin will segfault the program[1]. So, IMHO, the tts plugins are dispensable. So in my stardict-3.0.1-r2.ebuild, I disabled festival and espeak plugin unconditionally. The festival and espeak USE flag are still there, which control whether we have the runtime dependency of festival and espeak.

[1]For those who might be interested in the details of festival plugin problem: At first, I didn't sort the whole thing out. I thought festival plugin is required. So I tried to solve it. After some hard work, I found that the problem lies in speech-tools. speech-tools provides There is a "backtrace" symbol in festival plugin is dynamically linked with When loading festival plugin in stardict startup, the "backtrace" symbol will be magically solved to the backtrace variable in This never happened in festival's startup. Then I found that the backtrace variable is in fact only used in one compilation unit. So adding a "static" to it will solve the problem. Although the problem is solved, I still don't understand why there is no such problem with festival's startup.Then I found another problem. If the festival plugin is initially disabled, when you are trying to enable it while stardict is running, the program will segfault again. But at this time I decided to give up. Because at this time I have already understand how the whole thing works, i.e. the plugin is not required.

--- speech_tools/siod/ 2007-11-11 22:49:27.000000000 +0800
+++ speech_tools/siod/ 2007-11-11 15:52:33.000000000 +0800
@@ -128,7 +128,7 @@
long interrupt_differed = 0;
LISP oblistvar = NIL;
LISP current_env = NIL;
-LISP backtrace = NIL;
+static LISP backtrace = NIL;
LISP restricted = NIL;
LISP truth = NIL;
LISP eof_val = NIL;