Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

パラレルなcatkin buildでエラーになる #373

Closed
snozawa opened this issue Aug 28, 2015 · 23 comments
Closed

パラレルなcatkin buildでエラーになる #373

snozawa opened this issue Aug 28, 2015 · 23 comments

Comments

@snozawa
Copy link
Collaborator

snozawa commented Aug 28, 2015

#326
と同じようにまたエラーがでるきがします。
catkin buildでエラーがでて、-p1 -j1ならエラーでないです。

[ 83%] Generating /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_body.urdf
[ 83%] Built target urataleg_hrpsys_ros_bridge_tutorials_compile_lisp
[ 83%] Built target hrp2jsk_hrpsys_ros_bridge_tutorials_compile
[ 83%] [ 83%] Built target urataleg_hrpsys_ros_bridge_tutorials_compile_urdf
Built target hrp2jsknt_hrpsys_ros_bridge_tutorials_compile
[ 83%] Built target hrp2jsknts_hrpsys_ros_bridge_tutorials_compile
[ 83%] Built target hrp2w_hrpsys_ros_bridge_tutorials_compile
[ 83%] Built target hrp3hand_l_hrpsys_ros_bridge_tutorials_compile_all
[ 83%] [ 83%] Built target hrp3hand_r_hrpsys_ros_bridge_tutorials_compile_all
Built target hrp4r_hrpsys_ros_bridge_tutorials_compile
[ 83%] Generating /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED.urdf, /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED_meshes
;; Adding gazebo description
;; Use assimp export
;; output file is: /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED.urdf
;; mesh_prefix is: package://hrpsys_ros_bridge_tutorials/models/JAXON_RED_meshes
;; Mesh output directory is: /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED_meshes
;; Input file is: /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED.dae
[ 84%] Generating /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/jaxon_red.l
Traceback (most recent call last):
  File "/home/nozawa/ros/hydro/src/jsk-ros-pkg/jsk_model_tools/euscollada/scripts/remove_sensor_from_urdf.py", line 46, in <module>
    main(sys.argv[1:])
  File "/home/nozawa/ros/hydro/src/jsk-ros-pkg/jsk_model_tools/euscollada/scripts/remove_sensor_from_urdf.py", line 40, in main
    updateURDF(link_names, input_file, output_file)
  File "/home/nozawa/ros/hydro/src/jsk-ros-pkg/jsk_model_tools/euscollada/scripts/remove_sensor_from_urdf.py", line 26, in updateURDF
    xdoc = minidom.parse(input_file)
  File "/usr/lib/python2.7/xml/dom/minidom.py", line 1920, in parse
    return expatbuilder.parse(file)
  File "/usr/lib/python2.7/xml/dom/expatbuilder.py", line 924, in parse
    result = builder.parseFile(fp)
  File "/usr/lib/python2.7/xml/dom/expatbuilder.py", line 211, in parseFile
    parser.Parse("", True)
xml.parsers.expat.ExpatError: no element found: line 406, column 0
make[2]: *** [/home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_body.urdf]  1
make[1]: *** [CMakeFiles/JAXON_WH_SENSORS.urdf_generate.dir/all]  2
make[1]: *** ....
[ 84%] Built target staro_hrpsys_ros_bridge_tutorials_compile_urdf
   6370/  16471[ 84%] Built target jaxon_hrpsys_ros_bridge_tutorials_compile_urdf
  16380/  16471;
[ 85%] Generating staro_joint_minmax_conf_done
Xserver connection failedSensor HEAD_LEFT_CAMERA is attached to HEAD_LINK1 base_pinhole_camera #sensor3 0
Sensor lhsensor is attached to LARM_LINK7 base_force6d #sensor4 3
Sensor rhsensor is attached to RARM_LINK7 base_force6d #sensor5 2
Sensor lfsensor is attached to LLEG_LINK5 base_force6d #sensor6 1
Sensor rfsensor is attached to RLEG_LINK5 base_force6d #sensor7 0
Sensor gsensor is attached to BODY base_imu #sensor1 0
Sensor gyrometer is attached to BODY base_imu #sensor2 0
[ WARN] [1440754338.337507003]: could not find collada joint kmodel1/jointsid1000!

[ WARN] [1440754338.465552156]: could not find collada joint kmodel1/jointsid1000!

[ 85%] Built target staro_hrpsys_ros_bridge_tutorials_compile_joint_minmax
[ 85%] Built target jaxon_red_hrpsys_ros_bridge_tutorials_compile_lisp
;; #<rotational-joint #X4ead5b8 RARM_JOINT2> :joint-angle(0.0) violate max-angle(-15.8251)
;; #<rotational-joint #X4e50870 LARM_JOINT2> :joint-angle(0.0) violate min-angle(15.8251)
  10740/  25418[ 85%] Built target jaxon_red_hrpsys_ros_bridge_tutorials_compile_urdf
  25060/  25418;
;; #<rotational-joint #X4ead5b8 RARM_JOINT2> :joint-angle(0.0) violate max-angle(-15.8251)
;; #<rotational-joint #X4e50870 LARM_JOINT2> :joint-angle(0.0) violate min-angle(15.8251)
  10740/  25418[ 85%] Generating /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED_body.urdf
  25060/  25418;
;; #<rotational-joint #X4ead5b8 RARM_JOINT2> :joint-angle(0.0) violate max-angle(-15.8251)
;; #<rotational-joint #X4e50870 LARM_JOINT2> :joint-angle(0.0) violate min-angle(15.8251)
    690/    897;
;; #<rotational-joint #X4ead5b8 RARM_JOINT2> :joint-angle(0.0) violate max-angle(-15.8251)
;; #<rotational-joint #X4e50870 LARM_JOINT2> :joint-angle(0.0) violate min-angle(15.8251)
   4550/   4810;
[ 86%] Generating jaxon_joint_minmax_conf_done
Xserver connection failed[ 88%] Generating /home/nozawa/ros/hydro/src/rtm-ros-robotics/rtmros_tutorials/hrpsys_ros_bridge_tutorials/models/JAXON_RED_WH.urdf
@snozawa
Copy link
Collaborator Author

snozawa commented Aug 28, 2015

前に#84 のissueでもかきましたが、
euscolaldaのremove_sensor.pyやadd_sensor的なpythonプログラムはすべて一つにまとめたほうが良いです。

複数プログラムにわかれてると、cmakeの書き方が複雑になり、不要な一時生成ファイルがたくさんでき、また並列実行に弱いです。

@k-okada
Copy link
Member

k-okada commented Aug 28, 2015

これより前のログが見たいです

2015年8月28日金曜日、Shunichi [email protected]さんは書きました:

前にhttps://github.com/start-jsk/rtmros_tutorials/issues/84のissueでもかきましたが、
pythonプログラムはすべて一つにまとめたほうが良いです。

複数プログラムにわかれてると、cmakeの書き方が複雑になり、また並列実行に弱いです。


Reply to this email directly or view it on GitHub
#373 (comment)
.

◉ Kei Okada

@garaemon
Copy link
Member

元のファイルが、urdfかな、が中途半端なファイルになってそうですね。
もしかして同じファイルを二回生成しているんだろうか

2015年8月28日金曜日、Kei [email protected]さんは書きました:

これより前のログが見たいです

2015年8月28日金曜日、Shunichi Nozawa<[email protected]
javascript:_e(%7B%7D,'cvml','[email protected]');>さんは書きました:

前にhttps://github.com/start-jsk/rtmros_tutorials/issues/84のissueでもかきましたが、

pythonプログラムはすべて一つにまとめたほうが良いです。

複数プログラムにわかれてると、cmakeの書き方が複雑になり、また並列実行に弱いです。


Reply to this email directly or view it on GitHub
<
https://github.com/start-jsk/rtmros_tutorials/issues/373#issuecomment-135713565>

.

◉ Kei Okada


Reply to this email directly or view it on GitHub
#373 (comment)
.

✉︎ from iPhone

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 28, 2015

https://gist.github.com/snozawa/3d3586d3bd3865c7e9aa
です。
#326
と同様に

roscd hrpsys_ros_bridge_tutorials
git clean -xfd
catkin bt --start-with-this --force-cmake

で確認できます。

@k-okada
Copy link
Member

k-okada commented Aug 29, 2015

かなり古い記憶であやふやなんだけど,どこかの時点でrtmros_common以下の部分(cmake/compile_robot_model.cmake)
では並列の問題は解決したはずで,
その時にcmakeの依存関係の書き方はちょっと直感的でないところがあって,これはハマリポイント,とおもってコメントどこかに書いた気がするんだけど,
思い出せない.

で,とうぜんハマリポイントも思い出せていないんだけど,
add_dependencyは他のターゲットに依存する
http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:add_dependencies
(93fc70a)

add_custom_targetのDEPENDSはファイルを書いておく.この名前がターゲット名と依存するファイルになる.
http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:add_custom_target
(Dependencies listed with the DEPENDS argument may reference files and
outputs of custom commands created with add_custom_command() in the
same directory (CMakeLists.txt file))
(
start-jsk/rtmros_common@4b0f136#diff-5ac07341a443eee9bd9a1be4df6f848aR122
はダメか.
あと,なので,おなじDEPENDSを使ってはだめだったかどうか.CMakeで作られたMakefileをみてデバッグした記憶がある

add_custom_commandは
The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS is not specified the command will run whenever the OUTPUT is missing; if the command does not actually create the OUTPUT then the rule will always run. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command. Additionally, if the target is an executable or library a file-level dependency is created to cause the custom command to re-run whenever the target is recompiled.
とあって,思い出したけど,これが重要だった.で,なんで重要かというのは思い出せないけど,
DEPENDSに書いてあるフイルが,他のadd_custom_commandのOUTPUTにしておかないと,ちゃんと依存関係が出来ない,みたいなことだったか.
で,

If DEPENDS is not specified the command will run whenever the OUTPUT
is missing; if the command does not actually create the OUTPUT then
the rule will always run.
```で例えば,他のadd_custom_command
のOUTPUTでもない場合(xx_generate.pyみたいなファイルをDEPENDSに書いちゃっている場合)は,ちゃんと依存かんけいを見られずに走ってしまうんだっけか.
なので,もともと有るファイルに依存したければ

add_custom_command(output_file
COMMAND genpy input_file> output_file
DEPENDS input_file)
add_custmo_command(input_file
COMMAND genpy origin_file > input_file
DEPENDS all_depends)
add_custom_target(all_depends DEPENDS genpy origin_file)
add_custom_target(all_target ALL DEPENDS output_file)

みたいにするんだったっけな.

で,DEPENDSに書いてあるものがターゲットで,他のadd_xx_(例えばadd_custom_targetとか)に書いてある場合はOKだけど,ちゃんとファイルを書いておいたほうがいいという話だったか.
https://github.com/start-jsk/rtmros_common/pull/708 かなぁ.ちゃんとコメント書かないとダメだね.ひどい.
http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:add_custom_command

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 29, 2015

#326
と今回のPRの問題は、cmake/compile_robot_model.cmakeとは別な部分でおきているもののようです。

projectGenerator起因の並列問題はおっしゃるとおりのPRで解決しています。

https://github.com/start-jsk/rtmros_tutorials/blob/master/hrpsys_ros_bridge_tutorials/CMakeLists.txt#L391
以降の部分は、cmakeのマクロがここでかかれてかつ使われているもので、
URDFファイルに情報を足したりをしている部分になっているようです。
これが並列実行に弱くて何度も問題がおきてますが、
#373 (comment)
の意見は、

  • 今はいくつかのscriptを読んで一時生成ファイルがいくつかできて、cmakeでたくみに変換をかく

となってるのをせめて

  • 一つのscriptで実行して、cmakeはたくみにかかなくてすむようにする

などのようにするのがよさそうとのことでした。
そもそももう少し良いかんじの修正ができるかは#84 でも議論されてる途中です

@k-okada
Copy link
Member

k-okada commented Aug 29, 2015

いや,僕もprojectGeneratorの話はしていなくて,純粋にcmakeの理解不足から正しくないcmakeの依存関係が書かれているところが有るはず,という指摘です.で,それは,cmake/compile_robot_model.cmake と hrpsys_ros_bridge_tutorials/CMakeLists.txt の両方で起きる可能性があって,前者は直したつもりだけど,後者は最後まで見きれていないです,というのが僕の最新情報です.

で,#373 (comment) の理解が正しければ,
https://github.com/start-jsk/rtmros_tutorials/blob/master/hrpsys_ros_bridge_tutorials/CMakeLists.txt#L439

  add_custom_command(OUTPUT ${_model_dir}/HRP2JSK_WH.urdf
    COMMAND ${xacro_exe} ${_model_dir}/HRP2JSK.urdf.xacro > ${_model_dir}/HRP2JSK_WH.urdf
    DEPENDS ${_model_dir}/HRP2JSK.urdf.xacro ${_model_dir}/HRP2JSK.urdf)

みたいに,元から有るファイルがDEPENDSにあるのは危険ですね.という指摘です.

変なスクリプトを作ってその場しのぎをしていくのはやめよう,には大賛成ですが,そういうところまで手と頭が回る人はレアなので,それはそれでぼちぼち進めるとして,それとはべつに,正しいcmakeの書き方を共有して,治せるところを直すのがいいと思います.という意見でした.

@k-okada
Copy link
Member

k-okada commented Aug 29, 2015

ところで,

catkin bt --start-with-this --force-cmake

したとき右下にはなんて出ているかな?

1/2 Active | 7/8 Completed

なんだけど,-p2 して同じように 1/2となるようにしてもエラーに成るかなん.

snozawa added a commit to snozawa/rtmros_tutorials that referenced this issue Aug 29, 2015
@snozawa
Copy link
Collaborator Author

snozawa commented Aug 29, 2015

いや,僕もprojectGeneratorの話はしていなくて

すいません、確かにそうでした。。。

英語力に自信ないですが、add_custom_commandのドキュメントには

The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS is not specified the command will run whenever the OUTPUT is missing; if the command does not actually create the OUTPUT then the rule will always run. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command. Additionally, if the target is an executable or library a file-level dependency is created to cause the custom command to re-run whenever the target is recompiled.

とあって,思い出したけど,これが重要だった.で,なんで重要かというのは思い出せないけど, DEPENDSに書いてあるフイルが,他のadd_custom_commandのOUTPUTにしておかないと,ちゃんと依存関係が出来ない,みたいなことだったか. で,

ということなのでしょうか。
If any dependency ...の文章は、DEPENDSされてるものが他のadd_custom_commandのOUTPUTだったら、ちゃんと解決しますよ、ということくらいしかいっていないようにみえます。

また、

If DEPENDS is not specified the command will run whenever the OUTPUT is missing; if the command does not actually create the OUTPUT then the rule will always run. 

は、

で例えば,他のadd_custom_command のOUTPUTでもない場合(xx_generate.pyみたいなファイルをDEPENDSに書いちゃっている場合)は,ちゃんと依存かんけいを見られずに走ってしまうんだっけか.

はDEPENDSがなければ、普通に単品でtarget指定してるのと同じで(依存関係に規程されないテキトーなタイミングで)buildされますよ、ということをいっているようにみえます。

add_custom_xxで指定されない既存ファイルをDEPENDSにいれては動かない、とは明示的には書いてないきがします。
CMakeLists実行以前からある既存ファイルは、さすがにdependできるのではないでしょうか。。。

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 29, 2015

ところで,
catkin bt --start-with-this --force-cmake
したとき右下にはなんて出ているかな?

catkin bt --start-with-this --force-cmake -i -vしてみて、
8/8 Jobs | 1/8 Active | 11/12 Completed
のようなかんじになります。
Jobsは、hrpsys_ros_bridge/cmake/compile_robot_model.cmakeでサポートされてる変換部分のときで
8/8 Jobsくらい、その後の今回エラるところで2/8 Jobsくらいになります。

なんだけど,-p2 して同じように 1/2となるようにしてもエラーに成るかなん.

成功確率はあがりますが、エラったきがします。

SUCCESSNUM=0;NUM=0;while [ $NUM -lt 50 ]; do git clean -xfd . && catkin bt --force-cmake --start-with-this && SUCCESSNUM=`expr $SUCCESSNUM + 1`; NUM=`expr $NUM + 1`;done; echo "SUCCESS $SUCCESSNUM / $NUM"

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 29, 2015

エラー箇所ですが、見た限りでは必ずeuscollada/scripts以下のもので起こっているようでした。
もしかしたらこれ自体が並列実行に対応してない、とかがあるのかもしれません。

@k-okada
Copy link
Member

k-okada commented Aug 30, 2015

[ 4/4 Jobs | 1/4 Active | 7/8 Completed ]
k-okada@kokada-t440s:~/catkin_ws/ws_rtmros/src$ wstool  info
workspace: /home/k-okada/catkin_ws/ws_rtmros/src

 Localname        S SCM  Version-Spec UID  (Spec)  URI  (Spec) [http(s)://...]
 ---------        - ---- ------------ -----------  ---------------------------
 trans_system       git               47bba9fe39aa github.com/jsk-ros-pkg/trans_system
 rtmros_tutorials   git               474ea74bb30b github.com/start-jsk/rtmros_tutorials
 rtmros_gazebo      git               dd58f4c52d31 github.com/start-jsk/rtmros_gazebo
 rtmros_hrp2        git               236bbe66eb01 github.com/start-jsk/rtmros_hrp2
 rtmros_nextage   M git               0724b27bc120 github.com/tork-a/rtmros_nextage
 rtmros_hironx      git               d6c94aa3bdf6 github.com/start-jsk/rtmros_hironx
 rtmros_common      git               3dcb893889ea github.com/start-jsk/rtmros_common

indigoではあるけど上の状況でエラーがでないんだけど,もうなおしちゃったりしたのかな.

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 30, 2015

#376
でなおしました。

[ 4/4 Jobs | 1/4 Active | 7/8 Completed ]

4になってますね。(これでも前のバージョンならエラーになるとは思うのですが、、、)

@k-okada
Copy link
Member

k-okada commented Aug 30, 2015

治っているならまあいいか.

 The DEPENDS option specifies files on which the command depends. If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built. If DEPENDS is not specified the command will run whenever the OUTPUT is missing; if the command does not actually create the OUTPUT then the rule will always run. If DEPENDS specifies any target (created by an ADD_* command) a target-level dependency is created to make sure the target is built before any target using this custom command. Additionally, if the target is an executable or library a file-level dependency is created to cause the custom command to re-run whenever the target is recompiled.

の解釈だけど,#373 (comment) は間違いかな.もう少し思い出してきたのは,If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built
の部分だった気がしてきた.

add_custom_command(OUTPUT file_0 DEPENDS file_1 COMMAND 1_to_0)
add_custom_command(OUTPUT file_1 DEPENDS file_2 COMMAND 2_to_1)
add_custom_command(OUTPUT file_0 DEPENDS file_3 COMMAND 3_to_0)

とあると,automatically brings the other command into the target というのが,

file_0: file_1
   2_to_1              -> これができる
   1_to_0
file_1: file_2
   2_to_1    ー> これと並列に走る
file_0: file_3
   3_to_0

みたいになるんだっけな.

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 30, 2015

こちらは

add_custom_command(OUTPUT file_1 DEPENDS file_0 COMMAND 1_to_0)
add_custom_command(OUTPUT file_2 DEPENDS file_1 COMMAND 2_to_1)
add_custom_command(OUTPUT file_3 DEPENDS file_0 COMMAND 3_to_0)

file_1: file_0
   1_to_0
file_2: file_1
   2_to_1
   1_to_0
file_3: file_0
   3_to_0

でしょうか。

@k-okada
Copy link
Member

k-okada commented Aug 30, 2015

ん,どっちも同じだと思うけど(https://github.com/start-jsk/rtmros_tutorials/issues/373#issuecomment-136094620 の例だと1_to_0 というコマンドでfile_1 が出来る)
いずれにせよ,#373 (comment) だと,

file_2: file_1
   2_to_1       << こいつが余計
   1_to_0

で,この例だといいけど,outputに無いファイルがあるとか,謎な中間ファイルがあるとか,そういう風になって破綻していた気がします.直感的には(こいつが余計)な行は無いだろうと思ってCMake書くけど,実はこれが出てくるので,COMMANDの入出力がちゃんとOUTPUT, DEPENDにかかれているように作らないとダメだね,という話だったかと思います.

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 30, 2015

試しに

add_custom_command(
  OUTPUT ${PROJECT_SOURCE_DIR}/file1
  COMMAND touch ${PROJECT_SOURCE_DIR}/file1
  DEPENDS ${PROJECT_SOURCE_DIR}/file0)
add_custom_command(
  OUTPUT ${PROJECT_SOURCE_DIR}/file2
  COMMAND touch ${PROJECT_SOURCE_DIR}/file2
  DEPENDS ${PROJECT_SOURCE_DIR}/file1)
add_custom_command(
  OUTPUT ${PROJECT_SOURCE_DIR}/file3
  COMMAND touch ${PROJECT_SOURCE_DIR}/file3
  DEPENDS ${PROJECT_SOURCE_DIR}/file0)
add_custom_target(file_generated ALL DEPENDS ${PROJECT_SOURCE_DIR}/file1 ${PROJECT_SOURCE_DIR}/file2 ${PROJECT_SOURCE_DIR}/file3)

をCMakeLists.txtとしてみて、あらかじめ

touch file0

とした状態で

cmake . && make

としたら、CMakeFiles/file_generated/build.cmakeの中身は

CMakeFiles/file_generated: file1
CMakeFiles/file_generated: file2
CMakeFiles/file_generated: file3

file1: file0
        $(CMAKE_COMMAND) -E cmake_progress_report /tmp/aa/CMakeFiles $(CMAKE_PROGRESS_1)
        @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating file1"
        touch /tmp/aa/file1

file2: file1
        $(CMAKE_COMMAND) -E cmake_progress_report /tmp/aa/CMakeFiles $(CMAKE_PROGRESS_2)
        @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating file2"
        touch /tmp/aa/file2

file3: file0
        $(CMAKE_COMMAND) -E cmake_progress_report /tmp/aa/CMakeFiles $(CMAKE_PROGRESS_3)
        @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating file3"
        touch /tmp/aa/file3

file_generated: CMakeFiles/file_generated
file_generated: file1
file_generated: file2
file_generated: file3
file_generated: CMakeFiles/file_generated.dir/build.make
.PHONY : file_generated

# Rule to build all files generated by this target.
CMakeFiles/file_generated.dir/build: file_generated
.PHONY : CMakeFiles/file_generated.dir/build

CMakeFiles/file_generated.dir/clean:
        $(CMAKE_COMMAND) -P CMakeFiles/file_generated.dir/cmake_clean.cmake
.PHONY : CMakeFiles/file_generated.dir/clean

CMakeFiles/file_generated.dir/depend:
        cd /tmp/aa && $(CMAKE_COMMAND) -E cmake_depends "Unix Makefiles" /tmp/aa /tmp/aa /tmp/aa /tmp/aa /tmp/aa/CMakeFiles/file_generated.dir/DependInfo.cmake --color=$(COLOR)
.PHONY : CMakeFiles/file_generated.dir/depend

となって、「余計」部分がはいってなさそうでした。
もう少し複雑なCmakeをかくと際限するのかもしれません。

@k-okada
Copy link
Member

k-okada commented Aug 30, 2015

うーん.たしかにそうですねぇ.勘違いだったかなぁ?

@k-okada
Copy link
Member

k-okada commented Aug 30, 2015

cmake_minimum_required(VERSION 2.8)

add_custom_target(file0_target DEPENDS /tmp/file0)
add_custom_target(file1_target DEPENDS /tmp/file1)
add_custom_target(file2_target DEPENDS /tmp/file2)
add_custom_target(file3_target DEPENDS /tmp/file3)

add_custom_command(OUTPUT /tmp/file1
                   COMMAND sleep 1
                   COMMAND touch /tmp/file1
                   DEPENDS /tmp/file0)
add_custom_command(OUTPUT /tmp/file2
                   COMMAND touch /tmp/file2
                   DEPENDS /tmp/file1)
add_custom_command(OUTPUT /tmp/file3
                   COMMAND touch /tmp/file3
                   DEPENDS /tmp/file1)

#add_custom_target(file_generated DEPENDS /tmp/file1 /tmp/file2 /tmp/file3)                                
add_custom_target(all_file_generated ALL)
#add_dependencies(all_file_generated DEPENDS file_generated)                                               
add_dependencies(all_file_generated DEPENDS file3_target file2_target file1_target)
k-okada@kokada-t440s:/tmp/hoge/build$ rm /tmp/file* ;touch /tmp/file0; rm -fr CMakeFiles/ CMakeCache.txt; cmake .. && make -j4; grep -ri touch *
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/hoge/build
Scanning dependencies of target file1_target
Scanning dependencies of target file3_target
Scanning dependencies of target file2_target
[ 20%] [ 40%] [ 60%] Generating /tmp/file1
Generating /tmp/file1
Generating /tmp/file1
[ 60%] [ 80%] [100%] Built target file1_target
Generating /tmp/file3
Generating /tmp/file2
[100%] Built target file3_target
[100%] Built target file2_target
Scanning dependencies of target all_file_generated
[100%] Built target all_file_generated
CMakeFiles/file2_target.dir/build.make: touch /tmp/file2
CMakeFiles/file2_target.dir/build.make: touch /tmp/file1
CMakeFiles/file1_target.dir/build.make: touch /tmp/file1
CMakeFiles/file3_target.dir/build.make: touch /tmp/file3
CMakeFiles/file3_target.dir/build.make: touch /tmp/file1

ちなみに,コメントアウトを戻して最後のadd_dependencies(all_file_generated DEPENDS file3_target file2_target file1_target) をコメントアウトするとちゃんと動くから本当に微妙そう.

@snozawa
Copy link
Collaborator Author

snozawa commented Aug 31, 2015

ちょっと直してみました。
#384

まず原因ですが、euscolladaのスクリプトでほぼ落ちていて、
試しにhrpsys_ros_bridge_tutorials/models/gen_hand_attached_staro_model.sh(中でeuscollada系のスクリプトを読んでる)などで
input fileとされてるxx.urdfをwc -lで行数を調べてみました。
すると、catkin buildがちゃんと終わった後の行数とeuscollada系の中で呼ばれるときの行数が違いました。

つまり、xx.urdfをcollada_to_urdfで生成するのは時間がかかっていて、
生成途中で別なeuscollada系のスクリプトが走っていました。

岡田先生が元々おっしゃっていたのも多分これ系だと思われますが、cmakeをちゃんとした書き方にしてないとでてきそうです。
例えば、

add_custom_command(
  OUTPUT file0
  COMMAND [時間のかかるコマンド])
add_custom_command(
  OUTPUT file1
  COMMAND [file1のためのこまんど]
  DEPENDS file0)

として、file1がfile0のファイル自体にdependした場合、file0が存在したらfile1をつくるためのコマンドが実行されるようです。
そうすると、並列実行時にはファイルの中身が正しくできてないときに次のfile1のコマンドが実行されて、
なかみがちゃんとしてないfile0を山椒するのでエラーになります。

上記を

add_custom_command(
  OUTPUT file0
  COMMAND [時間のかかるコマンド])
add_custom_target(file0_generated DEPENDS file0)
add_custom_command(
  OUTPUT file1
  COMMAND [file1のためのこまんど]
  DEPENDS file0_generated)

としてfile0自体でなくてfile0_generatedのようなtargetという形態で依存させたら、
file0が生成されたタイミングでなくてコマンド実行終了をまっているように見えて、
なおるように見えます。

ただ、documentではっきりした記述がなくて
http://www.cmake.org/cmake/help/v3.2/command/add_custom_target.html
いまいちよく分かってない状況ではあります。

#384
ではxx.urdfをファイル自体でなくてtargetに依存させたら成功率100%になります(10回中10回)

@k-okada
Copy link
Member

k-okada commented Sep 1, 2015

#373 (comment) で注目すべきは,

[ 20%] [ 40%] [ 60%] Generating /tmp/file1
Generating /tmp/file1
Generating /tmp/file1
[ 60%] [ 80%] [100%] Built target file1_target
Generating /tmp/file3
Generating /tmp/file2

でfile1が3回つくられていることです.If any dependency is an OUTPUT of another custom command in the same directory (CMakeLists.txt file) CMake automatically brings the other custom command into the target in which this command is built がおこっています.これではダメで,期待している挙動はfile1は1回しか作られないようにすることです.

#373 (comment) との違いはtargetの数で,CMakeではtargetの数だけ別のディレクトリがCMakeFiles以下に作られて,その時に上に有るようにOUTPUTが無いときに,別のtargetにoutputが依存していると,それぞれのtargetにそのoutputを書き出すコマンドが自動挿入されるんだとおもいます.

なので,何かを生成するにはそのためのターゲットをつくっておいて,それに依存するものが複数有るときは,それぞれのターゲットが,最初のターゲットに依存する,という形にしないといけないということだとおもいます.

@snozawa
Copy link
Collaborator Author

snozawa commented Sep 1, 2015

なるほど、だいぶわかってきました。
確かにこの例でもfile2,file3をfile1でなくてfile1_generatedのtarget依存にすると
file1の生成も1階で適切に呼ばれてもいますね。

@snozawa
Copy link
Collaborator Author

snozawa commented Apr 8, 2016

現状なおっているので、closeします。

cmkaeの書き方(add_custom_target)まわりはちゃんと挙動を調べるひつようがありそうなのと、
それはさておきhrpsys_ross\bridge_tutorialsのurdf変換が現状複雑なので
更新時には中尉が必要

@snozawa snozawa closed this as completed Apr 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants