I am investigating using PhoneGap as a platform for building mobile apps for several operating systems including Android. While doing so I have ran into various issues, and this article is intended to help others avoid the same headaches (with a focus on Android).

PhoneGap vs Cordova

The PhoneGap installation documentation says you could install PhoneGap using this command (will come back to that later).

But if you check the documentation or take various online tutorials you’ll notice they say you should install and use cordova. So what is PhoneGap and what is Cordova and which one should you use?

The best explanation comes from the PhoneGap itself:

PhoneGap is a distribution of Apache Cordova. You can think of Apache Cordova as the engine that powers PhoneGap, similar to how WebKit is the engine that powers Chrome or Safari.

Over time, the PhoneGap distribution may contain additional tools that tie into other Adobe services, which would not be appropriate for an Apache project. For example, PhoneGap Build and Adobe Shadow together make a whole lot of strategic sense. PhoneGap will always remain free, open source software and will always be a free distribution of Apache Cordova.

Currently, the only difference is in the name of the download package and will remain so for some time.

In summary, PhoneGap is a distribution of Cordova and for the time being there is no other difference than the name of the package.

(Bonus read: PhoneGap or Cordova? Don’t confuse and tell me the differences!)

The question is then, which one should you use? If you plan to use Adobe’s utilities and services such as PhoneGap Build, then you should use PhoneGap. Otherwise you could pick Cordova. That is what I picked.

(Bonus read: Apache Cordova vs Adobe PhoneGap: the differences and which one to use)

Pre-requisites

In order to install either PhoneGap or Cordova you need to first install Node.js. Node.js is is a cross-platform runtime environment and a library for running applications written in JavaScript outside the browser.

  1. download and install Node.js
  2. add Node.js installation folder (e.g. C:\Program Files\nodejs) to the PATH environment variable

Installing Cordova

To install Cordova run this command in a console:

The version I have installed is 3.5.0. The rest of the article relates to this version of Cordova.

Dependencies for Android

In order to be able to create and build for Android you need additional components.

  • Java
  • Apache Ant, a Java library and command-line tool for building software
  • Android SDK that provides libraries and tools for building, testing and debugging apps for Android

However, just installing these components is not enough. You need to set-up several environment variables, as they are required by Cordova/Phonegap.

  • create a variable called JAVA_HOME and set it to the Java installation folder (e.g. C:\Program Files\Java\jdk)
  • create a variable called ANT_HOME and set it to the Apache Ant installation folder
  • create a variable called ANDROID_HOME and set it to the Android SDK installation folder

After you have created these environment variables you also need to update the PATH variable to enable all these command line tools to be run from a console. Add the following paths to PATH:

Just having the Android SDK installed is not enough. You need to use the Android SDK Manager to install the appropriate tools for your Cordova version. For 3.5.0 the target API is 19 (or Android 4.4.2). When you install the tools make sure you also install a system image so you could create an Android emulator later. (Note that installation may take a while.)
android19
The next step is creating a virtual device for Android. You can run the following command to open up the Android Virtual Device Manager.

android-avd

Having done all this you can go ahead and create a cordova/phonegap application.

Create a HelloWorld application

To create, build and run a first cordova application execute the following commands in a console:

  1. create an application called HelloWorld
  2. edit the application index.html page replacing the text of the text of the “event received” class paragraph:

    with

  3. add the Android platform to the application

  4. build the application for Android:

  5. run the application in an Android emulator

Here is a screenshot of the Android application running in the emulator.
cordova-hw

Troubleshooting

If you missed any of the steps described in this article you will run into various errors when you try to create, edit, build or emulate your application. Below are several possible problems you may encounter and their solution.

Missing Apache Ant

When you try to add a platform to your application you may get this error message:

Error : Executing command ‘ant’, make sure you have ant installed and added to your path.

This is either because you did not install Apache Ant or because you have not setup the environment variables as described above.

Error querying Android targets

When you try to add a platform to your application you may get this error message:

Checking Android requirements…
(Error: An error occurred while listing Android targets)

This is either because you did not install the Android SDK or because you have not setup the environment variables as described above.

Missing Android target

When you try to add a platform to your application you may get this error message:

Error: Please install Android target 19 (the Android newest SDK). Make sure you have the latest Android tools installed as well. Run “android” from your command-line to install/update any missing SDKs or tools.

This is because you do not have the appropriate Android tools required by the installed cordova/phonegap version. For Cordova 3.5.0 the required platform tools are version 19 or Android 4.4.2. You can use the SDK Manager to install the appropriate tools.

No emulator available

When you try to emulate your application you may get this error message:

ERROR : No emulator images (avds) found, if you would like to create an avd follow the instructions provided here: http://developer.android.com/tools/devices/index.html
Or run ‘android create avd –name –target ‘ in on the command line.

This is because no emulator is defined. You need to use the Android Virtual Device Manager to create one or more emulators.

Using Eclipse

You probably do not want to do everything from the command line and plan to use an IDE. Eclipse comes bundled with everything you need for developing for Android. See the following references for using Android with Cordova.

, , , , , Hits for this post: 377 .

Visual Studio “14″ CTP ships with a refactored C Runtime. The first thing you’ll notice is that msvcrXX.dll has been replaced by three new DLLs: appcrtXX.dll, desktopcrtXX.dll and vcruntimeXX.ddl (where XX stands for the version number so in this version it’s appcrt140.dll, desktopcrt140.dll and vcruntime140.dll).

crtdlls
You can see in this image that both desktopcrt140.dll and vcruntime140.dll depend on appcrt140.dll.

These three new DLLs export run-time routines in different categories, with some of them overlapping, as shown by the bellow table (assembled by directly analyzing the exports of the three modules).


Function

Appcrt140.dll

Desktopcrt140.dll

Vcruntime140.dll
Buffer Manipulation
Byte Classification
Character Classification
Console and Port I/O
Data Alignment
Data Conversion
Debug Routines
Directory Control
Error Handling
Exception Handling
File Handling
Floating-Point Support
Low-Level I/O
Process and Environment Control
Robustness
Searching and Sorting
Stream I/O
String Manipulation
System Calls
Time Management

Breaking CRT routines in several DLLs is not the only change. The CRT has been rewritten for safety and const correctness. Many of the routines have been re-written in C++. Here is a random example: the _open function, that was available in open.c was implemented like this in Visual Studio 2013:

In Visual Studio “14″ CTP it is available in function appcrt\open.cpp and looks like this:

UPDATE

To read more about the refactoring see the VC++ team’s blog posts:

, , , , Hits for this post: 2572 .

Visual Studio 2012 introduced a new framework for writing debugger visualizers for C++ types that replaced the old autoexp.dat file. The new framework offers xml syntax, better diagnostics, versioning and multiple file support.

Visualizers are defined in XML files with extension .natvis. These visualizers are loaded each time the debugger starts. That means if you make a change to visualizers, it is not necessary to re-start Visual Studio, just re-start the debugger (for instance detach and re-attach the debugger to the process you debug).

These files can be located under one of these locations:

  • %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
  • %USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
  • VS extension folders

In Visual Studio “14″ CTP (in response to a UserVoice request) these files can also be added to a Visual C++ project for easier management and source control integration. All you have to do is add the .natvis file to your .vcxproj file.

Here is an example. Suppose we have the following code:

If you run this in debugger you can inspect the value of p and it looks like this:
natvis1

To change the way the point objects are visualized create a file called point.natvis with the following content:

Add this file to the project.
natvis3
When you run the application in debugger again the point object is visualized according to the per-project .natvis file.
natvis2

UPDATE
There are two things to note:

  • changes in the natvis files are now picked up automatically by the debugger; you no longer need to stop the debugging session and then start again if you make changes to a natvis file
  • natvis files from the project are evaluated after all the other files from the other possible locations; that means you can override existing (general) visualizers with project-specific visualizers

For more see Project Support for Natvis.

, , , , , Hits for this post: 2504 .

Visual Studio 2012 provides support for new features, such as code review and feedback through the use of the Work Item tracking system in TFS. (You can read more about it in this article New Code Review feature in Visual Studio 2012).

However, to be able to use these features you must use a process template that supports them. If you try to access these features without upgrading the process template you get errors.

This feature can’t be used until your Team Foundation administrator has enabled it on the team project.

To use My Work to multi-task and manage your changes, you must enable the feature on the server.
Click here to enable the new features

features1
features2

The error in the verification step for configuring the team project happen because an old process template is in use.

If your current process template is MSF for Agile Software Development version 4.x then you need to follow the steps in this article: Update a Team Project Based on an MSF v4.2 Process Template.

To being able to update, you first have to download the latest version of the process template. You can do this from Visual Studio. Go to Team > Team Project Collection Settings > Process Template Manager and download the template.
updatetemplate2

After you have the process template files go ahead and update according to the steps defined in the before mentioned article. However, there is a missing command in the first step of the process. You need to change an additional system field than those mentioned in the article:

If you need to do this for multiple projects then you’ll have to run most of these steps for each project. So here are two batch files with commands you need to run:

  • update the Team Project collection (run only once):

    Note: Make sure you set the correct URL to your collection and replace TemplateDir with the actual path of the process template that you downloaded.

  • Update the Team Project (run once for each project)

    You execute the batch passing the name of the project (in quotes if it contains spaces).

After these commands have executed successfully you can go ahead and use the new features.
updatetemplate3

, , , , , Hits for this post: 4838 .

My first Windows Store app (for Window 8.1) is now available in Windows Store. It’s called Your Chemical Name and shows names (and text) using chemical elements symbols in the Breaking Bad style.

yourchemicalname11

The application allows to:

  • customize the appearance of text, colors, background
  • customize the position of the text on the background
  • save image to a file
  • post image on a facebook album
  • share image with other apps

yourchemicalname12

yourchemicalname13

yourchemicalname14

You save the images to disk or share them on facebook or with apps supporting the Windows Share Charm.

yourchemicalname15

Here are a few screenshots:
yourchemicalname2

yourchemicalname3

yourchemicalname5

More about the application here.

Download Your Chemical Name from Windows Store.

, , , , , , , Hits for this post: 6694 .

Windows 8 features a Settings charm to display both application (the top part) and system (the bottom part) settings (you get it from swiping from the side of the screen). The system provides two entry points, Permissions and Rate and Review, the later only for applications installed through the store.

You can customize the settings charm by adding new entry points. For instance, you may want to add an About pane. If your application uses network capabilities then you have to add a privacy policy, otherwise your application will not pass the Windows Store Certification.

charms settingscharm6

In this post I will show how you can add new entries to the settings charm for Windows 8.1 applications (this won’t work for Windows 8 applications). We have to use two classes:

  • SettingsPane: enables the app to control the Settings Charm pane. The app can add or remove commands, receive a notification when the user opens the pane, or open the pane programmatically.
  • SettingsFlyout: represents a control that provides in-context access to settings that affect the current app. This class is new to Windows 8.1

The following code adds a new entry to the settings pane called Privacy policy and provides a handler for the command. In the handler we create a new instance of a SettingsFlayout and show it.

The text of the privacy policy is kept in a text file under the Settings folder. We asynchronously open and read the content of the file and when the text is available we create a new TextBlock control and use it as the content of the flyout content control.

Then we have to initialize the settings pane when the application starts.

When you start the application and swipe the right edge of the screen the charms bar shows up. Opening the Settings charm will now show two entries for the application: Privacy Policy and Permissions.
settingscharm2 settingscharm3

The next sample shows how to add an About page. It’s very similar actually.

Notice that the entries in the settings charm appear in the order they where added.
settingscharm4 settingscharm5

The content of the flyout can be any visual object (the simple TextBlock is used only for demo purposes). It is also possible to customize the flyout header, icon, background, etc. Here is the same About page with additional flyout settings.

settingscharm7

Here is some additional reading: Guidelines for app settings (Windows Store apps).

, , , , , Hits for this post: 7971 .

In WPF, Silverlight and Windows Phone it is possible to render a visual object into a bitmap using the RenderTargetBitmap. This functionality, that I find pretty basic, was not available for Windows Store applications. Fortunately, Windows 8.1 provides that functionality for Windows Store applications too, through the same RenderTargetBitmap class.

There are some limitations though:

  • it should be used in the code behind (not declared in XAML) because you have to call RenderAsync
  • collapsed visual objects are not rendered (only visible ones)
  • in rare circumstances the content can be lost due to the interaction with lower level systems; in this case a specific exception is triggered
  • the rendered target bitmap does not automatically scale when the current DPI settings change
  • the maximum rendered size of a XAML visual tree is restricted by the maximum dimensions of a DirectX texture

Here is a demo Windows Store application that has several controls and a button that when pressed a screenshot of the area shown in red (it’s a grid) is taken. The bitmap is saved on disk, but also displayed as the source for the image control shown in the preview area.

wsas1

The handler for the Click button even looks like this:

SaveScreenshotAsync is an async method that takes the reference to the FrameworkElement to be rendered to a bitmap (in this case the constrolsGrid) and returns a Task<RenderedTargetBitmap> that can be awaited on. As soon as we have the bitmap we set it as the source for the image control (imagePreview).

wsas2

SaveScreenshotAsync is an async method that takes the FrameworkElement to be rendered to a bitmap and returns a Task<RenderedTargetBitmap> that can be awaited on. This method first prompts the user to select a destination file for the rendered bitmap. When the file is available it calls SaveToFileAsync to rendered the bitmap and write it to the file.

SaveToFileAsync is an async method that takes the FrameworkElement to be rendered to a bitmap and the StorageFile when the bitmap is to be saved and returns a Task<RenderedTargetBitmap> that can be awaited on. The file is opened asynchronous for read-write access and the returned IRandomAccessStream is passed further together with the framework element and the bitmap encoder id (that specifies how the bitmap should be encoded, i.e. BMP, JPEG, PNG, GIF, etc.) to CaptureToStreamAsync.

CaptureToStreamAsync creates a new RenderTargetBitmap object and calls RenderAsync to render the visual tree of the framework element to a bitmap. After the bitmap is rendered it retries the image as a buffer of byes in the BGRA8 format. It then asynchronously creates a BitmapEncoder for the IRandomAccessStream stream that it received as an argument, it calls SetPixelData to set the pixels data (notice the BitmapPixelFormat.Bgra8 parameter that matches the pixels format returned by GetPixelsAsync) and later asynchronously flushes all the image data, basically writing it to the file. It then returns that RenderTargetBitmap object that it created, which is used eventually as the source for the image control.

Here is how the saved JPEG image (also seen in the preview screenshot above) looks likes:
wsas3

You can check the source code of the attached WinRT Screenshot demo (361). It requires Visual Studio 2013 and Windows 8.1.

, , , , , , Hits for this post: 9067 .

A friend of mine recently proposed the following problem on twitter:

I didn’t pay much attention to his warning and fell for the trap. I though I could write a small program in two minutes to compute the series and find what was the value of x[80]. So here is (a slightly modified version of) the C++ code that I put together in a couple of minutes.

C++

When I ran it I was surprised to notice that the series was converging to 100 by x[26].

Actually, the initial program didn’t call std::setprecision and the numbers you get without that are less precise, but that doesn’t change the convergence, since it is just a printing artifact.

Finding the series interesting I searched a bit and then I understood his warning. I found this was a well known problem proposed around 1980 by Jean-Michel Muller and discussed in several papers by Prof. W. Kahan.

Given the function
Œ(y, z) := 108 – ( 815 – 1500/z )/y
and initial values x0 := 4 and x1 := 4.25 , define xn+1 := Œ(xn, xn-1) for n = 1, 2, 3, … in turn.
Our task is to compute xN for some moderately big preassigned integer N, say N = 80 .

For details see How Futile are Mindless Assessments of Roundoff in Floating-Point Computation? and Three Problems for Math.

This exercise is intended to show the problem that arises in using floating-point numbers. The float and double (both an IEEE Standard for Floating-Point Arithmetic, IEEE 754) representations use inverse powers of 2, which means most numbers require a an infinite number of bits for a precise representation. Numbers such as 0.25 or 0.875 can be exactly encoded as 1/4 and 1/2+1/4+1/8, but numbers such as 0.10 cannot be encoded with a finite sum of such terms. The result is problems with accuracy of calculations. Rand-offs can propagate through calculations in unexpected ways, just like Muller’s recurrence shows.

The actual limit of Muller’s series is not 100, but 5.

I was curios then how the decimal type from .NET compares to double. decimal (that uses base 10 instead of 2) has more precision (but a smaller range) than float or double which makes is more suitable for some applications, such as financial ones. (For a discussion of when to use decimal and when to use double see decimal vs double! – Which one should I use and when?).

So here is my C# program that uses decimal.

The output of this program is:

This represents and improvement, but in the end suffers from the same accumulated round-offs problem. It takes more iterations, but eventually the series also converges to 100.

My friend then suggested trying a data type that doesn’t suffer from rounding issues. Such a type is BigRational for F# (it can be used with any .NET language). It is available in the F# PowerPack that is an open-source project available on CodePlex. Below is the F# equivalent of the previous program that uses BigRational.

The output looks like this:

Now this is a totally different story. The values converge to the expected value of 5.

You probably noticed the casting to double for printing. It is necessary because otherwise the output would look like this:

That isn’t very helpful. I can’t even read these insane large numbers, not to mention dividing them. So to get the actual real number and be able to compare with the previous programs a conversion to double is necessary.

As I mentioned earlier, BigRational can also be used from C#.

It yields the very same output as the F# program so I will not list it again. However, below is a comparison table with the results for various number data types.

index C++ with float C++/C# with double C# with decimal C#/F# with BigRational
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
4
4.25
4.47058868408203
4.64474487304688
4.77070617675781
4.85921478271484
4.98312377929688
6.39543151855469
27.6326293945313
86.9937591552734
99.2555084228516
99.9625854492188
99.9981307983398
99.9999084472656
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
4
4.25
4.47058823529412
4.64473684210522
4.77053824362508
4.85570071256856
4.91084749866063
4.94553739553051
4.966962408041
4.98004220429301
4.98790923279579
4.99136264131455
4.96745509555227
4.42969049830883
-7.81723657845932
168.939167671065
102.039963152059
100.09994751625
100.004992040972
100.000249579237
100.00001247862
100.000000623922
100.000000031196
100.00000000156
100.000000000078
100.000000000004
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
4
4.25
4.47058823529411764705882353
4.64473684210526315789473686
4.77053824362606232294617603
4.85570071258907363420428376
4.91084749908279320044042857
4.94553740412391672477683015
4.96696258176270059878160878
4.98004570135563116267108889
4.98797944847839228829979003
4.99277028806206866201151005
4.99565589150664533306792637
4.99739126838157043427422171
4.99843394394934565979621707
4.99906007206149646425952424
4.99943593895922460992955065
4.99966156035548033890851805
4.99979762579572007199519838
4.99989263769854913604459541
5.00021692999623515255759378
5.00575688343630115907717069
5.11585535860978057839952266
7.26513170553842597520695497
36.178328937337879304087182981
91.17958879988455033108590199
99.51631713443793014723080822
99.97569833055963020623148188
99.99878462167868201734350518
99.99993923036059445960870932
99.99999696151664049461733529
99.99999984807584112595945239
99.99999999240379245628007687
99.99999999962018963513083004
99.99999999998100948212683970
99.99999999999905047411745292
99.99999999999995252370620598
99.99999999999999762618532030
99.99999999999999988130926632
99.99999999999999999406546333
99.99999999999999999970327317
99.99999999999999999998516366
99.99999999999999999999925818
99.99999999999999999999996291
99.99999999999999999999999815
99.99999999999999999999999991
100.00000000000000000000000000
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
4
4.25
4.47058823529412
4.64473684210526
4.77053824362606
4.85570071258907
4.91084749908279
4.94553740412392
4.9669625817627
4.98004570135563
4.98797944847839
4.99277028806207
4.99565589150663
4.99739126838134
4.99843394394482
4.99906007197089
4.99943593714684
4.99966152410377
4.99979690071342
4.99987813547793
4.9999268795046
4.99995612706116
4.99997367600571
4.99998420552027
4.99999052328223
4.99999431395856
4.99999658837126
4.99999795302136
4.99999877181231
4.99999926308721
4.99999955785226
4.99999973471133
4.99999984082679
4.99999990449607
4.99999994269764
4.99999996561859
4.99999997937115
4.99999998762269
4.99999999257362
4.99999999554417
4.9999999973265
4.9999999983959
4.99999999903754
4.99999999942252
4.99999999965351
4.99999999979211
4.99999999987527
4.99999999992516
4.9999999999551
4.99999999997306
4.99999999998384
4.9999999999903
4.99999999999418
4.99999999999651
4.9999999999979
4.99999999999874
4.99999999999925
4.99999999999955
4.99999999999973
4.99999999999984
4.9999999999999
4.99999999999994
4.99999999999996
4.99999999999998
4.99999999999999
4.99999999999999
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5

The conclusion is that you should be aware that round-offs can accumulate and lead to unexpected results. Use the most appropriate data types suitable. Do not use double (not to mention float) for financial data.

, , , , , , , , Hits for this post: 7568 .

Speed-up VC++ builds

The larger a VC++ project is (or any project for that matter) the more time it takes to build. If you have solutions with many large projects the build times could get into your way. Starting a rebuild and going to lunch was a common scenario for me, as building took 20-25 minutes. Of course, you don’t rebuild everything all the time, but sometimes is enough to change something in a header somewhere deep inside the dependency web and trigger a rebuild of many or all the projects in a solution.

Using compiler switches and other tricks I managed to reduce the build time with about 50% or more (the percent of speedup is similar on different machines, regardless of the previous build times on those machines). Replacing the hard disk with an SSD provided an additional 25% speed. My full build times have decreased from 20-25 minutes to about 7 minutes.

First off all, Visual Studio enables parallel projects builds by default. As long as your projects don’t have dependency and can be built in parallel, it is possible to have up to 32 projects built at the same time. By default the number of projects built in parallel is set to the number of available cores. This option can be change from Tools > Options > Projects and Solutions > Build and Run.

vcbuild1

The VC++ compiler also supports multi-processor compilation. This can be enabled with a compiler switch, /MP. The result of this switch is that the compiler spawns into additional processes that simultaneous compile the source files. This option can be set per project from Project > Properties > Configuration Properties > C/C++ > General.

vcbuild2

This option is however incompatible with several compiler and language features. In case of incompatibility the behavior differs:

  • if the incompatibility is with another compiler option a warning is displayed and the /MP options is ignored
  • if the incompatibility is with a language feature an error is issued and compilation stops or continues depending on the error level

The incompatible features are: #import processor directive, /GM (enables incremental build), /Yc (writes a precompiled header file), /E and /EP (copies pre-processor output to the standard console), /showIncludes (writes a list of include files to the standard error console). These features are incompatible with /MP because they would imply shared resources (console or file) to be used possible at the same time from different processes.

The workaround for the #import processor directive is to move the directives to a file that is not built with the /MP option. However, in practice I had problems with that and the workaround that actually worked was to move the #import directives to the pre-compiled header. That is built (the corresponding source file actually) synchronously before the compilation of any other translation unit starts, so there are no incompatibilities. However, this has the drawback that any change in the imported type library will trigger a rebuild of the precompiled header and of the whole project.

vcbuild3

Below is a table of full build times for various VC++ projects from the same solution. The values were reported by MSBuild. The actual time values (shown to hundredths of a second) are not important (as they vary across builds and machines). What is important is the speed-up before enabling /MP and after it.

Before After
Release Debug Release Debug
00:00:58.43 00:00:53.14 00:00:37.32 00:00:25.23
00:00:45.41 00:00:33.25 00:00:12.16 00:00:07.47
00:00:56.85 00:00:54.90 00:00:51.35 00:00:50.72
00:00:45.41 00:00:44.34 00:00:24.41 00:00:20.16
00:01:00.92 00:01:05.97 00:01:15.40 00:01:14.07
00:04:17.89 00:04:25.88 00:01:34.66 00:01:17.97
00:02:59.41 00:02:26.42 00:01:11.99 00:00:54.07
00:00:46.96 00:00:43.96 00:00:17.70 00:00:17.41
00:00:46.05 00:00:46.05 00:00:16.69 00:00:14.40
00:01:44.84 00:01:35.11 00:00:30.29 00:00:28.13
00:00:11.02 00:00:14.26 00:00:07.97 00:00:08.24
00:00:09.28 00:00:12.75 00:00:07.59 00:00:07.59
00:00:08.46 00:00:08.95 00:00:10.89 00:00:08.25
00:00:18.68 00:00:19.79 00:00:14.32 00:00:11.35
00:02:46.37 00:00:50.76 00:01:52.16 00:00:28.88
00:00:13.87 00:00:11.66 00:00:09.24 00:00:11.06
00:01:05.37 00:00:54.76 00:00:25.45 00:00:26.83
00:00:29.00 00:00:16.68 00:00:13.32 00:00:12.94
00:00:25.79 00:00:14.05 00:00:12.09 00:00:12.04
00:00:22.80 00:00:11.50 00:00:11.60 00:00:11.93
00:00:31.76 00:00:39.33 00:00:25.00 00:00:21.19
00:00:56.01 00:00:59.04 00:00:26.62 00:00:23.95
00:00:20.40 00:00:12.92 00:00:08.64 00:00:07.99
00:00:16.48 00:00:18.61 00:00:09.18 00:00:08.71
00:00:09.74 00:00:10.49 00:00:06.84 00:00:09.84

Another strategy for increasing the build times is to reduce the number of times framework headers (STL, MFC, ATL, etc.) or headers from your project that do not change often and are included in many places are included into the various source files of your projects. These headers can be put in the pre-compilead header, and therefore compiled just once.

The next table shows the additional speed-up gain for several projects after moving framework headers to the pre-compiled header of each project.

Before After
Release Debug Release Debug
00:00:37.32 00:00:25.23 00:00:32.79 00:00:19.24
00:00:12.16 00:00:07.47 00:00:04.90 00:00:02.41
00:00:51.35 00:00:50.72 00:00:44.15 00:00:37.25
00:00:24.41 00:00:20.16 00:00:20.19 00:00:20.16
00:01:15.40 00:01:14.07 00:01:14.10 00:01:10.56
00:01:34.66 00:01:17.97 00:01:23.60 00:01:22.15
00:01:11.99 00:00:54.07 00:01:11.70 00:00:43.20

The speed-up gain by using these techniques may vary depending on your project specifics. In some cases the gain may not be significant or the build time may actually increase. You should play around with these settings and enable them only when they help you.

In summary, some of the strategies that can help increase your build times are:

  • break dependencies between projects they can be built in parallel
  • if you have large projects try to break them in smaller, independent projects; the more such projects you have the more work can be done in parallel
  • use multi-processor compilation (/MP) for C++ projects to enable compiling multiple translation units at the same time
  • move framework headers (STL, MFC, ATL, etc.) and other headers that do not change and are included all over your project to the pre-compiled header
  • use a SSD and keep your sources on it
, , , , , Hits for this post: 8155 .

Many years ago I published on my blog a helper class for working with the Windows console that was wrapping the Windows console API. Looking back at it I realized it was a pretty naive implementation. So I decided to start a new and make something more flexible and easier to use. Hopefully, I was more successful. The result is a small C++ template library called cppconlib, available on codeplex.

cppconlib is built with C++11 features and requires Visual Studio 2012 or newer. The library is available in a single header called conmanip.h and provides a set of helper classes, functions and constants for manipulating a Windows console (using the Windows console functions). The library features the following components:

  • console_context<T>: represents a context object for console operations; its main purpose is restoring console settings; typedefs for the three consoles are available (console_in_context, console_out_context and console_err_context)
  • console<T>: represents a console objects providing operations such as changing the foreground and background colors, the input mode, screen buffer size, title, and others; typedefs for the three consoles are available (console_in, console_out and console_err)
  • manipulating functions that can be used with cout/wcout and cin/wcin: settextcolor()/restoretextcolor(), setbgcolor()/restorebgcolor(), setcolors(), setmode()/clearmode(), setposx()/setposy()/setpos().

The library can be downloaded from here. Detailed documentation is available here.

cppconlib

Examples

The following example prints some text in custom colors and then reads text in a different set of colors.

cppconlib2

The following code prints a rhomb to the console:

cppconlib3

For more details and updates check the project at codeplex: https://cppconlib.codeplex.com.

UPDATE: A NuGet package for cppconlib is available.

, , , , , , , Hits for this post: 10300 .