-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
virtio-bindings: use bindgen library from build.rs
Since commit 3e51e2d ("virtio-bindings: regenerate with bindgen 0.70.1") there are compile-time alignment checks in virtio-bindings code. These checks are specific to the architecture where bindgen was run and they can break builds on other architectures. Here is an example i686 build failure after upgrading from virtio-bindings 0.2.2 to 0.2.4: https://koji.fedoraproject.org/koji/taskinfo?taskID=127997322 The bindgen User Guide recommends generating bindings from build.rs because it avoids portability issues and the need to maintain a copy of the bindings for each target: https://rust-lang.github.io/rust-bindgen/library-usage.html Introduce an import-linux-headers.sh script that copies required virtio headers from a Linux headers tree into include/. Do not distribute the full Linux headers tree because it is large and has falls under various software licenses that are not compatible with this crate's license. Generate the actual bindings at compile-time in build.rs and then include!() the output from src/lib.rs. You can verify that the generated bindings from Linux 6.12 have not changed significantly for x86_64 by diffing them against the previous commit. For example: --- orig/virtio_gpu.rs +++ new/virtio_gpu.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.70.1 */ +/* automatically generated by rust-bindgen 0.71.1 */ #[repr(C)] #[derive(Default)] @@ -58,7 +58,7 @@ pub const VIRTIO_GPU_MAP_CACHE_WC: u32 = 3; pub type __u8 = ::std::os::raw::c_uchar; pub type __u32 = ::std::os::raw::c_uint; -pub type __u64 = ::std::os::raw::c_ulonglong; +pub type __u64 = ::std::os::raw::c_ulong; pub type __le32 = __u32; pub type __le64 = __u64; pub const virtio_gpu_ctrl_type_VIRTIO_GPU_UNDEFINED: virtio_gpu_ctrl_type = 0 The __u64 change is due to how <linux/types.h> defined __u64. We should avoid using that non-BSD licensed header. The result is equivalent now that the bindings are generated at compile-time. Fixes: #326 Signed-off-by: Stefan Hajnoczi <[email protected]>
- Loading branch information
1 parent
67d5be7
commit 31f7c73
Showing
29 changed files
with
2,407 additions
and
2,931 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,47 @@ | ||
# Contributing to virtio-bindings | ||
|
||
## Dependencies | ||
## Overview | ||
|
||
### Bindgen | ||
The bindings are currently generated using | ||
[bindgen](https://rust-lang.github.io/rust-bindgen/) version 0.70.1: | ||
```bash | ||
cargo install bindgen-cli --vers 0.70.1 | ||
``` | ||
virtio-bindings is periodically updated with imported virtio headers from the | ||
Linux kernel. The Linux header files have kernel header dependencies that are | ||
removed during import so that bindgen can process them in isolation without a | ||
full set of kernel headers. This is also necessary because the licenses of | ||
individual kernel header files varies and we only want to distribute | ||
BSD-licensed virtio headers. | ||
|
||
### Linux Kernel | ||
## Importing kernel headers | ||
Generating bindings depends on the Linux kernel, so you need to have the | ||
repository on your machine: | ||
|
||
```bash | ||
git clone https://github.com/torvalds/linux.git | ||
``` | ||
|
||
## Example for updating to a new kernel version | ||
Install the headers so they can be used for import: | ||
```bash | ||
cd linux | ||
git checkout <linux-version> | ||
make headers_install INSTALL_HDR_PATH=headers-<linux-version> | ||
``` | ||
|
||
For this example we assume that you have both linux and virtio-bindings | ||
repositories in your root. | ||
Import kernel headers into `include/`: | ||
```bash | ||
cd ~/vm-virtio/virtio-bindings | ||
./import-linux-headers.sh path/to/headers-<linux-version> | ||
``` | ||
|
||
Test that the build still works: | ||
```bash | ||
# linux is the repository that you cloned at the previous step. | ||
cd linux | ||
# Step 1: Checkout the version you want to generate the bindings for. | ||
git checkout v5.0 | ||
|
||
# Step 2: Generate the bindings from the kernel headers. We need to generate a | ||
# file for each one of the virtio headers. For the moment, we are only picking | ||
# headers that we are interested in. Feel free to add additional header files if | ||
# you need them for your project. | ||
make headers_install INSTALL_HDR_PATH=v5_0_headers | ||
cd v5_0_headers | ||
for i in \ | ||
virtio_blk \ | ||
virtio_config \ | ||
virtio_gpu \ | ||
virtio_ids \ | ||
virtio_input \ | ||
virtio_mmio \ | ||
virtio_net \ | ||
virtio_ring \ | ||
virtio_scsi \ | ||
; do \ | ||
bindgen include/linux/$i.h -o $i.rs \ | ||
--allowlist-file include/linux/$i.h \ | ||
--with-derive-default \ | ||
--with-derive-partialeq \ | ||
-- -Iinclude | ||
done | ||
cd ~ | ||
|
||
# Step 6: Copy the generated files to the new version module. | ||
cp linux/v5_0_headers/*.rs vm-virtio/virtio-bindings/src | ||
mv vm-virtio/virtio-bindings/src/virtio_net.rs vm-virtio/virtio-bindings/src/virtio_net/generated.rs | ||
cargo build | ||
``` | ||
|
||
## Adding bindings for new header files | ||
New kernel headers can be added as follows: | ||
1. Add the new file to import-linux-headers.sh so it is imported from the Linux | ||
kernel header directory into include/. | ||
2. Add the new file to build.rs so bindgen generates bindings. | ||
3. Add the new module to src/lib.rs so the generated bindings are exposed in | ||
the crate. | ||
4. Check if `cargo build` still succeeds. If the header has new kernel header | ||
dependencies then you need to add them (if they are BSD licensed) or stub | ||
them out (if they are not BSD licensed). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright Red Hat, Inc. | ||
// SPDX-License-Identifier: (BSD-3-Clause OR Apache-2.0) | ||
|
||
use std::env; | ||
use std::path::PathBuf; | ||
|
||
fn generate_bindings(header: &str) { | ||
let bindings = bindgen::Builder::default() | ||
.header(format!("include/linux/{header}.h")) | ||
.allowlist_file(format!("include/linux/{header}.h")) | ||
.derive_default(true) | ||
.derive_partialeq(true) | ||
.clang_arg("-Iinclude") | ||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) | ||
.generate() | ||
.unwrap_or_else(|_| panic!("Unable to generate bindings for {header}")); | ||
|
||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
bindings | ||
.write_to_file(out_path.join(format!("{header}.rs"))) | ||
.unwrap_or_else(|_| panic!("Couldn't write bindings for {header}")); | ||
} | ||
|
||
fn main() { | ||
// If you change this list, remember to update src/lib.rs | ||
for header in [ | ||
"virtio_blk", | ||
"virtio_config", | ||
"virtio_gpu", | ||
"virtio_ids", | ||
"virtio_input", | ||
"virtio_mmio", | ||
"virtio_net", | ||
"virtio_ring", | ||
"virtio_scsi", | ||
] { | ||
generate_bindings(header); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: (BSD-3-Clause OR Apache-2.0) | ||
# Copyright Red Hat, Inc. | ||
# | ||
# ./import-linux-headers.sh path/to/kernel/headers | ||
# | ||
# Import header files from a Linux kernel header tree. Be sure to run `cargo | ||
# build` to test that bindgen succeeds before committing the updated headers. | ||
|
||
src=$1 | ||
dst=include/linux | ||
|
||
import_header() { | ||
# Use our local header files rather than system headers | ||
sed -e 's%#include <\([^>]*\)>%#include "\1"%' "$1" >"$2" | ||
} | ||
|
||
mkdir -p "$dst" | ||
|
||
# If you change this list, remember to update build.rs | ||
for header in \ | ||
version \ | ||
virtio_blk \ | ||
virtio_config \ | ||
virtio_gpu \ | ||
virtio_ids \ | ||
virtio_input \ | ||
virtio_mmio \ | ||
virtio_net \ | ||
virtio_ring \ | ||
virtio_scsi \ | ||
virtio_types; do | ||
import_header "$src/include/linux/$header.h" "$dst/$header.h" | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/* SPDX-License-Identifier: (BSD-3-Clause OR Apache-2.0) */ | ||
|
||
#pragma once | ||
|
||
#define ETH_ALEN 6 /* needed by virtio_net */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* SPDX-License-Identifier: (BSD-3-Clause OR Apache-2.0) */ | ||
|
||
#pragma once | ||
|
||
/* Built-ins avoid the need for <stdint.h> */ | ||
typedef __UINT8_TYPE__ __u8; | ||
typedef __UINT16_TYPE__ __u16; | ||
typedef __UINT32_TYPE__ __u32; | ||
typedef __UINT64_TYPE__ __u64; | ||
|
||
typedef __u16 __le16; | ||
typedef __u32 __le32; | ||
typedef __u64 __le64; | ||
|
||
#define __bitwise /* ignore */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#define LINUX_VERSION_CODE 396288 | ||
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c))) | ||
#define LINUX_VERSION_MAJOR 6 | ||
#define LINUX_VERSION_PATCHLEVEL 12 | ||
#define LINUX_VERSION_SUBLEVEL 0 |
Oops, something went wrong.