diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..64b38df24 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,146 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + schedule: [cron: "40 1 * * *"] + +jobs: + test: + name: ${{matrix.name || format('Rust {0}', matrix.rust)}}-test + runs-on: ${{matrix.os || 'ubuntu'}}-latest + strategy: + fail-fast: false + matrix: + include: + - rust: nightly + - rust: beta + - rust: stable + - name: macOS + rust: nightly + os: macos + - name: Windows (gnu) + rust: nightly-x86_64-pc-windows-gnu + os: windows + - name: Windows (msvc) + rust: nightly-x86_64-pc-windows-msvc + os: windows + flags: /EHsc + env: + CARGO_TERM_COLOR: always + CXXFLAGS: ${{matrix.flags}} + RUSTFLAGS: --cfg deny_warnings -Dwarnings + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + components: rustfmt + # For operating systems that have it packaged, install creduce + - name: Install creduce (Linux) + if: matrix.os == '' + run: sudo apt-get install creduce + - name: Install creduce (MacOS) + if: matrix.os == 'macOS' + run: brew install creduce + - name: Set LIBCLANG_PATH (Windows) + # Windows github action doesn't set the path for clang, so set it + # See https://github.com/rust-lang/rust-bindgen/issues/1797 + if: matrix.os == 'windows' + run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV + - name: Exclude failing targets and tests + # no creduce on Windows, so exclude tests needing creduce there + run: | + echo RUSTFLAGS=$RUSTFLAGS >> $GITHUB_ENV + echo ::set-output name=exclude::${{runner.os == 'Windows' && '--exclude autocxx-reduce --exclude autocxx-gen' || ''}} + env: + # non-linux failures https://github.com/google/autocxx/issues/819 + # beta failing tests https://github.com/google/autocxx/issues/818 + RUSTFLAGS: ${{matrix.name == 'Windows (msvc)' && '--cfg skip_windows_msvc_failing_tests' || ''}} ${{matrix.name == 'Windows (gnu)' && '--cfg skip_windows_gnu_failing_tests' || ''}} ${{matrix.rust == 'beta' && '--cfg skip_beta_failing_tests' || ''}} + id: testsuite + shell: bash + - run: cargo test --workspace ${{steps.testsuite.outputs.exclude}} + + examples: + name: ${{matrix.name || format('Rust {0}', matrix.rust)}}-examples + runs-on: ${{matrix.os || 'ubuntu'}}-latest + strategy: + fail-fast: false + matrix: + include: + - rust: nightly + - rust: beta + - rust: stable + - name: macOS + rust: nightly + os: macos + - name: Windows (gnu) + rust: nightly-x86_64-pc-windows-gnu + os: windows + - name: Windows (msvc) + rust: nightly-x86_64-pc-windows-msvc + os: windows + flags: /EHsc + env: + CARGO_TERM_COLOR: always + CXXFLAGS: ${{matrix.flags}} + RUSTFLAGS: --cfg deny_warnings -Dwarnings + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{matrix.rust}} + components: rustfmt + - name: Set LIBCLANG_PATH (Windows) + # Windows github action doesn't set the path for clang, so set it + # See https://github.com/rust-lang/rust-bindgen/issues/1797 + if: matrix.os == 'windows' + run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV + - name: Build s2 example + working-directory: ./examples/s2 + # s2 doesn't link on Windows + if: matrix.os != 'windows' + run: cargo build + - name: Build steam example + working-directory: ./examples/steam-mini + run: cargo build + - name: Build subclass example + working-directory: ./examples/subclass + run: cargo build + - name: Build pod example + working-directory: ./examples/pod + run: cargo build + - name: Build chromium render-frame-host example + working-directory: ./examples/chromium-fake-render-frame-host + # chromium-fake-render-frame-host doesn't link on Windows + if: matrix.os != 'windows' + run: cargo build + - name: Build non-trivial-type-on-stack example + working-directory: ./examples/non-trivial-type-on-stack + run: cargo build + + clippy: + name: Clippy + runs-on: ubuntu-latest + env: + CARGO_TERM_COLOR: always + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/rust-toolchain@clippy + - run: cargo clippy --workspace --tests -- -Dclippy::all + + outdated: + name: Outdated + runs-on: ubuntu-latest + env: + CARGO_TERM_COLOR: always + if: github.event_name != 'pull_request' + steps: + - uses: actions/checkout@v2 + - uses: dtolnay/install@cargo-outdated + - run: cargo outdated --exit-code 1 diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml deleted file mode 100644 index b5fd94dfb..000000000 --- a/.github/workflows/clippy.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Clippy -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] -jobs: - clippy_check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - components: clippy - override: true - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --all-features --tests diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml deleted file mode 100644 index 23f8d51ed..000000000 --- a/.github/workflows/examples.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Examples - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - name: Checkout with submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Build s2 example - working-directory: ./examples/s2 - run: cargo build --all --verbose - - name: Build steam example - working-directory: ./examples/steam-mini - run: cargo build --all --verbose - - name: Build subclass example - working-directory: ./examples/subclass - run: cargo build --all --verbose - - name: Build pod example - working-directory: ./examples/pod - run: cargo build --all --verbose - - name: Build chromium render-frame-host example - working-directory: ./examples/chromium-fake-render-frame-host - run: cargo build --all --verbose - - name: Build non-trivial-type-on-stack example - working-directory: ./examples/non-trivial-type-on-stack - run: cargo build --all --verbose diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 1435c7abe..000000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Rust - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Build - run: cargo build --all --verbose - - name: Install creduce - run: sudo apt-get install creduce - - name: Run tests - run: cargo test --all --verbose diff --git a/engine/src/parse_file.rs b/engine/src/parse_file.rs index fd60a2a22..ad75df0e1 100644 --- a/engine/src/parse_file.rs +++ b/engine/src/parse_file.rs @@ -107,7 +107,7 @@ fn parse_file_contents(source: syn::File, auto_allowlist: bool) -> Result { Segment::Autocxx( - crate::IncludeCppEngine::new_from_syn(mac.mac.clone()) + crate::IncludeCppEngine::new_from_syn(mac.mac) .map_err(ParseError::AutocxxCodegenError)?, ) } @@ -273,9 +273,7 @@ pub trait CppBuildable { impl ParsedFile { /// Get all the autocxxes in this parsed file. pub fn get_rs_buildables(&self) -> impl Iterator { - fn do_get_rs_buildables( - segments: &Vec, - ) -> impl Iterator { + fn do_get_rs_buildables(segments: &[Segment]) -> impl Iterator { segments .iter() .flat_map(|s| -> Box> { @@ -292,9 +290,7 @@ impl ParsedFile { /// Get all items which can result in C++ code pub fn get_cpp_buildables(&self) -> impl Iterator { - fn do_get_cpp_buildables( - segments: &Vec, - ) -> impl Iterator { + fn do_get_cpp_buildables(segments: &[Segment]) -> impl Iterator { segments .iter() .flat_map(|s| -> Box> { @@ -316,7 +312,7 @@ impl ParsedFile { fn get_autocxxes_mut(&mut self) -> impl Iterator { fn do_get_autocxxes_mut( - segments: &mut Vec, + segments: &mut [Segment], ) -> impl Iterator { segments .iter_mut() @@ -333,7 +329,7 @@ impl ParsedFile { } pub fn include_dirs(&self) -> impl Iterator { - fn do_get_include_dirs(segments: &Vec) -> impl Iterator { + fn do_get_include_dirs(segments: &[Segment]) -> impl Iterator { segments .iter() .flat_map(|s| -> Box> { diff --git a/examples/chromium-fake-render-frame-host/build.rs b/examples/chromium-fake-render-frame-host/build.rs index b709bad96..c329fac96 100644 --- a/examples/chromium-fake-render-frame-host/build.rs +++ b/examples/chromium-fake-render-frame-host/build.rs @@ -15,7 +15,8 @@ fn main() { let path = std::path::PathBuf::from("src"); let mut b = autocxx_build::Builder::new("src/main.rs", &[&path]).expect_build(); - b.flag_if_supported("-std=c++17") + b.flag_if_supported("-std=c++17") // clang + .flag_if_supported("/std:c++17") // msvc .file("src/fake-chromium-src.cc") .compile("autocxx-fake-render-frame-host-example"); println!("cargo:rerun-if-changed=src/main.rs"); diff --git a/gen/cmd/src/main.rs b/gen/cmd/src/main.rs index 4690d2012..b3bb959fa 100644 --- a/gen/cmd/src/main.rs +++ b/gen/cmd/src/main.rs @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(test)] -mod cmd_test; - use autocxx_engine::parse_file; use clap::{crate_authors, crate_version, App, Arg, ArgGroup}; use proc_macro2::TokenStream; diff --git a/gen/cmd/src/cmd_test.rs b/gen/cmd/tests/cmd_test.rs similarity index 96% rename from gen/cmd/src/cmd_test.rs rename to gen/cmd/tests/cmd_test.rs index 83692fa9d..a650e5127 100644 --- a/gen/cmd/src/cmd_test.rs +++ b/gen/cmd/tests/cmd_test.rs @@ -19,6 +19,7 @@ use tempdir::TempDir; static MAIN_RS: &str = include_str!("../../../demo/src/main.rs"); static INPUT_H: &str = include_str!("../../../demo/src/input.h"); +static BLANK: &str = "// Blank autocxx placeholder"; #[test] fn test_help() -> Result<(), Box> { @@ -158,7 +159,7 @@ fn assert_contentful(outdir: &TempDir, fname: &str) { panic!("File {} didn't exist", p.to_string_lossy()); } assert!( - p.metadata().unwrap().len() > super::BLANK.len().try_into().unwrap(), + p.metadata().unwrap().len() > BLANK.len().try_into().unwrap(), "File {} is empty", fname ); @@ -170,7 +171,7 @@ fn assert_not_contentful(outdir: &TempDir, fname: &str) { panic!("File {} didn't exist", p.to_string_lossy()); } assert!( - p.metadata().unwrap().len() <= super::BLANK.len().try_into().unwrap(), + p.metadata().unwrap().len() <= BLANK.len().try_into().unwrap(), "File {} is not empty", fname ); diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 53cbd70cc..0254c97ec 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "autocxx-integration-tests" version = "0.1.0" +autotests = false edition = "2021" [dev-dependencies] @@ -27,3 +28,8 @@ itertools = "0.10" version = "1.0.39" features = [ "full" ] #features = [ "full", "extra-traits" ] + +[[test]] +name = "integration_tests" +path = "tests/lib.rs" +harness = true \ No newline at end of file diff --git a/integration-tests/src/tests.rs b/integration-tests/tests/integration_test.rs similarity index 99% rename from integration-tests/src/tests.rs rename to integration-tests/tests/integration_test.rs index e4b532ac1..a9d26db1d 100644 --- a/integration-tests/src/tests.rs +++ b/integration-tests/tests/integration_test.rs @@ -3511,6 +3511,8 @@ fn test_root_ns_meth_ret_nonpod() { run_test("", hdr, rs, &["Bob"], &["B::C"]); } +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_forward_declaration() { let hdr = indoc! {" @@ -3558,6 +3560,8 @@ fn test_ulong() { run_test("", hdr, rs, &["daft"], &[]); } +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_typedef_to_ulong() { let hdr = indoc! {" @@ -3632,6 +3636,8 @@ fn test_reserved_name() { run_test("", hdr, rs, &["async_"], &[]); } +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_nested_type() { // Test that we can import APIs that use nested types. @@ -4461,6 +4467,8 @@ fn test_double_underscores_ignored() { run_test("", hdr, rs, &["B"], &[]); } +// This test fails on Windows gnu but not on Windows msvc +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] #[test] fn test_double_underscore_typedef_ignored() { let hdr = indoc! {" @@ -5343,6 +5351,8 @@ fn test_blocklist_not_overly_broad() { run_test("", hdr, rs, &["rust_func", "std_func"], &[]); } +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] #[test] fn test_stringview() { // Test that APIs using std::string_view do not otherwise cause errors. @@ -5413,6 +5423,7 @@ fn test_include_cpp_in_path() { do_run_test_manual("", hdr, rs, None, None).unwrap(); } +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_bitset() { let hdr = indoc! {" @@ -5915,6 +5926,7 @@ fn test_rust_reference() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_rust_reference_autodiscover() { let hdr = indoc! {" @@ -6014,6 +6026,7 @@ fn test_rust_reference_method() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_box() { let hdr = indoc! {" @@ -6308,6 +6321,7 @@ fn test_pv_subclass_not_pub() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_ptr_param() { let hdr = indoc! {" @@ -6352,6 +6366,8 @@ fn test_pv_subclass_ptr_param() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_pv_subclass_return() { let hdr = indoc! {" @@ -6393,6 +6409,7 @@ fn test_pv_subclass_return() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_passed_to_fn() { let hdr = indoc! {" @@ -6435,6 +6452,7 @@ fn test_pv_subclass_passed_to_fn() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_derive_defaults() { let hdr = indoc! {" @@ -6564,6 +6582,7 @@ fn test_two_subclasses() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_two_superclasses_with_same_name_method() { let hdr = indoc! {" @@ -6660,6 +6679,7 @@ fn test_pv_protected_constructor() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_protected_method() { let hdr = indoc! {" @@ -6843,6 +6863,7 @@ fn test_pv_subclass_allocation_not_self_owned() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_allocation_self_owned() { let hdr = indoc! {" @@ -7002,6 +7023,7 @@ fn test_pv_subclass_allocation_self_owned() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_calls() { let hdr = indoc! {" @@ -7207,6 +7229,7 @@ fn test_pv_subclass_calls() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_types() { let hdr = indoc! {" @@ -7517,6 +7540,7 @@ fn test_pv_subclass_overrides() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_pv_subclass_namespaced_superclass() { let hdr = indoc! {" @@ -7689,6 +7713,8 @@ fn test_copy_and_move_constructor_moveit() { run_test("", hdr, rs, &["A"], &[]); } +// This test fails on Windows gnu but not on Windows msvc +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] #[test] fn test_uniqueptr_moveit() { let hdr = indoc! {" @@ -7711,6 +7737,8 @@ fn test_uniqueptr_moveit() { run_test("", hdr, rs, &["A"], &[]); } +// This test fails on Windows gnu but not on Windows msvc +#[cfg_attr(skip_windows_gnu_failing_tests, ignore)] #[test] fn test_various_emplacement() { let hdr = indoc! {" @@ -7739,6 +7767,7 @@ fn test_various_emplacement() { run_test("", hdr, rs, &["A"], &[]); } +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_emplace_uses_overridden_new_and_delete() { let hdr = indoc! {" @@ -7913,6 +7942,7 @@ fn test_no_rvo_move() { ); } +#[cfg_attr(skip_beta_failing_tests, ignore)] #[test] fn test_abstract_up() { let hdr = indoc! {" @@ -7962,6 +7992,7 @@ fn test_class_having_protected_method() { run_test("", hdr, rs, &[], &["A"]); } +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_protected_inner_class() { let hdr = indoc! {" @@ -7987,6 +8018,7 @@ fn test_protected_inner_class() { run_test("", hdr, rs, &["A"], &[]); } +#[cfg_attr(skip_windows_msvc_failing_tests, ignore)] #[test] fn test_private_inner_class() { let hdr = indoc! {" @@ -8064,6 +8096,7 @@ fn size_and_alignment_test(pod: bool) { "}, type_definitions, function_definitions ); + #[allow(clippy::unnecessary_to_owned)] // wrongly triggers on into_iter() below let allowlist_fns: Vec = TYPES .iter() .flat_map(|(name, _)| { diff --git a/integration-tests/src/lib.rs b/integration-tests/tests/lib.rs similarity index 94% rename from integration-tests/src/lib.rs rename to integration-tests/tests/lib.rs index ada9cf221..c66a9c56f 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/tests/lib.rs @@ -12,8 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(test)] -mod tests; - -#[cfg(test)] +mod integration_test; mod test_utils; diff --git a/integration-tests/src/test_utils.rs b/integration-tests/tests/test_utils.rs similarity index 98% rename from integration-tests/src/test_utils.rs rename to integration-tests/tests/test_utils.rs index 56e574124..dc1a13b86 100644 --- a/integration-tests/src/test_utils.rs +++ b/integration-tests/tests/test_utils.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![cfg(test)] + use std::{ fs::File, io::{BufRead, BufReader, Read, Write}, @@ -86,7 +88,7 @@ impl LinkableTryBuilder { } for generated_rs in generated_rs_files { self.move_items_into_temp_dir( - &generated_rs.parent().unwrap().to_path_buf(), + &generated_rs.parent().unwrap(), generated_rs.file_name().unwrap().to_str().unwrap(), ); } @@ -108,7 +110,7 @@ fn write_to_file(tdir: &TempDir, filename: &str, content: &str) -> PathBuf { } /// A positive test, we expect to pass. -pub(crate) fn run_test( +pub fn run_test( cxx_code: &str, header_code: &str, rust_code: TokenStream, @@ -382,7 +384,8 @@ where .host(&target) .target(&target) .opt_level(1) - .flag("-std=c++14"); + .flag("-std=c++14") // For clang + .flag_if_supported("/GX"); // Enable C++ exceptions for msvc let b = if let Some(builder_modifier) = builder_modifier { builder_modifier.modify_cc_builder(b) } else { diff --git a/tools/reduce/src/main.rs b/tools/reduce/src/main.rs index 994ae08a8..01c2abb8b 100644 --- a/tools/reduce/src/main.rs +++ b/tools/reduce/src/main.rs @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#[cfg(test)] -mod reduce_test; - use std::{ fs::File, io::Write, @@ -266,7 +263,7 @@ fn do_run(matches: ArgMatches, tmp_dir: &TempDir) -> Result<(), std::io::Error> .unwrap() .to_string(); let gen_cmd = matches.value_of("gen-cmd").unwrap_or(&default_gen_cmd); - if Path::new(gen_cmd).exists() == false { + if !Path::new(gen_cmd).exists() { panic!( "autocxx-gen not found in {}. hint: autocxx-reduce --gen-cmd /path/to/autocxx-gen", gen_cmd diff --git a/tools/reduce/src/reduce_test.rs b/tools/reduce/tests/reduce_test.rs similarity index 100% rename from tools/reduce/src/reduce_test.rs rename to tools/reduce/tests/reduce_test.rs