Labels: c++ (6) scripting (4) the perfect project (3) coding (1) firefox (1) idea (1)
Showing posts with label scripting. Show all posts
Showing posts with label scripting. Show all posts

Friday, September 28, 2007

Idea: background building of Visual Studio C++ projects

Sometimes I come up with crazy ideas about programs or scripts that could do magic.

Since I don't have time or knowledge to implement them all, I decided at least describe them here. Hopefully somebody else finds them useful and decides to make them a reality. In this case, I will be the first to help. When you think of something long enough, it gets more and more details, single blog post cannot describe them all but just some key points only.

CPP background compiler

Ok, today's idea is about compiling source files. I often wish that Visual Studio compiled projects on a background, while you editing them. Of course, the changed files would need to be recompiled. Updating headers would require many cpp files to be recompiled... So what? Those files will take their time anyway, when you press "Build". But if you have most of the files compiled on a background, building the project from IDE would be much faster, since only the recently changed files would need to be compiled and only linkage would left.

Simple and stupid approach: build it all

Just pick up the solution or project and run a batch file which would constantly call devenv with /build switch to attempt to build the project. Make that process idle priority, so it would not affect other programs much.

Visual Studio doesn't like much if you're saving source files during compilation. If that is a cpp file which was saved, then during next build request, it should figure out that obj file has creation time less than cpp and recompile it. Not a big deal, but this shall work only if my following assumptions are true:

  1. Compiler loads entire cpp file into memory before compiling it (including preprocessing)
  2. Obj file creation time equals to the time when file was started to be written on disk, not when it was closed
  3. The time between cpp was loaded into compiler's memory and the time obj file was opened on disk is negligibly small (or even better — obj file is opened before cpp file was read from the disk.

Of course, modifying header may cause more recompilations, since Visual Studio must figure out what cpp files depend on it and recompile them. I don't see much problems, as soon as the assumptions above are ok.

Well, almost no problems. If you update stdafx.h this means you should recompile stdafx.cpp. And if you're recompiling stdafx.cpp this means you should recompile all cpps in the project. I am not sure Visual Studio /build is smart enough to figure that out, so this is better to be tested.

One small thing:

Synchronization with Visual Studio IDE

Having another instance of compiler writing some obj file will prevent Visual Studio to compile that file from IDE. This means we should synchronize IDE with our background script. Practically this means we should stop or kill that background IDE before building project from IDE.

I see this could be done by creating a macro, which would call pskill.exe (written by Mark Russinovich from Sysinternals) before actually starting a build from IDE. To avoid running background compilation script manually after IDE build finishes, we could run it from project post-build event. However this will only work if IDE compilation was successful. Otherwise — alas, I don't see how to call a macro after build finishes with error. Maybe creating IDE add-on would help?

Ok, that seems not too efficient to build an entire project on background, since it will do scanning all of the project files and sometimes that can be a lot. The synchronization problems with IDE make it worse too.

How about we compile only cpps?

We could run compiler itself (cl.exe) on all cpp files of the project, just like IDE does. It would require to pick up project options from vcproj file, also we would need to clean the objs after compiler options were updated in vcproj (and don't forget about IDE environment variables). That seems like more difficult to do, but still nothing too special.

This way IDE would do the linkage and all post-build stuff and our background script would only compile the cpps as they get updated.

Synchronization would be less required, since the background script would do nothing after all cpps are compiled. So every time you start the build, it could just wait until the background script finishes compiling all the recently updated cpps and then start IDE build (presumably only linkage would left at this point). As a signal that he is done, the background script could create an empty file with predefined name in project directory, which could be easily checked by macro for existence. Also, this macro would need to call "SaveAllFiles" manually so background script would not wake up after IDE saves the modified source files before starting a build.

The only thing which makes complicates this approach more is that background script should watch header files too and recompile all affected cpps (having stdafx in mind too), i.e. reproduce more of the IDE logic. Having many nested include files makes this task not so trivial. However still doable.

Sounds familiar?

If we can do pretty much what IDE does with the builds, maybe we could leave it only editing of files and projects and avoid synchronization problems just by relying on background compilation scripts?

We could remap standard shortcuts so they pass commands to our "engine" and even redirect it's output to IDE build windows probably. If that cannot be done with macros, maybe add-on could work instead.

Another thing I often desperately need in Visual Studio is queueing the projects compilation. Usually this is required when you have big solution and few projects you want to be built. You start "Build this project only" on one project and then wait patiently until it finishes, then you run nother project the same way... Of course you can create build configuration and group such projects there. But sometimes it is just "this and that" and not worth creating a configuration for a single case.

So, at this point having a command "add to the building queue" would be perfect, but there is no such thing in IDE (at least in Visual Studio 7.1 aka 2003). But if we had a script-engine capable of building projects, adding some queueing to it would be pretty simple and convenient.

This is pretty close actually to having own IDE for C++ projects, but that is another big idea. =)

Let me know if you implement some of these approaches. Of course, if I ever do this, I will write about it here. Maybe having a plan and design in form of a blog post will make this come true sooner — we'll see…

Saturday, February 10, 2007

My Firefox extensions

I decided to put my list of Firefox extensions here. First, so I can always pick them up and quickly install on a new machine and don't forget anything. Second, probably you find some of them useful for you too! =) Used frequently:
  • Del.icio.us: this one is for bookmarks. I keep most of my bookmarks on del.icio.us now. However sometimes I feel like it's working slower and slower, so I may switch to something else soon, like Google bookmarks. I am sure that if Google ever get del.icio.us instead of Yahoo, the servuce would be much faster and interesting than it is now… Also since del.icio.us bookmarks are public, I am using browser bookmarks for intranet sites at work.
  • Tab Mix Plus: tabs support became standard feature of Firefox 2.0, however I kept using this extension, cause I suspect it provides way more ways for customizing the tabs interface and behavior.
  • Adblock Plus: you set it and forget it, but it saves you from tons of banners over the web. And it disables flash banners too.
  • BugMeNot: just added this one, so can't tell much. It goes to Bugmenot.com and picks up a password for the site which demands free registration. So you don't need to do that manually.
  • Link Alert: displays small icon near the cursor when you place it over the link. The icon gives a hint what the link is pointing to: new window, word or excel document, java script or something else. Sometimes that turns out to be handy.
  • Winestripe: this is not an addon but Firefox 2.0 theme which makes buttons to appear similar to Firefox 1.5. I didn't like those new shadows and glares, so this theme is a must for me. =)
  • IE Tab: let you open some sites in a tab which displayed using IE engine. Useful for ugly sites which are IE-compatible only. Normally I avoid such sites, but sometimes I can't (company intranet again) and this addon strikes.
Used occasionally:
  • Greasemonkey: this one is a hit. It maintains collection of scripts which can tweak any page you are viewing, for example, remove something, add new links or change site layout. There's online library of such scripts too. So far I installed:
  • gTranslate: web translator which uses Google translation service to translate either a highlighted word (no extra pages are opened!) or an entire website. Comes very useful when I suddenly surf to germal or french blog to find answers for my questions...
  • translator: similar to the previous one. Actually I am not sure which one of them I am using when... This addon puts an icon in the status bar so one can select manually languages to translate from and into. Also uses Google.
  • Copy Plain Text: removes formatting when you copy-paste text from web page to some editor, so you won't get crazy fonts, styles or headers pasted in your document.
  • Video Downloader: this one seems to be very popular, but I used it maybe once or twice. The fact is that normally I don't need to download videos from Youtube or whatsoever, I just bookmark them. Only when I need to watch a long video offline I use this addon.
  • keyconfig: I use this one only once and only for single thing — make Ctrl+N open new tab instead of opening new window. I don't want to get used to Ctrl+T, because its more difficult to press =) and because IE uses Ctrl+N.
  • PDF Download: let you decide whether you want to open clicked PDF document in the browser tab or using Acrobat Reader, or just download it. Pretty handy.
  • Sage: RSS reader, pretty simple, fast and snappy. I read all my blogs in Google Reader, because I want to access them from anywhere and this addon stores them locally. However its still handy for intranet blogs (yes, we have them, can you imagine that?), which I don't want to store in Google Reader.
Just in case:
  • Save As Image: Saves entire web page as an image, including scrollable part. Should be very useful for web reviews or web designers. I didn't used it so far, however I just like the idea to have this ability handy.
  • DOM Inspector: another web developer's tool which let you explore the page content and design. Probably it comes in standard Firefox package, I'm not sure.

Sunday, February 4, 2007

Prepare sources in HTML file

This is a quick way to gather all your .h and .cpp files in one HTML file and print them out. dir /o-n /b *.hpp *.h *.cpp | perl -e "print '<html><body><pre>';while(<>){local $/;print'<h1>';print;print'</h1>';open IN, $_;my $t=<IN>;$t =~ s/</&lt;/gs;print $t;}" >src.htm

Saturday, February 3, 2007

Touch for C++ h and cpp files

This is the batch file Touch.bat which I use for creating new files. When you create C++ source file it fills it with custom headers and includes. Pretty handy for adding new source files to Visual Studio projects. =)
@echo off
if exist %1 goto alreadyexist
goto nop >%1
:nop
if "%~x1"==".h" goto horcpp
if "%~x1"==".cpp" goto horcpp
goto :EOF

:horcpp
echo /** >>%1
echo * @file %1 >>%1
echo * >>%1
echo * @version \$Id: Exp $ >>%1
echo */ >>%1
if "%~x1"==".h" goto h
if "%~x1"==".cpp" goto cpp
echo Error, file is expected to be .h or .cpp on this point.
goto :EOF

:h
echo #pragma once >>%1
goto :EOF

:cpp
rem use ^> ^< to escape.
echo #include "StdAfx.h" >>%1
echo #include "%~n1.h" >>%1
goto :EOF

:alreadyexist
echo File %1 already exists, please delete it manually.
goto :EOF