This sounds great, but keeping the software building on all three operating systems can be a challenge. Developers working on one operating system can make changes that work great for them, but break the build on other operating systems or compilers.
Automated build-and-test servers help to some extent, but they can get bogged down. It's better if developers can at least compile the app for two operating systems on their own machine before submitting their changes.
However, Linux and Mac developers don't like having to buy a copy of Windows to run it in a virtual machine on their computers. This is where Wine comes in. Wine is a clean-room, open source, and free reimplementation of the Win32 API on top of the Unix API; it can run the Visual C++ commandline compiler on Linux or Mac OS X without a copy of Windows. This makes the build tools for Firefox happy... except for one thing: wine's implementation of cmd.exe doesn't support all the features used by Firefox's build scripts.
In particular, the batch file start-msvc8.bat doesn't work in Wine because Wine's cmd.exe doesn't support the ( and else commands. Likewise, the vcvars.bat batch file that comes with Visual C++ doesn't work.
Worse, Wine doesn't (or didn't until very recently) have a test suite for cmd.exe, so we don't really know what works and what doesn't.
Your mission, should you choose to accept it, is to improve Wine's cmd.exe so it runs vcvars32.bat and start-msvc8.bat properly without breaking anything. (Bonus points for implementing new features like the calculator built in to set /a.)
To succeed, we'll need to tackle the problem from three different angles at the same time.
The test suite will be a set of batch files and their expected output. They should work identically on the cmd.exe from either Windows or Wine. Here's a prototype of the test suite: cmdtest.tar.gz. The suite consists of the files test-*.cmd and their expected output logs (generated on Windows Vista). There are only two .cmd files at the moment:
Here are some places to get ideas for what tests to write:
I don't remember the *exact* steps now, but the first ones are:It gets really horribly painfully complicated from here by the fact that built-in commands and external commands are treated very differently. For starters, they use different tokenizers (that's why "cd.." is parsed as "cd .." and why "cmd.exe" instead stays whole). Then, most built-in commands have their own command-line parser, some changing the syntax considerably
- join multiple lines (caret escapes newline)
- expand %VARIABLES% (caret escapes %)
- ...
The non-obvious example is "(" - yes, open-parenthesis is a command, yes you can do most "command" stuff with it (included I/O redirection, which unfortunately can get very quirky if you get too creative, like if you try to pipe one "(" into another, and I don't really recommend it), and easily the most powerful one. Its parser digests anything up until an unescaped ")" that occurs outside another built-in command (built-in command parsers nest), and parses multiple lines as multiple statements. It's also the most reliable way to delimit a statement, such as the "true" branch of an IF.
So far, I know of the following shortcomings:
I'm experimenting with a new parser in a tiny prototype parser written in Python. ideas from this should be easy to translate to C if it proves useful.
It may help to use yacc to parse internal commands (wine already eight yacc parsers for various tasks), or then again, maybe the existing builtin command parser is ok. If we do it, we'll probably want to enable it for just one or two builtin commands at first.
So, to avoid that fate, let's get improved parsing into wine's wcmd incrementally. That means something like this:
I'll have a link to a walkthrough for that here soon, too.
Submit your code to wine-patches after it passes review on the team mailing list. (Some features, like set /a, are too big to implement in one week, but you can do at least a trivial implementation for starters.)
Also resubmit your test, with improvements, if it hasn't been accepted yet.
Also, It's likely that the wine maintainer found some issues with your patch, and hasn't committed it yet. Use this week to figure out what he wants and give it to him. (Remember, the maintainer is always right.)
The main repository is of course the git repository at winehq.org. However, because that one is very challenging to commit to, I'm setting up a git repository at http://github.com/dankegel/wcmd-uplift we can use until our code is ready to submit to winehq.
The mailing list ucla-cs130-wine is set up for students currently enrolled in the class. Please use this to ask questions about the project or run ideas past the coordinator or other students.
I've also set up a chat room for this project using IRC; it's at irc://irc.freenode.net/#ucla-cs130-wine
My favorite way to access IRC is with the Chatzilla plugin to Firefox (Tools / Addons / Get Addons, search for IRC). Then you can just click on the above link, and/or add it to your bookmarks.
Sometimes I use IRCII (sudo apt-get install ircii; irc -c '#ucla-cs130-wine' $USER irc.freenode.net) That's handy when I need to use irc without X (e.g., if my ISP is blocking IRC but not ssh, I can use irc at a remote computer via ssh).
Also, in person weekly meetings might be a good idea. If anyone wants those, let's set them up.
wget http://winezeug.googlecode.com/svn/trunk/install-wine-deps.sh sudo sh install-wine-deps.sh(see RecommendedPackages).
git clone git://source.winehq.org/git/wine.git wine-gitThis creates a Wine source tree in a new directory named wine-git.
cd ~/wine-git ./wine programs/cmd/cmd.exe.so
cd ~/wine-git make -k test > log 2>&1(The -k makes it continue past failing tests; the "2>&1 log" redirects both stdout and stderr to a file named "log".) This should take about five minutes. If a test hangs, you may need to kill the process or wineserver from another window.)
To see a list of failures, just look for lines with "Test failed" in them, e.g.
grep "Test failed" log | moreYou can get a count of failures with wc:
grep "Test failed" log | wcYou shouldn't see more than ten or so errors in 32 bit Wine (assuming your have an nvidia graphics card).
Once you have made a change to Wine or its test suite that you're happy with, create a patch (see here and here for how), and make sure the patch applies cleanly to a fresh checkout of the Wine sources, and still builds and runs properly. If you used git to retrieve the sources, you should be able to use 'git diff > my.patch' to create a patch.
Once your patch works, add a changelog entry at the top, giving your name and the license (LGPL), and saying very briefly what it does. Then have a friend review the patch for errors, and clean up anything they found confusing or wrong.
If you're a student working in a structured project, send it to your project leader for review, and clean up any issues they find.
Finally, post it to the wine-patches mailing list, and watch for replies on the wine-devel mailing list.
If the patch isn't accepted right away, don't worry, just address any feedback you're given, and resubmit it once a week or so. Ask on wine-devel if you're unsure what's happening. Continue resubmitting until it makes it in. (Sometimes the Wine maintainer's mailbox overflows, so don't expect approval to be quick or easy.)