/dev/log

Blog technique de Benjamin Billet

cygwin

wxWidget : résoudre l'erreur de compilation "undefined reference to `_IID_IPersistFile'", "undefined reference to `glFrustum'", etc.

Rédigé par Benjamin Billet -
Classé dans : Projet similarity-finder - Mots clés : cygwin, wxwidget

Lors de la compilation de wxWidgets (ici 3.0.2), il peut arriver que la compilation échoue sur l'erreur suivante :
g++ -shared -o /home/win7/wxWidgets-3.0.2/lib/cygwxbase30u_gcc_custom-0.dll basedll_version_rc.o basedll_any.o basedll_appbase.o basedll_arcall.o basedll_arcfind.o basedll_archive.o basedll_arrstr.o basedll_base64.o basedll_clntdata.o basedll_cmdline.o basedll_config.o basedll_convauto.o basedll_datetime.o basedll_datetimefmt.o basedll_datstrm.o basedll_dircmn.o basedll_dynarray.o basedll_dynlib.o basedll_dynload.o basedll_encconv.o basedll_evtloopcmn.o basedll_extended.o basedll_ffile.o basedll_file.o basedll_fileback.o basedll_fileconf.o basedll_filefn.o basedll_filename.o basedll_filesys.o basedll_filtall.o basedll_filtfind.o basedll_fmapbase.o basedll_fs_arc.o basedll_fs_filter.o basedll_hash.o basedll_hashmap.o basedll_init.o basedll_intl.o basedll_ipcbase.o basedll_languageinfo.o basedll_list.o basedll_log.o basedll_longlong.o basedll_memory.o basedll_mimecmn.o basedll_module.o basedll_mstream.o basedll_numformatter.o basedll_object.o basedll_platinfo.o basedll_powercmn.o basedll_process.o basedll_regex.o basedll_stdpbase.o basedll_sstream.o basedll_stdstream.o basedll_stopwatch.o basedll_strconv.o basedll_stream.o basedll_string.o basedll_stringimpl.o basedll_stringops.o basedll_strvararg.o basedll_sysopt.o basedll_tarstrm.o basedll_textbuf.o basedll_textfile.o basedll_threadinfo.o basedll_common_time.o basedll_timercmn.o basedll_timerimpl.o basedll_tokenzr.o basedll_translation.o basedll_txtstrm.o basedll_unichar.o basedll_uri.o basedll_ustring.o basedll_variant.o basedll_wfstream.o basedll_wxcrt.o basedll_wxprintf.o basedll_xlocale.o basedll_xti.o basedll_xtistrm.o basedll_zipstrm.o basedll_zstream.o basedll_fswatchercmn.o basedll_fswatcherg.o basedll_basemsw.o basedll_crashrpt.o basedll_debughlp.o basedll_dde.o basedll_msw_dir.o basedll_dlmsw.o basedll_evtloopconsole.o basedll_msw_mimetype.o basedll_power.o basedll_regconf.o basedll_registry.o basedll_msw_snglinst.o basedll_msw_stackwalk.o basedll_msw_stdpaths.o basedll_msw_thread.o basedll_timer.o basedll_msw_utils.o basedll_msw_utilsexc.o basedll_fswatcher.o  basedll_event.o basedll_fs_mem.o basedll_msgout.o basedll_utilscmn.o basedll_main.o basedll_mslu.o basedll_volume.o     -L/home/win7/wxWidgets-3.0.2/lib  -Wl,--out-implib=/home/win7/wxWidgets-3.0.2/lib/libwx_baseu-3.0.dll.a      -lwxregexu-3.0  -lz -lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 -lkernel32 -luser32  -lz -lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 -lkernel32 -luser32
basedll_filename.o:filename.cpp:(.text+0x511c): undefined reference to `IID_IShellLinkW'
basedll_filename.o:filename.cpp:(.text+0x5162): undefined reference to `IID_IPersistFile'
collect2: error: ld returned 1 exit status
Makefile:15531: recipe for target '/home/win7/wxWidgets-3.0.2/lib/cygwxbase30u_gcc_custom-0.dll' failed
make: *** [/home/win7/wxWidgets-3.0.2/lib/cygwxbase30u_gcc_custom-0.dll] Error 1

Cette erreur se produit lorsque libuuid-devel est installé, conduisant l'option -luuid à lier /usr/lib/libuuid.a au lieu de /usr/lib/w32api/libuuid.a. Pour résoudre ce problème, il est nécessaire d'éditer le fichier Makefile et d'ajouter -L /usr/lib/w32api à la variable LDFLAGS. Ainsi, ayant connaissance du répertoire approprié, g++ va lier la bonne librairie.

Une fois ce problème résolu, une autre erreur survient un peu plus tard, indiquant notamment que des éléments d'OpenGL sont manquants :

g++ -shared -o /home/win7/wxWidgets-3.0.2/lib/cygwxmsw30u_gl_gcc_custom-0.dll gldll_version_rc.o gldll_glcmn.o gldll_msw_glcanvas.o    -L/home/win7/wxWidgets-3.0.2/lib  -Wl,--out-implib=/home/win7/wxWidgets-3.0.2/lib/libwx_mswu_gl-3.0.dll.a   -L /usr/lib/w32api  -lwxtiff-3.0 -lwxjpeg-3.0 -lwxpng-3.0    -lwxregexu-3.0 -lwxexpat-3.0 -lz -lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 -lkernel32 -luser32  -lwx_mswu_core-3.0 -lwx_baseu-3.0  -lopengl32 -lglu32 -lz -lrpcrt4 -loleaut32 -lole32 -luuid -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwsock32 -lgdi32 -lkernel32 -luser32
gldll_glcmn.o:glcmn.cpp:(.text+0x363): undefined reference to `glFrustum'
gldll_glcmn.o:glcmn.cpp:(.text+0x428): undefined reference to `glGetBooleanv'
gldll_glcmn.o:glcmn.cpp:(.text+0x91a): undefined reference to `glColor3f'
gldll_glcmn.o:glcmn.cpp:(.text+0xae1): undefined reference to `glIndexi'
gldll_glcmn.o:glcmn.cpp:(.text+0x371): undefined reference to `glBegin'
gldll_glcmn.o:glcmn.cpp:(.text+0x381): undefined reference to `glTexCoord2f'
gldll_glcmn.o:glcmn.cpp:(.text+0x391): undefined reference to `glVertex3f'
gldll_glcmn.o:glcmn.cpp:(.text+0x3a1): undefined reference to `glNormal3f'
gldll_glcmn.o:glcmn.cpp:(.text+0x3b1): undefined reference to `glColor4f'
gldll_glcmn.o:glcmn.cpp:(.text+0x3c1): undefined reference to `glColor3f'
gldll_glcmn.o:glcmn.cpp:(.text+0x3d1): undefined reference to `glEnd'
collect2: error: ld returned 1 exit status
Makefile:16086: recipe for target '/home/win7/wxWidgets-3.0.2/lib/cygwxmsw30u_gl_gcc_custom-0.dll' failed
make: *** [/home/win7/wxWidgets-3.0.2/lib/cygwxmsw30u_gl_gcc_custom-0.dll] Error 1

Il semble que le lien avec OpenGL ne soit pas fait et doive être ajouté. De la même façon que le problème précédent, il est nécessaire d'aller modifier le fichier Makefile. Il suffit de trouver la variable EXTRALIBS_OPENGL et d'y ajouter -lGl.

Compiler wxWidget 3.0.2 avec cygwin 2.0.0 sous windows

Rédigé par Benjamin Billet -
Classé dans : Projet similarity-finder - Mots clés : cygwin, wxwidget

En premier lieu, il est nécessaire d'installer cygwin (2.0.0) avec les paquets suivants : automake, autoconf, make, gcc-g++.

Concrètement, wxWidgets spécifie un ensemble d'API communes, qui sont implémentées sur différentes plateformes. Pour windows, nous allons compiler wxMSW mais nous pourrions aussi utiliser wxX11 ou wxGTK.

Après s'être placé dans le dossier des sources de wxWidgets-3.0.2 avec la console cygwin, la configuration/compilation est classique :

$> ./configure --with-msw --enable-unicode
$> make
$> make install

Par défaut la compilation construit des librairies dynamiques, les librairies statiques pouvant être générées avec l'option --disable-shared. De nombreuses options sont disponibles pour le ./configure, la liste complète pouvant être obtenue avec :

$> ./configure --help

A noter que wxWidgets est directement fourni avec le code source de ses dépendances, la configuration permettant de préciser s'il est préférable d'utiliser les versions fournies (p. ex. --with-jpeg=builtin) ou les librairies éventuellement installées sur le système (p. ex. --with-jpeg=sys).

Une fois l'installation terminée, la commande suivante devrait être disponible :

$> wx-config --version
3.0.2

Pour un test plus poussé, il est possible de compiler les exemples fournis dans le dossier "samples" :

$> cd samples/treelist
$> make

Après avoir intégré les dll de wxWidgets, disponibles dans wxWidgets-3.0.2/lib, et celles de cygwin (/bin), l'exécutable treelist.exe devrait s'afficher ainsi :

treelist-screen

Environnement

J'utilise Eclipse IDE for C/C++ pour gérer le projet mais, globalement, les informations suivantes s'appliquent à tout projet basé sur wxWidget. Le type de projet C/C++ crée est un Makefile project vide. Pour assurer que toutes les options de configurations soient disponibles (constantes, flags, includes, libs, etc.), il faut en outre activer la génération automatique du makefile (options du projet -> C/C++ Build).
Remarque : pour une détection de Cygwin par Eclipse, il suffit d'ajouter simplement le dossier chemin/vers/cygwin/bin au PATH de windows.

C++ Compiler   Concrètement, la commande wx-config génère les paramètres cohérents pour g++ :

$> wx-config --static=no --cxxflags --linkdeps
-I/usr/local/lib/wx/include/msw-unicode-3.0 -I/usr/local/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXMSW__ 

Aussi, la configuration d'Eclipse se fait simplement en ajoutant `/usr/local/bin/wx-config --static=no --cxxflags --linkdeps` à la commande g++ (adapter le chemin si nécessaire).

C++ Linker   Ici, il est nécessaire de changer le Command Line Pattern en déplaçant le bloc FLAGS à la fin :

${COMMAND} ${FLAGS} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}
devient
${COMMAND} ${OUTPUT_FLAG}${OUTPUT_PREFIX}${OUTPUT} ${INPUTS} ${FLAGS}
En effet, nous utilisons les flags pour qu'Eclipse construise le makefile avec la commande wx-config à la fin de la commande g++. Pour ce faire, dans Miscellaneous, nous spécifions `/usr/local/bin/wx-config --libs --static=no` dans le champ Linker flags. En outre les paramètres suivants peuvent être ajoutés à ce champ :

Utiliser windres pour avoir un rendu visuel conforme à Window

Si l'on crée un nouveau projet vierge à partir des fichiers treelist.cpp et treelist.h fourni dans l'exemple samples/treelist et que l'on compile, l'application s'affiche comme suit :

treelist-screen

Contrairement à la première capture, les composants graphiques s'affichent ici comme si l'application était exécutée sous Windows 95. Pour résoudre ce problème, il est nécessaire de créer un fichier de ressource (voir Ressource Windows), de le "compiler" avec windres (fourni avec wxWidgets) et de linker la ressource compilée à notre projet.

wxWidgets fournit un fichier de ressource basique, samples/sample.rc :

/////////////////////////////////////////////////////////////////////////////
// Name:        samples/samples.rc
// Purpose:     a standard Win32 .rc file for the wxWindows samples
// Author:      Vadim Zeitlin
// Modified by:
// Created:     04.08.03
// Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// this minimal resource file is all what is needed for most of the wxWindows
// samples

// note that the icon used by the Explorer (i.e. the programs icon) is the
// first icon in the executable and the icons are sorted both by their order
// (Win9x) and by alphabetically (!) (NT), so put this icon first and give it
// a name starting with "a"
aaaaaaaa ICON "sample.ico"

// this icon is used with wxFrame::SetIcon()
sample ICON "sample.ico"

// set this to 1 if you don't want to use manifest resource (manifest resource
// is needed to enable visual styles on Windows XP - see docs/msw/winxp.txt
// for more information)
#define wxUSE_NO_MANIFEST 0

// this is not always needed but doesn't hurt (except making the executable
// very slightly larger): this file contains the standard icons, cursors, ...
#include "wx/msw/wx.rc"

Ce fichier doit être ajouté aux sources du projet Eclipse et sa compilation par windres est spécifiée dans les Pre Build Steps du projet. Il est nécessaire de préciser explicitement le chemin vers les headers de wxWidgets ainsi que le chemin vers le fichier ressource (ici, my_resource_file.rc) : windres -i"../src/my_resource_file.rc" -omy_resource_file_rc.o -I"/usr/local/include/wx-3.0". Enfin, dans la configuration du C++ Linker, nous ajoutons my_resource_file_rc.o à la liste Other Objects de Miscellaneous.