amdgpu_device_libs_build/
lib.rs

1// Update: cargo readme > README.md
2
3#![allow(clippy::needless_doctest_main)]
4//! Build script support for `amdgpu-device-libs`.
5//!
6//! Adds linker flags to link device-libs.
7//! Add `amdgpu-device-libs-build` as a `build-dependency` and call it in the build script.
8//! ```rust,no_run
9//! // build.rs
10//! fn main() {
11//!     amdgpu_device_libs_build::build();
12//! }
13//! ```
14//!
15//! This link to the [ROCm device-libs](https://github.com/ROCm/llvm-project/tree/amd-staging/amd/device-libs) and a pre-compiled helper library.
16//! The libraries are linked from a ROCm installation.
17//! To make sure the libraries are found, set the environment variable `ROCM_PATH` or `ROCM_DEVICE_LIB_PATH` (higher priority if it is set).
18//! It looks for `amdgcn/bitcode/*.bc` files in this path.
19//! See the documentation of [`amdgpu-device-libs`](https://docs.rs/amdgpu-device-libs) for more information.
20
21use std::collections::HashSet;
22
23use rustflags::Flag;
24
25/// Link libraries for `amdgpu-device-libs`.
26///
27/// Call in a cargo buildscript:
28/// ```rust,no_run
29/// // build.rs
30/// fn main() {
31///     amdgpu_device_libs_build::build();
32/// }
33/// ```
34pub fn build() {
35    let cur_dir = env!("CARGO_MANIFEST_DIR");
36    println!("cargo::rerun-if-env-changed=CARGO_CFG_TARGET_FEATURE");
37
38    let rocm_path = std::env::var("ROCM_PATH").unwrap();
39    let rocm_device_lib_path = std::env::var("ROCM_DEVICE_LIB_PATH").unwrap_or(rocm_path);
40    let device_libs = format!("{}/amdgcn/bitcode", rocm_device_lib_path);
41    println!("cargo::rerun-if-env-changed=ROCM_PATH");
42    println!("cargo::rerun-if-env-changed=ROCM_DEVICE_LIB_PATH");
43    println!("cargo::rustc-link-arg={}/ockl.bc", device_libs);
44
45    // Find out target cpu and enabled features
46    let mut target_features = std::env::var("CARGO_CFG_TARGET_FEATURE")
47        .unwrap_or_default()
48        .split(',')
49        .filter(|s| !s.is_empty())
50        .map(|s| s.to_string())
51        .collect::<HashSet<_>>();
52
53    let mut target_cpu = None;
54    for flag in rustflags::from_env() {
55        if let Flag::Codegen { opt, value } = flag {
56            if opt == "target-cpu" {
57                target_cpu = value;
58            } else if opt == "target-feature" {
59                if let Some(feat) = value {
60                    if let Some(feat) = feat.strip_prefix('-') {
61                        target_features.remove(feat);
62                    } else {
63                        let feat = feat.trim_start_matches('+');
64                        target_features.insert(feat.into());
65                    }
66                }
67            }
68        }
69    }
70    let target_cpu = target_cpu.expect("Did not find target-cpu in RUSTFLAGS");
71    let gfxip = target_cpu
72        .strip_prefix("gfx")
73        .unwrap_or_else(|| panic!("target-cpu '{target_cpu}' did not start with gfx"));
74
75    println!("cargo::rustc-link-arg={}/ockl.bc", device_libs);
76    println!(
77        "cargo::rustc-link-arg={}/oclc_isa_version_{}.bc",
78        device_libs, gfxip,
79    );
80    println!(
81        "cargo::rustc-link-arg={}/oclc_abi_version_500.bc",
82        device_libs,
83    );
84
85    let mut is_wave64 = target_features.contains("wavefrontsize64");
86    // wave64 is the default on gfx9 and before
87    is_wave64 |= gfxip.starts_with('9') && gfxip.len() == 3;
88    is_wave64 |= gfxip.starts_with("9-") && gfxip.ends_with("-generic");
89    let is_wave64 = is_wave64;
90    let wavesize = if is_wave64 { 64 } else { 32 };
91    println!(
92        "cargo::rustc-link-arg={}/oclc_wavefrontsize64_{}.bc",
93        device_libs,
94        if is_wave64 { "on" } else { "off" },
95    );
96
97    println!("cargo::rerun-if-changed={}/util{}.bc", cur_dir, wavesize);
98    println!("cargo::rustc-link-arg={}/util{}.bc", cur_dir, wavesize);
99
100    // Workarounds to make linker-plugin-lto work
101    println!("cargo::rustc-link-arg=--undefined-version");
102    println!("cargo::rustc-link-arg=--no-gc-sections");
103}