error: Unable to locate Java directoriesの対処法


こちらで詳しく質問させて頂いています。
http://ruzxa.hatenablog.com/entry/2014/11/21/140901

$ ./configure --enable-java --enable-dynamic --with-arith=gmp
~省略~
configure: error: Unable to locate Java directories
$ echo $PATH
省略:/usr/local/java/jdk1.8.0_40/bin


==エラーの箇所(configure)==
if ! ( test -n "${JAVA_INCLUDE_PATH}" -a -d "${JAVA_INCLUDE_PATH}" ) ; then
if test -d ${JAVA_HOME}/include ; then
JAVA_INCLUDE_PATH=${JAVA_HOME}/include
elif test -d ${JAVA_HOME}/Headers; then
JAVA_INCLUDE_PATH=-I${JAVA_HOME}/Headers
else
as_fn_error "Unable to locate Java directories" "$LINENO" 5
fi

"${JAVA_INCLUDE_PATH}が何を指しているのかわかれば問題がきちんとわかりそうなので追ってみました。

# Check whether --with-java-includes was given.
if test "${with_java_includes+set}" = set; then :
withval=$with_java_includes; JAVA_INCLUDE_PATH="${withval}"
fi

問題はここかなと思うのですが、shellに関して詳しくないためうまく構文が把握できません。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2014/11/21 14:16:30
  • 終了:2014/11/21 17:44:57
id:ruzxa

質問者から

ruzxa2014/11/26 15:45:38

configureファイルを添付させて頂きます。
Dropbox - configure
https://www.dropbox.com/s/uqve32vdzbgdu4k/configure?dl=0

質問①:
>if test "${with_java_includes+set}" = set; then :
これはtest構文かと思うのですが、 = は "eq"を意味し、"${with_java_includes+set}" と set が同値であるかの真偽判定をしているのでしょうか?

質問②:
setとは何を指すものなのでしょうか?
configure中にはsetは無数にあり、
shellではセットはオプションであり、今回のsetとは関係ないように感じ、どう解釈すべきか迷っています。

質問③:

このエラーの原因について
JAVA_HOMEが設定されているので、きちんとJDKが導入されていないという事になるのでしょうか?
普通はconfigureを追う事なく、JDKの確認を皆様ならされますか?



任意質問④:

># Check whether --with-java-includes was given.

は./configure 実行時にオプションとして--with-java-includesが存在するかどうかチェックしているといった解説なのでしょうか。

ベストアンサー

id:a-kuma3 No.1

a-kuma3回答回数4462ベストアンサー獲得回数18412014/11/21 16:13:12

質問③:
このエラーの原因について
JAVA_HOMEが設定されているので、きちんとJDKが導入されていないという事になるのでしょうか?

環境変数 JAVA_HOME は、きちんと設定されてますか?
/usr/local/java/jdk1.8.0_40 になってないと、駄目だと思います(PATH から判断して)。

質問の最後にある、echo $PATH じゃなくて、echo $JAVA_HOME を確認してみてください。
念には念を入れて、以下の二つが同じ出力になることも確認してみてください。

$ ls ${JAVA_HOME}
$ ls /usr/local/java/jdk1.8.0_40

どこかの回答に書きましたが、CVC3 は JNI という、java と C を橋渡しする仕組みを使っています。
これをコンパイルするには、JDK に含まれている jni.h という、C のヘッダファイルが必要です。
configure を引用してもらった範囲では、 jni.h があるはずの JAVA_HOME 配下の include もしくは、Headers というディレクトリがあるかどうかの確認をしています。

  # 「シェル変数 JAVA_INCLUDE_PATH に何か設定されてて、それがディレクトリだ」というとき以外
  if ! ( test -n "${JAVA_INCLUDE_PATH}" -a -d "${JAVA_INCLUDE_PATH}" ) ; then
    # つまり、ここには、シェル変数 JAVA_INCLUDE_PATH に設定されているものがディレクトリを指していないときに来ます

    # JAVA_HOME のディレクトリの下に、include というディレクトリがある場合
    if test -d ${JAVA_HOME}/include ; then
      JAVA_INCLUDE_PATH=${JAVA_HOME}/include

    # include はないけど、Headers というディレクトリがある場合
    elif test -d ${JAVA_HOME}/Headers; then
      JAVA_INCLUDE_PATH=-I${JAVA_HOME}/Headers

    # どちらもないときには、エラー
    else
      as_fn_error $? "Unable to locate Java directories" "$LINENO" 5
    fi
  fi


この部分よりも、ちょっと前のところに、こんなコードが書いてあるので、環境変数 JAVA_HOME を指定してから、configure を起動するか、configure のパラメータで JAVA_HOME を指定すれば、良さそうです。

# Check whether --with-java-home was given.
if test "${with_java_home+set}" = set; then :
  withval=$with_java_home; JAVA_HOME=${withval}
fi

java をインストールした先が /usr/local/java/jdk1.8.0_40 だとして、

$ JAVA_HOME=/usr/local/java/jdk1.8.0_40
$ export JAVA_HOME
$ ./configure --enable-java --enable-dynamic --with-arith=gmp

と、するか、

$ ./configure --enable-java --enable-dynamic --with-arith=gmp
          --with-java-home=/usr/local/java/jdk1.8.0_40

と、すれば良いと思います(見切れちゃうので、折り返しましたが、一行で入力です)。


もし、JAVA_HOME が正しく設定されているのであれば、configure のエラーは /usr/local/java/jdk1.8.0_40/include というディレクトリが存在していないということです。権限が無くても test -d は 真 を返したはずですので。
# ちょっと信じられないけど


普通はconfigureを追う事なく、JDKの確認を皆様ならされますか?

まず、簡単なプログラムを javac でコンパイルして、動かしてみます。
もし、動かなければ JDK は、正しくインストールできていないのでしょう。

もし、動くのなら、configure を読んでいると思います。
せっかく、中身を読めるものがそこにあるのだから、やみくもに色々なことを試すよりは、近道です。

それが、「普通」なのかどうかは知りません。

他3件のコメントを見る
id:a-kuma3

色々と調べてみたら、.bashrcにexport JAVA_HOMEがありませんでした。。。

おっと。
環境変数とシェル変数の違いで、はまってたわけですね。

bash (sh) の世界だと、見た目には export するかどうかの差しかないのですが、以下の挙動が違います。

  • シェル変数
    そのシェル (コマンドプロンプトを exit で抜けるまで、もしくは、与えられたシェルスクリプトが終わるまで) の中だけで有効です
  • 環境変数
    そのシェルから起動された子プロセスでも参照できます



褒められたことに気をよくして、残りの質問にも、答えておきます。

質問①:
>if test "${with_java_includes+set}" = set; then :
これはtest構文かと思うのですが、 = は "eq"を意味し、"${with_java_includes+set}" と set が同値であるかの真偽判定をしているのでしょうか?

${with_java_includes+set} は、シェル変数 with_java_includes に何か設定されていると "set" に置き換えられ、何も設定されてないと with_java_include の中身(つまり、空文字)に展開されます。

configure って、ああいう風に書きます。同じことをやるなら、ぼくはこう書きますが。

if test "${with_java_includes:+set}" = set; then :

コロンが付いてない書き方は、man sh に載ってないので、気持ちが悪いです。
尻のコロンも、気持ち悪いなあ。

ちなみに、test コマンドは = で文字列を、-eq で数値を比較します。

質問②:
setとは何を指すものなのでしょうか?
configure中にはsetは無数にあり、
shellではセットはオプションであり、今回のsetとは関係ないように感じ、どう解釈すべきか迷っています。

質問①の +set の set のことを言っているのであれば、どんな文字でも構わないんです。

if test "${with_java_includes+HOGE}" = HOGE; then :

「セットされてるかどうか」というコードなので、その意味を持つ単語を書いているだけです。
シェルの内部コマンドである set とは、何の関係もありません。

任意質問④:
># Check whether --with-java-includes was given.

は./configure 実行時にオプションとして--with-java-includesが存在するかどうかチェックしているといった解説なのでしょうか。

そうです。英語の意味そのまんま。

# --with-java-includes が与えられてるかどうかをチェック

マニュアル英語だと、given じゃなくて specified の方が良く使われるような気はする。

2014/11/21 18:41:01
id:ruzxa

ご回答頂きありがとうございます!
本当にunixの世界は広いですね。海を想像してしまいました。

気づいてしまえば当然ですが、一つ一つのコマンドについてもきちんと意味や違いがあって、常にアンテナを張るなり注意を払わなければ気づけない事も沢山あって、でも見過ごしてしまっている事も沢山あるんだろうなあと。
もっと言えば、付け焼刃ではどうにもならず実際に開発していなければ気づけない事もある。

などと、ご回答より、まざまざと感じた次第です。

毎回a-kuma3様よりご回答頂いているので、できる限り負担を減らさせて頂こうと
色々と突っ込んで調べてなんとかしようといったプレッシャー(笑)を感じるという
よい経験を積んでいるなあと感じます。
手元に見えるものは極力自分で解決をするスキルも大事です。

2014/11/22 00:32:50

その他の回答(0件)

id:a-kuma3 No.1

a-kuma3回答回数4462ベストアンサー獲得回数18412014/11/21 16:13:12ここでベストアンサー

質問③:
このエラーの原因について
JAVA_HOMEが設定されているので、きちんとJDKが導入されていないという事になるのでしょうか?

環境変数 JAVA_HOME は、きちんと設定されてますか?
/usr/local/java/jdk1.8.0_40 になってないと、駄目だと思います(PATH から判断して)。

質問の最後にある、echo $PATH じゃなくて、echo $JAVA_HOME を確認してみてください。
念には念を入れて、以下の二つが同じ出力になることも確認してみてください。

$ ls ${JAVA_HOME}
$ ls /usr/local/java/jdk1.8.0_40

どこかの回答に書きましたが、CVC3 は JNI という、java と C を橋渡しする仕組みを使っています。
これをコンパイルするには、JDK に含まれている jni.h という、C のヘッダファイルが必要です。
configure を引用してもらった範囲では、 jni.h があるはずの JAVA_HOME 配下の include もしくは、Headers というディレクトリがあるかどうかの確認をしています。

  # 「シェル変数 JAVA_INCLUDE_PATH に何か設定されてて、それがディレクトリだ」というとき以外
  if ! ( test -n "${JAVA_INCLUDE_PATH}" -a -d "${JAVA_INCLUDE_PATH}" ) ; then
    # つまり、ここには、シェル変数 JAVA_INCLUDE_PATH に設定されているものがディレクトリを指していないときに来ます

    # JAVA_HOME のディレクトリの下に、include というディレクトリがある場合
    if test -d ${JAVA_HOME}/include ; then
      JAVA_INCLUDE_PATH=${JAVA_HOME}/include

    # include はないけど、Headers というディレクトリがある場合
    elif test -d ${JAVA_HOME}/Headers; then
      JAVA_INCLUDE_PATH=-I${JAVA_HOME}/Headers

    # どちらもないときには、エラー
    else
      as_fn_error $? "Unable to locate Java directories" "$LINENO" 5
    fi
  fi


この部分よりも、ちょっと前のところに、こんなコードが書いてあるので、環境変数 JAVA_HOME を指定してから、configure を起動するか、configure のパラメータで JAVA_HOME を指定すれば、良さそうです。

# Check whether --with-java-home was given.
if test "${with_java_home+set}" = set; then :
  withval=$with_java_home; JAVA_HOME=${withval}
fi

java をインストールした先が /usr/local/java/jdk1.8.0_40 だとして、

$ JAVA_HOME=/usr/local/java/jdk1.8.0_40
$ export JAVA_HOME
$ ./configure --enable-java --enable-dynamic --with-arith=gmp

と、するか、

$ ./configure --enable-java --enable-dynamic --with-arith=gmp
          --with-java-home=/usr/local/java/jdk1.8.0_40

と、すれば良いと思います(見切れちゃうので、折り返しましたが、一行で入力です)。


もし、JAVA_HOME が正しく設定されているのであれば、configure のエラーは /usr/local/java/jdk1.8.0_40/include というディレクトリが存在していないということです。権限が無くても test -d は 真 を返したはずですので。
# ちょっと信じられないけど


普通はconfigureを追う事なく、JDKの確認を皆様ならされますか?

まず、簡単なプログラムを javac でコンパイルして、動かしてみます。
もし、動かなければ JDK は、正しくインストールできていないのでしょう。

もし、動くのなら、configure を読んでいると思います。
せっかく、中身を読めるものがそこにあるのだから、やみくもに色々なことを試すよりは、近道です。

それが、「普通」なのかどうかは知りません。

他3件のコメントを見る
id:a-kuma3

色々と調べてみたら、.bashrcにexport JAVA_HOMEがありませんでした。。。

おっと。
環境変数とシェル変数の違いで、はまってたわけですね。

bash (sh) の世界だと、見た目には export するかどうかの差しかないのですが、以下の挙動が違います。

  • シェル変数
    そのシェル (コマンドプロンプトを exit で抜けるまで、もしくは、与えられたシェルスクリプトが終わるまで) の中だけで有効です
  • 環境変数
    そのシェルから起動された子プロセスでも参照できます



褒められたことに気をよくして、残りの質問にも、答えておきます。

質問①:
>if test "${with_java_includes+set}" = set; then :
これはtest構文かと思うのですが、 = は "eq"を意味し、"${with_java_includes+set}" と set が同値であるかの真偽判定をしているのでしょうか?

${with_java_includes+set} は、シェル変数 with_java_includes に何か設定されていると "set" に置き換えられ、何も設定されてないと with_java_include の中身(つまり、空文字)に展開されます。

configure って、ああいう風に書きます。同じことをやるなら、ぼくはこう書きますが。

if test "${with_java_includes:+set}" = set; then :

コロンが付いてない書き方は、man sh に載ってないので、気持ちが悪いです。
尻のコロンも、気持ち悪いなあ。

ちなみに、test コマンドは = で文字列を、-eq で数値を比較します。

質問②:
setとは何を指すものなのでしょうか?
configure中にはsetは無数にあり、
shellではセットはオプションであり、今回のsetとは関係ないように感じ、どう解釈すべきか迷っています。

質問①の +set の set のことを言っているのであれば、どんな文字でも構わないんです。

if test "${with_java_includes+HOGE}" = HOGE; then :

「セットされてるかどうか」というコードなので、その意味を持つ単語を書いているだけです。
シェルの内部コマンドである set とは、何の関係もありません。

任意質問④:
># Check whether --with-java-includes was given.

は./configure 実行時にオプションとして--with-java-includesが存在するかどうかチェックしているといった解説なのでしょうか。

そうです。英語の意味そのまんま。

# --with-java-includes が与えられてるかどうかをチェック

マニュアル英語だと、given じゃなくて specified の方が良く使われるような気はする。

2014/11/21 18:41:01
id:ruzxa

ご回答頂きありがとうございます!
本当にunixの世界は広いですね。海を想像してしまいました。

気づいてしまえば当然ですが、一つ一つのコマンドについてもきちんと意味や違いがあって、常にアンテナを張るなり注意を払わなければ気づけない事も沢山あって、でも見過ごしてしまっている事も沢山あるんだろうなあと。
もっと言えば、付け焼刃ではどうにもならず実際に開発していなければ気づけない事もある。

などと、ご回答より、まざまざと感じた次第です。

毎回a-kuma3様よりご回答頂いているので、できる限り負担を減らさせて頂こうと
色々と突っ込んで調べてなんとかしようといったプレッシャー(笑)を感じるという
よい経験を積んでいるなあと感じます。
手元に見えるものは極力自分で解決をするスキルも大事です。

2014/11/22 00:32:50

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません