From fa55fb14c7ebfce3744cea6af94bf514fc21602c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 01:20:17 +0200 Subject: [PATCH 01/16] Clean up CI setup - Enable caching - Move things out of script files, and into the .travis.yml file - Use "jobs" key, so that we can name each job --- objc/.travis.yml | 85 +++++++++++++++++++++++++++++------------- objc/Cargo.toml | 2 - objc/travis_install.sh | 26 ------------- objc/travis_test.sh | 10 ----- 4 files changed, 60 insertions(+), 63 deletions(-) delete mode 100755 objc/travis_install.sh delete mode 100755 objc/travis_test.sh diff --git a/objc/.travis.yml b/objc/.travis.yml index 20118f8a4..2ef39f5d7 100644 --- a/objc/.travis.yml +++ b/objc/.travis.yml @@ -1,31 +1,66 @@ -language: rust -rust: - - stable - - nightly -os: - - osx - - linux -env: - - FEATURES="" IOS_ARCHS="" -matrix: - include: - - os: osx - rust: stable - env: FEATURES="exception verify_message" IOS_ARCHS="" - - os: osx - osx_image: xcode7.3 - rust: 1.41.0 - env: FEATURES="exception" IOS_ARCHS="i386 x86_64 armv7 armv7s aarch64" sudo: false -install: ./travis_install.sh +language: rust +cache: cargo + +addons: + apt: + packages: + - clang + - cmake +install: > + if [ "$TRAVIS_OS_NAME" = "linux" ]; then + git clone -b 1.9 https://github.com/gnustep/libobjc2.git && + mkdir libobjc2/build && + cd libobjc2/build && + export CC="clang" && + export CXX="clang++" && + cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/libobjc2_staging ../ && + make install + fi before_script: > if [ "$TRAVIS_OS_NAME" = "linux" ]; then export LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LIBRARY_PATH; export LD_LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LD_LIBRARY_PATH; fi -script: ./travis_test.sh -addons: - apt: - packages: - - clang - - cmake +script: cargo test --verbose + +jobs: + include: + - name: Check formatting + os: linux + rust: stable + install: rustup component add rustfmt + script: cargo fmt --all -- --check + + - name: MacOS stable + os: osx + rust: stable + - name: MacOS nightly + os: osx + rust: nightly + - name: MacOS stable w. features + os: osx + rust: stable + script: cargo test --verbose --features "exception verify_message" + + - name: Linux stable + os: linux + rust: stable + - name: Linux nightly + os: linux + rust: nightly + + - name: iOS + os: osx + osx_image: xcode7.3 + rust: 1.41.0 + before_install: > + rustup target add + i386-apple-ios + x86_64-apple-ios + armv7-apple-ios + armv7s-apple-ios + aarch64-apple-ios + install: curl -LO https://github.com/SSheldon/rust-test-ios/releases/download/0.1.1/rust-test-ios && chmod +x rust-test-ios + env: FEATURES="exception" + script: ./rust-test-ios diff --git a/objc/Cargo.toml b/objc/Cargo.toml index 9c8523dd6..83eaa46e5 100644 --- a/objc/Cargo.toml +++ b/objc/Cargo.toml @@ -15,8 +15,6 @@ exclude = [ ".gitignore", ".travis.yml", "doc.sh", - "travis_install.sh", - "travis_test.sh", "tests-ios/**", ] diff --git a/objc/travis_install.sh b/objc/travis_install.sh deleted file mode 100755 index 13b0fc330..000000000 --- a/objc/travis_install.sh +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env sh - -set -eu - -gnustep_install() { - git clone -b 1.9 https://github.com/gnustep/libobjc2.git - mkdir libobjc2/build - cd libobjc2/build - export CC="clang" - export CXX="clang++" - cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/libobjc2_staging ../ - make install -} - -for arch in $IOS_ARCHS; do - rustup target add "${arch}-apple-ios" -done - -if [ -n "$IOS_ARCHS" ]; then - curl -LO https://github.com/SSheldon/rust-test-ios/releases/download/0.1.1/rust-test-ios - chmod +x rust-test-ios -fi - -if [ "$TRAVIS_OS_NAME" = "linux" ]; then - gnustep_install -fi diff --git a/objc/travis_test.sh b/objc/travis_test.sh deleted file mode 100755 index 1e0999389..000000000 --- a/objc/travis_test.sh +++ /dev/null @@ -1,10 +0,0 @@ -#! /usr/bin/env sh - -set -eu - -if [ -z "$IOS_ARCHS" ]; then - cargo build --verbose --features "$FEATURES" - cargo test --verbose --features "$FEATURES" -else - ./rust-test-ios -fi From 63bf322278a5b801a781df6ecaeb6f8a88b1f980 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 01:22:54 +0200 Subject: [PATCH 02/16] Test MacOS 32-bit --- objc/.travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/objc/.travis.yml b/objc/.travis.yml index 2ef39f5d7..3ac4b0308 100644 --- a/objc/.travis.yml +++ b/objc/.travis.yml @@ -42,6 +42,13 @@ jobs: os: osx rust: stable script: cargo test --verbose --features "exception verify_message" + - name: MacOS 32bit + os: osx + osx_image: xcode9.4 + rust: nightly + # 32-bit targets only have tier 3 support + install: rustup component add rust-src + script: cargo test -Z build-std --target i686-apple-darwin --verbose - name: Linux stable os: linux From 1d5c958b018a04dc52a397cf89ad9217e428091c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 3 Jun 2021 15:35:43 +0200 Subject: [PATCH 03/16] Run iOS on nightly instead of 1.41.0 --- objc/.travis.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/objc/.travis.yml b/objc/.travis.yml index 3ac4b0308..cb51db9ed 100644 --- a/objc/.travis.yml +++ b/objc/.travis.yml @@ -57,17 +57,14 @@ jobs: os: linux rust: nightly - - name: iOS + - name: iOS nightly os: osx osx_image: xcode7.3 - rust: 1.41.0 - before_install: > - rustup target add - i386-apple-ios - x86_64-apple-ios - armv7-apple-ios - armv7s-apple-ios - aarch64-apple-ios + rust: nightly + before_install: rustup component add rust-src + # Install rust-test-ios install: curl -LO https://github.com/SSheldon/rust-test-ios/releases/download/0.1.1/rust-test-ios && chmod +x rust-test-ios + # Enable -Z build-std, 32-bit targets only have tier 3 support + before_script: printf '[unstable]\nbuild-std = ["std"]\n' > $HOME/.cargo/config.toml env: FEATURES="exception" script: ./rust-test-ios From 66999a01ab10bd30f513b779609b3f0815dcbd65 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 15:49:45 +0200 Subject: [PATCH 04/16] Move .travis.yml to the correct top-level directory --- objc/.travis.yml => .travis.yml | 4 ++-- Cargo.toml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) rename objc/.travis.yml => .travis.yml (95%) diff --git a/objc/.travis.yml b/.travis.yml similarity index 95% rename from objc/.travis.yml rename to .travis.yml index cb51db9ed..19476d8f5 100644 --- a/objc/.travis.yml +++ b/.travis.yml @@ -66,5 +66,5 @@ jobs: install: curl -LO https://github.com/SSheldon/rust-test-ios/releases/download/0.1.1/rust-test-ios && chmod +x rust-test-ios # Enable -Z build-std, 32-bit targets only have tier 3 support before_script: printf '[unstable]\nbuild-std = ["std"]\n' > $HOME/.cargo/config.toml - env: FEATURES="exception" - script: ./rust-test-ios + # TODO: env: FEATURES="exception" + script: cd objc && ../rust-test-ios diff --git a/Cargo.toml b/Cargo.toml index aa57a694a..47b27aed7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ members = [ "objc_foundation", "objc_id", ] +exclude = ["objc/tests-ios"] From d4b34b76de6e70c38a934341a906b0b6f305e74d Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 1 Jun 2021 16:11:19 +0200 Subject: [PATCH 05/16] Don't include objc headers in exception.m To fix cross compile issues (and also, it's faster to call objc_retain directly instead of using a selector) --- objc_exception/extern/exception.m | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/objc_exception/extern/exception.m b/objc_exception/extern/exception.m index 700439ecf..52b47e375 100644 --- a/objc_exception/extern/exception.m +++ b/objc_exception/extern/exception.m @@ -1,5 +1,6 @@ -#include -#include +// Always available in Objective-C +// See https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain +id objc_retain(id value); void RustObjCExceptionThrow(id exception) { @throw exception; @@ -9,12 +10,12 @@ int RustObjCExceptionTryCatch(void (*try)(void *), void *context, id *error) { @try { try(context); if (error) { - *error = nil; + *error = (id)0; // nil } return 0; } @catch (id exception) { if (error) { - *error = [exception retain]; + *error = objc_retain(exception); } return 1; } From 3ac8efd77cc211159bb9997af6fe85c1abe93f7c Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 14:39:18 +0200 Subject: [PATCH 06/16] Make `throw` more efficient, and add a note about UB Note: The function was also UB before (`RustObjCExceptionThrow` would need to be marked with `C-unwind`) --- objc_exception/extern/exception.m | 4 ---- objc_exception/src/lib.rs | 20 ++++++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/objc_exception/extern/exception.m b/objc_exception/extern/exception.m index 52b47e375..be3ea58e3 100644 --- a/objc_exception/extern/exception.m +++ b/objc_exception/extern/exception.m @@ -2,10 +2,6 @@ // See https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-runtime-objc-retain id objc_retain(id value); -void RustObjCExceptionThrow(id exception) { - @throw exception; -} - int RustObjCExceptionTryCatch(void (*try)(void *), void *context, id *error) { @try { try(context); diff --git a/objc_exception/src/lib.rs b/objc_exception/src/lib.rs index 5b591257e..80098a24f 100644 --- a/objc_exception/src/lib.rs +++ b/objc_exception/src/lib.rs @@ -5,10 +5,17 @@ use std::os::raw::{c_int, c_void}; use std::ptr; #[link(name = "objc", kind = "dylib")] -extern "C" {} +// TODO: "C-unwind" +extern "C" { + /// See [`objc-exception.h`][objc-exception]. + /// + /// [objc-exception]: https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-exception.h.auto.html + // Header marks this with _Nonnull, but LLVM output shows otherwise + fn objc_exception_throw(exception: *mut c_void) -> !; + // fn objc_exception_rethrow(); +} extern "C" { - fn RustObjCExceptionThrow(exception: *mut c_void); fn RustObjCExceptionTryCatch( r#try: extern "C" fn(*mut c_void), context: *mut c_void, @@ -26,9 +33,14 @@ pub enum Exception {} /// /// This unwinds from Objective-C, and the exception must be caught using an /// Objective-C exception handler. +/// +/// This also invokes undefined behaviour until `C-unwind` is stabilized, see +/// [RFC-2945]. +/// +/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html +#[inline] pub unsafe fn throw(exception: *mut Exception) -> ! { - RustObjCExceptionThrow(exception as *mut _); - unreachable!(); + objc_exception_throw(exception as *mut _) } unsafe fn try_no_ret(closure: F) -> Result<(), *mut Exception> From 2f52c81ec1e7b04eae4e2a7e192d66e87b0990b9 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 01:51:30 +0200 Subject: [PATCH 07/16] Enable C compiler option `-fobjc-exceptions` for `objc_exception` --- objc_exception/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/objc_exception/build.rs b/objc_exception/build.rs index a17b0cc09..e53b0b8c6 100644 --- a/objc_exception/build.rs +++ b/objc_exception/build.rs @@ -1,5 +1,6 @@ fn main() { cc::Build::new() .file("extern/exception.m") + .flag("-fobjc-exceptions") .compile("libexception.a"); } From 87e13749a94a679adef3791e158e467b55a03046 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 16:30:55 +0200 Subject: [PATCH 08/16] Setup GitHub Actions --- .github/workflows/ci.yml | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..40b74f029 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI + +on: + push: + pull_request: + +env: + CARGO_TERM_COLOR: always + RUST_BACKTRACE: 1 + # Faster compilation and error on warnings + RUSTFLAGS: "-C debuginfo=0 -D warnings" + +jobs: + fmt: + name: Check formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Check formatting + uses: actions-rs/cargo@v1 + with: + command: fmt + args: -- --check + + test: + name: Test + strategy: + matrix: + platform: + - { os: ubuntu-latest } + - { os: macos-10.15 } + - { os: macos-11 } + # - { target: x86_64-apple-ios, os: macos-latest, } + # - { target: aarch64-apple-ios, os: macos-latest, } + + runs-on: ${{ matrix.platform.os }} + + steps: + - uses: actions/checkout@v2 + - name: Cache Rust + uses: actions/cache@v2 + with: + path: | + ~/.cargo/ + target/ + key: cargo-${{ matrix.platform.os }} + + - name: Install different Rust toolchain + # A default toolchain is already installed + if: matrix.platform.target + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: ${{ matrix.platform.target }} + profile: minimal + override: true + + - name: Install Objective-C compiler + if: contains(matrix.platform.os, 'ubuntu') + run: sudo apt-get install gobjc + + - name: Check documentation + uses: actions-rs/cargo@v1 + with: + # TODO: Disallow warnings here + command: doc + args: --no-deps --document-private-items + + - name: Run checks + uses: actions-rs/cargo@v1 + with: + command: check + args: --verbose + + - name: Install GNUStep + if: contains(matrix.platform.os, 'ubuntu') + run: | + sudo apt-get install clang make + git clone -b 1.9 https://github.com/gnustep/libobjc2.git && + mkdir libobjc2/build && + cd libobjc2/build && + export CC="clang" && + export CXX="clang++" && + cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/libobjc2_staging ../ && + make install && + echo "LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LIBRARY_PATH" >> $GITHUB_ENV && + echo "LD_LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + + - name: Build and run tests + uses: actions-rs/cargo@v1 + with: + command: test + args: --verbose From 66b5df9e6891f74aa28ec899bb4becb733ab9aee Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 17:16:05 +0200 Subject: [PATCH 09/16] Make Travis CI only run MacOS jobs They have wider OS support than GitHub Actions, but they also give less free build minutes Also fixes the iOS tests --- .travis.yml | 68 ++++++++++++--------------------------- objc/tests-ios/prelude.rs | 3 ++ 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/.travis.yml b/.travis.yml index 19476d8f5..bfa70fb9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,70 +1,42 @@ sudo: false language: rust cache: cargo +os: osx -addons: - apt: - packages: - - clang - - cmake -install: > - if [ "$TRAVIS_OS_NAME" = "linux" ]; then - git clone -b 1.9 https://github.com/gnustep/libobjc2.git && - mkdir libobjc2/build && - cd libobjc2/build && - export CC="clang" && - export CXX="clang++" && - cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/libobjc2_staging ../ && - make install - fi -before_script: > - if [ "$TRAVIS_OS_NAME" = "linux" ]; then - export LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LIBRARY_PATH; - export LD_LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LD_LIBRARY_PATH; - fi -script: cargo test --verbose +script: +- cargo test --workspace --verbose +- # TODO: cargo test --workspace --verbose --all-features jobs: include: - - name: Check formatting - os: linux - rust: stable - install: rustup component add rustfmt - script: cargo fmt --all -- --check + - name: MacOS 10.11 + osx_image: xcode7.3 - - name: MacOS stable - os: osx - rust: stable - - name: MacOS nightly - os: osx - rust: nightly - - name: MacOS stable w. features - os: osx - rust: stable - script: cargo test --verbose --features "exception verify_message" - - name: MacOS 32bit - os: osx + - name: MacOS 10.13 (with 32bit) osx_image: xcode9.4 rust: nightly # 32-bit targets only have tier 3 support install: rustup component add rust-src - script: cargo test -Z build-std --target i686-apple-darwin --verbose + script: + - cargo test --workspace --verbose + - # TODO: cargo test --workspace --verbose --all-features + - # objc_exception doesn't work on 32bit? + cargo test --workspace --exclude objc_exception --verbose -Z build-std --target i686-apple-darwin + - # TODO: cargo test --workspace --verbose --all-features -Z build-std --target i686-apple-darwin - - name: Linux stable - os: linux - rust: stable - - name: Linux nightly - os: linux - rust: nightly + - name: MacOS 11.3 + osx_image: xcode12.5 - name: iOS nightly - os: osx osx_image: xcode7.3 rust: nightly before_install: rustup component add rust-src # Install rust-test-ios install: curl -LO https://github.com/SSheldon/rust-test-ios/releases/download/0.1.1/rust-test-ios && chmod +x rust-test-ios - # Enable -Z build-std, 32-bit targets only have tier 3 support - before_script: printf '[unstable]\nbuild-std = ["std"]\n' > $HOME/.cargo/config.toml + before_script: + # Enable -Z build-std, 32-bit targets only have tier 3 support + - printf '[unstable]\nbuild-std = ["std"]\n' > $HOME/.cargo/config.toml + # Remove workspace since `rust-test-ios` is not made for that + - rm Cargo.toml # TODO: env: FEATURES="exception" script: cd objc && ../rust-test-ios diff --git a/objc/tests-ios/prelude.rs b/objc/tests-ios/prelude.rs index 8ec4c55ad..2eabd4c83 100644 --- a/objc/tests-ios/prelude.rs +++ b/objc/tests-ios/prelude.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate objc; + use objc::rc::*; use objc::runtime::*; pub use objc::*; From 1326a2e8c438937ac1aca70baa5440e66c5a2ff7 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 01:53:08 +0200 Subject: [PATCH 10/16] Don't run CI twice on PRs --- .github/workflows/ci.yml | 1 + .travis.yml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 40b74f029..0f098bd44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,6 +2,7 @@ name: CI on: push: + branches: [master] pull_request: env: diff --git a/.travis.yml b/.travis.yml index bfa70fb9c..08d0abd4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,9 @@ language: rust cache: cargo os: osx +# Run on master and PRs +if: branch = master + script: - cargo test --workspace --verbose - # TODO: cargo test --workspace --verbose --all-features From 21037f17bddfd673724810d2d718926fa62c2a0e Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 16:30:29 +0200 Subject: [PATCH 11/16] Better GNUStep testing setup --- .github/workflows/ci.yml | 59 ++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f098bd44..1704df41e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: strategy: matrix: platform: - - { os: ubuntu-latest } + - { os: ubuntu-latest } # TODO: 32bit and gcc-multilib - { os: macos-10.15 } - { os: macos-11 } # - { target: x86_64-apple-ios, os: macos-latest, } @@ -46,6 +46,10 @@ jobs: target/ key: cargo-${{ matrix.platform.os }} + - name: Install Packages + if: contains(matrix.platform.os, 'ubuntu') + run: sudo apt-get install gobjc clang make + - name: Install different Rust toolchain # A default toolchain is already installed if: matrix.platform.target @@ -56,10 +60,6 @@ jobs: profile: minimal override: true - - name: Install Objective-C compiler - if: contains(matrix.platform.os, 'ubuntu') - run: sudo apt-get install gobjc - - name: Check documentation uses: actions-rs/cargo@v1 with: @@ -67,28 +67,51 @@ jobs: command: doc args: --no-deps --document-private-items - - name: Run checks + - # Run before we install GNUStep as a "fail fast" mechanism + name: Run checks uses: actions-rs/cargo@v1 with: command: check args: --verbose - - name: Install GNUStep + - name: Install GNUStep libobjc2 + if: contains(matrix.platform.os, 'ubuntu') + run: | + git clone -b 1.9 https://github.com/gnustep/libobjc2.git + mkdir libobjc2/build + cd libobjc2/build + export CC="clang" + export CXX="clang++" + cmake ../ + sudo make install + + - name: Install GNUStep make if: contains(matrix.platform.os, 'ubuntu') run: | - sudo apt-get install clang make - git clone -b 1.9 https://github.com/gnustep/libobjc2.git && - mkdir libobjc2/build && - cd libobjc2/build && - export CC="clang" && - export CXX="clang++" && - cmake -DCMAKE_INSTALL_PREFIX:PATH=$HOME/libobjc2_staging ../ && - make install && - echo "LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LIBRARY_PATH" >> $GITHUB_ENV && - echo "LD_LIBRARY_PATH=$HOME/libobjc2_staging/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + git clone -b make-2_9_0 https://github.com/gnustep/tools-make.git + cd tools-make + ./configure --with-library-combo=ng-gnu-gnu + sudo make install + + - name: Install GNUStep-Base + if: contains(matrix.platform.os, 'ubuntu') + run: | + git clone -b base-1_28_0 https://github.com/gnustep/libs-base.git + cd libs-base + ./configure --disable-tls + sudo make install + + - name: Setup environment + if: contains(matrix.platform.os, 'ubuntu') + run: | + ls -al /usr/local/lib + ls -al /usr/local/include + echo "LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV + echo "CPATH=/usr/local/include:$CPATH" >> $GITHUB_ENV - name: Build and run tests uses: actions-rs/cargo@v1 with: command: test - args: --verbose + args: --verbose --no-fail-fast From 4ff9a8b03a35b07162859ce3af99d3abddaf9f48 Mon Sep 17 00:00:00 2001 From: Niels Grewe Date: Wed, 27 Jul 2016 01:30:46 +0200 Subject: [PATCH 12/16] Ensure linkage of the gnustep-base The linker is smart enough to figure out that we are not using any symbols from the Foundation library, and elides the request to link it. To circumvent this, we define a (unused) function referencing the symbol for NSObject --- objc_foundation/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/objc_foundation/src/lib.rs b/objc_foundation/src/lib.rs index 564c6de0f..96eb6e8e3 100644 --- a/objc_foundation/src/lib.rs +++ b/objc_foundation/src/lib.rs @@ -11,9 +11,23 @@ pub use self::object::{INSObject, NSObject}; pub use self::string::{INSCopying, INSMutableCopying, INSString, NSString}; pub use self::value::{INSValue, NSValue}; +#[cfg(any(target_os = "macos", target_os = "ios"))] #[link(name = "Foundation", kind = "framework")] extern "C" {} +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +use objc::runtime::Class; + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[link(name = "gnustep-base", kind = "dylib")] +extern { static _OBJC_CLASS_NSObject : Class; } + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[allow(dead_code)] +unsafe fn get_class_to_force_linkage() -> &'static Class { + &_OBJC_CLASS_NSObject +} + #[macro_use] mod macros; From 807c72e085f25e18ba63183e3966fefb90cec3c4 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 15:43:12 +0200 Subject: [PATCH 13/16] Fix linking of classes under test in objc_foundation and objc_id --- objc_foundation/src/lib.rs | 9 ++++++++- objc_foundation/src/string.rs | 6 ++++++ objc_id/src/id.rs | 6 ++++++ objc_id/src/lib.rs | 22 +++++++++++++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/objc_foundation/src/lib.rs b/objc_foundation/src/lib.rs index 96eb6e8e3..da610293e 100644 --- a/objc_foundation/src/lib.rs +++ b/objc_foundation/src/lib.rs @@ -20,7 +20,14 @@ use objc::runtime::Class; #[cfg(not(any(target_os = "macos", target_os = "ios")))] #[link(name = "gnustep-base", kind = "dylib")] -extern { static _OBJC_CLASS_NSObject : Class; } +extern "C" {} + +// Split up to illustrate that the linking doesn't have to be annotated on the +// correct `extern` block. +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +extern "C" { + static _OBJC_CLASS_NSObject: Class; +} #[cfg(not(any(target_os = "macos", target_os = "ios")))] #[allow(dead_code)] diff --git a/objc_foundation/src/string.rs b/objc_foundation/src/string.rs index 3c9d55ade..38bb80b47 100644 --- a/objc_foundation/src/string.rs +++ b/objc_foundation/src/string.rs @@ -84,6 +84,12 @@ impl fmt::Display for NSString { mod tests { use super::{INSCopying, INSString, NSString}; + #[cfg(not(any(target_os = "macos", target_os = "ios")))] + #[test] + fn ensure_linkage() { + unsafe { crate::get_class_to_force_linkage() }; + } + #[test] fn test_utf8() { let expected = "ประเทศไทย中华Việt Nam"; diff --git a/objc_id/src/id.rs b/objc_id/src/id.rs index b5ed2829e..a7bf2e730 100644 --- a/objc_id/src/id.rs +++ b/objc_id/src/id.rs @@ -206,6 +206,12 @@ mod tests { use objc::runtime::Object; use objc::{class, msg_send}; + #[cfg(not(any(target_os = "macos", target_os = "ios")))] + #[test] + fn ensure_linkage() { + unsafe { crate::get_class_to_force_linkage() }; + } + fn retain_count(obj: &Object) -> usize { unsafe { msg_send![obj, retainCount] } } diff --git a/objc_id/src/lib.rs b/objc_id/src/lib.rs index 2a82acf9a..b291bd086 100644 --- a/objc_id/src/lib.rs +++ b/objc_id/src/lib.rs @@ -11,7 +11,7 @@ which can be cloned to allow multiple references. Weak references may be created using the [`WeakId`](struct.WeakId.html) struct. -``` +```no_run # use objc::msg_send; use objc::runtime::{Class, Object}; use objc_id::{Id, WeakId}; @@ -41,3 +41,23 @@ assert!(weak.load().is_none()); pub use id::{Id, Owned, Ownership, ShareId, Shared, WeakId}; mod id; + +// TODO: Remove the need for this hack + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +use objc::runtime::Class; + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[link(name = "gnustep-base", kind = "dylib")] +extern "C" {} + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +extern "C" { + static _OBJC_CLASS_NSObject: Class; +} + +#[cfg(not(any(target_os = "macos", target_os = "ios")))] +#[allow(dead_code)] +unsafe fn get_class_to_force_linkage() -> &'static Class { + &_OBJC_CLASS_NSObject +} From f17306a804ecfa689030417406d06d7facb13849 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Mon, 30 Aug 2021 15:00:56 +0200 Subject: [PATCH 14/16] Feature-gate block support in objc_foundation --- .github/workflows/ci.yml | 4 +++- objc_foundation/Cargo.toml | 5 ++++- objc_foundation/src/data.rs | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1704df41e..cde012dec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,4 +114,6 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --verbose --no-fail-fast + # TODO: `objc/exception` feature is broken in objc_foundation + # TODO: `objc_foundation/block` feature doesn't work on GNUStep + args: --verbose --no-fail-fast --no-default-features diff --git a/objc_foundation/Cargo.toml b/objc_foundation/Cargo.toml index dd28da395..faa8dcf7b 100644 --- a/objc_foundation/Cargo.toml +++ b/objc_foundation/Cargo.toml @@ -12,7 +12,10 @@ license = "MIT" exclude = [".gitignore"] +[features] +default = ["block"] + [dependencies] -block = "0.1" +block = { optional = true, version = "0.1" } objc = { path = "../objc", version = "0.2.7" } objc_id = { path = "../objc_id", version = "0.1" } diff --git a/objc_foundation/src/data.rs b/objc_foundation/src/data.rs index c73d5fdec..8d377082a 100644 --- a/objc_foundation/src/data.rs +++ b/objc_foundation/src/data.rs @@ -1,9 +1,9 @@ -use std::mem; use std::ops::Range; use std::os::raw::c_void; use std::slice; use super::{INSCopying, INSMutableCopying, INSObject, NSRange}; +#[cfg(feature = "block")] use block::{Block, ConcreteBlock}; use objc::msg_send; use objc_id::Id; @@ -39,6 +39,7 @@ pub trait INSData: INSObject { } } + #[cfg(feature = "block")] fn from_vec(bytes: Vec) -> Id { let capacity = bytes.capacity(); let dealloc = ConcreteBlock::new(move |bytes: *mut c_void, len: usize| unsafe { @@ -56,7 +57,7 @@ pub trait INSData: INSObject { let obj: *mut Self = msg_send![obj, initWithBytesNoCopy:bytes_ptr length:bytes.len() deallocator:dealloc]; - mem::forget(bytes); + std::mem::forget(bytes); Id::from_retained_ptr(obj) } } @@ -192,6 +193,7 @@ mod tests { assert!(data.bytes() == [8, 17]); } + #[cfg(feature = "block")] #[test] fn test_from_vec() { let bytes = vec![3, 7, 16]; From d0155704b10c00a42d3830a4b84bc37ff6256e16 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 17:06:45 +0200 Subject: [PATCH 15/16] Fix GitHub Actions caching and make GNUStep downloads faster --- .github/workflows/ci.yml | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cde012dec..4dce6d46f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,13 +38,16 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Cache Rust uses: actions/cache@v2 with: path: | ~/.cargo/ target/ - key: cargo-${{ matrix.platform.os }} + key: ${{ matrix.platform.os }}-cargo-${{ hashFiles('**/Cargo.toml') }} + restore-keys: | + ${{ matrix.platform.os }}-cargo- - name: Install Packages if: contains(matrix.platform.os, 'ubuntu') @@ -77,9 +80,10 @@ jobs: - name: Install GNUStep libobjc2 if: contains(matrix.platform.os, 'ubuntu') run: | - git clone -b 1.9 https://github.com/gnustep/libobjc2.git - mkdir libobjc2/build - cd libobjc2/build + wget https://github.com/gnustep/libobjc2/archive/refs/tags/v1.9.tar.gz + tar -xzf v1.9.tar.gz + mkdir libobjc2-1.9/build + cd libobjc2-1.9/build export CC="clang" export CXX="clang++" cmake ../ @@ -88,16 +92,18 @@ jobs: - name: Install GNUStep make if: contains(matrix.platform.os, 'ubuntu') run: | - git clone -b make-2_9_0 https://github.com/gnustep/tools-make.git - cd tools-make + wget https://github.com/gnustep/tools-make/archive/refs/tags/make-2_9_0.tar.gz + tar -xzf make-2_9_0.tar.gz + cd tools-make-make-2_9_0 ./configure --with-library-combo=ng-gnu-gnu sudo make install - name: Install GNUStep-Base if: contains(matrix.platform.os, 'ubuntu') run: | - git clone -b base-1_28_0 https://github.com/gnustep/libs-base.git - cd libs-base + wget https://github.com/gnustep/libs-base/archive/refs/tags/base-1_28_0.tar.gz + tar -xzf base-1_28_0.tar.gz + cd libs-base-base-1_28_0 ./configure --disable-tls sudo make install From b819901fce01389f3a80d9f935f07521b7ab2d0e Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 31 Aug 2021 17:28:43 +0200 Subject: [PATCH 16/16] Disable Travis CI I've used up my free credits and getting MacOS credits were more expensive than i thought --- .travis.yml => .travis-disabled.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .travis.yml => .travis-disabled.yml (100%) diff --git a/.travis.yml b/.travis-disabled.yml similarity index 100% rename from .travis.yml rename to .travis-disabled.yml