Gcc 5.30 sur Slackware-14.2
Le
Herve Autret

Bonjour,
J'ai des problèmes pour obtenir un exécutable à partir d'un source Lex
sur cette distro.
gcc 5.30
flex 2.6.0
Le source (linkPlus.l, disons)
%-
%option c++
%option noyywrap
%{
#include <iostream>
using namespace std;
#include <cstdio> // pour EOF
int mylineno = 0;
%}
%%
%%
int main (void) {
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;
return 0;
}
%--
La commande de compilation :
flex -olinkPlus.cc linkPlus.l
La mauvaise commande d'édition de liens :
g++ -o linkPlus linkPlus.cc -lfl
Le résultat :
/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../lib64/libfl.so:
undefined reference to `yylex'
La bonne commande d'édition :
g++ -o linkPlus linkPlus.cc
Y a-t-il un moyen d'éviter que le fait de préciser la bibliothèque libfl
ne fasse rater la manoeuvre ?
à +
--
Hervé
J'ai des problèmes pour obtenir un exécutable à partir d'un source Lex
sur cette distro.
gcc 5.30
flex 2.6.0
Le source (linkPlus.l, disons)
%-
%option c++
%option noyywrap
%{
#include <iostream>
using namespace std;
#include <cstdio> // pour EOF
int mylineno = 0;
%}
%%
%%
int main (void) {
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;
return 0;
}
%--
La commande de compilation :
flex -olinkPlus.cc linkPlus.l
La mauvaise commande d'édition de liens :
g++ -o linkPlus linkPlus.cc -lfl
Le résultat :
/usr/lib64/gcc/x86_64-slackware-linux/5.3.0/../../../../lib64/libfl.so:
undefined reference to `yylex'
La bonne commande d'édition :
g++ -o linkPlus linkPlus.cc
Y a-t-il un moyen d'éviter que le fait de préciser la bibliothèque libfl
ne fasse rater la manoeuvre ?
à +
--
Hervé
Essaye avec
flex --c++ -olinkPlus.cc linkPlus.l
pour dire à flex de générer du C++ (mais je m'étonne de l'absence d'erreurs
avant si c'est bien la solution).
A+
--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Aucune idée, mais chez moi libfl.so est un script qui renvoie a une lib
statique (libfl_pic.a), laquelle ne contient que deux choses : yywrap(),
et un main() qui appelle yylex(). C'est le second qui manifestement pose
problème, puisque le code produit par flex en c++ ne contient pas de
fonction yylex().
(Le fait que Slackware utilise une vraie lib dynamique -- apparemment --
ne change rien au problème je pense.)
Tu peux essayer de définir "int yylex() { return 0; }"... Mais à ce
stade ça vaudrait le coup de faire l'effort de supprimer le -lfl,
puisque tu as déjà noyywrap.
-- Alain.
Alain Ketterlin a écrit :
Tu fais tourner ça sur du Pic ?
Ça pourrait tenir à ça, parce que flex marche pour le C, mais :
- Ce fichier donne un exé en C++ avec gcc-4.7.1 et flex-2.5.35, qu'on
spécifie -lfl ou non, et il marchait aussi avec gcc-4.8
- il y a bien un main() dans mon code : celui de la libfl ne devrait pas
être pris en compte...
En fait ce serait peut-être le couple gcc/ld qui est en cause.
Gcc-6 est sorti ; s'il ne résoud pas le pb je peux rétrograder vers le
4.7.1 pour voir.
Comme dit plus haut : avant, ça marchait(©)
Bien essayé, mais : pas mieux.
Le problème c'est que je compile un truc que je n'ai pas écrit moi-même,
qui comporte une vingtaine de .l, qui utilise scons et qui marche encore
très bien chez les autres. Et pour modifier quelquechose, il faudrait
déjà que je trouve comment dire à scons de ne pas utiliser -lfl s'il y a
un main()...
Merci pour tes tests, ça me convainc de l'origine "compilo" du problème
à +
--
Hervé
Jean-Marc Bourguet a écrit :
En fait la ligne "%option c++" du code flex lui dit déjà de produire du C+
+, donc il n'y a pas d'amélioration.
Flex aurait pu avoir un bug à ce niveau, note, donc merci d'avoir essayé.
à +
--
Hervé
Oops, j'avais pas vu. Ca ressemble à un bug quelque part, car avec des
versions légèrement différentes (celles d'Ubuntu 15.10) :
~/src]$ cat herve.l
%option c++
%option noyywrap
%{
#include <iostream>
using namespace std;
#include <cstdio> // pour EOF
int mylineno = 0;
%}
%%
%%
int main (void) {
FlexLexer* lexer = new yyFlexLexer;
while(lexer->yylex() != 0)
;
return 0;
}
[~/src]$ flex --version
flex 2.5.39
[~/src]$ gcc --version
gcc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[~/src]$ flex -oherve.cc herve.l
[~/src]$ g++ -o herve herve.cc -lfl
[~/src]$
A+
--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Non, mais j'imagine que puisqu'elle doit faire office de .so il faut
qu'elle soit pic.
Je penche plutot pour une config spécifique à Slackware.
Le message du linker indique qu'il cherche yylex, et la seule réfà ©rence
à yylex() vient du main de libfl.
Bon, mais je n'arrive pas à reproduire chez moi, avec des outils moins
récents.
C'est forcément gcc ou ld. Essaie avec gcc -v (ou -###) pour voir la
commande de link.
-- Alain.
Pas nécessairement. Plus précisémenent, il y a deux aspects dans les .so:
- le fait qu'elle soit chargée dynamiquement (automatiquement au démarage
du programme ou à la demande avec dlopen)
- le fait qu'un seul exemplaire puisse être chargé en mémoire et partagé
entre différents processus.
Le PIC ne sert pas (du moins sous Linux) pour le premier aspect (et si j'ai
bonne mémoire il y a même un gain de perf à ne pas être PIC, au moins en 32
bits sur x86; d'autres jeux d'instructions peuvent permettre du code PIC
moins coûteux, et x86_64 doit avoir ce qu'il faut). Le système peut
charger en mémoire une .so avec du code non PIC et effectuer le même type
d'ajustements que pour un exécutable lié statiquement.
Le PIC sert pour le second aspect, les pages mémoires où le code est chargé
peuvent être mappées à différentes adresses dans différents processus sans
géner l'exécution du code (il faut quelques pages propres au processus pour
y mettre les infos propres au processus)
A+
--
Jean-Marc
FAQ de fclc++: http://web.archive.org/web/*/http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alain Ketterlin a écrit :
Reading specs from /usr/lib64/gcc/x86_64-slackware-linux/5.3.0/specs
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-slackware-linux/5.3.0/lto-
wrapper
Target: x86_64-slackware-linux
Configured with: ../gcc-5.3.0/configure --prefix=/usr --libdir=/usr/lib64
--mandir=/usr/man --infodir=/usr/info --enable-shared --enable-bootstrap
--enable-languagesa,c,c++,fortran,go,java,lto,objc --enable-
threads=posix --enable-checking=release --enable-objc-gc --with-system-
zlib --with-python-dir=/lib64/python2.7/site-packages --enable-libstdcxx-
dual-abi --with-default-libstdcxx-abi=gcc4-compatible --disable-libunwind-
exceptions --enable-__cxa_atexit --enable-libssp --enable-lto --disable-
install-libiberty --with-gnu-ld --verbose --enable-java-home --with-java-
home=/usr/lib64/jvm/jre --with-jvm-root-dir=/usr/lib64/jvm --with-jvm-jar-
dir=/usr/lib64/jvm/jvm-exports --with-arch-directory=amd64 --with-antlr-
jar=/root/slackware64-current/source/d/gcc/antlr-runtime-3.4.jar --enable-
java-awt=gtk --disable-gtktest --disable-multilib --target=x86_64-
slackware-linux --build=x86_64-slackware-linux --host=x86_64-slackware-
linux
Thread model: posix
gcc version 5.3.0 (GCC)
C'est dans ce qui précède ?
à +
--
Hervé
[...]
Non. J'aurais du préciser : il faut passer cette option à gcc dan s la
commande de link, pour qu'il affiche ce qu'il fait (ou devrait faire
avec -###).
Cela dit, en tapant betement le message dans google j'arrive Ã
http://lists.linuxfromscratch.org/pipermail/blfs-support/2015-April/076525. html
qui semble dire que c'est un problème de flex... La page de flex (et la
mailing list) ne semblent pas accessibles actuellement.
-- Alain.
[...]
L'idée de cette commande est de voir si le linker ne fait pas de zà ¨le
avec les symbols (du style -z now).
A part ça, tu as deux possibilités :
1) Passer l'option "-Wl,-unresolved-symbols=ignore-in-shared-libs" (ou
"-Wl,--warn-unresolved-symbols") au moment du link. Cela dit, si c'est
difficile d'enlever -lfl je ne vois pas pourquoi ce serait facile
d'ajouter une option...
2) ajouter la déclaration suivante dans ton code :
extern "C" { int yylex() { return 0; } }
Je t'avais déjà proposé cela, mais sans le extern "C", ce qu i ne pouvait
pas marcher. Cela devrait satisfaire le linker, et ce ne sera jamais
utilisé de toute façon.
-- Alain.