CPUの個数でcatkin_makeが通ったり通らなかったり
Fri Jul 7 23:04:49 JST 2017 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 7491, keywords:C++,C/C++,ROS この記事は最終更新日が7年以上前のものです。
表題の通り少しハマりました。ROSについては本を書いたものの、基礎的な内容+Pythonなので、C++のコードのビルドについてはほとんど勉強しておらず、良く分かってないのが良くわかりました。同じようにハマる人がこの記事を見つけてくれたらと。また、この症状の回避方法について良く知られているのならば教えていただければと。
症状
- 1. .msgファイルと、それを使うC++のコードを含むパッケージのcatkin_makeが、.msgファイルの処理の前にノードのコードのコンパイルを始めて一度コケるが、2度目で通る。
- 2. Travis CIだと2回catkin_makeしても通らない。
ちなみにエラーはこんな感じです。Buttons.hとLeds.hが、.msgファイルから作られるヘッダファイルで、これがないとC++のコードのところでヘッダファイルが無いと叱られます。
原因
自分のPCやラズパイでは1回目のcatkin_makeはエラーを出すものの.msgの処理を完了できて、一方Travis CIの場合は完了できないということは、非同期処理のズレだろうというのがまず思いつきました。そして、Travis CIのエラーにInvoking "make -j2 -l2" failed
とあったので、たぶんズレはコア数の違いで起こるんだろうと思いました。(makeのjオプションは、何並列で処理をするかを指定するオプションです。)
ということで、手元で
catkin_make -j2 $
を繰り返したら、何回catkin_makeしても失敗するという、Travis CIで起きたのと同じ現象が起こりました。ちなみにPCのCPUのコア数は8、ラズパイでも4だったので、Travis CIの方が少ないということになります。
解決(超小手先)
ということで、Travis CIでcatkin_makeするシェルスクリプトの行をcatkin_make -j8 || catkin_make -j8 #CPU2個だけど8並列頑張ってね。しかも1回目コケたらもう一回やってね。
というように変更したらテストにパスしました。
お断りしておきますが、小手先です。何かすればコンパイルの順番を制御できるはずなのですが・・・。
完全解決
・・・と書いたら教えていただきました。
同じパッケージ内でC++のターゲットより先にmsgを先に処理したい場合、
— akio (@__akio__) July 7, 2017
add_dependencies(${TARGET_NAME} ${PROJECT_NAME}_generate_messages_cpp)
などと明示的に依存を指定するといいですよ
(もっと短い書き方がありそうですが)とりあえずベタにCMakeLists.txtに以下のように書いたら一回のcatkin_make(オプションなし)で通りました。
add_dependencies(leds ${TARGET_NAME} ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(buttons ${TARGET_NAME} ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(lightsensors ${TARGET_NAME} ${PROJECT_NAME}_generate_messages_cpp)
ありがとうございました!!!