diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 29e22df..8aa74f7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -55,4 +55,25 @@ jobs:
           path: target
           key: target-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }}
       - run: cargo test --features vendored
-      - run: cargo test --features vendored
+
+  build_n_test_ios:
+    strategy:
+      fail-fast: false
+    runs-on: macos-latest
+    steps:
+    - uses: actions/checkout@v4
+    - name: Install cargo lipo and rust compiler for ios target
+      if: ${{ !cancelled() }}
+      run: |
+        cargo install --locked cargo-lipo
+        rustup target add x86_64-apple-ios aarch64-apple-ios
+    - name: clippy
+      if: ${{ !cancelled() }}
+      run: cargo clippy --target x86_64-apple-ios --all-features -- -D warnings
+    - name: Build
+      if: ${{ !cancelled() }}
+      run: |
+        cargo lipo --verbose --all-features
+    - name: Abort on error
+      if: ${{ failure() }}
+      run: echo "iOS build job failed" && false
diff --git a/.gitignore b/.gitignore
index 2deeb18..5b04ad2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+.VSCodeCounter/
 target
 Cargo.lock
 .idea
diff --git a/Cargo.toml b/Cargo.toml
index dc50f8c..90d6a00 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,9 @@ rust-version = "1.53.0"
 features = ["alpn"]
 rustdoc-args = ["--cfg", "docsrs"]
 
+[lib]
+crate-type = ["staticlib", "rlib"]
+
 [features]
 vendored = ["openssl/vendored"]
 alpn = ["security-framework/alpn"]
diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs
index 8fc4362..8b889e7 100644
--- a/src/imp/openssl.rs
+++ b/src/imp/openssl.rs
@@ -16,7 +16,7 @@ use std::fmt;
 use std::io;
 use std::sync::Once;
 
-use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder};
+use crate::{Protocol, TlsAcceptorBuilder, TlsConnectorBuilder};
 
 #[cfg(have_min_max_version)]
 fn supported_protocols(
diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs
index 302791a..b7d79b5 100644
--- a/src/imp/security_framework.rs
+++ b/src/imp/security_framework.rs
@@ -15,7 +15,6 @@ use std::error;
 use std::fmt;
 use std::io;
 use std::str;
-use std::sync::Mutex;
 use std::sync::Once;
 
 #[cfg(not(any(
@@ -58,6 +57,7 @@ use self::security_framework::os::macos::keychain::{self, KeychainSettings, SecK
 
 use {Protocol, TlsAcceptorBuilder, TlsConnectorBuilder};
 
+#[allow(dead_code)]
 static SET_AT_EXIT: Once = Once::new();
 
 #[cfg(not(any(
@@ -66,7 +66,8 @@ static SET_AT_EXIT: Once = Once::new();
     target_os = "tvos",
     target_os = "visionos"
 )))]
-static TEMP_KEYCHAIN: Mutex<Option<(SecKeychain, tempfile::TempDir)>> = Mutex::new(None);
+static TEMP_KEYCHAIN: std::sync::Mutex<Option<(SecKeychain, tempfile::TempDir)>> =
+    std::sync::Mutex::new(None);
 
 fn convert_protocol(protocol: Protocol) -> SslProtocol {
     match protocol {
@@ -233,6 +234,7 @@ impl Identity {
     }
 }
 
+#[allow(dead_code)]
 fn random_password() -> Result<String, Error> {
     use std::fmt::Write;
     let mut bytes = [0_u8; 10];
@@ -479,6 +481,7 @@ impl TlsAcceptor {
 
 pub struct TlsStream<S> {
     stream: secure_transport::SslStream<S>,
+    #[allow(dead_code)]
     cert: Option<SecCertificate>,
 }
 
@@ -641,6 +644,7 @@ impl<S: io::Read + io::Write> io::Write for TlsStream<S> {
     }
 }
 
+#[allow(dead_code)]
 enum Digest {
     Sha224,
     Sha256,
@@ -649,9 +653,10 @@ enum Digest {
 }
 
 impl Digest {
+    #[allow(dead_code)]
     fn hash(&self, data: &[u8]) -> Vec<u8> {
         unsafe {
-            assert!(data.len() <= CC_LONG::max_value() as usize);
+            assert!(data.len() <= CC_LONG::MAX as usize);
             match *self {
                 Digest::Sha224 => {
                     let mut buf = [0; CC_SHA224_DIGEST_LENGTH];
@@ -679,16 +684,24 @@ impl Digest {
 }
 
 // FIXME ideally we'd pull these in from elsewhere
+#[allow(dead_code)]
 const CC_SHA224_DIGEST_LENGTH: usize = 28;
+#[allow(dead_code)]
 const CC_SHA256_DIGEST_LENGTH: usize = 32;
+#[allow(dead_code)]
 const CC_SHA384_DIGEST_LENGTH: usize = 48;
+#[allow(dead_code)]
 const CC_SHA512_DIGEST_LENGTH: usize = 64;
-#[allow(non_camel_case_types)]
+#[allow(non_camel_case_types, dead_code)]
 type CC_LONG = u32;
 
 extern "C" {
+    #[allow(dead_code)]
     fn CC_SHA224(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8;
+    #[allow(dead_code)]
     fn CC_SHA256(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8;
+    #[allow(dead_code)]
     fn CC_SHA384(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8;
+    #[allow(dead_code)]
     fn CC_SHA512(data: *const u8, len: CC_LONG, md: *mut u8) -> *mut u8;
 }
diff --git a/src/lib.rs b/src/lib.rs
index 0f738df..7994733 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -106,7 +106,7 @@ use std::result;
 #[cfg(not(any(target_os = "windows", target_vendor = "apple",)))]
 #[macro_use]
 extern crate log;
-#[cfg(any(target_vendor = "apple",))]
+#[cfg(target_vendor = "apple")]
 #[path = "imp/security_framework.rs"]
 mod imp;
 #[cfg(target_os = "windows")]