bind_builder/types/
local_library.rs

1use std::path::{Path, PathBuf};
2use crate::types::cmake_builder::CMakeBuilder;
3
4const DEFAULT_LIBRARY_DIRECTORIES: [&str; 2] = [
5    "lib",
6    "lib64",
7];
8
9const DEFAULT_INCLUDE_DIRECTORIES: [&str; 1] = [
10    "include",
11];
12
13/// Local library configuration.
14///
15/// This contains all the information required to link against a local library.
16#[derive(Clone)]
17pub struct LocalLibrary {
18    install_directory: PathBuf,
19
20    link_targets: Vec<String>,
21    system_link_targets: Vec<String>,
22
23    include_directories: Vec<PathBuf>,
24    library_directories: Vec<PathBuf>,
25}
26
27impl LocalLibrary {
28
29    /// Create a new `LocalLibrary` instance from a specific path.
30    ///
31    /// This is useful when you want to ship binaries with your crate.
32    pub fn new(install_directory: &Path) -> LocalLibrary {
33
34        let mut local_library = LocalLibrary {
35            install_directory: install_directory.into(),
36
37            link_targets: Vec::new(),
38            system_link_targets: Vec::new(),
39
40            include_directories: Vec::new(),
41            library_directories: Vec::new(),
42        };
43
44        // Add default include and library directories.
45        for include_directory in DEFAULT_INCLUDE_DIRECTORIES {
46            local_library.add_include_directory(Path::new(include_directory));
47        }
48
49        for library_directory in DEFAULT_LIBRARY_DIRECTORIES {
50            local_library.add_library_directory(Path::new(library_directory));
51        }
52
53        local_library
54    }
55
56    /// Create a new `LocalLibrary` instance from a `CMakeBuilder`.
57    pub fn from(
58        repository: CMakeBuilder,
59    ) -> LocalLibrary {
60
61        let install_directory = match repository.get_install_directory().exists() {
62            true => repository.get_install_directory(),
63            false => panic!("Could not find install directory, is repository built?")
64        };
65
66        let build_target = repository.get_build_target().clone().unwrap_or("all".to_string());
67        let mut local_library = LocalLibrary::new(install_directory);
68
69        if build_target.to_lowercase() != "all"{
70            local_library.link_target(build_target.as_str());
71        }
72
73        local_library
74    }
75
76    /// Add a directory that will be searched for include files.
77    ///
78    /// The path should be relative to the installation directory.
79    pub fn add_include_directory(
80        &mut self,
81        path: &Path,
82    ) -> &mut LocalLibrary {
83
84        // Check include directory exists
85        let include_directory = self.install_directory.join(path);
86        if include_directory.exists() && include_directory.is_dir() {
87            self.include_directories.push(include_directory)
88        }
89
90        self
91    }
92
93    /// Add a directory that will be searched for library files.
94    ///
95    /// The path should be relative to the installation directory.
96    pub fn add_library_directory(
97        &mut self,
98        path: &Path,
99    ) -> &mut LocalLibrary {
100
101        // Check library directory exists
102        let library_directory = self.install_directory.join(path);
103        if library_directory.exists() && library_directory.is_dir() {
104            self.library_directories.push(library_directory)
105        }
106
107        self
108    }
109
110    /// Add a target to link against.
111    ///
112    /// Before linking, the crate will check if the library exists. If it finds a static and shared
113    /// library with the same name, it will always prefer the static library.
114    ///
115    /// When linking against a shared library, the shared object will be copied to the target
116    /// directory.
117    pub fn link_target(
118        &mut self,
119        target: &str,
120    ) -> &mut LocalLibrary {
121        self.link_targets.push(target.to_string());
122        self
123    }
124
125    /// Add a system target to link against.
126    ///
127    /// Unlike `link_target`, this will not check if the library exists and will always assume that
128    /// the library is shared and available on the system.
129    ///
130    /// system link targets will not be copied to the target directory.
131    pub fn link_system_target(
132        &mut self,
133        target: &str,
134    ) -> &mut LocalLibrary {
135        self.system_link_targets.push(target.to_string());
136        self
137    }
138
139    /// Finalize the `LocalLibrary` configuration.
140    pub fn get(&self) -> LocalLibrary {
141        self.clone()
142    }
143
144    pub (crate) fn get_link_targets(&self) -> &Vec<String> {
145        &self.link_targets
146    }
147
148    pub (crate) fn get_system_link_targets(&self) -> &Vec<String> {
149        &self.system_link_targets
150    }
151
152    pub (crate) fn get_include_directories(&self) -> &Vec<PathBuf> {
153        &self.include_directories
154    }
155
156    pub (crate) fn get_library_directories(&self) -> &Vec<PathBuf> {
157        &self.library_directories
158    }
159}