2008年8月26日火曜日

(FreeBSD) ports/devel/kdesdk3: /usr/local/include/FlexLexer.h:130: error: expected unqualified-id before numeric constant

portsのdevel/kdesdk3をportupgradeしたら、エラーになりました。



エラーが出た様子:



Making all in libgettext
gmake[4]:  `/ports.work/usr/ports/devel/kdesdk3/work/kdesdk-3.5.9/kbabel/common/libgettext'
flex -+ -opofiles.cc ./pofiles.ll
/bin/sh /usr/local/bin/libtool --silent --tag=CXX   --mode=compile c++ -DHAVE_CONFIG_H -I. -I../../..   -D_THREAD_SAFE -pthread -DQT_THREAD_SUPPORT   -I/usr/local/include -I/usr/local/include  -I/usr/local/include -D_GETOPT_H -D_THREAD_SAFE   -Wno-long-long -Wundef -Wall -W -Wpointer-arith -DNDEBUG -DNO_DEBUG -O2 -O2 -fno-strict-aliasing -pipe -Wno-non-virtual-dtor -fno-exceptions -fno-check-new -fno-common -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION  -MT pofiles.lo -MD -MP -MF .deps/pofiles.Tpo -c -o pofiles.lo pofiles.cc
pofiles.cc:450:5: warning: "YY_STACK_USED" is not defined
pofiles.cc:1518:5: warning: "YY_MAIN" is not defined
In file included from pofiles.cc:249:
/usr/local/include/FlexLexer.h:130: error: expected unqualified-id before numeric constant
pofiles.cc: In member function 'virtual int GettextBaseFlexLexer::yylex()':
pofiles.cc:575: error: 'yy_current_buffer' was not declared in this scope
pofiles.cc:731: error: 'yy_current_buffer' was not declared in this scope
pofiles.cc:754: error: 'yy_current_buffer' was not declared in this scope
pofiles.cc: In constructor 'GettextBaseFlexLexer::GettextBaseFlexLexer(std::istream*, std::ostream*)':
pofiles.cc:871: error: 'yy_current_buffer' was not declared in this scope
pofiles.cc: In destructor 'virtual GettextBaseFlexLexer::~GettextBaseFlexLexer()':
pofiles.cc:883: error: 'yy_current_buffer' was not declared in this scope
pofiles.cc: In member function 'virtual void GettextBaseFlexLexer::switch_streams(std::istream*, std::ostream*)':
pofiles.cc:890: error: 'yy_current_buffer' was not declared in this scope
(以下略)



後半のエラーは、一番最初のエラー



/usr/local/include/FlexLexer.h:130: error: expected unqualified-id before numeric constant



をきっかけに発生していると思われるので、最初のエラーだけ調べてみます。



/usr/local/include/FlexLexer.h を見ると、130行目あたりはこんな感じ。



    virtual int yylex();
    virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
    virtual int yywrap();



「cc」に「-E」オプションをつけると、プリプロセッサを通した後のコードが見られるので、そうやってエラーが出た130行目(に相当する行)を見ると



virtual int yylex();
virtual void switch_streams( std:: istream* new_in, std:: ostream* new_out = 0 );
virtual int 1;



となってまして、「virtual int 1;」という意味不明な行があり、これがエラーになっているんでしょう。なんじゃこりゃ?!



pofiles.ccを見たら



#define yywrap() 1



というのがあるから、このマクロが展開されて「1」が出てきているようです。



実は、FlexLexer.hは、/usr/include/FlexLexer.h にもあって、似たような記述を探すと



    virtual int yylex();
    virtual void switch_streams( std::istream* new_in, std::ostream* new_out );



こっちには、yywrap()はありません。



これで、ピンときました。



上の「エラーが出た様子」のログで、flexが実行されていますが、



  • flexは、/usr/bin/flexがつかわれていた


  • includeされたFlexLexer.hは、/usr/local/include/FlexLexer.h だった


というわけで、ツールとヘッダファイルが食い違っているのでエラーが出ているのでした。



とりあえずPATHの順番を変えて



# setenv PATH /usr/local/bin:$PATH



/usr/local/bin/flexをつかわせることで、正常にコンパイルできるようになり、portupgradeが完了しました。





だいたい、flexという名前のコマンドが、/usr/binと/usr/local/binの2箇所にあるのが、そもそも紛らわしいというか、混乱の元ですね。



# /usr/bin/flex --version
/usr/bin/flex version 2.5.4



# /usr/local/bin/flex --version
flex 2.5.35



/usr/local/bin/gflexとか、名前を変えてインストールしてくれればいいのにと思ったのですが、
http://sourceforge.net/projects/flex/
をみると、BSD Licenseになってるので、それじゃあgflexにはなりえませんか。





そうか。
pofiles.ccってflexが生成したファイルです。
flex自身は、自分が、/usr/bin/flexなのか、/usr/local/bin/flexなのか区別はつくはずだし、flex自身をビルドした際に、FlexLexer.hがどこにインストールされるのか、flexに教えておくことはできるはずです。flexがpofiles.ccを生成するときに



#include "/usr/include/FlexLexer.h"



もしくは



#include "/usr/local/include/FlexLexer.h"



のどちらか、適切な方のコードを生成してくれていれば、上のような、違うヘッダファイルをインクルードしてしまう、ってことは無くなるんじゃないですかね?うまくいかないかな?



とはいえ、同名で別バージョンのコマンドをインストールするというのは、紛らわしいことですし、できるだけ避けるべきでしょう。



1 件のコメント:

  1. はじめまして。私も同じエラーが出て、検索してこちらにたどり着きました。
    おかげさまで、PATHの設定を変更して無事KDE3をビルドすることができました。
    ありがとうございます。

    返信削除