blob: d9ff8932b492661841c8202e23402b4379eee01e [file] [log] [blame]
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +01001extern crate cc;
Kristian H. Kristensen7c45ef12021-04-06 21:54:57 +00002extern crate wayland_scanner;
Kristian H. Kristensen974c7cd2021-01-24 12:50:23 +00003
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +01004use rayon::prelude::*;
Kristian H. Kristensene8d3b4d2021-02-05 16:39:09 +00005use std::env;
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +01006use std::fs::File;
7use std::io::ErrorKind;
8use std::io::Write;
Kristian H. Kristensen974c7cd2021-01-24 12:50:23 +00009use std::path::Path;
Kristian H. Kristensene8d3b4d2021-02-05 16:39:09 +000010use std::path::PathBuf;
Kristian H. Kristensenb54da802021-09-09 12:35:09 +000011use std::process::Command;
Kristian H. Kristensen974c7cd2021-01-24 12:50:23 +000012use wayland_scanner::*;
13
Kristian H. Kristensenb54da802021-09-09 12:35:09 +000014fn run_bindgen(header: &str, output: &str) {
15 let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
16
Kristian H. Kristensen1cea60c2021-09-17 12:41:35 +000017 let sysroot = env::var("SYSROOT").unwrap_or("/".to_string());
18
19 let status = Command::new("bindgen")
Kristian H. Kristensen129df192021-09-27 08:48:04 +000020 .args(&["-o", out_path.join(output).to_str().unwrap()])
21 .arg("--no-doc-comments")
22 .arg("--no-layout-tests")
23 .args(&["--new-type-alias", "wl_fixed_t"])
24 .args(&["--default-enum-style", "rust_non_exhaustive"])
25 .args(&["--bitfield-enum", "weston_keyboard_modifier"])
Kristian H. Kristensene1d57ee2021-11-10 23:33:29 +010026 .args(&["--bitfield-enum", "weston_activate_flag"])
Kristian H. Kristensen5ef03bd2022-02-23 16:45:36 +010027 .args(&["--bitfield-enum", "wl_event_mask"])
Kristian H. Kristensenb7d53512021-11-12 14:24:17 +010028 .args(&["--no-copy", "shell_surface"])
Kristian H. Kristensen129df192021-09-27 08:48:04 +000029 .arg(header)
30 .arg("--")
31 .arg(format!("--sysroot={}", sysroot))
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +010032 .arg("-I./wayland-server")
Kristian H. Kristensen129df192021-09-27 08:48:04 +000033 .arg("-I/usr/include/pixman-1")
Kristian H. Kristensen37e86ea2021-10-06 21:13:25 +000034 .arg("-I./weston/include")
Kristian H. Kristensen129df192021-09-27 08:48:04 +000035 .arg("-I./bindgen/block")
36 .status()
37 .unwrap();
Kristian H. Kristensen1cea60c2021-09-17 12:41:35 +000038
39 assert!(status.success())
Kristian H. Kristensenb54da802021-09-09 12:35:09 +000040}
41
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +010042struct ConfigHeader {
43 contents: String,
44}
45
46impl ConfigHeader {
47 fn new() -> ConfigHeader {
48 ConfigHeader {
49 contents: "/* automatically generated header */\n\n".to_string(),
50 }
51 }
52
53 fn define(&mut self, name: &str, value: impl std::fmt::Display) -> &mut Self {
54 self.contents
55 .push_str(&format!("#define {} {}\n", name, value.to_string()));
56
57 self
58 }
59
60 fn define_escaped(&mut self, name: &str, value: impl std::fmt::Display) -> &mut Self {
61 self.define(name, format!("\"{}\"", value));
62
63 self
64 }
65
66 fn build(&self, path: &str, name: &str) {
67 File::create(format!("{}/{}", path, name))
68 .unwrap()
69 .write(self.contents.as_bytes())
70 .unwrap();
71 }
72}
73
74fn generate_header_files(config: &Config) {
75 ConfigHeader::new()
76 .define("HAVE_ACCEPT4", 1)
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +010077 .define("HAVE_MEMFD_CREATE", 1)
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +010078 .define_escaped("LIBWESTON_MODULEDIR", "/dev/null")
79 .define_escaped("DATADIR", &config.data_dir)
80 .define("_GNU_SOURCE", 1)
81 .define("_ALL_SOURCE", 1)
82 .define("MAJOR_IN_SYSMACROS", 1)
83 .build(&config.out_path, "config.h");
84
85 ConfigHeader::new()
86 .define("BUILD_ID", "c001bead")
87 .build(&config.out_path, "git-version.h");
88
89 std::fs::create_dir(format!("{}/libweston", config.out_path))
90 .or_else(|e| {
91 if e.kind() == ErrorKind::AlreadyExists {
92 Ok(())
93 } else {
94 Err(e)
95 }
96 })
97 .unwrap();
98
99 ConfigHeader::new()
100 .define("WESTON_VERSION_MAJOR", 9)
101 .define("WESTON_VERSION_MINOR", 0)
102 .define("WESTON_VERSION_MICRO", 0)
103 .define_escaped("WESTON_VERSION", "9.0.0")
104 .build(&config.out_path, "libweston/version.h");
105}
106
107fn generate_rust_protocol_code(config: &Config) {
Kristian H. Kristensencad53c42021-03-08 16:19:24 +0000108 let protocols = [
Kristian H. Kristensen7c45ef12021-04-06 21:54:57 +0000109 "wayland",
Kristian H. Kristensen999d8402021-10-13 13:40:29 +0000110 "xdg-shell",
Kristian H. Kristensen73a22cf2021-10-11 12:09:18 +0000111 "weston-screenshooter",
Kristian H. Kristensen7c45ef12021-04-06 21:54:57 +0000112 "linux-dmabuf-unstable-v1",
113 "croscomp",
114 "alpha-compositing-unstable-v1",
115 "aura-shell",
116 "cursor-shapes-unstable-v1",
117 "gaming-input-unstable-v2",
118 "keyboard-configuration-unstable-v1",
119 "keyboard-extension-unstable-v1",
120 "pointer-gestures-unstable-v1",
121 "remote-shell-unstable-v1",
122 "secure-output-unstable-v1",
123 "stylus-tools-unstable-v1",
124 "stylus-unstable-v2",
125 "vsync-feedback-unstable-v1",
Kristian H. Kristensencad53c42021-03-08 16:19:24 +0000126 ];
127
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100128 let out_dir = Path::new(&config.out_path);
129
130 protocols.par_iter().for_each(|e| {
Kristian H. Kristensen7c45ef12021-04-06 21:54:57 +0000131 let spec = Path::new("protocol").join(e).with_extension("xml");
132 let out = out_dir.join(e).with_extension("rs");
133 println!("cargo:rerun-if-changed={}", spec.to_str().unwrap());
Kristian H. Kristensen7c45ef12021-04-06 21:54:57 +0000134 generate_code_with_destructor_events(spec, out, Side::Server, &[("wl_callback", "done")]);
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100135 });
136}
137
138fn generate_protocol_code(config: &Config) -> Vec<String> {
139 let wp = "/usr/share/wayland-protocols";
140
141 let stable = ["viewporter", "presentation-time", "xdg-shell"];
142
143 let unstable = [
144 ("input-method", 1),
145 ("input-timestamps", 1),
146 ("linux-dmabuf", 1),
147 ("linux-explicit-synchronization", 1),
148 ("xdg-output", 1),
149 ("relative-pointer", 1),
150 ("pointer-constraints", 1),
151 ("fullscreen-shell", 1),
152 ];
153
154 let internal = [
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +0100155 "wayland",
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100156 "weston-content-protection",
157 "weston-touch-calibration",
158 "weston-debug",
159 "weston-direct-display",
160 "text-cursor-position",
161 ];
162
163 let protocols = stable
164 .iter()
165 .map(|name| {
166 (
167 format!("{}/stable/{}/{}.xml", wp, name, name),
168 format!("{}/{}", config.out_path, name),
169 )
170 })
171 .chain(unstable.iter().map(|(name, version)| {
172 (
173 format!(
174 "{}/unstable/{}/{}-unstable-v{}.xml",
175 wp, name, name, version
176 ),
177 format!("{}/{}-unstable-v{}", config.out_path, name, version),
178 )
179 }))
180 .chain(internal.iter().map(|name| {
181 (
182 format!("protocol/{}.xml", name),
183 format!("{}/{}", config.out_path, name),
184 )
185 }));
186
187 fn generate(xml: &str, output: &str) -> String {
188 for (t, suffix) in [
189 ("client-header", "client-protocol.h"),
190 ("server-header", "server-protocol.h"),
191 ("private-code", "protocol.c"),
192 ] {
193 let output_file = format!("{}-{}", output, suffix);
194 Command::new("wayland-scanner")
195 .args([t, &xml, &output_file])
196 .status()
197 .unwrap();
198 }
199
200 format!("{}-protocol.c", output)
Kristian H. Kristensencad53c42021-03-08 16:19:24 +0000201 }
Kristian H. Kristensene8d3b4d2021-02-05 16:39:09 +0000202
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100203 protocols
204 .map(|(xml, output)| generate(&xml, &output))
205 .collect()
206}
207
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100208struct Files {
209 files: Vec<String>
210}
211
212impl Files {
213 fn new() -> Files {
214 Files { files: Vec::new() }
215 }
216
217 fn subdir<A: std::fmt::Display>(&mut self, prefix: &str, iter: impl IntoIterator<Item = A>) {
218 self.files.extend(
219 iter.into_iter()
220 .map(|f| format!("{}/{}", prefix, f)));
221 }
222
223 fn metadata(&self) {
224 for f in &self.files {
225 println!("cargo:rerun-if-changed={}", f);
226 }
227 }
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100228}
229
230fn build_libweston(config: &Config) {
231 generate_header_files(&config);
232
233 let protocol_c_files = generate_protocol_code(&config);
234
235 let mut builder = cc::Build::new();
236
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100237 let mut files = Files::new();
238
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +0100239 let mut deps = vec!["libdrm", "pixman-1", "xkbcommon", "libffi"];
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100240
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100241 files.subdir(
242 "weston/libweston",
243 [
244 "animation.c",
245 "bindings.c",
246 "clipboard.c",
247 "compositor.c",
248 "content-protection.c",
249 "data-device.c",
250 "input.c",
251 "linux-dmabuf.c",
252 "linux-explicit-synchronization.c",
253 "linux-sync-file.c",
254 "log.c",
255 "noop-renderer.c",
256 "pixel-formats.c",
257 "pixman-renderer.c",
258 "plugin-registry.c",
259 "screenshooter.c",
260 "timeline.c",
261 "touch-calibration.c",
262 "weston-log-wayland.c",
263 "weston-log-file.c",
264 "weston-log-flight-rec.c",
265 "weston-log.c",
266 "weston-direct-display.c",
267 "zoom.c",
268 ]);
269 files.subdir(
270 "weston/shared",
271 [
272 "file-util.c",
273 "image-loader.c",
274 "matrix.c",
275 "os-compatibility.c",
276 ]);
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100277
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +0100278 // Internal wayland-server
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100279 files.subdir(
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +0100280 "wayland-server",
281 [
282 "wayland-server.c",
283 "wayland-shm.c",
284 "event-loop.c",
285 "connection.c",
286 "wayland-os.c",
287 "wayland-util.c",
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100288 ]);
Kristian H. Kristensen4cc76c12022-02-18 20:45:10 +0100289
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100290 #[cfg(feature = "wayland-backend")]
291 {
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100292 files.subdir("weston/libweston/backend-wayland", ["wayland.c"]);
293 files.subdir("weston/shared", ["frame.c", "cairo-util.c"]);
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100294 deps.extend(["wayland-client", "wayland-cursor", "cairo", "libpng"])
295 }
296
297 #[cfg(feature = "drm-backend")]
298 {
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100299 files.subdir(
300 "weston/libweston/backend-drm",
301 &[
302 "drm.c",
303 "fb.c",
304 "modes.c",
305 "kms.c",
306 "state-helpers.c",
307 "state-propose.c",
308 "libbacklight.c",
309 ]);
310 files.subdir(
311 "weston/libweston",
312 &[
313 "launcher-direct.c",
314 "launcher-util.c",
315 "launcher-weston-launch.c",
316 "libinput-device.c",
317 "libinput-seat.c",
318 ]);
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100319
320 deps.extend(["libinput", "libevdev", "libudev"]);
321 }
322
Kristian H. Kristensenbe96d9a2022-03-10 16:06:56 +0100323 files.metadata();
324
325 builder
326 .cargo_metadata(false)
327 .files(files.files)
328 .files(protocol_c_files)
329 .extra_warnings(false)
330 .flag("-std=gnu99")
331 .include("weston/include")
332 .include("weston/libweston")
333 .include("weston")
334 .include(&config.out_path);
335
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100336 // builder.compile() normally prints these, but we need to list
337 // them now so that croscomp-libweston will appear before the
338 // pkg-config shared libraries on the link line.
339 println!("cargo:rustc-link-lib=static=croscomp-libweston");
340 println!("cargo:rustc-link-search=native={}", config.out_path);
341
342 for d in deps {
343 let lib = pkg_config::probe_library(d).unwrap();
344 builder.includes(&lib.include_paths);
345 }
346
347 builder.compile("croscomp-libweston");
348}
349
350struct Config {
351 out_path: String,
352 data_dir: String,
353}
354
355fn main() {
356 let config = Config {
357 out_path: env::var("OUT_DIR").unwrap(),
358 data_dir: "/usr/share".to_string(),
359 };
360
361 build_libweston(&config);
362
Kristian H. Kristensenb54da802021-09-09 12:35:09 +0000363 run_bindgen("/usr/include/linux/input.h", "input.rs");
Kristian H. Kristensen73599dc2021-10-07 20:05:00 +0000364 run_bindgen("./weston/croscomp_weston.h", "croscomp_weston.rs");
Kristian H. Kristensen8cc818f2021-02-12 22:52:36 +0000365
Kristian H. Kristensen431d00b2022-02-18 20:06:05 +0100366 generate_rust_protocol_code(&config);
Kristian H. Kristensen4dd859a2021-01-25 17:28:59 +0000367}