LLVM on OpenIndiana
ことの始まりは、Qt のビルドから。
一応、gcc-4.8.2 ではビルドできたし、qtconfig
などはちゃんと動いている。OpenGL でプログラムを作成する用事があった (実際には Qt ではなく Windows Forms なのだが…) ので、その Qt で練習していた分には問題なかった。しかし、desinger
や qtdemo
は動かなかった。
$ /opt/kde/bin/designer
Segmentation Fault (core dumped)
何が原因かよく分からないので、clang
でもビルドしてみることにした (Qt では clang でのビルドは unsupported 扱いになっているが…)。
その辺はあくまで発見した経緯で、問題になったのは次のソースを C++ としてコンパイルした場合。
#include <stdlib.h>
#include <math.h>
int main() {
return 0;
}
もちろん(?)、g++
では問題なく通る。これを clang++
でコンパイルすると、…
/usr/include/floatingpoint.h:204:15: error: declaration conflicts with target of
using declaration already in scope
extern double atof __P((const char *));
^
/usr/include/iso/stdlib_iso.h:124:15: note: target of using declaration
extern double atof(const char *);
^
/usr/include/stdlib.h:52:12: note: using declaration
using std::atof;
^
(atof
のほか strtod
に対しても出る)
ちなみに、stdlib.h
→cstdlib
、math.h
→cmath
としても変わらず (libstdc++
、libc++
ともに)。
また、stdlib.h
と math.h
の include 順を変えた場合は通る。
何が問題って、何で math.h
(の中の floatingpoint.h
) で atof
(や strtod
) を宣言しているのかっていう点と、cstdlib
でもないのに、std::atof
と std
名前空間の中に閉じ込めて using
で global からも呼び出せるようにしているのかという点。
ちなみに、string.h
と sys/socket.h
でも起こる。
どちらも __EXTENSIONS__
の定義が無ければ回避できるが、かなりの量の宣言が消えるので、たとえコンパイルが通ったとしても、それはそれで問題がある。
/opt/llvm/3.4/include/c++/v1/cstdio:148:9: error: no member named 'vfscanf' in
the global namespace; did you mean 'fscanf'?
using ::vfscanf;
~~^
(※ vfscanf
は C++11 では宣言されているはずであるが、OpenIndiana では対応していない。)
だから、floatingpoint.h
とか普通使わない拡張機能のヘッダを math.h
を読む前にあらかじめ読んで、別の名前空間に入れてしまえば一応解決できる(?)。
#include <stdlib.h>
namespace _fp {
extern "C" {
#include <floatingpoint.h>
}
}
#include <math.h>
sys/socket.h
の方はこんな感じ。
#include <string.h>
namespace _sys_un {
extern "C" {
#include <sys/un.h>
}
}
using _sys_un::sa_family_t;
#include <sys/socket.h>
ちなみに Qt では mutex
という名前の変数 (QMutex
型) を使っているが、sys/mutex.h
で構造体の名前として使われているため、それの回避も。
namespace _sys_mut {
extern "C" {
#include <sys/mutex.h>
}
}
using _sys_mut::kmutex_t;
あれ、でもそれって本来問題ない様な…
LLVM
LLVM (clang) がなんかホットみたいだから、 OpenIndiana で clang をビルドしてやろうと思って、ビルドしてて何か不思議なエラーが大量にでるなと思ったら、変な定数が define されてた。
#include <cstdlib> int main(void) { return ES; }
$ g++ -o a a.cpp -Wl,-R/opt/gcc/4.8.2/lib $ ./a $ echo $? 2
#include <cstdlib> #define ES ES int main(void) { return ES; }
$ g++ -o a a.cpp -Wl,-R/opt/gcc/4.8.2/lib a.cpp:2:0: warning: "ES" redefined [enabled by default] #define ES ES ^ In file included from /usr/include/sys/ucontext.h:36:0, from /usr/include/sys/signal.h:245, from /usr/include/sys/procset.h:42, from /usr/include/sys/wait.h:43, from /usr/include/stdlib.h:38, from /opt/gcc/4.8.2/include/c++/4.8.2/cstdlib:72, from a.cpp:1: /usr/include/sys/regset.h:111:0: note: this is the location of the previous definition #define ES 2 ^ (以下略)
あんなところに定義されているのか。付近のソースを読んだところ、__EXTENSIONS__
を undef しておけば大丈夫だろう*2。
ちなみに Solaris Studio の C++ コンパイラ CC では cstdlib が stdlib.h を読み込む形になっていないだけでなく、__EXTENSIONS__
も定義していない様です。
$ CC -o a a.cpp "a.cpp", 行 4: エラー: ES は定義されていません. 1 個のエラーが検出されました.
PS: make clang-test で Abort が頻発しているので、再コンパイルだな。
Trying to build KDE on OpenIndiana - Part 1
I just want to use KDE!
I searched, but I couldn't get information about this.
This is my memo to remeber what I did. So some details may be omitted.
I'm not good at English.
Environment
- HARDWARE
- SOFTWARE
Build Qt-4.8.5
- Download source.
Fix source.
Line 899 in
qt-everywhere-opensource-src-4.8.5/src/gui/dialogs/qfiledialog.cpp
,getpwnum_r
in OI151 is defined as conformed to POSIX, Qt detects as Solaris OS and_POSIX_C_SOURCE
is not defined.err = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize, &tmpPw);
CC=cc CXX=CC CFLAGS="-xarch=sse3 -m64 -O5" CXXFLAGS="-xarch=sse3 -m64" LDFLAGS="-xarch=sse3 -m64" ./configure --prefix=/opt/kde
-O5
option seems ignored. Because they use-O2
.
gmake
and pray for all.gmake install
Build CMake-2.8.12
- Download source.
Fix source.
CMake configure detects that OI have the function
backtrace_symbols
, but at the line 1383 incmake-2.8.12/Source/kwsys/SystemInformation.cxx
they use that function without includingexecinfo.h
. Workaround fix is to add#include <execinfo.h>
somewhere in global scope before that line.CC=cc CXX=CC CFLAGS="-xarch=sse3 -m64 -O5" CXXFLAGS="-xarch=sse3 -m64" LDFLAGS="-xarch=sse3 -m64" ./configure --prefix=/opt/kde
gmake
and pray for all.gmake install
ポケダンのスクラッチくじ
ものの本性を見たくなるのは常にあることである(謎)。
真相は「たいようのいし」が欲しい (景品の中にあるのかも「僕は」知らないが…たしか「つきのいし」は見かけた)。
LV100 になるまえに絶対チュリネを進化させるぞ! と思っていたのだが、LV100 になるほうが残念ながら先になってしまった。『ドレディアを直接仲間にしろ』という話は受け付けないのでよろしく。
実力が伴う「ホッケー」や「潜水」は問題外として、くじはランダムだから、目的の物をゲットするのが少しむずかしいと思うのね。本当はダンジョン内で見つかるのが一番早いけど…。
なぜスクラッチかというと、
- スピードくじはくじびきけんをとってくるのが面倒
- けんしょうくじはダンジョンに行かないといけないのが面倒
というわけ。まあ、お金も 9,999 しか持てないからこれをいっぱいやっていると結構頻繁にあずかりボックスまで戻ることになるが…。
確認事項
- 店員さんは乱数に無関係
- 複数建設する理由もまずない
- 1枚のスクラッチカードに対して、数学的なあたる確率は 。大当たりする確率は 。計算は省略。
- 削る場所を選り好みしない。
- ある特定の景品をゲットするのに何回くじをやれば良いかを考える。
ゲームから未確認の前提条件
- 景品の種類があたり用、おおあたり用それぞれ別の 40 種類と仮定
- 実際にカウントする際には、「てきしばりだま」「てきしばりだま×2」は別物と考える。
- ここでは番号できめることにする (1〜80)。
- 乱数にメルセンヌツイスタを使う
そこで、したのようなプログラムを作る (このプログラムは Ruby 1.9 以降でしか動かない上、いくつか問題を抱えています)。
#!/usr/bin/ruby # カード (1 がマークのあるところ) card = [0, 0, 1, 1, 1, 1] # 景品 (1〜40 は あたり用、41〜80 はおおあたり用) award = { :win => (1..40).to_a, :jackpot => (41..80).to_a } # ゲットした景品 get = [] # ほしい景品 want = 51 # 統計情報用 (それぞれ得た回数) data = { :lose => 0, :win => 0, :jackpot => 0, :got_time => [], :got_time_max => nil, :got_time_min => nil, } # 1000回トライしてみて、取れるまでの平均を求める。 1000.times do # 得た景品をリセット get = [] loop do |i| # 景品を決める aw = { :win => award[:win].sample, :jackpot => award[:jackpot].sample } # カードを作る card = card.shuffle # 削るところを選ぶ kezuri = card.sample(3) # 判定 case kezuri.inject(0) { |s, m| s + m } when 1 data[:lose] += 1 when 2 data[:win] += 1 get << aw[:win] # 欲しい景品ならループを抜ける break if aw[:win] == want when 3 data[:jackpot] += 1 get << aw[:jackpot] break if aw[:jackpot] == want end end # 集計 s = get.size data[:got_time] << s data[:got_time_max] ||= s data[:got_time_min] ||= s if data[:got_time_max] < s then data[:got_time_max] = s end if data[:got_time_min] > s then data[:got_time_min] = s end end # 結果を表示 puts "LOSE : %7d" % data[:lose] puts "WIN : %7d" % data[:win] puts "JACKPOT: %7d" % data[:jackpot] puts "" ave = data[:got_time].inject(0) { |s, m| s + m } / data[:got_time].size.to_f puts "Average Challenge to get #{want}: #{ave}"
実行すると、
$ ruby scratch.rb LOSE : 40570 WIN : 121298 JACKPOT: 40242 Average Challenge to get 51: 161.54 Maximum Challenge to get 51: 1622 Minimum Challenge to get 51: 1
となります。最悪で 1600 回もやらないと得られないとか、だるすぎる。
次、その景品が「あたり」の場合。
$ ruby scratch.rb LOSE : 13599 WIN : 41162 JACKPOT: 13697 Average Challenge to get 11: 54.859 Maximum Challenge to get 11: 539 Minimum Challenge to get 11: 1
これでも最悪で 539 とかまで行ってますね。当然、あたる確率が3倍なので、必要な挑戦回数は3分の1で済みますね。また景品の種類が倍なら、必要な挑戦回数も倍になります。
ただ具体的な目安が欲しかったという話。
PS: そうとう金をつぎ込んだけど、やっぱり景品にない…?