The Man Who Fell From The Wrong Side Of Sky:2019年9月2日分

2019/9/2(Mon)

[オレオレN6] math.h(libm) vs cmath(libstdc++)

前回ちょっと書いたように、オレオレN6のgccは4.5.3とクソ古いので-std=c++11を要求するものがビルドできねえのでmk.confにGCC_REQD=8としてgcc8を使ってるのだけど、それでもなおビルドが通らないケースが多くて困る。

というのもlibstdc++においてC++11で導入されたcmathの新機能はlibmの同等の機能、例えばstd::round()であればround()を呼びだす事で実装されてるんだけど、N6のlibmにおいては一部の関数が未実装なので、c++config.hで_GLIBCXX_USE_C99_MATH_TR1が未定義となり一律無効化されてしまうので、-std=c++11する意味がねえのですわ。

$ grep _GLIBCXX_USE_C99_MATH_TR1 /usr/pkg/gcc8/include/c++/x86_64--netbsd/bits/c++config.h
/* #undef _GLIBCXX_USE_C99_MATH_TR1 */

libstdc++/configureを確認すると_GLIBCXX_USE_C99_MATH_TR1を有効にする為に現状で不足しとる関数は

acoshl
asinhl
atanhl
cbrtl
erfl
erfcl
exp2l
expm1l
fma/fmaf/fmal
hypotl
lgammal
llrintl
llroundl
log1pl
log2l
lrintl
lroundl
nearbyint/nearbyintf/nearbyintl
nexttowardf/nexttowardl
remainderl
remquol
rintl
roundl
scalbln/scalblnf/scalblnl
scalbnf/scalbnl
tgammal
truncl

うーん結構な数あるのよね、N8のlibmに更新すればかなりの部分が実装済ではあるんだけど、それでもなお

expm1l
lgammal
log2l
remainderl
remquol
tgammal

あたりは未実装なもよう。

なのでtextproc/icuとかビルドするとこんなエラーが出るわけだ。

c++ -I/usr/include -I/usr/pkg/include -D_REENTRANT -DU_HAVE_ELF_H=1 -DU_HAVE_NETBSD_ATOMIC_OPS=1 -DU_HAVE_ATOMIC=1 -DU_HAVE_STRTOD_L=0 -I. -I../common -DU_ATTRIBUTE_DEPRECATED= -DU_I18N_IMPLEMENTATION -O2 -march=i486 -I/usr/include -I/usr/pkg/include -W -Wall -pedantic -Wpointer-arith -Wwrite-strings -Wno-long-long -std=c++11 -c -o number_decimfmtprops.ao number_decimfmtprops.cpp

number_decimalquantity.cpp: In member function 'void icu_60::number::impl::DecimalQuantity::_setToDoubleFast(double)':
number_decimalquantity.cpp:387:40: error: 'round' is not a member of 'std'
     auto result = static_cast<int64_t>(std::round(n));
                                        ^
number_decimalquantity.cpp:387:40: note: suggested alternative:
In file included from /usr/pkg/gcc48/include/c++/cmath:44:0,
                 from number_decimalquantity.cpp:9:
/usr/pkg/gcc48/lib/gcc/i486--netbsdelf/4.8.5/include-fixed/math.h:347:8: note: 'round'
 double round(double);
        ^
../config/mh-bsd-gcc:43: recipe for target 'number_decimalquantity.ao' failed
gmake[1]: *** [number_decimalquantity.ao] Error 1

他にもdevel/cmakeとかわりと重要なシロモノが同様のエラーでビルドできひんので、連鎖的にビルド不能に陥るパッケージ多過ぎィ!で困るのよね。

とりあえずtextproc/icuやdevel/cmakeでエラーになる箇所はlibmに実装はあるので、この場合は回避策はあって

--- i18n/number_decimalquantity.cpp.orig        2018-03-26 13:38:30.000000000 +0000
+++ i18n/number_decimalquantity.cpp     2018-05-28 02:21:50.000000000 +0000
@@ -391,7 +391,7 @@ void DecimalQuantity::_setToDoubleFast(d
         for (; i <= -22; i += 22) n /= 1e22;
         n /= DOUBLE_MULTIPLIERS[-i];
     }
-    auto result = static_cast<int64_t>(std::round(n));
+    auto result = static_cast<int64_t>(round(n));
     if (result != 0) {
         _setToLong(result);
         scale -= fracLength;

としてcmathでなくmath.hのround関数を使うようなkludge patchを適用すればとりあえず何とかなる、でもこれビルド止まる度にこの手のパッチ書くのもめんどくせえよなぁ。

とりあえずコード監査途中で飽きて放置中のOpenSSLの件が片付いたら、次はlibmをとりあえず最新にしてそれから未実装の関数どうにかするかなんやな。