以下のような tweet を見かけた。
多分、
多分、
- GitHub / takashi-chikayama / SamurAI-Dig-Here-2020-21
$ cd /tmp $ git clone https://github.com/takashi-chikayama/SamurAI-Dig-Here-2020-21 Cloning into 'SamurAI-Dig-Here-2020-21'... remote: Enumerating objects: 419, done. remote: Counting objects: 100% (419/419), done. remote: Compressing objects: 100% (380/380), done. remote: Total 419 (delta 68), reused 389 (delta 38), pack-reused 0 Receiving objects: 100% (419/419), 11.74 MiB | 1.52 MiB/s, done. Resolving deltas: 100% (68/68), done. $ cd SamurAI-Dig-Here-2020-21/
$ git log -1 commit 3825c3dd0e2a31355d0ddafe320a9acf2316ec20 (HEAD -> master, origin/master, origin/HEAD) Author: Takashi <takashi.cikayama@gmail.com> Date: Fri Nov 27 16:16:41 2020 +0900 Fixed the problem of exportation in dighere.html page
$ make cd manager; make all make[1]: ディレクトリ '/tmp/SamurAI-Dig-Here-2020-21/manager' に入ります c++ -c -g -Wall -std=c++14 main.cc -o main.o c++ -MM -g -Wall -std=c++14 main.cc > main.d c++ -c -g -Wall -std=c++14 field.cc -o field.o c++ -MM -g -Wall -std=c++14 field.cc > field.d c++ -c -g -Wall -std=c++14 gamelog.cc -o gamelog.o c++ -MM -g -Wall -std=c++14 gamelog.cc > gamelog.d c++ -c -g -Wall -std=c++14 playgame.cc -o playgame.o playgame.cc: 関数 ‘void killPlayerProcess(int)’ 内: playgame.cc:30:3: エラー: ‘kill’ was not declared in this scope 30 | kill(playerIds[p], SIGKILL); | ^~~~ playgame.cc: 関数 ‘std::vector<StepLog> playGame(const Configuration&, char**, char*, int)’ 内: playgame.cc:136:39: エラー: ‘fdopen’ was not declared in this scope; did you mean ‘fopen’? 136 | close(pipeOut[0]); toPlayers[p] = fdopen(pipeOut[1], "w"); | ^~~~~~ | fopen playgame.cc:138:5: エラー: ‘kill’ was not declared in this scope 138 | kill(playerIds[p], SIGSTOP); | ^~~~ playgame.cc:181:7: エラー: ‘kill’ was not declared in this scope 181 | kill(playerIds[p], SIGCONT); | ^~~~ playgame.cc:194:2: エラー: ‘usleep’ was not declared in this scope; did you mean ‘sleep’? 194 | usleep(1000*checkInterval); | ^~~~~~ | sleep make[1]: *** [Makefile:14: playgame.o] エラー 1 make[1]: ディレクトリ '/tmp/SamurAI-Dig-Here-2020-21/manager' から出ます make: *** [Makefile:2: all] エラー 2みたいな感じで、スコープ内に kill() の宣言がないぞと言われて腐る。
Cygwin で kill(2) は /usr/include/sys/signal.h の 175-177 行目で以下のように宣言されている。
ところが、どうもこれを設定する際に参照しているマクロが -std=standard の設定で変化するらしく、-std=c++14 だと __POSIX_VISIBLE = 0 となってしまうため kill() の宣言をしてくれない。
これは、以下のようにすることで確認できる。
175 #if __POSIX_VISIBLE 176 int kill (pid_t, int); 177 #endifここで、__POSIX_VISIBLE は /usr/include/sys/signal.h にて、幾つかのマクロの設定状況を反映して、マクロ定義されてる。
ところが、どうもこれを設定する際に参照しているマクロが -std=standard の設定で変化するらしく、-std=c++14 だと __POSIX_VISIBLE = 0 となってしまうため kill() の宣言をしてくれない。
これは、以下のようにすることで確認できる。
$ echo "#include <signal.h>" >killcheck.cc
$ g++ -fdump-tree-all -E killcheck.cc | grep kill # 1 "killcheck.cc" # 1 "killcheck.cc" int kill (pid_t, int); int killpg (pid_t, int); int pthread_kill (pthread_t, int); # 2 "killcheck.cc" 2
$ g++ -std=c++14 -fdump-tree-all -E killcheck.cc | grep kill # 1 "killcheck.cc" # 1 "killcheck.cc" # 2 "killcheck.cc" 2
$ g++ -dM -E killcheck.cc | grep -E "VISIBLE|SOURCE" #define _ATFILE_SOURCE 1 #define _POSIX_SOURCE 1 #define _DEFAULT_SOURCE 1 #define __LARGEFILE_VISIBLE 0 #define __ISO_C_VISIBLE 2011 #define __RCSID_SOURCE(s) struct __hack #define __XSI_VISIBLE 0 #define __GNU_VISIBLE 0 #define __BSD_VISIBLE 1 #define __POSIX_VISIBLE 200809 #define __SVID_VISIBLE 1 #define _POSIX_C_SOURCE 200809L #define __ATFILE_VISIBLE 1 #define __MISC_VISIBLE 1
$ g++ -std=c++14 -dM -E killcheck.cc | grep -E "VISIBLE|SOURCE" #define __LARGEFILE_VISIBLE 0 #define __ISO_C_VISIBLE 2011 #define __RCSID_SOURCE(s) struct __hack #define __XSI_VISIBLE 0 #define __GNU_VISIBLE 0 #define __BSD_VISIBLE 0 #define __POSIX_VISIBLE 0 #define __SVID_VISIBLE 0 #define __ATFILE_VISIBLE 0 #define __MISC_VISIBLE 0
「g++ posix_visible std c++11」でググって、以下のページを見つけた。
− stackoverflow / 2018-09-04: Compiling with -std=c++11 on Cygwin hides available system calls
曰く、最近の g++ は標準で C++14 準拠なので -std=c++14 は不要との事。古い g++ 対策でもし付ける場合 -std=gnu++14 とかしとけと。
ということで、g++ でシステムコールを使う場合、-std=c++11 とか -std=c++14 とかは使っちゃ駄目ってことらしい。
SamurAI-Dig-Here-2020-21 に限って言えば g++ の場合
また clang++ は -std=c++14 付けても影響ないらしく
Pull Request 投げてみた。
− stackoverflow / 2018-09-04: Compiling with -std=c++11 on Cygwin hides available system calls
曰く、最近の g++ は標準で C++14 準拠なので -std=c++14 は不要との事。古い g++ 対策でもし付ける場合 -std=gnu++14 とかしとけと。
ということで、g++ でシステムコールを使う場合、-std=c++11 とか -std=c++14 とかは使っちゃ駄目ってことらしい。
SamurAI-Dig-Here-2020-21 に限って言えば g++ の場合
make CXXFLAGS='-g -Wall'または
make CXXFLAGS='-g -Wall -std=gnu++14'とすれば OK
また clang++ は -std=c++14 付けても影響ないらしく
make CXX=clang++としても大丈夫だった。
Pull Request 投げてみた。
- GitHub / takashi-chikayama / SamurAI-Dig-Here-2020-21 / Pull Request / Support: Cygwin g++ #1
Pull Request に返信付いて、こちらにもコメントを頂いたのだが、
コンパイルは出来たけど実行時にエラーになって、対処が難しそうとの事。
試しに
Cygwin だと一見きちんと動いているように見えて、何度か繰り返し実行してみると確かに何かおかしい。
調子が良いときは何事もなく動いているようなのだが、
調子が悪いと
agent が simple や digger だと不安定さが高い気もしたのが、何度かやってみると、発生頻度もかなりばらついているようで、どうも種類自体はあまり関係なさそうな雰囲気。
apt-cyg の裏で散々 pipe や fork は使われてるはずなのだが、こんな変な挙動は出会ったこと無いので、pipe や fork 自体が問題ってわけでもないと思うのだが、
なんだ、これ?
Ruby で OLE が安定しない件と関係あったりするんだろうか?
コンパイルは出来たけど実行時にエラーになって、対処が難しそうとの事。
試しに
manager/manager -S samples/sample.dighere players/{random,random}Player >result.dighereみたいにしてみると動くんだけど、
Cygwin だと一見きちんと動いているように見えて、何度か繰り返し実行してみると確かに何かおかしい。
調子が良いときは何事もなく動いているようなのだが、
調子が悪いと
Step: 1 Golds known: 6@(6,6) Agent 0 timed outとなって止まったり、
Agent 2 error in flushing pipeとなって、それ以降 Agent 2 が
Agent 2@(4,1) stay (4,1) 0 msec leftみたいににゲーム進行から脱落したりと挙動が安定しない。
agent が simple や digger だと不安定さが高い気もしたのが、何度かやってみると、発生頻度もかなりばらついているようで、どうも種類自体はあまり関係なさそうな雰囲気。
apt-cyg の裏で散々 pipe や fork は使われてるはずなのだが、こんな変な挙動は出会ったこと無いので、pipe や fork 自体が問題ってわけでもないと思うのだが、
なんだ、これ?
Ruby で OLE が安定しない件と関係あったりするんだろうか?
タグ
このページへのコメント
ご提案の方法でコンパイルはできるのですが,実行時エラーが出ます.これが簡単には直せそうにないので,当面 Windows 上では Windows Subsystem for Linux をお使いいただければと思います.