Créer des exécutables liés au runtime par défaut du système

vehicule
parce que c’est plus léger, et plus portable…

Reprenons notre code « simple » :

#include <stdio.h>

int main(int argc, char **argv)
{
	printf("Hello Kiwi\n");
	return 0;
}

Introduction

Afin de construire cet exécutable, aussi simple soit-il, le compilateur doit savoir ou « trouver » la fonction printf.
printf fait heureusement partis des fonctions « de base » et est inclus dans les runtimes C/C++ de Visual Studio.

Visual Studio devra donc lier notre exécutable à la librairie contenant le code de printf :

sous Visual Studio 2010, avec msvcr100.dll

  Version      : 0
  Machine      : 14C (x86)
  TimeDateStamp: 4DF2B873 Sat Jun 11 02:36:03 2011
  SizeOfData   : 00000015
  DLL name     : MSVCR100.dll
  Symbol name  : _printf
  Type         : code
  Name type    : no prefix
  Hint         : 1495
  Name         : printf

sous Visual Studio 2012, avec msvcr110.dll

  Version      : 0
  Machine      : 14C (x86)
  TimeDateStamp: 50988325 Tue Nov 06 04:25:25 2012
  SizeOfData   : 00000015
  DLL name     : MSVCR110.dll
  Symbol name  : _printf
  Type         : code
  Name type    : no prefix
  Hint         : 1584
  Name         : printf

Mais comment fait Windows pour son fonctionnement interne ?
Nous savons que les runtimes C/C++ de Visual Studio 2010 ou 2012 ne sont pas installés par défaut sous Windows, alors comment fait-il pour se passer de ces librairies ?

Runtimes du système

Prenons un programme, dont nous sommes sûrs qu’il utilise la sortie console (et donc a priori printf) : l’Invite de commandes (cmd.exe).

Dump of file c:\Windows\System32\cmd.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    msvcrt.dll
              4AD01000 Import Address Table
              4AD2286C Import Name Table
              FFFFFFFF time date stamp
              FFFFFFFF Index of first forwarder reference

      6FF636AA    48F exit
      [...]
      6FF5A73F    560 wcsrchr
      6FF59910    4EA memcpy
      6FF6C5B9    4F3 printf
      6FFF2900    1DB _iob
      6FF63E00    49F fprintf
      [...]

Windows utilise donc la librairie msvcrt.dll (%SystemRoot%\System32), soit les runtimes par défaut du système. Ce qui paraît logique…

Cette librairie est très pratique :

  • pas de déploiement de runtimes !
  • nous sommes sûrs de la trouver sur toutes les versions de Windows
  • sauf exceptions, elle répond à la plupart de nos usages

Limitation : pas de librairie de débogage des runtimes système présente sur les systèmes (la compilation et les programmes ne fonctionneront qu’en version « release »).

Comment pourrions-nous aussi en bénéficier ?

  • Utilisons le contenu du Windows Driver Kit !
  • recréons le fichier .lib permettant de nous lier à ce runtime par défaut fastidieux !

Pré-requis

Le Windows Driver Kit (WDK) contient les fichiers .lib nécessaires et il est tout à fait possible de modifier les propriétés de son projet C/C++ pour abandonner l’utilisation des librairies de Visual Studio pour pointer vers celles du WDK.

C’est assez hasardeux ; les résultats ne sont pas toujours au rendez-vous.
Peut-être pouvons-nous faire plus simple et tirer encore plus parti du WDK ?

Les plateformes MsBuild

Microsoft nous offre énormément de fonctionnalités/possibilités avec ses nouvelles versions de Visual Studio (2010, 2012…).
L’un d’elle est de pouvoir personnaliser ses environnements de compilation.

  1. se placer dans le répertoire des définitions des plateformes de compilation : %ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms (ou ProgramFiles(x86))
  2. décompresser le fichier ddk2003.zip, cela doit donner l’arborescence suivante
    C:\PROGRAM FILES\MSBUILD\MICROSOFT.CPP\V4.0\PLATFORMS
    +---Win32
    |   |
    |   \---PlatformToolsets
    |       +---ddk2003
    |       |       Microsoft.Cpp.Win32.ddk2003.props
    |       |       Microsoft.Cpp.Win32.ddk2003.targets
    |       |
    |       +---v100
    |       \---v90
    |
    \---x64
        |
        \---PlatformToolsets
            +---ddk2003
            |       Microsoft.Cpp.x64.ddk2003.props
            |       Microsoft.Cpp.x64.ddk2003.targets
            |
            +---v100
            \---v90
  3. éventuellement, modifier les fichiers .props pour pointer sur un autre emplacement du WDK, ou sur d’autres librairies que celles de Windows 2003 (elles ont l’avantage de couvrir l’ensemble des versions de Windows)

Visual Studio

Il suffit de placer le projet en « release » puis de sélectionner les outils de plateforme ddk2003 dans les propriétés du projet :
plateforme
… et de compiler

C:\[...]\Release>ConsoleApplication1.exe
Hello Kiwi

C:\[...]\Release>dumpbin /imports ConsoleApplication1.exe | findstr /i .dll
    msvcrt.dll
    KERNEL32.dll

C:\[...]\Release>dir ConsoleApplication1.exe
[...]
27/05/2013  02:41             7 680 ConsoleApplication1.exe

Notes : l’utilisation du WDK peut nécessiter la récupération de quelques « headers » non présent dans le WDK.

Bonus Visual Studio 2012

Un modèle tout prêt et optimisé pour cette nouvelle plateforme de compilation « Application console Win32-DDK » : console_ddk2003.zip.
A poser (non décompressé) dans le répertoire : %userprofile%\Documents\Visual Studio 2012\Templates\ProjectTemplates

template_c