Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/gpu_display/build.rs
5394 views
1
// Copyright 2018 The ChromiumOS Authors
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;
9
use std::path::PathBuf;
10
use std::process::Command;
11
12
// Performs a recursive search for a file with name under path and returns the full path if such a
13
// file is found.
14
fn scan_path<P: AsRef<Path>, O: AsRef<OsStr>>(path: P, name: O) -> Option<PathBuf> {
15
for entry in (fs::read_dir(path).ok()?).flatten() {
16
let file_type = match entry.file_type() {
17
Ok(t) => t,
18
Err(_) => continue,
19
};
20
21
if file_type.is_file() && entry.file_name() == name.as_ref() {
22
return Some(entry.path());
23
} else if file_type.is_dir() {
24
if let Some(found) = scan_path(entry.path(), name.as_ref()) {
25
return Some(found);
26
}
27
}
28
}
29
None
30
}
31
32
// Searches for the given protocol in both the system wide and bundles protocols path.
33
fn find_protocol(name: &str) -> PathBuf {
34
let protocol_file_name = PathBuf::from(format!("{name}.xml"));
35
// Prioritize the systems wayland protocols before using the bundled ones.
36
if let Ok(protocols_path) = pkg_config::get_variable("wayland-protocols", "pkgdatadir") {
37
if let Some(found) = scan_path(protocols_path, &protocol_file_name) {
38
return found;
39
}
40
}
41
let protocols_path = format!("/usr/share/wayland-protocols/stable/{name}");
42
if let Some(found) = scan_path(protocols_path, &protocol_file_name) {
43
return found;
44
}
45
// Use bundled protocols as a fallback.
46
let protocol_path = Path::new("protocol").join(protocol_file_name);
47
assert!(
48
protocol_path.is_file(),
49
"unable to locate wayland protocol specification for `{name}`"
50
);
51
protocol_path
52
}
53
54
fn compile_protocol<P: AsRef<Path>>(name: &str, out: P) -> PathBuf {
55
let in_protocol = find_protocol(name);
56
println!("cargo:rerun-if-changed={}", in_protocol.display());
57
let out_code = out.as_ref().join(format!("{name}.c"));
58
let out_header = out.as_ref().join(format!("{name}.h"));
59
eprintln!("building protocol: {name}");
60
61
let wayland_scanner = which::which("wayland-scanner")
62
.expect("missing wayland-scanner - please install libwayland-dev");
63
64
Command::new(&wayland_scanner)
65
.arg("code")
66
.arg(&in_protocol)
67
.arg(&out_code)
68
.output()
69
.expect("wayland-scanner code failed");
70
Command::new(&wayland_scanner)
71
.arg("client-header")
72
.arg(&in_protocol)
73
.arg(&out_header)
74
.output()
75
.expect("wayland-scanner client-header failed");
76
out_code
77
}
78
79
fn build_wayland() {
80
println!("cargo:rerun-if-env-changed=WAYLAND_PROTOCOLS_PATH");
81
let out_dir = env::var("OUT_DIR").unwrap();
82
83
let mut build = cc::Build::new();
84
build.warnings(true);
85
build.warnings_into_errors(true);
86
build.include(&out_dir);
87
build.flag("-std=gnu11");
88
build.file("src/display_wl.c");
89
println!("cargo:rerun-if-changed=src/display_wl.c");
90
91
for protocol in &[
92
"aura-shell",
93
"linux-dmabuf-unstable-v1",
94
"xdg-shell",
95
"viewporter",
96
"virtio-gpu-metadata-v1",
97
] {
98
build.file(compile_protocol(protocol, &out_dir));
99
}
100
build.compile("display_wl");
101
102
println!("cargo:rustc-link-lib=dylib=wayland-client");
103
}
104
105
fn main() {
106
// Skip installing dependencies when generating documents.
107
if std::env::var("CARGO_DOC").is_ok() {
108
return;
109
}
110
111
match std::env::var("CARGO_CFG_TARGET_OS").as_deref().unwrap() {
112
"linux" | "android" => {
113
build_wayland();
114
}
115
_ => {}
116
}
117
}
118
119