Cargo subcommand to automatically create universal libraries for iOS.

Overview

cargo lipo Build Status Crates.io

Provides a cargo lipo subcommand which automatically creates a universal library for use with your iOS application.

Maintenance Status

Please consider this project deprecated / passively maintained. This is partly because I am not currently working on any iOS projects, and partly because I believe that there exists a better alternative to using lipo:

One can use architecture (and OS) specific environment variables in Xcode. The OS specific part could be configured in the Xcode project editor last time I tried, but the architecture specific part needed to be added by manually editing the project.pbxproj file, for example like this:

    "LIBRARY_SEARCH_PATHS[sdk=iphoneos*]" = ../path/to/target/debug/<...>;
    "LIBRARY_SEARCH_PATHS[sdk=macosx11.1][arch=arm64]" = ../path/to/target/<...>;
    "LIBRARY_SEARCH_PATHS[sdk=macosx11.1][arch=x86_64]" = ../path/to/target/<...>;

Thus, I believe that a future iOS support crate should offer primarily two features:

  • Something similar to the current --xcode-integ flag.
  • Something which can do the project.pbxproj editing.

Usage

From anywhere you would usually run cargo you can now run cargo lipo or cargo lipo --release to create a universal library for ios, which can be found in $target/universal/{release|debug}/$lib_name.a.

Make sure you have a library target in your Cargo.toml with a crate type of staticlib:

[lib]
name = "..."
crate-type = ["staticlib"]

Xcode Integration

cargo-lipo easily integrates with Xcode. Although note that this functionality has only been added recently and may not yet be perfect (the Xcode build process is somewhat of a blackbox to me).

  1. In your "Build Settings" change "Enable Bitcode" to No.

  2. Add a new "Run Script" phase to your "Build Phases". Place it before "Compile Sources". Add something like the following to the script:

    # The $PATH used by Xcode likely won't contain Cargo, fix that.
    # This assumes a default `rustup` setup.
    export PATH="$HOME/.cargo/bin:$PATH"
    
    # --xcode-integ determines --release and --targets from Xcode's env vars.
    # Depending your setup, specify the rustup toolchain explicitly.
    cargo lipo --xcode-integ --manifest-path ../something/Cargo.toml
  3. Build the project once, then update the "Link Binary with Libraries" phase: Click the +, then choose "Add Other...". Navigate to your-cargo-project/target/universal/{debug-or-release} and select your library(s).

  4. Go back to your "Build Settings" and add "Library Search Paths" for "Debug" and "Release", pointing to your-cargo-project/target/universal/{debug-or-release}.

Installation

Install cargo lipo with cargo install cargo-lipo. cargo lipo should always be buildable with the latest stable Rust version. For the minimum supported version check .travis.yml.

You also need a rust compiler which can compile for the iOS targets. If you use rustup all you should have to do is

# 64 bit targets (real device & simulator):
rustup target add aarch64-apple-ios x86_64-apple-ios
# 32 bit targets (you probably don't need these):
rustup target add armv7-apple-ios i386-apple-ios

Troubleshooting

Cargo fails with error: can't find crate for `std` : Your rust compiler most likely does not support cross-compiling to iOS.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Link errors in XCode

    Link errors in XCode

    When I attempt to build my project in XCode, I get the following errors when linking my rust library:

    Undefined symbols for architecture armv7:
      "__aeabi_idiv", referenced from:
          ___aeabi_idivmod in libmyrust_c.a(compiler_builtins-f6c69d64299ff1c7.compiler_builtins0.rcgu.o)
         (maybe you meant: ___aeabi_idiv, ___aeabi_idivmod )
      "__divmoddi4", referenced from:
          ___aeabi_ldivmod in libmyrust_c.a(compiler_builtins-f6c69d64299ff1c7.compiler_builtins0.rcgu.o)
         (maybe you meant: ___divmoddi4)
      "__udivmoddi4", referenced from:
          ___aeabi_uldivmod in libmyrust_c.a(compiler_builtins-f6c69d64299ff1c7.compiler_builtins0.rcgu.o)
         (maybe you meant: ___udivmoddi4)
      "__udivmodsi4", referenced from:
          ___aeabi_uidivmod in libmyrust_c.a(compiler_builtins-f6c69d64299ff1c7.compiler_builtins0.rcgu.o)
         (maybe you meant: ___udivmodsi4)
    ld: symbol(s) not found for architecture armv7
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    It looks like it can't find some symbols, but can find variants with three underscores. I'm not sure if this is a lipo error or not. I am using ring in my rust library. Do you have any ideas why this might be failing?

    These are the versions I have installed:

    $ cargo --version
    cargo 0.24.0 (45043115c 2017-12-05)
    $ cargo lipo --version
    cargo-lipo 1.0.1
    
    opened by jprider63 16
  • XCode 7 complains: building for iOS simulator, but linking in object file built for OSX, for architecture x86_64

    XCode 7 complains: building for iOS simulator, but linking in object file built for OSX, for architecture x86_64

    See https://github.com/google/j2objc/issues/611. Looks like the solution is to lipo macOS targets separately from iOS targets (that's what j2objc did: https://github.com/google/j2objc/commit/5be2b442600387b48bdc8c12b9b62e31df9240d1).

    Bummer.

    opened by tamird 12
  • cargo-lipo doesn't work with workspaces

    cargo-lipo doesn't work with workspaces

    I have a project which defines a cargo workspace as per http://doc.crates.io/manifest.html#the-workspace-section

    I'd like to invoke cargo lipo on one of the members of my workspace (it's a sub-crate exposing C bindings for the main crate), but both cargo lipo -p MEMBER or cargo lipo --all are missing.

    Is there any plan to make cargo-lipo support workspaces?

    opened by poros 11
  • error: linking with `cc` failed: exit code: 1 in Xcode 9.4.1

    error: linking with `cc` failed: exit code: 1 in Xcode 9.4.1

    cargo lipo works fine in mac terminal, but I will get error: linking withccfailed: exit code: 1 in Xcode when I run custom script.

    rustc -vV
    rustc 1.30.0-nightly (b2028828d 2018-08-16)
    binary: rustc
    commit-hash: b2028828db7e4870cb6a310f8ad8169ac9ea134d
    commit-date: 2018-08-16
    host: x86_64-apple-darwin
    release: 1.30.0-nightly
    LLVM version: 7.0
    
    cc -v
    Apple LLVM version 9.1.0 (clang-902.0.39.2)
    Target: x86_64-apple-darwin17.5.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    
    clang -v
    Apple LLVM version 9.1.0 (clang-902.0.39.2)
    Target: x86_64-apple-darwin17.5.0
    Thread model: posix
    InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
    

    error detail:

      = note: "cc" "-m64" "-L" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build0.rcgu.o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build1.rcgu.o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build2.rcgu.o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build3.rcgu.o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build4.rcgu.o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.build_script_build5.rcgu.o" "-o" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/build/security-framework-sys-69682004e1447249/build_script_build-69682004e1447249.crate.allocator.rcgu.o" "-Wl,-dead_strip" "-nodefaultlibs" "-L" "/Users/zoey.weng/Desktop/Study/PJToDo/PJToDo/Rust/pj_to_do_corelib/target/debug/deps" "-L" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libstd-d9af9c9ee75d1d46.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_unwind-2ad58b52bb812329.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc_jemalloc-1bc3e7256eaffb7f.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libunwind-77ff946ed091e776.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc_system-5019a7c1f162c628.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liblibc-e10360ce0d79ef62.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc-e51a1c9172064039.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libcore-877355077ec8f233.rlib" "/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libcompiler_builtins-b0eb581bdf96e971.rlib" "-lSystem" "-lresolv" "-lpthread" "-lc" "-lm"
    
    
      = note: ld: warning: URGENT: building for iOS simulator, but linking in object file (/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc_jemalloc-1bc3e7256eaffb7f.rlib(jemalloc.pic.o)) built for OSX. Note: This will be an error in the future.
    
    
              ld: warning: object file (/Users/zoey.weng/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/liballoc_jemalloc-1bc3e7256eaffb7f.rlib(jemalloc.pic.o)) was built for newer OSX version (10.7) than being linked (10.0)
    
    
              Undefined symbols for architecture x86_64:
                "_opendir$INODE64", referenced from:
                    _macho_try_dsym in libstd-d9af9c9ee75d1d46.rlib(macho.o)
                    _macho_add in libstd-d9af9c9ee75d1d46.rlib(macho.o)
                "_readdir$INODE64", referenced from:
                    _macho_try_dsym in libstd-d9af9c9ee75d1d46.rlib(macho.o)
                    _macho_add in libstd-d9af9c9ee75d1d46.rlib(macho.o)
              ld: symbol(s) not found for architecture x86_64
              clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    opened by piaojin 8
  • Update lipo command to accept a package name

    Update lipo command to accept a package name

    We have moved our FFI boundary into a subcrate as we only need to build our code as a library for deployment on iOS and Android. However, once that was done we were no longer able to use cargo lipo in order to build our universal iOS library. I amended cargo-lipo to take an optional --package argument in order to specify a package in which to find the library. I thought you might find it useful.

    opened by fluffyemily 8
  • Add awareness of the new simulator platform SDK

    Add awareness of the new simulator platform SDK

    This PR fixes #52, which has the details of the problem. It also updates the README instructions about XCode integration and fixes an old compiler warning.

    opened by brotskydotcom 6
  • Replace - by _ in library names

    Replace - by _ in library names

    The crate name we get from the cargo metadata has not been normalized to the crate name according to RFC 940 (a package named foo-bar will produce a library called foo_bar.a, not foo-bar.a), so we need to do the normalization ourselves.

    opened by abustany 4
  • Release Version 3.0

    Release Version 3.0

    This (currently WIP) PR is a complete reimplementation of cargo-lipo (what 2.0 should have been originally).

    The main new features are:

    • Reimplementation following current best-practices, including a switch to the 2018 edition.
    • Use cargo_metadata to understand the project rather than some custom logic.
    • Automatically remove environment variables that can cause issues with build scripts.
    • Simplify integration with XCode build scripts: Automatically discover targets and profile from the environment.

    This PR is still missing some tests (the basic functionality was manually tested, the XCode integration not at all).

    Todo:

    • [x] Add tests for:
      • [x] Building a simple project
      • [x] Building a workspace with multiple packages, only some of which are staticlibs
      • [x] Building only specific packages in a workspace
      • [x] Building a package with a build script and dependencies with build scripts
    • [x] Improve CI:
      • [x] Run & enforce no-warnings clippy
      • [x] Run & enforce no-diff rustfmt
    • [ ] Improve Readme.md:
      • [ ] Document important options
      • [x] Document XCode integration

    Fixes #22.

    opened by TimNN 3
  • Release 2.0 version

    Release 2.0 version

    Would it be possible to release the 2.0 version on crates.io or is it still missing some stuff? We have to use cargo install --force --git https://github.com/TimNN/cargo-lipo to get a proper version of cargo lipo, which is not super obvious for new contributors. Thank you!

    opened by eoger 3
  • Add support for using --no-default-features

    Add support for using --no-default-features

    This also adds a struct to hold the arguments to build_triple, rather than add another argument. If you would prefer it take a longer list of arguments then I can do that instead.

    opened by thomcc 3
  • How to *only* build on ios and ignore x86/x64?

    How to *only* build on ios and ignore x86/x64?

    Hi thanks for the lib! I only want to build the iOS version, and only the arm version, since iphones and ipads has no x86/x64 architecture (is it correct?). So how can I do this? Thanks

    opened by fzyzcjy 2
  • LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=x86_64] doesn't work

    LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*][arch=x86_64] doesn't work

    When I supply [arch=x86_64] or [arch=arm64] to my LIBRARY_SEARCH_PATHS envvar, it doesn't work and the envvar is not populated correctly. When I change it to [arch=*] or remove that condition, it works. [sdk=...] doesn't have this problem.

    This seems to be a trend:

    • https://developer.apple.com/forums/thread/699984
    • https://stackoverflow.com/questions/70999932/architecture-specific-build-settings-in-xcode-13

    FWIW, I printed out my build settings using xcodebuild ... -showBuildSettings and confirmed that the envvar doesn't work with [arch=x86_64] or [arch=arm64].

    Has anyone seen this before? Thanks!

    opened by jzxchiang1 0
  • Support for named profiles

    Support for named profiles

    The named profiles feature has been stabilized in 1.57.0. It would be good to have it supported in cargo lipo (ex: cargo lipo --profile custom-profile).

    Thanks !

    opened by appaquet 0
  • [Question] universal lib size

    [Question] universal lib size

    Hi, I've tried cargo-lipo today, and everything seems works, and I have following questions

    • I found that the universal static library size is 79M, is it normal ?
    • If that's normal, is it possible to make it smaller or how can I analyze the output to reduce the most space-consumtion thing.
    opened by chux0519 0
  • Break output by platform (iOS, macOS etc)

    Break output by platform (iOS, macOS etc)

    This was mentioned in #14 but probably can be it's own ticket. I've run into issues due to my rust library being used by both macOS & iOS but sharing the same output path. Or when trying to build iOS & iOS Simulator libraries. I ended up in an example I shared with someone doing cargo clean before cargo lipo --xcode-integrity to ensure it doesn't accidentally link the wrong platform library.

    This same change could also do a bonus and check that you're not trying to build iOS & macOS into the same library. Apple seems to say this is not supported. They point at their XCFramework if you want 1 thing across platforms.

    The output path could be something like what rust already does except just trim everything but the platform: target/universal-macos/debug/<lib> target/universal-iossimulator/debug/<lib> target/universal-ios/debug/<lib> Etc.

    I possibly can try to PR something up even if I find some time.

    opened by jfro 4
  • Check if the universal library is updated before running lipo

    Check if the universal library is updated before running lipo

    This PR checks if the universal library is updated by comparing the mtime of it to the inputs.

    If I am working on the non-rust part of an Xcode project, everytime I hit the run button cargo-lipo runs. In this case I expect the cargo-lipo to finish quickly since everything in rust is updated, but it takes noticeable time, because of the lipo command. This PR solves this problem by doing a Makefile-style check before running lipo.

    opened by patr0nus 0
Owner
Tim Neumann
Tim Neumann
Android / iOS app with shared Rust logic

Rust core for native Android and iOS apps [TODO iOS badge] This is an example that shows how to use a shared Rust core in native Android and iOS apps.

Ivan Schütz 193 Dec 5, 2022
Fable Rust Raytracer - iOS version

Fable Rust Raytracer - iOS version Originally made by @ncave (https://github.com/ncave/fable-raytracer), port to iOS by @delneg Pre-requisites Rust, b

Denis 4 May 2, 2022
Android / iOS app with shared Rust logic

Rust core for native Android and iOS apps [TODO iOS badge] This is an example that shows how to use a shared Rust core in native Android and iOS apps.

null 193 Dec 5, 2022
iOS app example - AI Selfies Generator like Lensa: Stable Diffusion In Action

Magic Avatars In this repository, we look at several approaches to creating avatars, changing backgrounds, and deep image processing for more detailed

Perpetio 3 Jan 17, 2023
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
Automated license checking for rust. cargo lichking is a Cargo subcommand that checks licensing information for dependencies.

cargo-lichking Automated license checking for rust. cargo lichking is a Cargo subcommand that checks licensing information for dependencies. Liches ar

Nemo157 120 Dec 19, 2022
cargo-lambda a Cargo subcommand to help you work with AWS Lambda

cargo-lambda cargo-lambda is a Cargo subcommand to help you work with AWS Lambda. This subcommand compiles AWS Lambda functions natively and produces

David Calavera 184 Jan 5, 2023
cargo-lambda is a Cargo subcommand to help you work with AWS Lambda.

cargo-lambda cargo-lambda is a Cargo subcommand to help you work with AWS Lambda. The new subcommand creates a basic Rust package from a well defined

null 184 Jan 5, 2023
Cargo subcommand for running cargo without dev-dependencies.

cargo-no-dev-deps Cargo subcommand for running cargo without dev-dependencies. This is an extraction of the --no-dev-deps flag of cargo-hack to be use

Taiki Endo 5 Jan 12, 2023
A cargo subcommand that extends cargo's capabilities when it comes to code generation.

cargo-px Cargo Power eXtensions Check out the announcement post to learn more about cargo-px and the problems it solves with respect to code generatio

Luca Palmieri 33 May 7, 2023
Dead simple, memoized cargo subcommand to hoist cargo-built binaries into the current working directory, written in Rust.

cargo-hoist Dead simple cargo subcommand to hoist cargo-built binaries into scope. stable Install | User Docs | Crate Docs | Reference | Contributing

refcell.eth 6 Nov 9, 2023
Create a Python project automatically with rust (like create-react-app but for python)

create-python-project Create a Python project automatically with rust (like create-react-app but for python) Installation cargo install create-python-

Dhravya Shah 2 Mar 12, 2022
Rust bindings to Core Foundation and other low level libraries on Mac OS X and iOS

core-foundation-rs Compatibility Targets macOS 10.7 by default. To enable features added in macOS 10.8, set Cargo feature mac_os_10_8_features. To hav

Servo 685 Jan 2, 2023
Middleware/ios shortcut to setup alarms automatically based on the first class

Webuntis alarm This is a small little "middleware" / web server intended to connect to a webuntis timetable used in german schools which i wrote when

raizo 3 Dec 30, 2022
Using Rust to create an iOS static library

ObjCrust A modified ObjCrust which uses Rust cross-compiler. Cross-compiler needs to be built first (note: it is on a separate branch now, so don't fo

Valerii Hiora 39 May 10, 2021
Bundle Cargo crates for use with macOS/iOS in Xcode

cargo-cocoapods - Build Rust code for Xcode integration Installing cargo install cargo-cocoapods You'll also need to install all the toolchains you i

Brendan Molloy 14 Dec 29, 2022
Helps cargo build and run apps for iOS

cargo-xcodebuild Helps cargo build and run apps for iOS. ?? ⚙️ ?? Setup You need to install Xcode (NOT just Command Line Tools!), xcodegen, cargo-xcod

Igor Shaposhnik 29 Nov 22, 2022
A very simple third-party cargo subcommand to execute a custom command

cargo-x A very simple third-party cargo subcommand to execute a custom command Usage install cargo-x cargo install cargo-x or upgrade cargo install -

刘冲 9 Dec 26, 2022
a cargo subcommand for counting lines of code in Rust projects

cargo-count Linux: A cargo subcommand for displaying line counts of source code in projects, including a niave unsafe counter for Rust source files. T

Kevin K. 125 Dec 1, 2022
A cargo subcommand for creating GraphViz DOT files and dependency graphs

cargo-graph Linux: A cargo subcommand for building GraphViz DOT files of dependency graphs. This subcommand was originally based off and inspired by t

Kevin K. 213 Nov 24, 2022