ルギア君の戯言

雑多な記事。

LLVM on OpenIndiana

ことの始まりは、Qt のビルドから。 一応、gcc-4.8.2 ではビルドできたし、qtconfig などはちゃんと動いている。OpenGL でプログラムを作成する用事があった (実際には Qt ではなく Windows Forms なのだが…) ので、その Qt で練習していた分には問題なかった。しかし、desingerqtdemo は動かなかった。

$ /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.hcstdlibmath.hcmath としても変わらず (libstdc++libc++ ともに)。

また、stdlib.hmath.h の include 順を変えた場合は通る。

何が問題って、何で math.h (の中の floatingpoint.h) で atof (や strtod) を宣言しているのかっていう点と、cstdlib でもないのに、std::atofstd 名前空間の中に閉じ込めて using で global からも呼び出せるようにしているのかという点。

ちなみに、string.hsys/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;
      ~~^

(※ vfscanfC++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 されてた。

*1

#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 が頻発しているので、再コンパイルだな。

*1:gcc 4.8.2 は自分でビルドしたもの

*2:http://www.silversoft.net/docs/standards.html

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
    • Intel Core 2 Duo 2.53 GHz (I'm not sure how long takes to compile KDE.)
    • 4GB memory.
    • NVIDIA GeForce 7 (NVIDIA seems that they dropped the support of 304.xx driver for the newest Linux (3.10.xx or later), and the nouveau driver was useless for me*1.)
  • SOFTWARE
    • OpenIndiana 151.1.8 x86 (Build KDE as 64 bit application)
    • Solaris Studio 12.3 (Even GCC of recent version for OpenIndiana is in development. So I used stable compiler. I won't (re)distribute the executables of KDE.)

Build Qt-4.8.5

  1. Download source.
  2. 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);
    
  3. 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.
  4. gmake and pray for all.
  5. gmake install

Build CMake-2.8.12

  1. Download source.
  2. Fix source.

    CMake configure detects that OI have the function backtrace_symbols, but at the line 1383 in cmake-2.8.12/Source/kwsys/SystemInformation.cxx they use that function without including execinfo.h. Workaround fix is to add #include <execinfo.h> somewhere in global scope before that line.

  3.  CC=cc CXX=CC CFLAGS="-xarch=sse3 -m64 -O5" CXXFLAGS="-xarch=sse3 -m64" LDFLAGS="-xarch=sse3 -m64" ./configure --prefix=/opt/kde
    
  4. gmake and pray for all.
  5. gmake install

*2

*1:3D applications still does not work?

*2:PS: Solaris 11 seems to have KDE.

コバルオンの話

  • 先回りをして行動するのだ!
  • 働かざる者 食うべからず!
  • 立ち止まってはならない!
  • あいさつに はじまって あいさつに おわる!
  • 同じ まちがいを くりかえさない!
  • さらに高みをめざすのだ!
  • かんたんに あきらめてはいけない!
  • かんしゃの心を 大切に!
  • ときには 休むことも ひつようだ!
  • たくわえを たやすな!
  • コツコツ努力を!
  • さぁ! いざ 進むのだ!
  • いつでも準備は できている!
  • 「リーダー」についてゆこうぞ!
  • なにも おそれることは ない!
  • 強い敵は わたしにまかせろ!

当たり前のことではありますが。

ポケダンのスクラッチくじ

ものの本性を見たくなるのは常にあることである(謎)。


真相は「たいようのいし」が欲しい (景品の中にあるのかも「僕は」知らないが…たしか「つきのいし」は見かけた)。
LV100 になるまえに絶対チュリネを進化させるぞ! と思っていたのだが、LV100 になるほうが残念ながら先になってしまった。『ドレディアを直接仲間にしろ』という話は受け付けないのでよろしく。


実力が伴う「ホッケー」や「潜水」は問題外として、くじはランダムだから、目的の物をゲットするのが少しむずかしいと思うのね。本当はダンジョン内で見つかるのが一番早いけど…。


なぜスクラッチかというと、

  • スピードくじはくじびきけんをとってくるのが面倒
  • けんしょうくじはダンジョンに行かないといけないのが面倒

というわけ。まあ、お金も 9,999 しか持てないからこれをいっぱいやっていると結構頻繁にあずかりボックスまで戻ることになるが…。

確認事項

  • 店員さんは乱数に無関係
  • 複数建設する理由もまずない
  • 1枚のスクラッチカードに対して、数学的なあたる確率は \frac{3}{5}。大当たりする確率は \frac{1}{5}。計算は省略。
  • 削る場所を選り好みしない。
  • ある特定の景品をゲットするのに何回くじをやれば良いかを考える。

ゲームから未確認の前提条件

  • 景品の種類があたり用、おおあたり用それぞれ別の 40 種類と仮定
    • 実際にカウントする際には、「てきしばりだま」「てきしばりだま×2」は別物と考える。
    • ここでは番号できめることにする (1〜80)。
  • 乱数にメルセンヌツイスタを使う
    • アルゴリズム以外にもどこからどのように使うかも問題はある。
    • メルセンヌツイスタなのは下で出てくる Ruby がそうだから。それだけ。

そこで、したのようなプログラムを作る (このプログラムは 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: そうとう金をつぎ込んだけど、やっぱり景品にない…?