1use std::fs;
8use std::ops::Add;
9use std::path::Path;
10use crate::commands::{add_library_search_path, link_shared_library, link_static_library};
11use crate::types::local_library::LocalLibrary;
12use crate::variables::{platform, Platform, shared_library_extension, static_library_extension, target_directory};
13
14pub mod types;
15
16pub (crate) mod variables;
17pub (crate) mod commands;
18
19const LIBRARY_NAME_PREFIX: &str = "lib";
20
21fn get_static_library_name(library_name: &str) -> String {
22 if platform() == Platform::Windows {
24 return library_name.to_string()
25 .add(static_library_extension());
26 }
27
28 LIBRARY_NAME_PREFIX.to_string()
29 .add(library_name)
30 .add(static_library_extension())
31}
32
33fn get_shared_library_name(library_name: &str) -> String {
34 if platform() == Platform::Windows {
36 return library_name.to_string()
37 .add(shared_library_extension());
38 }
39
40 LIBRARY_NAME_PREFIX.to_string()
41 .add(library_name)
42 .add(shared_library_extension())
43}
44
45fn copy_shared_object(
46 target_directory: &Path,
47 library_path: &Path,
48) {
49 if !target_directory.exists() {
50 fs::create_dir_all(target_directory)
51 .expect("Could not create target directory.");
52 }
53
54 if !library_path.exists() {
55 panic!("Could not find shared object: {:?}", library_path);
56 }
57
58 fs::copy(
59 library_path,
60 target_directory.join(library_path.file_name().unwrap())
61 ).expect("Could not copy shared object.");
62}
63
64pub trait BindBuild {
66
67 fn bind_library(
69 &mut self,
70 library: LocalLibrary
71 ) -> &mut cc::Build;
72}
73
74impl BindBuild for cc::Build {
75
76 fn bind_library(
77 &mut self,
78 library: LocalLibrary
79 ) -> &mut cc::Build {
80
81 let mut include_directories = library
83 .get_include_directories()
84 .clone();
85
86 include_directories.dedup();
87 include_directories.retain(|x| x.is_dir());
88
89 self.includes(include_directories);
90
91 let mut library_directories = library
92 .get_library_directories()
93 .clone();
94
95 library_directories.dedup();
96 library_directories.retain(|x| x.is_dir());
97
98 for library_directory in library_directories.iter() {
99 add_library_search_path(library_directory.as_path())
100 }
101
102 let mut link_targets = library
103 .get_link_targets()
104 .clone();
105
106 link_targets.dedup();
107
108 let target_directory = target_directory();
109
110 for library in link_targets.iter() {
112 for library_directory in library_directories.iter() {
113 let static_library_path = library_directory
114 .join(get_static_library_name(library));
115
116 let shared_library_path = library_directory
117 .join(get_shared_library_name(library));
118
119 if static_library_path.exists() {
120 link_static_library(library);
121 } else if shared_library_path.exists() {
122 copy_shared_object(
124 target_directory.as_path(),
125 shared_library_path.as_path()
126 );
127 link_shared_library(library);
128 }
129 }
130 }
131
132 let mut system_link_targets = library
134 .get_system_link_targets()
135 .clone();
136
137 system_link_targets.dedup();
138
139 for library in system_link_targets.iter() {
140 link_shared_library(library);
141 }
142
143 self
144 }
145}