It is a wrapper around Adobe's fcsh, which gives you back the good thing about mxmlc: it's a simple and traditional command line compiler, which compiles your code and returns back an status code telling you if the compilation was successful or not. This may sound old-fashioned in the current shiny-powerful-and-bloated IDE times, but if you are a hardcore IDE person, you aren't interested in mxmlc nor in fcsh anyway.
If you are interested on mxmlc and fcsh, it's because you either don't like the Flex Builder, or because you realized that calling the IDE from your automated build system is not an option. I'm in both camps: Flex Builder is quite buggy in Linux (admittedly it is marked as an alpha release, but come on, it has been in such state for more than a year now!), and I obviously love continuous integration systems and fully automated build scripts.
Back to where I started: Fortunately Adobe released a command-line flex compiler, in the form of mxmlc, for people like me. Unfortunately, it is painfully slow. That's because its startup time is really bad.
Fortunately, Adobe realized this and released fcsh, which compiles your code and don't throw the precious data away by exiting after finishing. It keeps running, waiting for you to tell it when you want to run the same compilation again. Unfortunately, that doesn't work well for build scripts. Wait, I'm wrong. It doesn't work at all.
Fcshd is my humble solution: a simple wrapper written in Python, which spawns a daemonized fcsh wrapper, and calls it when ran from the command line. Yeah, the typical client/server sort of thing. So the client (which is invoked from the command line) can exit after the server has finished the compilation, while the server can keep the data around in memory. As an extra nicety all comes packaged in the same program, which almost always acts as the client, but if it detects that the server is not running then it forks the server. So you use it like this:
$ fcshd.py "mxmlc /path/to/foo.mxml -o /path/to/foo.swf"
Starting the server, please wait... OK
Loading configuration file [...]
[...]
/path/to/foo.swf (349854 bytes)
(fcsh)
$ fcshd.py "mxmlc /path/to/foo.mxml -o /path/to/foo.swf"
Loading configuration file [...]
Nothing has changed since the last compile. Skip...
/path/to/foo.swf (349854 bytes)
(fcsh)
Final result: You get your compiler output and status code back, while at the same time it runs blazingly fast.
Right now it is only tested with the Flex 2 SDK, but if it doesn't work with Flex 3, it should be really easy to fix that. It surely have a couple of bugs too, which I haven't found yet. Reports and patches are welcomed!


8 comments:
There has been several other attempts at this before. None of them particularly successfull.
What are you building with? Ant or maven? If you are building with maven, and using the flex-mojos plugin, it has integration with the hellfire compiler daemon, which is rather good and fast. It (hellfire) use the Java API to the compiler, to construct a compile server with.
Sweet.
Regards, Tech Per
Yeah, I was aware of the hellfire compiler daemon, but it seemed too java oriented. And the JVM startup time always hurts.
As I'm using rake for build scripting, a simple wrapper seemed like the good solution for us. But for java-oriented build toochains I'm sure that hfcd is a better option.
Hello, thanks for putting htis together, I've been looking for something like this for a while. I'm trying to get it up and running on osx, but am not a big python guy. This is the error I get, any ideas:
Traceback (most recent call last):
File "/usr/local/bin/fcshd.py", line 339, in < module >
sys.exit(main(sys.argv))
File "/usr/local/bin/fcshd.py", line 335, in main
return run_command(command)
File "/usr/local/bin/fcshd.py", line 282, in run_command
output = server.run_command(cmd)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/xmlrpclib.py", line 1147, in __call__
return self.__send(self.__name, args)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/xmlrpclib.py", line 1437, in __request
verbose=self.__verbose
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/xmlrpclib.py", line 1183, in request
self.send_content(h, request_body)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/xmlrpclib.py", line 1297, in send_content
connection.endheaders()
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/httplib.py", line 856, in endheaders
self._send_output()
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/httplib.py", line 728, in _send_output
self.send(msg)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/httplib.py", line 695, in send
self.connect()
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/httplib.py", line 679, in connect
raise socket.error, msg
socket.error: (61, 'Connection refused')
What do you get if you run:
lsof -i :2345
[Assuming that OSX has an lsof command -- I'm not an OSX user]
Looks like either the server had a problem and didn't started up, or it is running but the client didn't waited enough time.
Posting the contents of /tmp/fcshd.log may also help.
Hmm, yeah, there is an lsof, but "lsof -i :2345" returns nothing.
Here is what is in the log:
2008-10-22 10:30:22,096 INFO
return code = 0
process ID = 424
parent process ID = 1
process group ID = 423
session ID = 423
user ID = 502
effective user ID = 502
real group ID = 502
effective group ID = 502
Tester: so the daemon starts, but for some reason is crashing. Unfortunately, I don't have a Mac to test fcshd.py on it.
This might be of some help:
http://code.google.com/p/flex-compiler-shell-daemon/issues/detail?id=2
Good catch Peter, I just applied to patch!
Post a Comment