diff --git a/.github/workflows/bindgen.yml b/.github/workflows/bindgen.yml index 1778de1d2b..bd1489911e 100644 --- a/.github/workflows/bindgen.yml +++ b/.github/workflows/bindgen.yml @@ -95,7 +95,7 @@ jobs: runs-on: ${{matrix.os}} strategy: matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest] steps: - uses: actions/checkout@v4 @@ -103,10 +103,16 @@ jobs: run: cd bindgen-tests/tests/expectations && cargo test test: - runs-on: ${{matrix.os}} + runs-on: ${{matrix.platform.os}} strategy: matrix: - os: [ubuntu-latest] + platform: + - os: ubuntu-latest + libtinfo: libtinfo5_6.3-2ubuntu0.1_amd64.deb + ubuntu_repo: https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/ + - os: ubuntu-24.04-arm + libtinfo: libtinfo5_6.3-2ubuntu0.1_arm64.deb + ubuntu_repo: https://ports.ubuntu.com/ubuntu-ports/pool/universe/n/ncurses/ llvm_version: ["9.0", "16.0"] release_build: [0, 1] no_default_features: [0, 1] @@ -118,14 +124,18 @@ jobs: include: # Test with extra asserts + docs just with latest llvm versions to # prevent explosion - - os: ubuntu-latest + - platform: + os: ubuntu-latest + libtinfo: libtinfo5_6.3-2ubuntu0.1_amd64.deb + ubuntu_repo: https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/ llvm_version: "16.0" release_build: 0 no_default_features: 0 feature_extra_asserts: 1 # Ensure stuff works on macos too - - os: macos-latest + - platform: + os: macos-latest llvm_version: "16.0" release_build: 0 no_default_features: 0 @@ -138,22 +148,22 @@ jobs: with: toolchain: stable - name: Install libtinfo - if: matrix.os == 'ubuntu-latest' + if: startsWith(matrix.platform.os, 'ubuntu') run: | - wget https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb - sudo dpkg -i libtinfo5_6.3-2ubuntu0.1_amd64.deb + wget ${{matrix.platform.ubuntu_repo}}${{matrix.platform.libtinfo}} + sudo dpkg -i ${{matrix.platform.libtinfo}} - name: Install LLVM and Clang uses: KyleMayes/install-llvm-action@v2.0.5 with: version: ${{matrix.llvm_version}} - name: Run all the tests env: - GITHUB_ACTIONS_OS: ${{matrix.os}} + GITHUB_ACTIONS_OS: ${{matrix.platform.os}} BINDGEN_RELEASE_BUILD: ${{matrix.release_build}} BINDGEN_FEATURE_RUNTIME: ${{matrix.feature_runtime}} BINDGEN_FEATURE_EXTRA_ASSERTS: ${{matrix.feature_extra_asserts}} BINDGEN_NO_DEFAULT_FEATURES: ${{matrix.no_default_features}} - BINDGEN_RUST_FOR_LINUX_TEST: ${{matrix.os == 'ubuntu-latest' && matrix.llvm_version == '16.0' && matrix.feature_extra_asserts == 0 && 1 || 0}} + BINDGEN_RUST_FOR_LINUX_TEST: ${{startsWith(matrix.platform.os, 'ubuntu') && matrix.llvm_version == '16.0' && matrix.feature_extra_asserts == 0 && 1 || 0}} run: ./ci/test.sh test-book: diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index ef167775cf..fc9ee25d8b 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -288,7 +288,8 @@ fn setup_wrap_static_fns_test() { .expect("Path could not be converted to a str"); // generate external bindings with the external .c and .h files - let bindings = Builder::default() + #[allow(unused_mut)] + let mut builder = Builder::default() .header(input_header_file_path_str) .parse_callbacks(Box::new( bindgen::CargoCallbacks::new().rerun_on_header_files(true), @@ -298,9 +299,14 @@ fn setup_wrap_static_fns_test() { .wrap_static_fns_path( out_path.join("wrap_static_fns").display().to_string(), ) - .clang_arg("-DUSE_VA_HEADER") - .generate() - .expect("Unable to generate bindings"); + .clang_arg("-DUSE_VA_HEADER"); + + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + builder = builder.clang_arg("-DDISABLE_VA"); + } + + let bindings = builder.generate().expect("Unable to generate bindings"); println!("cargo:rustc-link-lib=static=wrap_static_fns"); // tell cargo to link libextern println!("bindings generated: {bindings}"); @@ -309,14 +315,20 @@ fn setup_wrap_static_fns_test() { let lib_path = out_path.join("libwrap_static_fns.a"); // build the external files to check if they work - let clang_output = std::process::Command::new("clang") + let mut command = std::process::Command::new("clang"); + command .arg("-c") .arg("-o") .arg(&obj_path) .arg(out_path.join("wrap_static_fns.c")) - .arg("-DUSE_VA_HEADER") - .output() - .expect("`clang` command error"); + .arg("-DUSE_VA_HEADER"); + + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + command.arg("-DDISABLE_VA"); + } + + let clang_output = command.output().expect("`clang` command error"); if !clang_output.status.success() { panic!( "Could not compile object file:\n{}", diff --git a/bindgen-integration/src/lib.rs b/bindgen-integration/src/lib.rs index 64f4926a8b..0b448222d9 100755 --- a/bindgen-integration/src/lib.rs +++ b/bindgen-integration/src/lib.rs @@ -336,13 +336,16 @@ fn test_wrap_static_fns() { extern_bindings::takes_qualified(&(&5 as *const _) as *const _); assert_eq!(5, tq); - let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(0); - assert_eq!(0, wv1); + #[cfg(not(all(target_arch = "aarch64", target_os = "linux")))] + { + let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(0); + assert_eq!(0, wv1); - let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(2, 5, 3); - assert_eq!(8, wv1); + let wv1 = extern_bindings::wrap_as_variadic_fn1_wrapped(2, 5, 3); + assert_eq!(8, wv1); - extern_bindings::wrap_as_variadic_fn2_wrapped(1, 2); + extern_bindings::wrap_as_variadic_fn2_wrapped(1, 2); + } } } diff --git a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c new file mode 100644 index 0000000000..a4269d8505 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns_aarch64_linux.c @@ -0,0 +1,14 @@ +#include "tests/headers/wrap-static-fns.h" + +// Static wrappers + +int foo__extern(void) { return foo(); } +int bar__extern(void) { return bar(); } +int takes_ptr__extern(int *arg) { return takes_ptr(arg); } +int takes_fn_ptr__extern(int (*f) (int)) { return takes_fn_ptr(f); } +int takes_fn__extern(int (f) (int)) { return takes_fn(f); } +int takes_alias__extern(func f) { return takes_alias(f); } +int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); } +enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); } +void nevermore__extern(void) { nevermore(); } +int takes_fn_with_no_args__extern(int (f) (void)) { return takes_fn_with_no_args(f); } diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h index 5cd3d41aee..27757a8476 100644 --- a/bindgen-tests/tests/headers/wrap-static-fns.h +++ b/bindgen-tests/tests/headers/wrap-static-fns.h @@ -60,6 +60,8 @@ static inline int variadic(int x, ...) { return x; } +#ifndef DISABLE_VA + static inline void no_extra_argument(__builtin_va_list va) {} static inline int many_va_list(int i, __builtin_va_list va1, __builtin_va_list va2) { @@ -84,3 +86,4 @@ static inline int wrap_as_variadic_fn1(int i, va_list va) { static inline void wrap_as_variadic_fn2(int i, va_list va) {} #endif +#endif diff --git a/bindgen-tests/tests/tests.rs b/bindgen-tests/tests/tests.rs index bcf9b7fcfa..637f66bb52 100644 --- a/bindgen-tests/tests/tests.rs +++ b/bindgen-tests/tests/tests.rs @@ -725,21 +725,35 @@ fn test_wrap_static_fns() { // This test is for testing diffs of the generated C source and header files // TODO: If another such feature is added, convert this test into a more generic // test that looks at `tests/headers/generated` directory. + + let wrap_static_fns_c_name = + if cfg!(all(target_arch = "aarch64", target_os = "linux")) { + "wrap_static_fns_aarch64_linux" + } else { + "wrap_static_fns" + }; + let expect_path = PathBuf::from("tests/expectations/tests/generated") - .join("wrap_static_fns"); + .join(wrap_static_fns_c_name); println!("In path is ::: {}", expect_path.display()); let generated_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("wrap_static_fns"); println!("Out path is ::: {}", generated_path.display()); - let _bindings = Builder::default() + #[allow(unused_mut)] + let mut builder = Builder::default() .header("tests/headers/wrap-static-fns.h") .wrap_static_fns(true) .wrap_static_fns_path(generated_path.display().to_string()) - .parse_callbacks(Box::new(parse_callbacks::WrapAsVariadicFn)) - .generate() - .expect("Failed to generate bindings"); + .parse_callbacks(Box::new(parse_callbacks::WrapAsVariadicFn)); + + #[cfg(all(target_arch = "aarch64", target_os = "linux"))] + { + builder = builder.clang_arg("-DDISABLE_VA"); + } + + builder.generate().expect("Failed to generate bindings"); let expected_c = fs::read_to_string(expect_path.with_extension("c")) .expect("Could not read generated wrap_static_fns.c"); diff --git a/dist-workspace.toml b/dist-workspace.toml index f2706c7473..9da713f523 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -25,3 +25,4 @@ global = "ubuntu-22.04" aarch64-apple-darwin = "macos-14" x86_64-apple-darwin = "macos-13" x86_64-unknown-linux-gnu = "ubuntu-22.04" +aarch64-unknown-linux-gnu = "ubuntu-24.04-arm"