Lloyd.NET

Programing experiments

Zip files after build

One of the pet project I am working on now is an installer application (in D!). One of the problem I need to solve is automatic archival of my files.

Well it turn out that MSBuild (the underlying build tool used by Visual Studio) is quite extensible. While I haven’t read anything which made me a MSBuild master yet, I found this library (msbuildtask) with plenty of MSBuild goodies (including a zip task).

And also a post on Bell Hall’s blog which explain how to take advantage of this task to zip your project output automatically.

Here, I reproduced it below:

Using MSBuild to create a deployment zip

Monday, September 01, 2008

Automated builds are one of the core fundamental musts for software development. However, your build doesn't just have to build the solution and execute your unit tests. For IronEditor, my build also creates two zip files. One zip is the output from the build for archiving purposes, the second is my deployment zip - the zip which actually gets pushed up to CodePlex containing only the files required by the application. In this post, I will cover how you can get MSBuild to zip your build output.

To use zipping functionality within your build scripts, you need to use the MSBuild Community Tasks which is a great collection of MSBuild extensions and a must if you are using MSBuild.

In order to zip your files, you need to specify which files you want to zip. In the script below, I create an ItemGroup called ZipFiles, this includes all the subdirectories (**) and files (*.*) from my Release directory which is my build output folder. I also specify that this group should not include any other zip files. I then create a Builds directory if it doesn't already exist. Finally, I use the Zip task, passing in my ZipFiles ItemGroup which the task uses to know which files to include.

<Target Name="BuildZip" DependsOnTargets="Test">
  <ItemGroup>
      <!-- All files from build -->
      <ZipFiles Include="$(BuildDir)\Release\**\*.*" Exclude="*.zip" />
  </ItemGroup>
  <MakeDir Directories="$(BuildDir)\Builds" Condition="!Exists('$(BuildDir)\Builds')" />
  <Zip Files="@(ZipFiles)"
       WorkingDirectory="$(BuildDir)\Release\"
       ZipFileName="$(BuildDir)\Builds\IronEditor-Build-$(Version).zip"
       ZipLevel="9" />
</Target>

The most important property is the WorkingDirectory, this is the root directory where all the files you want to exist live. If you don't have this set correctly, you will have the additional directories in your zip file which are navigated in order to get to your actual files and just looks rubbish.

My deployment zip also looks very similar and is executed after the above target. The only different is that I individually specify which files and directories to include. For some directories, such as Config, I still include all sub-directories and files it contains as they will all be relevant and required.

<Target Name="BuildInstallZip" DependsOnTargets="BuildZip">
  <ItemGroup>
      <!-- Selected Files -->
      <InstallFiles Include="$(BuildDir)\Release\Config\**\*.*" />
      <InstallFiles Include="$(BuildDir)\Release\LanguageBinaries\**\*.*" />
      <InstallFiles Include="$(BuildDir)\Release\SyntaxFiles\**\*.*" />
      <InstallFiles Include="$(BuildDir)\Release\Fireball.*.dll" />
      <InstallFiles Include="$(BuildDir)\Release\IronEditor.UI.WinForms.exe" />
      <InstallFiles Include="$(BuildDir)\Release\IronEditor.UI.WinForms.config" />
      <InstallFiles Include="$(BuildDir)\Release\IronEditor.Engine.dll" />
      <InstallFiles Include="$(BuildDir)\Release\Microsoft.Scripting.Core.dll" />
      <InstallFiles Include="$(BuildDir)\Release\Microsoft.Scripting.dll" />
      <InstallFiles Include="$(BuildDir)\Release\System.Core.dll" />
  </ItemGroup>
  <MakeDir Directories="$(BuildDir)\Builds" Condition="!Exists('$(BuildDir)\Builds')" />
  <Zip Files="@(InstallFiles)"
       WorkingDirectory="$(BuildDir)\Release\"
       ZipFileName="$(BuildDir)\Builds\IronEditor-$(Version).zip"
       ZipLevel="9" />
</Target>

One thing which tripped me up was that while my ItemGroup was created within a target, it actually has global scope. As such, you need to call the two groups within the two different targets something different.

Once my script has executed, I have two zip files created - one containing everything, the other ready to be released on CodePlex.

image


Categories: Visual Studio | link
Permalink | Comments (0) | Post RSSRSS comment feed

Quick Visual D update

A few last precision before launching into D coding.

 

Visual D configuration

It turns out that, if you have a few project which depends on each other, as in:

image

 

You don’t need to set the library path, include path, etc.… Visual D will take care of that for you!

 

Documentation

Ha well, there is one last thing that is needed before getting started coding D like crazy, it’s good documentation!

The Phobos documentation can be found here.

Well you also need to read about D language syntax! A web exhaustive description can be found there. I should say for such task I like to have a book. I bought this one (there are not that many! ^_^).

I bought the kindle version, then I though better of it (Kindle book are not good at being read back and forth and jumping chapter like crazy, as is needed in a learning process!) and then the paper back version! I left a bad comment because it didn’t answer the question how to compile the damn thing! (which, if you have read my D post so far, we figured out by now!) but I like it, sorry about the comment.

 

Ho, almost missed that, when you “installed” D (unzipped it!) you also installed the offline documentation!
Check out (on your disk)

DROOT/dmd2/html/d/index.html
DROOT/dmd2/html/d/features2.html
DROOT/dmd2/html/d/phobos/phobos.html
DROOT/dmd2/html/d/lex.html

 

Statement of the day

Thanks to the paper version of the D language I was able to browse through all 350 pages of it in an hour (it’s just a book about syntax hey!). I discover a really interesting and innovative statement, a “using” on steroid, scope()

exert from the web site:

Scope Guard Statement

ScopeGuardStatement:
	scope(exit) NonEmptyOrScopeBlockStatement
	scope(success) NonEmptyOrScopeBlockStatement
	scope(failure) NonEmptyOrScopeBlockStatement
 
The ScopeGuardStatement executes NonEmptyOrScopeBlockStatement at the close of the current scope, rather than at the point where theScopeGuardStatement appears. scope(exit) executes NonEmptyOrScopeBlockStatement when the scope exits normally or when it exits due to exception unwinding. scope(failure) executes NonEmptyOrScopeBlockStatement when the scope exits due to exception unwinding. scope(success)executes NonEmptyOrScopeBlockStatement when the scope exits normally.

If there are multiple ScopeGuardStatements in a scope, they are executed in the reverse lexical order in which they appear. If any scope instances are to be destructed upon the close of the scope, they also are interleaved with the ScopeGuardStatements in the reverse lexical order in which they appear.

writef("1");
{
    writef("2");
    scope(exit) writef("3");
    scope(exit) writef("4");
    writef("5");
}
writefln();
writes:
12543

 

Of course there are many more interesting stuff in D, just picking! Have a Go Smile with tongue out! Pun intended!


Categories: D | Visual Studio
Permalink | Comments (0) | Post RSSRSS comment feed

D for .NET programmer

Recently it appeared to me that, with D, I could finally write solve a long standing problem, that is write a good advanced installer.

What appealed to me where the following features:

  • Statically linked. Produce an exe with no dependency! (Save for win32 that is, fair enough!)
  • Elegant syntax on par with C# and Java
  • Compile time executable code, making it easy to include “resource” files (zip and include file to install inside the installer)
  • Finally with a nice IDE and GUI library (almost as good as a slim WinForm)
  • Can directly call into C (I plan to call into the MsiXXX function) at no cost!

So I started to try to use it.

Ho boy, just having 1 program, using 1 custom library to compile was quite an odyssey! Hopefully this blog entry could save future language explorer!

 

1. Installation

First thing first, you’ll need to download and installer the D SDK (the compiler, linker, runtime library, etc… The whole shebang!) That can be found there:

http://www.digitalmars.com/d/download.html

Unzip the latest version of DMD somewhere, you are done! Now that was easy.

And if you heard about DM / DMC, don’t worry about it. It was for D1, just ignore it.

 

2. IDE

Well, arguably you can go with the command line. The compiler flags and linker flags are simple enough. Yet I’m too spoiled by VS, I need my IDE!
In fact, on the D2 page, following the Editor link on the left (in Tools), I found 3 which were attractive: D-IDE, Entice and Visual D.

D-IDE is cool because it’s C# but that’s about it (it’s still basic and buggy, sadly).

Entice is a GUI designer. It was exciting at first, but I deleted it in the end because it is used for DFL or DWT which both requires to overwrite the base runtime library (aka Phobos). Which I don’t quite feel like doing yet.

And, finally, Visual D, a plugin for Visual Studio. Create D projects in Visual Studio, yoohoo! Download and install it now.

image

 

3. My first program

You can create a new module with Visual D (new D project), press F5, and voila, hello D world!

 

Now I wanted to create a GUI Hello world!

I had a look at DFL and DWT. DFL looks lighter / smaller and good enough for my need. Yet they both required Tango, which seem to be a popular D BCL (aka Phobos) replacement. Well that ended it for me. Tango might be popular but I’m not going to replace my BCL when I can’t even compile a(n advanced) program yet (you’ll see my library trouble next).

Finally I found DGui. Looking like WinForm. Depending just on Phobos (the BCL).

I downloaded, unzipped, copied a sample (in the sample directory) into my “hello.d” file and tried to compile.

Now the problems started…

First error would be:

Error    1    Error: module all is in file 'dgui\all.d' which cannot be read    C:\Dev\DTest\DTest1\hello.d    3

 

This is due to the import statement at the top:

import dgui.all;

 

3.a. file and hierarchy structure

D has 2 ‘code unit’ if I may call it that way. Module and package. It’s a bit like classes and packages in Java. A module is everything in one file. I’m not yet sure if the module should be named after the file it’s in, but that, at least, seems to be the convention.

The package is a folder of source code.

When I wrote “import dgui.all” the compiler looked for the module “all” (i.e. the file “all.d”) in the package (i.e. directory) “dgui”.

I need to specify the search path for those modules / packages for this to work. Go to project properties => Configuration => DMD and add the path to the source of the library.

image

Press F5, now we get an other error! (i.e. we progressed!…)

 

3.b. declaration file

So, what’s going on? And why does it look for a ‘.d’ file (a source file! I want to use the library not recompile it!)

Here is what happen, the compiler needs some declaration to describe the function that are going to be called. They could be defined inline in the program (if calling into Win32 from D for example, much like DllImport in C#), but more generally you it will look at declaration file defined by the library. There are 2 options there:

  1. Unlike C, where the developer should maintain and synchronise a definition (header / .h) and an implementation (.c /.cpp) file, D can use a single implementation file for both purpose. Hence it will look in the original D source file.
  2. If there is a need to protect some intellectual property, the developer can an generate an ‘interface file’ when compiling (ordinary D file with the ‘.di’ extension and only declaration inside) and deploy these instead of the source code.

 

3.c. linking

Much like C, C++ and other native environment, compiling D is a 2 stage program. First compiling the source files into object files (.o) and then linking all those files into various target (library (.lib or .dll), executable (.exe)).

But it’s all done on the key stroke of F5, hence a catch all usage meaning of compile for both compiling (making object files) and linking (creating the final output).

When I ‘compile’ now I get those kind of errors:

Error    1    Error 42: Symbol Undefined _D4dgui4form4Form13startPositionMFNdE4dgui4core5enums17FormStartPositionZv    C:\Dev\DTest\DTest1\   
Error    2    Error 42: Symbol Undefined _D4dgui7control7Control4sizeMFNdS4dgui4core8geometry4SizeZv    C:\Dev\DTest\DTest1\   
Error    3    Error 42: Symbol Undefined _D4dgui6button6Button6__ctorMFZC4dgui6button6Button    C:\Dev\DTest\DTest1\   
etc…

And so on.

'Symbol alien_looking_name’ generally mean a linker problem. It just happened that Visual D create a “buildlog.html” as well as a “$(project).build.cmd” file in the output folder. So you can see what command it ran to compile and the link the program.

Now I guess I need to include dgui.lib in my project. So go to project properties => linker and set the libraries  and search path.

image

Now it still doesn’t compile and give me this warning:

Warning    1    Warning 2: File Not Found dgui.lib    C:\Dev\DTest\DTest1\

 

I can see in the cmd file or build log that it build with the following command

Command Line set PATH=C:\D\dmd2\windows\bin;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\\bin;%PATH% set DMD_LIB=;C:\D\dgui\lib dmd …

Now I can see in D Linker’s documentation that DMD_LIB is not used, it is LIB that is used. I guess it’s a little bug with Visual D (maybe it was made for D1?) at any rate, I solved it by setting the whole path to the DGui library!

image

F5… build succeeded!

 

4. Bonus, compile DGui

Well, one could add all the file of DGui in Visual D I guess. But DGui comes with a “dgui_build_rel.bat”, I should use it, don’t you think?

Well all I had to do was to add the path to dmd.exe (i.e. C:\D\dmd2\windows\bin\) to the PATH environment variable.

As found in System Property => Advance System Settings => Advanced => Environment Variables…

image

Now I can just click on the bat file and… DGui build successfully, that was easy! Smile

 

5. Done

That’s it, I show how to install D, install a library and compile a program using it!


Tags:
Categories: D | Source Code | Visual Studio
Permalink | Comments (0) | Post RSSRSS comment feed

Speed up Visual Studio startup

Recently I had Visual Studio freezing every time I opened some project. A coworker had it crash. After some digging I thought of disabling VS  start-up Add-In.

There are so many of them, as you can see in the registry at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages

Anyway, there is no easy way to enable / disable them on an individual basis, but you could just disable them all.

Go to the Tools menu then Options:

image

Then go to Environment / Add-In and uncheck "Allow Add-in components to load"

image 

 

To be honest I have no clue what are all the add-in so disabled, but I haven't noticed any missing feature.
On the other hand I did notice big improvements, such as much faster VS startup and no slow or crashing start-up.

 

Later I discover another “trick” to reset Visual Studio to an almost pristine state. It’s not uninstall/reinstall which not only tool a lot of time but leave all the plugin/add-ons/etc… in place.

It’s resetting VS settings. Just in case you better save your settings before resetting them as well! smile_wink

Here are the steps:

Tools => Import and Export Settings…

image6

And then Reset All Settings

image_thumb2

 

 

And voila!


Categories: Visual Studio
Permalink | Comments (1) | Post RSSRSS comment feed