carla_src/
probe.rs

1use std::path::{Path, PathBuf};
2
3use anyhow::{bail, ensure, Result};
4
5#[derive(Debug, Clone)]
6pub struct Probe {
7    pub prefix: PathBuf,
8    pub include_dirs: IncludeDirs,
9    pub lib_dirs: LibDirs,
10}
11
12#[derive(Debug, Clone)]
13pub struct IncludeDirs {
14    pub carla_source: PathBuf,
15    pub carla_third_party: PathBuf,
16    pub recast: PathBuf,
17    pub rpclib: PathBuf,
18    pub boost: PathBuf,
19    pub libpng: PathBuf,
20}
21
22#[derive(Debug, Clone)]
23pub struct LibDirs {
24    pub recast: PathBuf,
25    pub rpclib: PathBuf,
26    pub boost: PathBuf,
27    pub libpng: PathBuf,
28    pub libcarla_client: PathBuf,
29}
30
31impl IncludeDirs {
32    pub fn into_vec(self) -> Vec<PathBuf> {
33        let Self {
34            recast,
35            rpclib,
36            boost,
37            libpng,
38            carla_source,
39            carla_third_party,
40        } = self;
41        vec![
42            recast,
43            rpclib,
44            libpng,
45            boost,
46            carla_source,
47            carla_third_party,
48        ]
49    }
50}
51
52impl LibDirs {
53    pub fn into_vec(self) -> Vec<PathBuf> {
54        let Self {
55            recast,
56            rpclib,
57            boost,
58            libpng,
59            libcarla_client,
60        } = self;
61        vec![recast, rpclib, libpng, boost, libcarla_client]
62    }
63}
64
65pub fn probe<P>(carla_src_dir: P) -> Result<Probe>
66where
67    P: AsRef<Path>,
68{
69    let find_match = |pattern: &str| -> Result<_> {
70        let mut iter = glob::glob(pattern)?;
71
72        let path = match iter.next() {
73            Some(Ok(path)) => path,
74            Some(Err(err)) => return Err(err.into()),
75            None => bail!("Unable to match '{pattern}'"),
76        };
77        ensure!(
78            iter.next().is_none(),
79            "'{pattern}' matches more than one file"
80        );
81        Ok(path)
82    };
83
84    let carla_src_dir = carla_src_dir.as_ref();
85    let carla_source_dir = carla_src_dir.join("LibCarla").join("source");
86    let carla_third_party_dir = carla_source_dir.join("third-party");
87    let build_dir = carla_src_dir.join("Build");
88
89    // Detect CARLA version to use appropriate dependency versions
90    let carla_version = std::env::var("CARLA_VERSION").unwrap_or_else(|_| "0.9.16".to_string());
91    let (boost_pattern, recast_pattern, rpclib_pattern) = match carla_version.as_str() {
92        "0.9.14" => (
93            "boost-1.80.0-c*-install",
94            "recast-0b13b0-c*-install",
95            "rpclib-v2.2.1_c5-c*-libstdcxx-install",
96        ),
97        "0.9.15" => (
98            "boost-1.80.0-c*-install",
99            "recast-c*-install",
100            "rpclib-v2.2.1_c5-c*-libstdcxx-install",
101        ),
102        "0.9.16" => (
103            "boost-1.84.0-c*-install",
104            "recast-c*-install",
105            "rpclib-v2.2.1_c5-c*-libstdcxx-install",
106        ),
107        _ => bail!(
108            "Unsupported CARLA version: {}. Supported versions: 0.9.14, 0.9.15, 0.9.16",
109            carla_version
110        ),
111    };
112
113    let recast_dir = find_match(build_dir.join(recast_pattern).to_str().unwrap())?;
114    let rpclib_dir = find_match(build_dir.join(rpclib_pattern).to_str().unwrap())?;
115    let boost_dir = find_match(build_dir.join(boost_pattern).to_str().unwrap())?;
116
117    let libpng_dir = build_dir.join("libpng-1.6.37-install");
118    ensure!(
119        libpng_dir.exists(),
120        "Unable to find '{}'",
121        libpng_dir.display()
122    );
123
124    let libcarla_client_lib_dir = build_dir
125        .join("libcarla-client-build.release")
126        .join("LibCarla")
127        .join("cmake")
128        .join("client");
129    ensure!(
130        libpng_dir.exists(),
131        "Unable to find '{}'",
132        libcarla_client_lib_dir.display()
133    );
134
135    let include_dirs = IncludeDirs {
136        carla_source: carla_source_dir,
137        carla_third_party: carla_third_party_dir,
138        recast: recast_dir.join("include"),
139        rpclib: rpclib_dir.join("include"),
140        boost: boost_dir.join("include"),
141        libpng: libpng_dir.join("include"),
142    };
143    let lib_dirs = LibDirs {
144        recast: recast_dir.join("lib"),
145        rpclib: rpclib_dir.join("lib"),
146        boost: boost_dir.join("lib"),
147        libpng: libpng_dir.join("lib"),
148        libcarla_client: libcarla_client_lib_dir,
149    };
150
151    Ok(Probe {
152        prefix: carla_src_dir.to_path_buf(),
153        include_dirs,
154        lib_dirs,
155    })
156}