31 juillet 2014

mod_perl ActiveState & MSVC 2013

Après ce mémo sur compilation de Apache 2.2.x avec MSCV 2013 voici la compilation de mod_perl 2.0.x en utilisant le perl de ActiveState. (Avec Strawberry c’est encore plus compliqué car il utilise le compilateur gcc de MinGW)

Le Perl utilisé doit être au minimum 5.8.2 et être compilé avec les options usethreads , useithreads et usemultiplicity.  Pour le vérifier taper: perl –V:uses.+

En théorie il suffit de 4 commandes pour installer mod_perl
perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x
nmake
nmake test
nmake install
Malheureusement il y a quelques bugs…


1) Première étape, premier bug

Télécharger les sources de mod_perl 2.0.x ici : http://apache.org/dist/perl/

Assurez vous d’avoir le Perl et le bin de msvc dans le PATH puis, depuis la racine des sources de mod_perl, tapez ces 3 commandes:

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"
set MP_USE_MY_EXTUTILS_EMBED=1
perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x


Premier problèmes; Vous n’avez pas la librairie apxs.
Il propose de la télécharger, mais l’url est invalide.

Install apxs now? [yes]
Download of http://perl.apache.org/dist/win32-bin/apxs_win32.tar.gz failed


La bonne url est: https://archive.apache.org/dist/perl/win32-bin/apxs_win32.tar.gz

Il faut éditer le fichier build\win32_fetch_apxs et remplacer
    my $remote = 'http://perl.apache.org/dist/win32-bin/' . $file;
par
    my $remote = 'https://archive.apache.org/dist/perl/win32-bin/' . $file;

Cette fois le commande perl Makefile.PL MP_AP_PREFIX=\Path\to\Apache2.2.x  doit aboutir.


2) Deuxième étape (compilation), deuxième bug

L'étape suivante consiste à exécuter (toujours depuis la racine des sources de mod_perl)
nmake
Mais ça ne marche pas car on obtient :

'C:\Program' is not recognized as an internal or external command, operable program or batch file.
NMAKE : fatal error U1077: 'cd' : return code '0x1'
Stop.


Il faudrait éditer le fichier Makefile et ajouter les quotes au path de MAKE.

MAKE = C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\nmake.exe

mais ce bug est dans tous les Makefile des sous répertoires. Au total cela en fait plus de 60 !

La solution que j’utilise est d'éditer le module \Perl\lib\ActivePerl\Config.pm  et d’ajouter des quotes autour de $prog
for (@make) {
    if (my $prog = _find_prog($_)) {
    $_[0] = $OVERRIDE{$key} = "\"$prog\"";
Mais en ajoutant ces quotes on rend une expression régulière invalide. Il faut éditer \Perl\lib\ExtUtils\MM_Win32.pm et corriger la fonction is_make_type() en supprimant le $ de la fin de l’expression régulière
sub is_make_type {
    my($self, $type) = @_;
    return !! ($self->make =~ /\b$type(?:\.exe)?$/);
}
Avec ces 2 modifs on peut exécuter nmake sans avoir d'erreurs.


3) Troisième étape (tests), troisième bug
nmake test
Le daemon httpd.exe va être exécuté, certains tests ne sont pas exécutés s’il manque des dépendances mais certains vont échouer (en tout cas avec la version mod_perl 2.0.8) !
t/api/err_headers_out.t (Wstat: 0 Tests: 6 Failed: 3)
Failed tests: 2-3, 5
Files=1, Tests=6, 2 

Result: FAIL
Failed 1/1 test programs. 3/6 subtests failed. 

Solution: Dans le fichier t\api\err_headers_out.t il faut remplacer à deux endroits:
  if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION==6.00;
par
  if defined HTTP::Headers->VERSION and HTTP::Headers->VERSION>=6.00;

Avec ces 2 modifs on peut exécuter nmake test sans avoir d'erreurs.


4) Dernière étape
nmake install
et ça marche (enfin) !



28 juillet 2014

Apache 2.2 & MSVC 2013



La branche 2.2.x du serveur http d’Apache a une importance particulière car mod_perl  y fonctionne correctement ce qui n’est pas le cas avec la nouvelle branche 2.4. Apache 2.2, bien qu'encore supporté, commence à dater. La version 2.2.0 date de décembre 2005. Depuis, les compilateurs ont évolués et des problèmes commencent à apparaitre. C’est le cas avec Visual Studio 2013 et sa « Plateform Toolset v120 ».

Voici ce qu’il faut corriger pour pouvoir compiler le serveur http 2.2 d'Apache avec MSVC 2013.

1) Télécharger

  1. Les sources du serveur http 2.2.xx d’Apache depuis : http://www.apache.org/dist/httpd/ 
  2. Les sources de APR-iconv. Les librairies pcre, APR et AP-utils sont incluses avec les sources de Apache mais pas APR-iconv  car les systèmes Unix fournissent déjà iconv() . Pour Windows ce n’est pas le cas, il faut donc télécharger cette librairie et la mettre dans le répertoire srclib sous le nom apr-iconv (sans aucun numéro de version). On trouve cette librairie ici : https://apr.apache.org/download.cgi 
  3. awk est utilisé pour générer la configuration du serveur (httpd.conf). On peut le télécharger ici  http://sourceforge.net/projects/gnuwin32/files/gawk/ sous le nom de gawk.

 2) Environnement

Le PATH doit inclure un chemin sur awk.exe et sur les binaires de MSVC
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin.

Ouvrir une console (cmd) dans le répertoire contenant les sources d'Apache.

Exécuter le script "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat"

3) Compiler

Normalement il suffirait de taper la commande
    nmake -f Makefile.win
mais ça ne marche pas car on obtient 5 erreurs du type:

pr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedXxxx referenced in function _apr_atomic_inc32@xx

Les 5 erreurs sont:

Creating library .\Release\libapr-1.lib and object .\Release\libapr-1.exp
apr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedIncrement referenced in function _apr_atomic_inc32@4
apr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedExchangeAdd referenced in function _apr_atomic_add32@8
apr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedExchange referenced in function _apr_atomic_set32@8
apr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedDecrement referenced in function _apr_atomic_dec32@4
apr_atomic.obj : error LNK2019: unresolved external symbol __InterlockedCompareExchange referenced in function _apr_atomic_cas32@12
.\Release\libapr-1.dll : fatal error LNK1120: 5 unresolved externals

NB; Ce problème n’apparait pas si on génère une version 64 bits d’apache.

4) Error LNK2019

Pour corriger cette erreur  il faut éditer le fichier srclib\apr\atomic\win32\apr_atomic.c et mettre en commentaire (ou supprimer)  tous les casts tel que celui-ci (il y en a 9 en tout) :

#else
return ( /*(apr_atomic_win32_ptr_ptr_ptr_fn)*/ InterlockedCompareExchange)(mem, with, cmp);
#endif


(apr_atomic_win32_xxxx) est mis en commentaire 10 fois.
NB: Ceci supprimera les erreurs mais en échange on aura 7 warnings C4047 et 5 warnings C4024 à la compilation.

5) Error LNK2011

A ce stade, si on tentait à nouveau de compiler on obtiendrait cette nouvelle erreur :

adobe-stdenc.obj : error LNK2011: precompiled object not linked in; image may not run
..\Release\iconv\adobe-stdenc.so : fatal error LNK1120: 1 unresolved externals
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\link.EXE"' : return code '0x460'
Stop.


Cette erreur, de manière générale, vient du fait que
1.    un fichier xxxx.c est compilé pour créer un fichier xxxx.pch,
2.    ce fichier xxxx.pch est utilisé pour compiler d’autres fichiers .c
3.    au moment de l’édition de lien xxxx.obj n’est pas utilisé
(Détail ici: http://msdn.microsoft.com/en-us/library/3ay26wa2.aspx)

La solution générique a cette erreur consiste donc à ajouter xxxx.obj à la liste des fichiers obj au moment de l’édition des liens.

Dans le cas de Apache 2.2.x, éditer le fichier srclib\apr-iconv\build\modules.mk.win, localiser cette règle et y ajouter la partie surlignée en vert.

.c{$(OUTPUT_DIR)}.so:
    $(SILENT)cl $(ALL_CFLAGS) /Fo$*.obj /Yuiconv.h /c $<
    $(SILENT)link $(ALL_LDFLAGS) $(MODRES).obj $*.obj $(API_LIBS) /out:$@ \
        /base:@"..\build\BaseAddr.ref",$(@F)


Pour comprendre il faut bien voir que $(ALL_CFLAGS) utilisé à chaque compilation contient ... /Fd$(MODRES).pdb /Fp$(MODRES).pch ...

6) Compiler (pour de bon)

Une fois ces erreurs corrigées on peut lancer depuis la racine des sources
  nmake -f Makefile.win   (pour seulement compiler)
ou
  nmake –f Makefile.win installr    (pour compiler et installer dans C:\Apache22)

Le répertoire d’installation peut être spécifié avec le paramètre INSTDIR

  nmake -f Makefile.win INSTDIR="D:\my\Path\Apache" installr

Regardez les commentaires au début du fichier Makefile.win pour découvrir les différents paramètres pouvant être utilisés  pour customiser la compilation et/ou l’installation.

7) Démarrer le serveur HTTPd

Aller dans le répertoire bin de apache (par défaut C:\Apache22\bin) et exécuter httpd.exe






21 juillet 2014

Recherche des lib et dll



Quand on ajoute la librairie XYZ a un projet C/C++ il y a trois informations à donner au compilateur et linkeur :
  1. Le répertoire où se trouve les entêtes des fonctions et classes  (-I /path/to/headers)
  2. Le répertoire où se trouve la librairie (-L /path/to/libs)
  3. Le nom de de la librairie (-l XYZ)
Ce qui est perturbant c’est que bien souvent le nom réel du fichier de cette librairie n’est pas juste ‘XYZ’. En fait quand vous passez l’option "-l XYZ" au linkeur de gcc sous Windows voici, dans l'ordre de recherche, les 7 noms de fichiers qui seront cherché par gcc :





  | "lib" | “XYZ”  | ".dll" | ".a" | ".lib" | Nom cherché
  +-------+--------+--------+------+--------|
1 |   X   |   X    |   X    |  X   |        | libXYZ.dll.a
  +-----------------------------------------|
7 |       |   X    |   X    |  X   |        | XYZ.dll.a
  +-----------------------------------------|
3 |       |   X    |        |  X   |        | XYZ.a
  +-----------------------------------------|
4 |       |   X    |        |      |    X   | XYZ.lib
  +-----------------------------------------|
5 |   X   |   X    |   X    |      |        | libXYZ.dll
  +-----------------------------------------|
6 |       |   X    |   X    |      |        | XYZ.dll
  +-----------------------------------------|
7 |   X   |   X    |        |  X   |        | libXYZ.a
  +-----------------------------------------|


Ceci est répété pour chaque chemin par défaut et pour chaque chemin définit par l'option -L /path/to/libs  jusqu’à ce que l’un de ces 7 noms soit trouvé.

Notez que toutes les combinaisons ne sont pas testées: libXYZ.lib ne sera pas cherché par le linkeur.

17 juillet 2014

GCC Cygwin MinGW and co


GCC est LA suite de compilation du projet GNU, surtout connue pour son compilateur C/C++ mais qui peut aussi compiler Ada, Fortran, Go, Java.

Bien sur on retrouve gcc sur tout les systèmes GNU (bsd, linux) mais aussi sur les Unix propriétaires (Aix, HPUX, MacOS, Solaris ...) et sous Windows. Ce qui fait de gcc LE système de compilation multi plates-formes par excellence.

Sous Windows, même si Microsoft propose, via les éditions “Express”, des versions allégées mais gratuites de sa suite Visual Studio on peut vouloir utiliser un compilateur multi plate-forme, multi langages, open source, avec des mises à jour régulières et conforme aux standards. Dans ce cas gcc est LE bon choix.


GNU GCC sous WINDOWS

Cygwin est une environnement très complet permettant de simuler un environnement POSIX (Unix, Linux, BSD) sous Windows. Les exécutables produits par cygwin/gcc dans cet environnement sont dépendants d’une DLL (cygwin1.dll) émulant l'environnement POSIX sous Windows.

Note : Microsoft Windows Services for Unix (SFU) est un environnement Unix/Posix développé par Microsoft, gratuit mais pas open source, proche de cygwin. SFU 3.5 inclus gcc 3.3. Une version allégée de SFU est incluse dans Win7 Enterprise et Ultimate.


MinGW (Minimalist GNU for Windows) est un portage des principaux outils de développement GNU sous Windows. Les exécutables produits par MinGW/gcc utilisent directement les DLL de Microsoft fournies avec Windows et ne nécessitent pas de couche d’émulation comme avec cygwin.

Actuellement MinGW fonctionne sur Windows 32 et 64 bits mais ne permet de produire que des exécutables 32 bits.

Optionnellement MinGW propose une ligne de commande Unix (bash) et quelques outils du monde Unix (grep, make …). Cet environnement Unix optionnel s’appelle MSYS et est basé sur cygwin mais il ne sert pas à produire des exécutables POSIX comme cygwin. MSYS est juste une facilité pour faire du ‘./configure et make’.

MinGW-w64 est un fork (non voulu) de MinGW. Son gros avantage est de pouvoir produire des exécutables 32 et 64 bits.

TDM-GCC de Twilight Dragon Media et une légère variante et un mix de MinGW et MinGW-w64.
Ces variantes sont principalement de nouvelles options pour gérer les exceptions suivant plusieurs méthodes : SJLJ, DWARF, SEH.

MingGW-builds même buts que TDM-GCC mais plus confidentiel.



GCC et les IDE C++ MULTI PLATE-FORME (Windows, Linux, Mac)

Le compilateur C/C++ de Microsoft fonctionne en ligne de commande mais est surtout réputé pour son interface graphique de qualité : Visual Studio. Mais Visual Studio n’est disponible que sous Windows. Heureusement il existe des environnements de développement graphiques multi plates-formes (Windows, Linux, Mac) utilisant le compilateur C/C++ de gcc. Voici les 3 principaux:

Code::Blocks Le compilateur par défaut pour Windows de Code::Blocks est TDM-GCC mais MinGW/gcc, cygwin/gcc, MSVC, BorlandC++, Watcom sont aussi supportés.

Qt va bien au-delà de l’IDE car il propose aussi une framework pour construire des interfaces graphiques utilisant le même code source sur toutes les plates-formes, y compris Android et iOS. MinGW/gcc et MVSC sont supportés

Eclipse est écrit en java donc plus lourd et plus lent que les IDE natifs. Eclipse est plus un atelier de génie logiciel qu'un simple IDE. Il fonctionne avec de (très) nombreux plugins et supporte ainsi plusieurs langages:  java, C/C++, PHP, SQL ... Le module CDT supporte plusieurs compilateurs dont MinGW/gcc et cygwin/gcc.