You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

run.rs 4.9 kB

5 months ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. use dora_tracing::set_up_tracing;
  2. use eyre::{Context, bail};
  3. use std::{env::consts::EXE_SUFFIX, path::Path};
  4. #[tokio::main]
  5. async fn main() -> eyre::Result<()> {
  6. set_up_tracing("c++-ros2-dataflow-example").wrap_err("failed to set up tracing")?;
  7. if cfg!(windows) {
  8. tracing::error!(
  9. "The c++ example does not work on Windows currently because of a linker error"
  10. );
  11. return Ok(());
  12. }
  13. let root = Path::new(env!("CARGO_MANIFEST_DIR"));
  14. let target = root.join("target");
  15. std::env::set_current_dir(root.join(file!()).parent().unwrap())
  16. .wrap_err("failed to set working dir")?;
  17. tokio::fs::create_dir_all("build").await?;
  18. let build_dir = Path::new("build");
  19. build_package("dora-node-api-cxx", &["ros2-bridge"]).await?;
  20. let node_cxxbridge = target.join("cxxbridge").join("dora-node-api-cxx");
  21. tokio::fs::copy(
  22. node_cxxbridge.join("dora-node-api.cc"),
  23. build_dir.join("dora-node-api.cc"),
  24. )
  25. .await?;
  26. tokio::fs::copy(
  27. node_cxxbridge.join("dora-node-api.h"),
  28. build_dir.join("dora-node-api.h"),
  29. )
  30. .await?;
  31. tokio::fs::copy(
  32. node_cxxbridge.join("dora-ros2-bindings.cc"),
  33. build_dir.join("dora-ros2-bindings.cc"),
  34. )
  35. .await?;
  36. tokio::fs::copy(
  37. node_cxxbridge.join("dora-ros2-bindings.h"),
  38. build_dir.join("dora-ros2-bindings.h"),
  39. )
  40. .await?;
  41. build_cxx_node(
  42. root,
  43. &[
  44. &dunce::canonicalize(Path::new("node-rust-api").join("main.cc"))?,
  45. &dunce::canonicalize(build_dir.join("dora-ros2-bindings.cc"))?,
  46. &dunce::canonicalize(build_dir.join("dora-node-api.cc"))?,
  47. ],
  48. "node_rust_api",
  49. &["-l", "dora_node_api_cxx"],
  50. )
  51. .await?;
  52. let dataflow = Path::new("dataflow.yml").to_owned();
  53. run_dataflow(&dataflow).await?;
  54. Ok(())
  55. }
  56. async fn build_package(package: &str, features: &[&str]) -> eyre::Result<()> {
  57. let cargo = std::env::var("CARGO").unwrap();
  58. let mut cmd = tokio::process::Command::new(&cargo);
  59. cmd.arg("build");
  60. cmd.arg("--package").arg(package);
  61. if !features.is_empty() {
  62. cmd.arg("--features").arg(features.join(","));
  63. }
  64. if !cmd.status().await?.success() {
  65. bail!("failed to compile {package}");
  66. };
  67. Ok(())
  68. }
  69. async fn build_cxx_node(
  70. root: &Path,
  71. paths: &[&Path],
  72. out_name: &str,
  73. args: &[&str],
  74. ) -> eyre::Result<()> {
  75. let mut clang = tokio::process::Command::new("clang++");
  76. clang.args(paths);
  77. clang.arg("-std=c++17");
  78. #[cfg(target_os = "linux")]
  79. {
  80. clang.arg("-l").arg("m");
  81. clang.arg("-l").arg("rt");
  82. clang.arg("-l").arg("dl");
  83. clang.arg("-l").arg("z");
  84. clang.arg("-pthread");
  85. }
  86. #[cfg(target_os = "windows")]
  87. {
  88. clang.arg("-ladvapi32");
  89. clang.arg("-luserenv");
  90. clang.arg("-lkernel32");
  91. clang.arg("-lws2_32");
  92. clang.arg("-lbcrypt");
  93. clang.arg("-lncrypt");
  94. clang.arg("-lschannel");
  95. clang.arg("-lntdll");
  96. clang.arg("-liphlpapi");
  97. clang.arg("-lcfgmgr32");
  98. clang.arg("-lcredui");
  99. clang.arg("-lcrypt32");
  100. clang.arg("-lcryptnet");
  101. clang.arg("-lfwpuclnt");
  102. clang.arg("-lgdi32");
  103. clang.arg("-lmsimg32");
  104. clang.arg("-lmswsock");
  105. clang.arg("-lole32");
  106. clang.arg("-lopengl32");
  107. clang.arg("-lsecur32");
  108. clang.arg("-lshell32");
  109. clang.arg("-lsynchronization");
  110. clang.arg("-luser32");
  111. clang.arg("-lwinspool");
  112. clang.arg("-Wl,-nodefaultlib:libcmt");
  113. clang.arg("-D_DLL");
  114. clang.arg("-lmsvcrt");
  115. }
  116. #[cfg(target_os = "macos")]
  117. {
  118. clang.arg("-framework").arg("CoreServices");
  119. clang.arg("-framework").arg("Security");
  120. clang.arg("-l").arg("System");
  121. clang.arg("-l").arg("resolv");
  122. clang.arg("-l").arg("pthread");
  123. clang.arg("-l").arg("c");
  124. clang.arg("-l").arg("m");
  125. }
  126. clang.args(args);
  127. clang.arg("-L").arg(root.join("target").join("debug"));
  128. clang
  129. .arg("--output")
  130. .arg(Path::new("../build").join(format!("{out_name}{EXE_SUFFIX}")));
  131. if let Some(parent) = paths[0].parent() {
  132. clang.current_dir(parent);
  133. }
  134. if !clang.status().await?.success() {
  135. bail!("failed to compile c++ node");
  136. };
  137. Ok(())
  138. }
  139. async fn run_dataflow(dataflow: &Path) -> eyre::Result<()> {
  140. let cargo = std::env::var("CARGO").unwrap();
  141. let mut cmd = tokio::process::Command::new(&cargo);
  142. cmd.arg("run");
  143. cmd.arg("--package").arg("dora-cli");
  144. cmd.arg("--release");
  145. cmd.arg("--")
  146. .arg("daemon")
  147. .arg("--run-dataflow")
  148. .arg(dataflow);
  149. if !cmd.status().await?.success() {
  150. bail!("failed to run dataflow");
  151. };
  152. Ok(())
  153. }