• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::env;
6 use std::ffi::OsStr;
7 use std::fs;
8 use std::path::{Path, PathBuf};
9 use std::process::Command;
10 
11 // Performs a recursive search for a file with name under path and returns the full path if such a
12 // file is found.
scan_path<P: AsRef<Path>, O: AsRef<OsStr>>(path: P, name: O) -> Option<PathBuf>13 fn scan_path<P: AsRef<Path>, O: AsRef<OsStr>>(path: P, name: O) -> Option<PathBuf> {
14     for entry in (fs::read_dir(path).ok()?).flatten() {
15         let file_type = match entry.file_type() {
16             Ok(t) => t,
17             Err(_) => continue,
18         };
19 
20         if file_type.is_file() && entry.file_name() == name.as_ref() {
21             return Some(entry.path());
22         } else if file_type.is_dir() {
23             if let Some(found) = scan_path(entry.path(), name.as_ref()) {
24                 return Some(found);
25             }
26         }
27     }
28     None
29 }
30 
31 // Searches for the given protocol in both the system wide and bundles protocols path.
find_protocol(name: &str) -> PathBuf32 fn find_protocol(name: &str) -> PathBuf {
33     let protocols_path = pkg_config::get_variable("wayland-protocols", "pkgdatadir")
34         .unwrap_or_else(|_| "/usr/share/wayland-protocols".to_owned());
35     let protocol_file_name = PathBuf::from(format!("{}.xml", name));
36 
37     // Prioritize the systems wayland protocols before using the bundled ones.
38     if let Some(found) = scan_path(protocols_path, &protocol_file_name) {
39         return found;
40     }
41 
42     // Use bundled protocols as a fallback.
43     let protocol_path = Path::new("protocol").join(protocol_file_name);
44     assert!(
45         protocol_path.is_file(),
46         "unable to locate wayland protocol specification for `{}`",
47         name
48     );
49     protocol_path
50 }
51 
compile_protocol<P: AsRef<Path>>(name: &str, out: P) -> PathBuf52 fn compile_protocol<P: AsRef<Path>>(name: &str, out: P) -> PathBuf {
53     let in_protocol = find_protocol(name);
54     println!("cargo:rerun-if-changed={}", in_protocol.display());
55     let out_code = out.as_ref().join(format!("{}.c", name));
56     let out_header = out.as_ref().join(format!("{}.h", name));
57     eprintln!("building protocol: {}", name);
58     Command::new("wayland-scanner")
59         .arg("code")
60         .arg(&in_protocol)
61         .arg(&out_code)
62         .output()
63         .expect("wayland-scanner code failed");
64     Command::new("wayland-scanner")
65         .arg("client-header")
66         .arg(&in_protocol)
67         .arg(&out_header)
68         .output()
69         .expect("wayland-scanner client-header failed");
70     out_code
71 }
72 
main()73 fn main() {
74     println!("cargo:rerun-if-env-changed=WAYLAND_PROTOCOLS_PATH");
75     let out_dir = env::var("OUT_DIR").unwrap();
76 
77     let mut build = cc::Build::new();
78     build.warnings(true);
79     build.warnings_into_errors(true);
80     build.include(&out_dir);
81     build.flag("-std=gnu11");
82     build.file("src/display_wl.c");
83     println!("cargo:rerun-if-changed=src/display_wl.c");
84 
85     for protocol in &[
86         "aura-shell",
87         "linux-dmabuf-unstable-v1",
88         "xdg-shell",
89         "viewporter",
90         "virtio-gpu-metadata-v1",
91     ] {
92         build.file(compile_protocol(protocol, &out_dir));
93     }
94     build.compile("display_wl");
95 
96     println!("cargo:rustc-link-lib=dylib=wayland-client");
97 }
98