Bug #14200
closedaddr2line.c compile error with C89 compilers on Solaris 10
Description
r60841 にて、 addr2line.c では stdbool.h を使用するようになりましたが、
stdbool.h は C99 にて追加された仕様のため、
デフォルトが C89 になっている Solaris 10 上の古めのコンパイラの多くでは、
Solarisの標準ヘッダファイルに含まれるC標準バージョンチェックを通過できず、
以下のようなエラーになり、コンパイルに失敗します。
cc -errtags=yes -xO4 -xtarget=sparc64xplus -m64 -DRUBY_DEVEL=1 -DRUBY_EXPORT -I/usr/local/64/lib/libffi-3.0.10/include -I/usr/local/64/include -D_XOPEN_SOURCE=500 -I. -I.ext/include/sparc64-solaris2.10 -I./include -I. -I./enc/unicode/10.0.0 -o addr2line.o -c addr2line.c
"/usr/include/stdbool.h", line 42: #error: "Use of <stdbool.h> is valid only in a c99 compilation environment."
cc: acomp failed for addr2line.c
make: *** [addr2line.o] Error 2
これは Solaris 10 上の Oracle Solaris Studio 12.4 でのエラーです。
他に、古い gcc や Fujitsu C Compiler などでも同様のエラーとなります。
なお、Solaris10上の多少古めのコンパイラでも、C99は概ねサポートしており、
オプションでC99準拠を指定したり、それ相当の _XOPEN_SOURCE を定義すると、
コンパイルは通るはずではありますが、それに伴う副作用もあるので、
現時点では、容易に可能なら、それを指定しなくても通るようにしたいと思っています。
Updated by ngoto (Naohisa Goto) about 7 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r61326.
Support C89 if possible
-
addr2line.c: Because stdbool.h is a C99 feature, compile error
occurs with some old compilers without specifying C99 options.
Fix compile error with Oracle Solaris Studio 12.4 on Solaris 10.
[Bug #14200] [ruby-dev:50366] -
missing/stdbool.h: Alternative of stdbool.h for C89 compilers.
Updated by k0kubun (Takashi Kokubun) about 6 years ago
オプションでC99準拠を指定したり、それ相当の _XOPEN_SOURCE を定義すると、
コンパイルは通るはずではありますが、それに伴う副作用もあるので、
現時点では、容易に可能なら、それを指定しなくても通るようにしたいと思っています。
@ngoto (Naohisa Goto) [Misc #15347] というのを検討しておりまして、オプションでC99準拠を指定するか _XOPEN_SOURCE の指定を行なった場合に、Soraris 11や10、あるいは9以前に関してそれぞれについて具体的にどのような懸念や副作用があるかをお聞きしたいと思っております。お時間のある時にお返事いただけないでしょうか。
Updated by ngoto (Naohisa Goto) about 6 years ago
Soraris 11や10、あるいは9以前に関してそれぞれについて具体的にどのような懸念や副作用があるか
Solaris 9 およびそれ以前はもう考慮する必要はないと思います。
Solaris 10/11 の公式コンパイラである Oracle Developer Studio (旧名称 Oracle Solaris Studio、旧旧名称 Sun Studio)では、遅くともバージョン12以降ではC99をサポートしています。
デフォルトは、12.3 以前は -xc99=all,no_lib
(標準ライブラリはC90以前のまま、それ以外はC99準拠)。12.4 以降では、C11をサポートした影響で、デフォルトが -std=c11
(C11準拠)と前述の -xc99=all,no_lib
がその他のオプションの付与状況により選ばれる状況のようです。
Fujitsu C Compiler (fcc) では、私が使っていたバージョン5.6ではデフォルトC90で、c99
という別コマンドを使うとC99が使えますが、製品自体が2016年3月に販売終了していますし、あまり考えなくてよいとは思います。
_XOPEN_SOURCE
については、既に、Rubyの ./configure で最適なものを付与するようにしたつもりです。私の手元の環境では、Oracle Solaris Studio 12.4 では -D_XOPEN_SOURCE=500
が、Oracle Developer Studio 12.5 以降では -D_XOPEN_SOURCE=600
が./configureにより付与されています。
-D_XOPEN_SOURCE=600
(SUSv3)では C99 が必須、-D_XOPEN_SOURCE=500
(SUSv2) では C90 が必須だったと記憶しています。
問題が生じる可能性があるとすれば、Ruby本体またはユーザーがインストールした拡張ライブラリ等が使っているCのヘッダファイルの内部で _XOPEN_SOURCE
をdefineしていたり、特定の値を想定している場合でしょうか?標準ヘッダを正しく使う限りは問題は発生しないはずですが、利用者が追加でインストールしたライブラリ等ではあり得るかもしれません。
とはいえ、真っ当に書かれたコードなら、本来、問題は発生しないはずです。つまり、問題が発生する環境の方がおかしいと言えるとは思います。
Updated by ngoto (Naohisa Goto) about 6 years ago
r63571 で対策された isnan のように、準拠規格によって定義が異なる関数やマクロがあったら、問題は発生するのかもしれません。(今の所、私の環境では、Rubyのコンパイル時には遭遇したことはないので、具体例は無いのですが)
Updated by k0kubun (Takashi Kokubun) about 6 years ago
非常に詳細なご説明をいただきありがとうございます。
では、標準ライブラリに関しては諦めた上でその他の範囲でC99の一部の機能を使うことにした場合、Solaris 10, 11で、
- 公式の Oracle Developer Studio ではバージョン12以降で動くことを保証する。それ以前のバージョンでは、C99を有効化する方法がある限りconfigureでそれに対応し、それが可能な限りサポートする。
- Fujitsu C Compiler (fcc) は販売終了しているためサポートはベストエフォートとし、C99を要求するようにしたバージョンではconfigureに
CC=c99
を使うのを案内する。 - gccでは、もしC90がデフォルトになるようになっていた場合は、configureを調整しC99が有効になるように変更する。
という方針を取るのはいかがでしょうか。
特に問題なければ、 -xc99=all,no_lib
で動く範囲を意識した上で、(既にmswin側はvs12要求することになっている)Ruby 2.7の早い段階で [Misc #15347] の準備を行なうコードを入れてみようと思います。
r63571 で対策された isnan のように、準拠規格によって定義が異なる関数やマクロがあったら、問題は発生するのかもしれません。
修正は可能な範囲と理解していますが、移行時問題にはなりそうですね。情報ありがとうございます。
Updated by k0kubun (Takashi Kokubun) about 6 years ago
- Related to Misc #15347: Require C99 added
Updated by k0kubun (Takashi Kokubun) almost 6 years ago
https://github.com/ruby/ruby/pull/2064 で普通にstdbool.hを使えると見なすことにしているので、Oracle Solaris Studio 12.4やそれ以前での (r61326 のような対応をしない場合の) 現在のstdbool.hの挙動について補足します。
Oracle Solaris Studio 12.4¶
https://docs.oracle.com/cd/E57200_01/html/E57228/cc-1.html
最初のデフォルトは c11 であり、ANSI C11 で定義されている C ソース言語を拡張したものを受け入れることを意味します。2 番目のデフォルトはありません。代わりに、値なしで -std を指定すると、エラーが生成されます。フラグ -Xc、-Xa、-Xt、または -xtransition のいずれかを指定すると、-std の最初のデフォルトは無効になり、コンパイラではデフォルトで -xc99=all,no_lib が指定されます。-Xs を指定すると、最初のデフォルトは無効になり、コンパイラではデフォルトで -xc99=none が指定されます。-xc99 を指定すると、-std の最初のデフォルトは無効になり、コンパイラは -xc99 の指定を受け入れます。
従ってデフォルト(-std=c11
相当)では使えるはずですが、このチケットでレポートされている環境では「-Xc、-Xa、-Xt、または -xtransition のいずれか」が指定されていて -xc99=all,no_lib
相当になっていたか -Xs
が指定されていて -xc99=none
になっていたと理解しています。
一方、最近 r66605 で私が追加した AC_PROG_CC_C99
により、configure時にstdbool.hを使ったコードのコンパイル可否を検証して必要に応じて -xc99=all
を付加するようになったため、 r61326 は不要になったと理解しています。
Oracle Solaris Studio 12.3以下¶
https://docs.oracle.com/cd/E19205-01/821-2496/bjate/index.html
-xc99 を指定しない場合は、コンパイラではデフォルトで -xc99=all,no_lib が設定されます。値を指定しないで -xc99 を指定すると、オプションは -xc99=all に設定されます。
これにより、こちらはデフォルトでもstdbool.hが使えないと理解していますが、 AC_PROG_CC_C99
により -xc99=all
が付加され、configureにより stdbool.h が利用可能になっていると理解しています。
Updated by k0kubun (Takashi Kokubun) almost 6 years ago
最初に https://github.com/ruby/ruby/pull/2064 で列挙した機能に関してもう少し調べたところ、stdbool.h 以外はSun Studio 11でもドキュメントに記述が見られますが https://docs.oracle.com/cd/E19422-01/819-4764/819-4764.pdf 、 https://docs.oracle.com/cd/E27069_01/html/E26448/gkeza.html を見るとstdbool.hは12.3で追加されたように見えるので、12.4以下では-xc99=allが渡るように保証しつつも、stdbool.h に関しては 12.2以下のために r61326 と同様 missing/stdbool.h を使っておくのが無難そうですね。