Using a Makefile to launch Oslo’s executables from Intellipad
In my previous post I mentioned Bryan Sumter’s GUI tool, which executes the right command from the configuration of the GUI. Sometimes I love my keyboard more than I love my mouse, so I decided to have a try on integrating the tool’s functionality into Intellipad using a Makefile to configure the commands. (Scroll down for download!)
Developing:
First of a snippet from the input Makefile:
###################################### # m builds +m #executable @All #target files = m\*.m out = bin\mx\Image.mx package = Image @AllToRepository files = m\*.m out = bin\sql\ImageRep.sql target = Repository @AllToTsql files = m\*.m out = bin\sql\ImageTsql.sql target = Tsql10
After specifying the input file, we continue..
- Create MGrammar to parse Makefile to a graph.
- Compile MGrammar to Mgx or MgxResource to use in the runtime.
- Build a runtime: at first I wanted to build a runtime in Intellipads scriptengine (IronPython), but I encountered errors on DynamicParser.Parse(), which I couldn’t resolve. Since IronPython was no use for me at the moment, I used the .NET 3.5 Console Application (mmake.exe <executable>.<target>) to parse the graph and execute the build command with the proper parameters from the graph.
- Create a new Minibuffer command in IronPython which takes a <executable>.<target> as parameter (eg m.All). A new process will be created to call mmake.exe m.All and its stdout will be redirected to a new BufferView in Intellipad.
Python Magic
FindHelper.py
from Microsoft.Intellipad.Host import HostWindow from System.Windows import MessageBox, MessageBoxButton, MessageBoxImage from System.Diagnostics import Process, ProcessStartInfo from System.IO import Directory, Path ... def BuildImpl(activeView, target): filePath = GetFriendlyFilePath(activeView.Buffer.Uri.AbsolutePath) if filePath.find("Makefile") >= 0: hostWindow = HostWindow.GetHostWindowForBufferView(activeView) buildBuffer = Common.BufferManager.GetBuffer(System.Uri('transient://build')) Common.Clear(buildBuffer) view = Common.GetView(hostWindow, buildBuffer) if view is None: hostWindow.ShowInRoot(buildBuffer, 40.0) fileDir = Path.GetDirectoryName(filePath) (exitCode, stdout, stderr) = RunBuildCommand("mmake", fileDir, target) Common.Write(buildBuffer, stdout + "\n" + stderr) else: message = "Error: Makefile needs to be in the active buffer." MessageBox.Show(message, IntellipadMessageBoxTitle , MessageBoxButton.OK, MessageBoxImage.Information) def GetFriendlyFilePath(fileUri): path = str(fileUri).replace('%20', ' ') return path.replace('/', '\\') def RunBuildCommand(cmd, pwd, args): processStartInfo = ProcessStartInfo() processStartInfo.WorkingDirectory = pwd processStartInfo.FileName = cmd processStartInfo.Arguments = args processStartInfo.UseShellExecute = False processStartInfo.RedirectStandardOutput = True processStartInfo.RedirectStandardError = True process = Process() process.StartInfo = processStartInfo process.Start() process.WaitForExit() stdout = process.StandardOutput.ReadToEnd() stderr = process.StandardError.ReadToEnd() return process.ExitCode, stdout, stderr
MiniBufferCommandSetup.py
def Build(target): FindHelper.BuildImpl(MiniBufferHelper.GetActiveView(), target)
Running the Makefile:
When I use Intellipad to work on my grammars and models, I have the following directory setup:
Now open up the Makefile in Intellipad:
Note: All paths specified in the Makefile are relative to the path of the Makefile.
Hit Ctrl+/ to bring up the Minibuffer and type: Build(’<executable>.<target>’)
Note: Intellipad needs to know what directory the Makefile is in, so the Makefile buffer should be active (selected) before bringing up the Minibuffer.
Command will run and output to a new BufferView:
Download:
- Sample project directory (Makefile and samples from Oslo SDK 1.0 for sample builds).
- mmake (1 runtime, 1 mgx and 2 .py): Extract archive in %PATH_TO_OSLO_SDK%\Bin
Install notes:
- Add %PATH_TO_OSLO_SDK%\Bin to system var: PATH
- Backup .py files in case Intellipad stops working: FindHelper.py and MiniBufferCommandSetup.
%PATH_TO_OSLO_SDK%\Bin\Intellipad\FindHelper.py
%PATH_TO_OSLO_SDK%\Bin\Intellipad\Components\Microsoft.Intellipad.Scripting\PrivateScripts - Write permission errors on %PATH_TO_OSLO_SDK%: fix directory settings.
What’s next?
- Hyperlinks on buildtargets in Intellipad: click to compile.
- Resolving IronPython issues with DynamicParser.Parse().
- Build a horizontal DSL instead of a vertical DSL for Makefiles.
Bugs and errors:
Post bugs or suggestions in the comments or drop me a line via email. :-)
References:
- http://blogs.msdn.com/Intellipad/
- http://www.ironpython.info/index.php/Contents
- http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2256



