ALVR-IPv6/alvr/server/build.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

193 lines
5.9 KiB
Rust
Raw Normal View History

#[cfg(target_os = "linux")]
use pkg_config;
2020-06-06 15:00:49 -05:00
use std::{env, path::PathBuf};
fn get_ffmpeg_path() -> PathBuf {
let ffmpeg_path = alvr_filesystem::deps_dir()
.join(if cfg!(target_os = "linux") {
"linux"
} else {
"windows"
})
.join("ffmpeg");
if cfg!(target_os = "linux") {
ffmpeg_path.join("alvr_build")
2022-05-11 06:39:04 -05:00
} else {
ffmpeg_path
}
}
#[cfg(feature = "local_ffmpeg")]
fn do_ffmpeg_config(build: &mut cc::Build) {
let ffmpeg_path = get_ffmpeg_path();
assert!(ffmpeg_path.join("include").exists());
build.include(ffmpeg_path.join("include"));
#[cfg(all(feature = "gpl", target_os = "linux"))]
{
let ffmpeg_pkg_path = ffmpeg_path.join("lib").join("pkgconfig");
assert!(ffmpeg_pkg_path.exists());
2022-05-11 06:39:04 -05:00
let ffmpeg_pkg_path = ffmpeg_pkg_path.to_string_lossy().to_string();
env::set_var(
"PKG_CONFIG_PATH",
2022-05-11 06:39:04 -05:00
env::var("PKG_CONFIG_PATH").map_or(ffmpeg_pkg_path.clone(), |old| {
format!("{ffmpeg_pkg_path}:{old}")
}),
);
let pkg = pkg_config::Config::new().cargo_metadata(false).to_owned();
let avutil = pkg.probe("libavutil").unwrap();
let avfilter = pkg.probe("libavfilter").unwrap();
let avcodec = pkg.probe("libavcodec").unwrap();
let swscale = pkg.probe("libswscale").unwrap();
build
.define("AVCODEC_MAJOR", avcodec.version.split(".").next().unwrap())
.define("AVUTIL_MAJOR", avutil.version.split(".").next().unwrap())
.define(
"AVFILTER_MAJOR",
avfilter.version.split(".").next().unwrap(),
)
.define("SWSCALE_MAJOR", swscale.version.split(".").next().unwrap());
// activate dlopen for libav libraries
build
.define("LIBRARY_LOADER_AVCODEC_LOADER_H_DLOPEN", None)
.define("LIBRARY_LOADER_AVUTIL_LOADER_H_DLOPEN", None)
.define("LIBRARY_LOADER_AVFILTER_LOADER_H_DLOPEN", None)
.define("LIBRARY_LOADER_SWSCALE_LOADER_H_DLOPEN", None);
println!("cargo:rustc-link-lib=dl");
}
}
fn do_ffmpeg_config_post() {
if cfg!(feature = "local_ffmpeg") {
// TODO: cfg!(feature = "gpl") - switch to static linking
let kind = if false { "static" } else { "dylib" };
let ffmpeg_path = get_ffmpeg_path();
let ffmpeg_lib_path = ffmpeg_path.join("lib");
assert!(ffmpeg_lib_path.exists());
println!(
"cargo:rustc-link-search=native={}",
ffmpeg_lib_path.to_string_lossy()
);
println!("cargo:rustc-link-lib={}=avutil", kind);
println!("cargo:rustc-link-lib={}=avfilter", kind);
println!("cargo:rustc-link-lib={}=avcodec", kind);
println!("cargo:rustc-link-lib={}=swscale", kind);
} else {
#[cfg(target_os = "linux")]
{
let pkg = pkg_config::Config::new().to_owned();
pkg.probe("libavutil").unwrap();
pkg.probe("libavfilter").unwrap();
pkg.probe("libavcodec").unwrap();
pkg.probe("libswscale").unwrap();
}
}
}
2020-06-06 15:00:49 -05:00
fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let cpp_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("cpp");
#[cfg(windows)]
let platform = "cpp/platform/win32";
#[cfg(target_os = "linux")]
let platform = "cpp/platform/linux";
2021-08-02 17:59:01 -05:00
#[cfg(target_os = "macos")]
let platform = "cpp/platform/macos";
let common_iter = walkdir::WalkDir::new("cpp")
2020-06-06 15:00:49 -05:00
.into_iter()
.filter_entry(|entry| entry.file_name() != "tools" && entry.file_name() != "platform");
let platform_iter = walkdir::WalkDir::new(platform).into_iter();
let cpp_paths = common_iter
.chain(platform_iter)
2020-06-06 15:00:49 -05:00
.filter_map(|maybe_entry| maybe_entry.ok())
.map(|entry| entry.into_path())
.collect::<Vec<_>>();
let source_files_paths = cpp_paths.iter().filter(|path| {
path.extension()
.filter(|ext| {
let ext_str = ext.to_string_lossy();
ext_str == "c" || ext_str == "cpp"
})
.is_some()
});
let mut build = cc::Build::new();
build
.cpp(true)
.files(source_files_paths)
.flag_if_supported("-isystemcpp/openvr/headers") // silences many warnings from openvr headers
.flag_if_supported("-std=c++17")
2020-06-06 15:00:49 -05:00
.include("cpp/openvr/headers")
.include("cpp");
#[cfg(windows)]
build
Vulkan based linux port (#604) * Vulkan based linux port This version replaces the "screen grab" version. The mechanism is based on frame capture in vrcompositor process, which are then shared with vrserver process, encoded there and transmitted to the headset. A vulkan layer is added to vrcompositor, this layer exposes the VK_EXT_direct_mode_display, VK_EXT_acquire_xlib_display and some other related vulkan functions. Functions implemented in the layer add one display to the list naturally returned by the driver, this display matches properties in ALVR settings (resolution and refresh rate), and all functions required by SteamVR are implemented (xlib acquire, properties enumeration, vsync event, swapchain creation). The layer then connects to a socket owned by the server, submits the VkImage creation parameters, and transfers file descriptors corresponding to the images in the swapchain and associated semaphores. The, on each frame, a packet is sent on the socket describing the image that has been submitted. On server side, vulkan frames are mapped to vaapi surfaces, using ffmpeg, then converted to a format suitable for encoding, encoded through vaapi and sent with the usual mechanism. In order to associate each frame with tracking information, timing details are requested to the compositor, and tracking history is queried to find the most suitable tracking index. This mechanism is still inaccurate and will need significant upgrades. Co-authored-by: Ron B <me@ronthecookie.me> * include pose age in timing calculation * linux: correctly set timestamps for bitrate * fix uninitialized variable, layer metadata * use stack inspection in layer to find pose In order to get the correct pose associated to an image, search the stack for the variable, then copy it and send to the server. * Automatically wrap vrcompositor-launcher This will allow the user to not have to modify `vrenv.sh` which is quite error-prone. * update vulkan-layer shell.nix Co-authored-by: Patrick Nicolas <patricknicolas@laposte.net> Co-authored-by: Ron B <me@ronthecookie.me> Co-authored-by: zarik5 <riccardo.zaglia5@gmail.com>
2021-04-22 06:00:45 -05:00
.debug(false) // This is because we cannot link to msvcrtd (see below)
2021-05-17 04:54:44 -05:00
.flag("/std:c++17")
.flag("/permissive-")
2020-11-04 07:18:45 -06:00
.define("NOMINMAX", None)
.define("_WINSOCKAPI_", None)
.define("_MBCS", None)
.define("_MT", None);
2020-11-04 07:18:45 -06:00
2021-11-13 06:52:45 -06:00
#[cfg(target_os = "macos")]
build.define("__APPLE__", None);
// #[cfg(debug_assertions)]
// build.define("ALVR_DEBUG_LOG", None);
#[cfg(feature = "local_ffmpeg")]
do_ffmpeg_config(&mut build);
#[cfg(all(windows, feature = "gpl"))]
build.define("ALVR_GPL", None);
2020-06-06 15:00:49 -05:00
build.compile("bindings");
do_ffmpeg_config_post();
2020-06-06 15:00:49 -05:00
bindgen::builder()
.clang_arg("-xc++")
.header("cpp/alvr_server/bindings.h")
2020-11-04 07:18:45 -06:00
.derive_default(true)
2020-06-06 15:00:49 -05:00
.generate()
.expect("bindings")
.write_to_file(out_dir.join("bindings.rs"))
.expect("bindings.rs");
println!(
"cargo:rustc-link-search=native={}",
cpp_dir.join("openvr/lib").to_string_lossy()
);
println!("cargo:rustc-link-lib=openvr_api");
2020-06-06 15:00:49 -05:00
#[cfg(target_os = "linux")]
{
pkg_config::Config::new().probe("vulkan").unwrap();
Vulkan based linux port (#604) * Vulkan based linux port This version replaces the "screen grab" version. The mechanism is based on frame capture in vrcompositor process, which are then shared with vrserver process, encoded there and transmitted to the headset. A vulkan layer is added to vrcompositor, this layer exposes the VK_EXT_direct_mode_display, VK_EXT_acquire_xlib_display and some other related vulkan functions. Functions implemented in the layer add one display to the list naturally returned by the driver, this display matches properties in ALVR settings (resolution and refresh rate), and all functions required by SteamVR are implemented (xlib acquire, properties enumeration, vsync event, swapchain creation). The layer then connects to a socket owned by the server, submits the VkImage creation parameters, and transfers file descriptors corresponding to the images in the swapchain and associated semaphores. The, on each frame, a packet is sent on the socket describing the image that has been submitted. On server side, vulkan frames are mapped to vaapi surfaces, using ffmpeg, then converted to a format suitable for encoding, encoded through vaapi and sent with the usual mechanism. In order to associate each frame with tracking information, timing details are requested to the compositor, and tracking history is queried to find the most suitable tracking index. This mechanism is still inaccurate and will need significant upgrades. Co-authored-by: Ron B <me@ronthecookie.me> * include pose age in timing calculation * linux: correctly set timestamps for bitrate * fix uninitialized variable, layer metadata * use stack inspection in layer to find pose In order to get the correct pose associated to an image, search the stack for the variable, then copy it and send to the server. * Automatically wrap vrcompositor-launcher This will allow the user to not have to modify `vrenv.sh` which is quite error-prone. * update vulkan-layer shell.nix Co-authored-by: Patrick Nicolas <patricknicolas@laposte.net> Co-authored-by: Ron B <me@ronthecookie.me> Co-authored-by: zarik5 <riccardo.zaglia5@gmail.com>
2021-04-22 06:00:45 -05:00
// fail build if there are undefined symbols in final library
println!("cargo:rustc-cdylib-link-arg=-Wl,--no-undefined");
}
2020-06-06 15:00:49 -05:00
for path in cpp_paths {
println!("cargo:rerun-if-changed={}", path.to_string_lossy());
}
}