diff --git a/.gitignore b/.gitignore index 2f7896d..3ff4ead 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ target/ +.idea +*.iml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index bfabe7f..5780646 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,43 @@ -FROM tomaka/rust-android +FROM rust:latest +RUN apt-get update +RUN apt-get install -yq openjdk-8-jre unzip wget + +RUN rustup target add armv7-linux-androideabi +RUN rustup target add aarch64-linux-android +RUN rustup target add i686-linux-android +RUN rustup target add x86_64-linux-android + +# Install Android SDK +ENV ANDROID_HOME /opt/android-sdk-linux +RUN mkdir ${ANDROID_HOME} && \ + cd ${ANDROID_HOME} && \ + wget -q https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip && \ + unzip -q sdk-tools-linux-4333796.zip && \ + rm sdk-tools-linux-4333796.zip && \ + chown -R root:root /opt +RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager "platform-tools" +RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager "platforms;android-29" +RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager "build-tools;29.0.0" +RUN ${ANDROID_HOME}/tools/bin/sdkmanager --update + +# Install Android NDK +RUN cd /usr/local && \ + wget -q http://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip && \ + unzip -q android-ndk-r20-linux-x86_64.zip && \ + rm android-ndk-r20-linux-x86_64.zip +ENV NDK_HOME /usr/local/android-ndk-r20 + +# Copy contents to container. Should only use this on a clean directory COPY . /root/cargo-apk + +# Run tests +RUN cd /root/cargo-apk/cargo-apk && cargo test --release + +# Install Binary and remove source and build files RUN cargo install --path /root/cargo-apk/cargo-apk RUN rm -rf /root/cargo-apk +# Make directory for user code RUN mkdir /root/src WORKDIR /root/src diff --git a/README.md b/README.md index 1bc9e69..3dc8785 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,24 @@ ## With Docker The easiest way to compile for Android is to use [Docker](https://www.docker.com/) and the -[tomaka/cargo-apk](https://hub.docker.com/r/tomaka/cargo-apk/) image. +[philipalldredge/cargo-apk](https://hub.docker.com/r/philipalldredge/cargo-apk/) image. In order to build an APK, simply do this: ``` -docker run --rm -v :/root/src tomaka/cargo-apk cargo apk build +docker run --rm -v :/root/src philipalldredge/cargo-apk cargo apk build ``` For example if you're on Linux and you want to compile the project in the current working directory. ``` -docker run --rm -v "$(pwd):/root/src" -w /root/src tomaka/cargo-apk cargo apk build +docker run --rm -v "$(pwd):/root/src" -w /root/src philipalldredge/cargo-apk cargo apk build ``` Do not mount a volume on `/root` or you will erase the local installation of Cargo. -After the build is finished, you should get an Android package in `target/android-artifacts/app/build/outputs/apk`. +After the build is finished, you should get an Android package in `target/android-artifacts/debug/apk`. ## Manual usage @@ -31,13 +31,15 @@ After the build is finished, you should get an Android package in `target/androi Before you can compile for Android, you need to setup your environment. This needs to be done only once per system. - Install [`rustup`](https://rustup.rs/). - - Run `rustup target add arm-linux-androideabi`, or any other target that you want to compile to. - - Install the Java JDK (on Ubuntu, `sudo apt-get install openjdk-8-jdk`). - - Install CMake (on Ubuntu, `sudo apt-get install cmake`). - - [Install Gradle](https://gradle.org/install/). + - Run `rustup target add ` for all supported targets to which you want to compile. Building will attempt to build for all supported targets unless the build targets are adjusted via `Cargo.toml`. + - `rustup target add armv7-linux-androideabi` + - `rustup target add aarch64-linux-android` + - `rustup target add i686-linux-android` + - `rustup target add x86_64-linux-android` + - Install the Java JRE or JDK (on Ubuntu, `sudo apt-get install openjdk-8-jdk`). - Download and unzip [the Android NDK](https://developer.android.com/ndk). - Download and unzip [the Android SDK](https://developer.android.com/studio). - - Install some components in the SDK: `./android-sdk/tools/bin/sdkmanager "platform-tools" "platforms;android-18" "build-tools;26.0.1"`. + - Install some components in the SDK: `./android-sdk/tools/bin/sdkmanager "platform-tools" "platforms;android-29" "build-tools;29.0.0"`. - Install `cargo-apk` with `cargo install cargo-apk`. - Set the environment variables `NDK_HOME` to the path of the NDK and `ANDROID_HOME` to the path of the SDK. @@ -46,7 +48,15 @@ Before you can compile for Android, you need to setup your environment. This nee In the project root for your Android crate, run `cargo apk build`. You can use the same options as with the regular `cargo build`. -This will build an Android package in `target/android-artifacts/app/build/outputs/apk`. +This will build an Android package in `target/android-artifacts//apk`. + +### Compiling Multiple Binaries + +`cargo apk build` supports building multiple binaries and examples using the same arguments as `cargo build`. It will produce an APK for each binary. + +Android packages for bin targets are placed in `target/android-artifacts//apk`. + +Android packages for example targets are placed in `target/android-artifacts//apk/examples`. ### Testing on an Android emulator @@ -72,62 +82,75 @@ the stdlib. ## The build process -The build process works by invoking `cargo rustc` and: +The build process works by running rustc and: -- Always compiles your crate as a shared library. -- Injects the `android_native_app_glue` file provided by the Android NDK. -- Injects some glue libraries in Rust, which ties the link between `android_native_app_glue` and - the `main` function of your crate. +- Always compiles your crate as a static library. +- Uses `ndk-build` provided by the NDK to to build a shared library. +- Links to the `android_native_app_glue` library provided by the Android NDK. +- Injects some glue libraries in Rust, which ties the link between `android_native_app_glue` and the `main` function of your crate. This first step outputs a shared library, and is run once per target architecture. -The command then sets up an Android build environment, which includes some Java code, in -`target/android-artifacts` and puts the shared libraries in it. Then it runs `gradle`. +The command then builds the APK using the shared library, generated manifest, and tools from the Android SDK. +It signs the APK with the default debug keystore used by Android development tools. If the keystore doesn't exist, it creates it using the keytool from the JRE or JDK. # Supported `[package.metadata.android]` entries ```toml -[package.metadata.android] +# The target Android API level. +# "android_version" is the compile SDK version. It defaults to 29. +# (target_sdk_version defaults to the value of "android_version") +# (min_sdk_version defaults to 18) It defaults to 18 because this is the minimum supported by rustc. +android_version = 29 +target_sdk_version = 29 +min_sdk_version = 26 + +# Specifies the array of targets to build for. +# Defaults to "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android". +build_targets = [ "armv7-linux-androideabi", "aarch64-linux-android", "i686-linux-android", "x86_64-linux-android" ] + +# +# The following value can be customized on a per bin/example basis. See multiple_targets example +# If a value is not specified for a secondary target, it will inherit the value defined in the `package.metadata.android` +# section unless otherwise noted. +# # The Java package name for your application. # Hyphens are converted to underscores. -package_name = "com.author-name.my-android-app" +# Defaults to rust. for binaries. +# Defaults to rust..example. for examples. +# For example: for a binary "my_app", the default package name will be "rust.my_app" +# Secondary targets will not inherit the value defined in the root android configuration. +package_name = "rust.cargo.apk.advanced" # The user-friendly name for your app, as displayed in the applications menu. +# Defaults to the target name +# Secondary targets will not inherit the value defined in the root android configuration. label = "My Android App" -# Path to your application's res/ folder. See `examples/use_icon/res`. +# Path to your application's resources folder. +# If not specified, resources will not be included in the APK res = "path/to/res_folder" -# Virtual path your application's icon for any mipmap level. See `examples/use_icon/icon`. -icon = "@mipmap/ic_laucher" +# Virtual path your application's icon for any mipmap level. +# If not specified, an icon will not be included in the APK. +icon = "@mipmap/ic_launcher" -# Path to the folder containing your application's assets. See `examples/use_assets/assets`. +# Path to the folder containing your application's assets. +# If not specified, assets will not be included in the APK assets = "path/to/assets_folder" -# The target Android API level. -# It defaults to 18 because this is the minimum supported by rustc. -# (target_sdk_version and min_sdk_version default to the value of "android_version") -android_version = 18 -target_sdk_version = 18 -min_sdk_version = 18 - # If set to true, makes the app run in full-screen, by adding the following line # as an XML attribute to the manifest's tag : # android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen # Defaults to false. fullscreen = false -# Specifies the array of targets to build for. -# Defaults to "arm-linux-androideabi". -# Other possible targets include "aarch64-linux-android", -# "armv7-linux-androideabi", "i686-linux-android" and "x86_64-linux-android". -build_targets = [ "arm-linux-androideabi", "armv7-linux-androideabi" ] - -# The maximum supported OpenGL ES version , as claimed by the manifest. Defaults to 2.0. +# The maximum supported OpenGL ES version , as claimed by the manifest. +# Defaults to 2.0. # See https://developer.android.com/guide/topics/graphics/opengl.html#manifest -opengles_version_major = 2 -opengles_version_minor = 0 +opengles_version_major = 3 +opengles_version_minor = 2 # Adds extra arbitrary XML attributes to the tag in the manifest. # See https://developer.android.com/guide/topics/manifest/application-element.html @@ -140,4 +163,28 @@ opengles_version_minor = 0 [package.metadata.android.activity_attributes] "android:screenOrientation" = "unspecified" "android:uiOptions" = "none" + +# Adds a uses-feature element to the manifest +# Supported keys: name, required, version +# The glEsVersion attribute is not supported using this section. +# It can be specified using the opengles_version_major and opengles_version_minor values +# See https://developer.android.com/guide/topics/manifest/uses-feature-element +[[package.metadata.android.feature]] +name = "android.hardware.camera" + +[[package.metadata.android.feature]] +name = "android.hardware.vulkan.level" +version = "1" +required = false + +# Adds a uses-permission element to the manifest. +# Note that android_version 23 and higher, Android requires the application to request permissions at runtime. +# There is currently no way to do this using a pure NDK based application. +# See https://developer.android.com/guide/topics/manifest/uses-permission-element +[[package.metadata.android.permission]] +name = "android.permission.WRITE_EXTERNAL_STORAGE" +max_sdk_version = 18 + +[[package.metadata.android.permission]] +name = "android.permission.CAMERA" ``` diff --git a/cargo-apk/Cargo.lock b/cargo-apk/Cargo.lock index 9351bda..02ce304 100644 --- a/cargo-apk/Cargo.lock +++ b/cargo-apk/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "adler32" version = "1.0.3" @@ -5,10 +7,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aho-corasick" -version = "0.6.8" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -16,148 +18,212 @@ name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "argon2rs" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", + "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "assert_cmd" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "escargot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "atty" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" -version = "0.3.9" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace-sys" -version = "0.1.24" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "build_const" -version = "0.2.1" +name = "blake2-rfc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bstr" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "byteorder" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bytesize" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cargo" -version = "0.32.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crates-io 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", - "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crates-io 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-hash 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", - "git2-curl 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ignore 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "home 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ignore 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "im-rc 12.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rustfix 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cargo-apk" version = "0.4.3" dependencies = [ - "cargo 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", + "assert_cmd 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.25" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "clap" -version = "2.32.0" +version = "2.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -167,7 +233,7 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -183,16 +249,21 @@ name = "commoncrypto-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "constant_time_eq" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "core-foundation" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -202,146 +273,178 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crates-io" -version = "0.20.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crc" -version = "1.8.1" +name = "crc32fast" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-channel" -version = "0.2.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crossbeam-epoch" -version = "0.6.0" +name = "crossbeam-utils" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "crypto-hash" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "curl" -version = "0.4.18" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "curl-sys" -version = "0.4.13" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "dirs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dirs-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "env_logger" -version = "0.5.13" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "escargot" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "filetime" -version = "0.2.1" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "flate2" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -364,77 +467,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fs2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "fuchsia-zircon" -version = "0.3.3" +name = "fuchsia-cprng" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "fwdansi" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "fwdansi" -version = "1.0.1" +name = "getrandom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "git2" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "git2-curl" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)", - "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "curl 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)", + "git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "glob" -version = "0.2.11" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "globset" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -444,16 +546,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "home" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "http" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "humantime" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -461,44 +573,71 @@ dependencies = [ [[package]] name = "idna" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ignore" -version = "0.4.4" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "im-rc" +version = "12.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sized-chunks 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "iovec" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itertools" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jobserver" -version = "0.1.11" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -512,34 +651,34 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazycell" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.43" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libgit2-sys" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "curl-sys 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -547,8 +686,8 @@ name = "libnghttp2-sys" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -556,74 +695,55 @@ name = "libssh2-sys" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libz-sys" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lock_api" -version = "0.1.4" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "matches" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memoffset" -version = "0.2.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "miniz-sys" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "miniz_oxide" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -631,13 +751,13 @@ dependencies = [ [[package]] name = "miniz_oxide_c_api" -version = "0.2.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -645,44 +765,42 @@ name = "miow" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.3.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "opener" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl" -version = "0.10.13" +version = "0.10.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -692,52 +810,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl-sys" -version = "0.9.38" +version = "0.9.48" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "owning_ref" -version = "0.3.3" +name = "percent-encoding" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "parking_lot" -version = "0.6.4" +name = "pkg-config" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "parking_lot_core" -version = "0.3.1" +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "predicates" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "pkg-config" -version = "0.3.14" +name = "predicates-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "predicates-tree" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "proc-macro2" -version = "0.4.20" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -750,101 +873,130 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quote" -version = "0.3.15" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "quote" -version = "0.6.8" +name = "rand" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand" -version = "0.4.3" +name = "rand_chacha" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand" -version = "0.5.5" +name = "rand_core" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_core" -version = "0.2.2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand_core" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "rand_core" -version = "0.3.0" +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rdrand" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "redox_syscall" -version = "0.1.40" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "redox_termios" -version = "0.1.1" +name = "redox_users" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "1.0.5" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.2" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "remove_dir_all" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-serialize" -version = "0.3.24" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -862,38 +1014,43 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ryu" -version = "0.2.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "same-file" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "schannel" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "scopeguard" version = "0.3.3" @@ -905,7 +1062,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -915,26 +1072,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde_derive" -version = "1.0.10" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "serde_derive_internals" -version = "0.15.1" +name = "serde_derive" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -942,17 +1093,17 @@ name = "serde_ignored" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.32" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -961,126 +1112,94 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "smallvec" -version = "0.6.5" +name = "sized-chunks" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "smallvec" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "socket2" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "stable_deref_trait" -version = "1.1.1" +name = "spin" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strsim" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "syn" -version = "0.11.11" +version = "0.15.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "synstructure" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tar" -version = "0.4.17" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tempfile" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "term" -version = "0.4.5" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termcolor" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "textwrap" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1091,83 +1210,85 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "toml" -version = "0.1.30" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "toml" -version = "0.4.2" +name = "treeline" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typenum" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "ucd-util" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "unicode-bidi" -version = "0.2.5" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-normalization" -version = "0.1.4" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "unicode-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "unreachable" -version = "1.0.0" +name = "url" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "url" -version = "1.4.0" +name = "url_serde" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "utf8-ranges" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "vcpkg" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1175,24 +1296,14 @@ name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "walkdir" -version = "2.2.5" +version = "2.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1202,7 +1313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1221,10 +1332,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1237,153 +1348,166 @@ name = "wincolor" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" +"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" -"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" +"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" +"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba" +"checksum assert_cmd 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2dc477793bd82ec39799b6f6b3df64938532fdf2ab0d49ef817eac65856a5a1e" +"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b" +"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6" +"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" +"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" +"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" +"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum bytesize 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "716960a18f978640f25101b5cbf1c6f6b0d3192fab36a2d98ca96f0ecbe41010" -"checksum cargo 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "399c966265f89b62ed12f662f51e7402c58820c86f9f1d3a9ee59a689c787d76" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" +"checksum cargo 0.37.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6924b75f0de3b87ffd13f291224a2eb0f92e961b287d900863fc586f8ecd833" +"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46" +"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum core-foundation 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "58667b9a618a37ea8c4c4cb5298703e5dfadcd3698c79f54fc43e6a2e94733ea" +"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -"checksum crates-io 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fe7a6ac23bd61c0d741650a064d243bffed8c2dce3d51df28b9b64740ed1ea88" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827" -"checksum crossbeam-epoch 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c90f1474584f38e270b5b613e898c8c328aa4f3dea85e0a27ac2e642f009416" -"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" -"checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4" -"checksum curl 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a9e5285b49b44401518c947d3b808d14d99a538a6c9ffb3ec0205c11f9fc4389" -"checksum curl-sys 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08459503c415173da1ce6b41036a37b8bfdd86af46d45abb9964d4c61fe670ef" -"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" -"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" -"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" -"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f" -"checksum flate2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3b0c7353385f92079524de3b7116cf99d73947c08a7472774e9b3b04bff3b901" +"checksum crates-io 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d550c74feb32f635f4b50fcd1312aac2e39018fceb716314f90fbc3d33ab7d6a" +"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" +"checksum crypto-hash 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "20ff87d28defc77c9980a5b81cae1a33c791dd0ead8af0cee0833eb98c8305b9" +"checksum curl 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f8ed9a22aa8c4e49ac0c896279ef532a43a7df2f54fcd19fa36960de029f965f" +"checksum curl-sys 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "5e90ae10f635645cba9cad1023535f54915a95c58c44751c6ed70dbaeb17a408" +"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" +"checksum dirs 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4ef5a8b902d393339e2a2c7fe573af92ce7e0ee5a3ff827b4c9ad7e07e4fa1" +"checksum dirs-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "937756392ec77d1f2dd9dc3ac9d69867d109a2121479d72c364e42f4cab21e2d" +"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" +"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +"checksum escargot 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ceb9adbf9874d5d028b5e4c5739d22b71988252b25c9c98fe7cf9738bee84597" +"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" +"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" +"checksum filetime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "450537dc346f0c4d738dda31e790da1da5d4bd12145aad4da0d03d713cb3794f" +"checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34dd4c507af68d37ffef962063dfa1944ce0dd4d5b82043dbab1dabe088610c3" -"checksum git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "591f8be1674b421644b6c030969520bc3fa12114d2eb467471982ed3e9584e71" -"checksum git2-curl 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0173e317f8ba21f3fff0f71549fead5e42e67961dbd402bf69f42775f3cc78b4" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4743617a7464bbda3c8aec8558ff2f9429047e025771037df561d383337ff865" +"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" +"checksum git2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7339329bfa14a00223244311560d11f8f489b453fb90092af97f267a6090ab0" +"checksum git2-curl 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d58551e903ed7e2d6fe3a2f3c7efa3a784ec29b19d0fbb035aaf0497c183fbdd" +"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" -"checksum home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff" -"checksum humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0484fda3e7007f2a4a0d9c3a703ca38c71c54c55602ce4660c419fd32e188c9e" -"checksum idna 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac85ec3f80c8e4e99d9325521337e14ec7555c458a14e377d189659a427f375" -"checksum ignore 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36ecfc5ad80f0b1226df948c562e2cddd446096be3f644c95106400eae8a5e01" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be" +"checksum home 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "29302b90cfa76231a757a887d1e3153331a63c7f80b6c75f86366334cbe70708" +"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" +"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum ignore 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c794c4736d7751238cc5f74f6a3a2a59698074672fe403620d53fecfd72e5d87" +"checksum im-rc 12.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e882e6e7cd335baacae574b56aa3ce74844ec82fc6777def7c0ac368837dc3d5" +"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f74e73053eaf95399bf926e48fc7a2a3ce50bd0eaaa2357d391e95b2dcdd4f10" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" -"checksum libgit2-sys 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4916b5addc78ec36cc309acfcdf0b9f9d97ab7b84083118b248709c5b7029356" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum libgit2-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "48441cb35dc255da8ae72825689a95368bf510659ae1ad55dc4aa88cb1789bf1" "checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4" "checksum libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d" -"checksum libz-sys 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "4401fe74560a0d46fce3464625ac8aa7a79d291dd28cee021d18852d5191c280" -"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" -"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1" -"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" -"checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" -"checksum miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28edaef377517fd9fe3e085c37d892ce7acd1fbeab9239c5a36eec352d8a8b7e" +"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" +"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" +"checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516" +"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" "checksum miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "396aa0f2003d7df8395cb93e09871561ccc3e785f0acb369170e8cc74ddf9226" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2" -"checksum opener 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "176cd8eadff5ef9fa5c6d19452535662c02c6bf29b3d594a3fc01f749bb24c94" -"checksum openssl 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5af9e83eb3c51ee806387d26a43056f3246d865844caa6dd704d2ba7e831c264" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" +"checksum opener 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "998c59e83d9474c01127a96e023b7a04bb061dd286bf8bb939d31dc8d31a7448" +"checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ff3d1b390ab1b9700f682ad95a30dc9c0f40dd212ca57266012cfc678b0e365a" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3d7b7eaaa90b4a90a932a9ea6666c95a389e424eff347f0f793979289429feee" +"checksum openssl-sys 0.9.48 (registry+https://github.com/rust-lang/crates.io-index)" = "b5ba300217253bcc5dc68bed23d782affa45000193866e025329aa8a7a9f05b8" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" +"checksum predicates 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "53e09015b0d3f5a0ec2d4428f7559bb7b3fff341b4e159fedd1d57fac8b939ff" +"checksum predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178" +"checksum predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" -"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372" -"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3058a43ada2c2d0b92b3ae38007a2d0fa5e9db971be260e0171408a4ff471c95" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" +"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" +"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" +"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" "checksum rustc-workspace-hack 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustfix 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "756567f00f7d89c9f89a5c401b8b1caaa122e27240b9eaadd0bb52ee0b680b1b" -"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" -"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c" -"checksum schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "0e1a231dc10abf6749cfa5d7767f25888d484201accbd919b66ab5413c502d56" +"checksum rustfix 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b96ea6eeae40f488397ccc9e1c0da19d720b23c75972bc63eaa6852b84d161e2" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" +"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" +"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" +"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef" -"checksum serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7b707cf0d4cab852084f573058def08879bb467fda89d99052485e7d00edd624" -"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" +"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72" +"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f" "checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142" -"checksum serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)" = "43344e7ce05d0d8280c5940cabb4964bea626aa58b1ec0e8c73fa2a8512a38ce" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" -"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" -"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" -"checksum tar 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)" = "83b0d14b53dbfd62681933fadd651e815f99e6084b649e049ab99296e05ab3de" -"checksum tempfile 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "55c1195ef8513f3273d55ff59fe5da6940287a0d7a98331254397f464833675b" -"checksum term 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d168af3930b369cfe245132550579d47dfd873d69470755a19c2c6568dbbd989" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" +"checksum sized-chunks 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3e7f23bad2d6694e0f46f5e470ec27eb07b8f3e8b309a4b0dc17501928b9f2" +"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +"checksum socket2 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df028e0e632c2a1823d920ad74895e7f9128e6438cbc4bc6fd1f180e644767b9" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e" +"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" +"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796" -"checksum toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b0601da6c97135c8d330c7a13a013ca6cd4143221b01de2f8d4edc50a9e551c7" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032" -"checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff" +"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" +"checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" +"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" -"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" +"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" +"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35" +"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" diff --git a/cargo-apk/Cargo.toml b/cargo-apk/Cargo.toml index 6288a24..9321a01 100644 --- a/cargo-apk/Cargo.toml +++ b/cargo-apk/Cargo.toml @@ -1,15 +1,20 @@ [package] name = "cargo-apk" version = "0.4.3" -authors = ["Pierre Krieger "] +authors = ["Pierre Krieger ", "Philip Alldredge "] license = "MIT" description = "Cargo subcommand that allows you to build Android packages" repository = "https://github.com/rust-windowing/android-rs-glue/tree/master/cargo-apk" +edition = "2018" [dependencies] -cargo = "0.32.0" -clap = "2.31" -failure = "0.1.2" -rustc-serialize = "0.3.19" -term = "0.4.4" -toml = "0.1.28" +cargo = "0.37.0" +clap = "2.33.0" +itertools = "0.8.0" +dirs = "2.0.1" +failure = "0.1.5" +serde = "1.0.97" +toml = "0.5.1" + +[dev-dependencies] +assert_cmd = "0.11.1" \ No newline at end of file diff --git a/cargo-apk/glue_obj.rs b/cargo-apk/glue_obj.rs deleted file mode 100644 index 774c6f4..0000000 --- a/cargo-apk/glue_obj.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![no_std] - -extern crate cargo_apk_injected_glue; - -extern { - fn main(_: isize, _: *const *const u8); -} - -// This function is here because we are sure that it will be included by the linker. -// So we call app_dummy in it, in order to be sure that the native glue will be included. -pub fn start(_: isize, _: *const *const u8) -> isize { - unsafe { cargo_apk_injected_glue::ffi::app_dummy() }; - 1 -} - -#[no_mangle] -#[inline(never)] -#[allow(non_snake_case)] -pub extern "C" fn android_main(app: *mut ()) { - cargo_apk_injected_glue::android_main2(app as *mut _, move |c, v| unsafe { main(c, v) }); -} diff --git a/cargo-apk/injected-glue/ffi.rs b/cargo-apk/injected-glue/ffi.rs index 9c143e1..d5abc43 100644 --- a/cargo-apk/injected-glue/ffi.rs +++ b/cargo-apk/injected-glue/ffi.rs @@ -62,10 +62,6 @@ pub const APP_CMD_PAUSE: i32 = 13; pub const APP_CMD_STOP: i32 = 14; pub const APP_CMD_DESTROY: i32 = 15; -extern { - pub fn app_dummy(); -} - pub const MODE_BUFFER: i32 = 3; pub const MODE_RANDOM: i32 = 1; pub const MODE_STREAMING: i32 = 2; diff --git a/cargo-apk/injected-glue/lib.rs b/cargo-apk/injected-glue/lib.rs index 8a01bba..6e7e144 100644 --- a/cargo-apk/injected-glue/lib.rs +++ b/cargo-apk/injected-glue/lib.rs @@ -45,13 +45,13 @@ pub unsafe extern fn cargo_apk_injected_glue_add_sender(sender: *mut ()) { #[no_mangle] pub unsafe extern fn cargo_apk_injected_glue_add_sync_event_handler(handler: *mut ()) { - let handler: Box> = Box::from_raw(handler as *mut _); + let handler: Box> = Box::from_raw(handler as *mut _); add_sync_event_handler(*handler); } #[no_mangle] pub unsafe extern fn cargo_apk_injected_glue_remove_sync_event_handler(handler: *mut ()) { - let handler: Box<*const SyncEventHandler> = Box::from_raw(handler as *mut _); + let handler: Box<*const dyn SyncEventHandler> = Box::from_raw(handler as *mut _); remove_sync_event_handler(*handler); } @@ -97,7 +97,7 @@ struct Context { // Event listeners that receive async events using channels. senders: Mutex>>, // Event listeners that receive sync events from the polling loop. - sync_event_handlers: Mutex>>, + sync_event_handlers: Mutex>>, // Any missed events are stored here. missed: Mutex>, // Better performance to track number of missed items. @@ -195,7 +195,7 @@ pub fn get_app<'a>() -> &'a mut ffi::android_app { /// This is the function that must be called by `android_main` #[doc(hidden)] pub fn android_main2(app: *mut ffi::android_app, main_function: F) - where F: FnOnce(isize, *const *const u8) + 'static + Send + where F: FnOnce() + 'static + Send { write_log("Entering android_main"); @@ -263,8 +263,8 @@ pub fn android_main2(app: *mut ffi::android_app, main_function: F) buf.capacity() - 1 - cursor); let len = if result == 0 { return ptr::null_mut(); } - else if result < 0 { return ptr::null_mut(); /* TODO: report problem */ } - else { result as usize + cursor }; + else if result < 0 { return ptr::null_mut(); /* TODO: report problem */ } + else { result as usize + cursor }; buf.set_len(len); @@ -306,13 +306,12 @@ pub fn android_main2(app: *mut ffi::android_app, main_function: F) let main_function = Box::into_raw(Box::new(main_function)); extern fn main_thread(main_function: *mut c_void) -> *mut c_void - where F: FnOnce(isize, *const *const u8) + 'static + Send + where F: FnOnce() + 'static + Send { unsafe { let main_function: Box = Box::from_raw(main_function as *mut _); - let argv = [b"android\0".as_ptr()]; // TODO: catch panic? (only once stable) - (*main_function)(1, argv.as_ptr()); + (*main_function)(); ptr::null_mut() } } @@ -420,7 +419,7 @@ fn send_event(event: Event) { /// information, and finally send the event, which normally would be recieved by /// the main application thread IF it has registered a sender. pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInputEvent) - -> i32 + -> i32 { let etype = unsafe { ffi::AInputEvent_getType(event) }; let action = unsafe { ffi::AMotionEvent_getAction(event) }; @@ -447,8 +446,8 @@ pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInpu }; let context = get_context(); let idx = ((action & ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) - >> ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT) - as usize; + >> ffi::AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT) + as usize; let pointer_id = unsafe { ffi::AMotionEvent_getPointerId(event, idx) }; if action_code == ffi::AMOTION_EVENT_ACTION_DOWN { @@ -531,13 +530,13 @@ pub fn add_sender(sender: Sender) { } /// Adds a SyncEventHandler which will process sync events from the polling loop. -pub fn add_sync_event_handler(handler: Box) { +pub fn add_sync_event_handler(handler: Box) { let mut handlers = get_context().sync_event_handlers.lock().unwrap(); handlers.push(handler); } /// Removes a SyncEventHandler. -pub fn remove_sync_event_handler(handler: *const SyncEventHandler) { +pub fn remove_sync_event_handler(handler: *const dyn SyncEventHandler) { let mut handlers = get_context().sync_event_handlers.lock().unwrap(); handlers.retain(|ref b| b.as_ref() as *const _ != handler); } diff --git a/cargo-apk/linker.rs b/cargo-apk/linker.rs deleted file mode 100644 index 72ec3bb..0000000 --- a/cargo-apk/linker.rs +++ /dev/null @@ -1,248 +0,0 @@ -//! This file contains the source code of a dummy linker whose path is going to get passed to -//! rustc. Rustc will think that this program is gcc and pass all the arguments to it. Then this -//! program will tweak the arguments as needed. - -use std::collections::HashSet; -use std::env; -use std::fs::File; -use std::io::{Write, BufReader, BufRead}; -use std::path::{Path, PathBuf}; -use std::process; -use std::process::{Command, Stdio}; - -fn main() { - let (args, passthrough) = parse_arguments(); - - // Write the arguments for the subcommand to pick up. - { - let mut lib_paths = File::create(Path::new(&args.cargo_apk_libs_path_output)).unwrap(); - for lib_path in args.library_path.iter() { - writeln!(lib_paths, "{}", lib_path.to_string_lossy()).unwrap(); - } - - let mut libs = File::create(Path::new(&args.cargo_apk_libs_output)).unwrap(); - for lib in args.shared_libraries.iter() { - writeln!(libs, "{}", lib).unwrap(); - } - } - - // Execute the real linker. - if Command::new(Path::new(&args.cargo_apk_gcc)) - .args(&*passthrough) - .arg(args.cargo_apk_native_app_glue) - .arg(args.cargo_apk_glue_obj) - .arg(args.cargo_apk_glue_lib) - .arg("-llog").arg("-landroid") // these two libraries are used by the injected-glue - .arg("--sysroot").arg(args.cargo_apk_gcc_sysroot) - .arg("-o").arg(args.cargo_apk_linker_output) - .arg("-shared") - .arg("-Wl,-E") - .stdout(Stdio::inherit()) - .stderr(Stdio::inherit()) - .status().unwrap().code().unwrap() != 0 - { - println!("Error while executing gcc"); - process::exit(1); - } -} - -struct Args { - // Paths where to search for libraries as passed with the `-L` options. - library_path: Vec, - - // List of libraries to link to as passed with the `-l` option. - shared_libraries: HashSet, - - cargo_apk_gcc: String, - cargo_apk_gcc_sysroot: String, - cargo_apk_native_app_glue: String, - cargo_apk_glue_obj: String, - cargo_apk_glue_lib: String, - cargo_apk_linker_output: String, - cargo_apk_libs_path_output: String, - cargo_apk_libs_output: String, -} - -/// Parses the arguments passed by the CLI and returns two things: the interpretation of some -/// arguments, and a list of other arguments that must be passed through to the real linker. -fn parse_arguments() -> (Args, Vec) { - let mut result_library_path = Vec::new(); - let mut result_shared_libraries = HashSet::new(); - let mut result_passthrough = Vec::new(); - - let mut cargo_apk_gcc: Option = None; - let mut cargo_apk_gcc_sysroot: Option = None; - let mut cargo_apk_native_app_glue: Option = None; - let mut cargo_apk_glue_obj: Option = None; - let mut cargo_apk_glue_lib: Option = None; - let mut cargo_apk_linker_output: Option = None; - let mut cargo_apk_libs_path_output: Option = None; - let mut cargo_apk_libs_output: Option = None; - - let mut args = RustCArgsReader::new(); - - loop { - let arg = match args.next() { - Some(arg) => arg, - None => { - let args = Args { - library_path: result_library_path, - shared_libraries: result_shared_libraries, - cargo_apk_gcc: cargo_apk_gcc - .expect("Missing cargo_apk_gcc option in linker"), - cargo_apk_gcc_sysroot: cargo_apk_gcc_sysroot - .expect("Missing cargo_apk_gcc_sysroot option in linker"), - cargo_apk_native_app_glue: cargo_apk_native_app_glue - .expect("Missing cargo_apk_native_app_glue option in linker"), - cargo_apk_glue_obj: cargo_apk_glue_obj - .expect("Missing cargo_apk_glue_obj option in linker"), - cargo_apk_glue_lib: cargo_apk_glue_lib - .expect("Missing cargo_apk_glue_lib option in linker"), - cargo_apk_linker_output: cargo_apk_linker_output - .expect("Missing cargo_apk_linker_output option in linker"), - cargo_apk_libs_path_output: cargo_apk_libs_path_output - .expect("Missing cargo_apk_libs_path_output option in linker"), - cargo_apk_libs_output: cargo_apk_libs_output - .expect("Missing cargo_apk_libs_output option in linker"), - }; - - return (args, result_passthrough); - } - }; - - match &*arg { - "--cargo-apk-gcc" => { - cargo_apk_gcc = Some(args.next().unwrap()); - }, - "--cargo-apk-gcc-sysroot" => { - cargo_apk_gcc_sysroot = Some(args.next().unwrap()); - }, - "--cargo-apk-native-app-glue" => { - cargo_apk_native_app_glue = Some(args.next().unwrap()); - }, - "--cargo-apk-glue-obj" => { - cargo_apk_glue_obj = Some(args.next().unwrap()); - }, - "--cargo-apk-glue-lib" => { - cargo_apk_glue_lib = Some(args.next().unwrap()); - }, - "--cargo-apk-linker-output" => { - cargo_apk_linker_output = Some(args.next().unwrap()); - }, - "--cargo-apk-libs-path-output" => { - cargo_apk_libs_path_output = Some(args.next().unwrap()); - }, - "--cargo-apk-libs-output" => { - cargo_apk_libs_output = Some(args.next().unwrap()); - }, - - "-o" => { - // Ignore `-o` and the following argument - args.next(); - }, - "-L" => { - let path = args.next().expect("-L must be followed by a path"); - result_library_path.push(PathBuf::from(path.clone())); - - // Also pass these through. - result_passthrough.push(arg); - result_passthrough.push(path); - }, - "-l" => { - let name = args.next().expect("-l must be followed by a library name"); - result_shared_libraries.insert(vec!["lib", &name, ".so"].concat()); - - // Also pass these through. - result_passthrough.push(arg); - result_passthrough.push(name); - } - _ => { - if arg.starts_with("-l") { - result_shared_libraries.insert(vec!["lib", &arg[2..], ".so"].concat()); - } - - // Also pass these through. - result_passthrough.push(arg); - } - }; - } -} - -struct RustCArgsReader { - reader: Option>, - args: env::Args -} - -impl RustCArgsReader { - pub fn new() -> RustCArgsReader { - let mut args = env::args(); - args.next(); - - RustCArgsReader { - reader: None, - args - } - } - - pub fn next(&mut self) -> Option { - - let mut replace = false; - let mut next_reader : Option> = None; - - loop { - if replace { - self.reader = next_reader.take(); - } - - if let Some(ref mut r) = &mut self.reader { - let mut line = String::new(); - match r.read_line(&mut line) { - Ok(size) => { - if size == 0 { - replace = true; - next_reader = None; - continue; - } - - if line.ends_with('\n') { - line.pop(); - } - - if line.ends_with('\r') { - line.pop(); - } - - return Some(line) - }, - Err(e) => { - println!("Error on file read: {}", e); - replace = true; - next_reader = None; - continue; - } - } - } else { - match self.args.next() { - Some(arg) => { - if arg.starts_with("@") { - let file = match File::open(&arg[1..]) { - Ok(f) => f, - Err(e) => { - println!("Error on file open: {}", e); - continue; - } - }; - - replace = true; - next_reader = Some(BufReader::new(file)); - continue; - } else { - return Some(arg); - } - } - None => return None - } - } - } - } -} diff --git a/cargo-apk/src/config.rs b/cargo-apk/src/config.rs index 5f796ac..27e2a2d 100644 --- a/cargo-apk/src/config.rs +++ b/cargo-apk/src/config.rs @@ -1,3 +1,10 @@ +use cargo::core::{TargetKind, Workspace}; +use cargo::ops; +use cargo::util::CargoResult; +use cargo::CliError; +use failure::format_err; +use itertools::Itertools; +use serde::Deserialize; use std::collections::btree_map::BTreeMap; use std::env; use std::fs; @@ -6,27 +13,166 @@ use std::io::Read; use std::iter::FromIterator; use std::path::Path; use std::path::PathBuf; -use cargo::core::Workspace; -use cargo::ops; -use cargo::util::errors::CargoError; use toml; -use toml::Parser as TomlParser; pub struct AndroidConfig { + /// Name of the cargo package + pub cargo_package_name: String, + + /// Path to the manifest + pub manifest_path: PathBuf, /// Path to the root of the Android SDK. pub sdk_path: PathBuf, /// Path to the root of the Android NDK. pub ndk_path: PathBuf, - /// How to invoke `gradle`. - pub gradle_command: String, + /// List of targets to build the app for. Eg. `armv7-linux-androideabi`. + pub build_targets: Vec, + + /// Path to the android.jar for the selected android platform + pub android_jar_path: PathBuf, + + /// Version of android:targetSdkVersion (optional). Default Value = android_version + pub target_sdk_version: u32, + /// Version of android:minSdkVersion (optional). Default Value = android_version + pub min_sdk_version: u32, + + /// Version of the build tools to use + pub build_tools_version: String, + + /// Should we build in release mode? + pub release: bool, + + /// Target configuration settings that are associated with a specific target + default_target_config: TomlAndroidTarget, + + /// Target specific configuration settings + target_configs: BTreeMap<(TargetKind, String), TomlAndroidTarget>, +} + +impl AndroidConfig { + /// Builds the android target config based on the default target config and the specific target configs defined in the manifest + pub fn resolve(&self, target: (TargetKind, String)) -> CargoResult { + let primary_config = self.target_configs.get(&target); + let target_name = target.1; + let is_default_target = target_name == self.cargo_package_name; + let example = target.0 == TargetKind::ExampleBin; + + Ok(AndroidTargetConfig { + package_name: primary_config + .and_then(|a| a.package_name.clone()) + .or_else(|| { + if is_default_target { + self.default_target_config.package_name.clone() + } else { + None + } + }) + .unwrap_or_else(|| { + if example { + format!("rust.{}.example.{}", self.cargo_package_name, target_name) + } else { + format!("rust.{}", target_name) + } + }), + package_label: primary_config + .and_then(|a| a.label.clone()) + .or_else(|| { + if is_default_target { + self.default_target_config.label.clone() + } else { + None + } + }) + .unwrap_or_else(|| target_name.clone()), + package_icon: primary_config + .and_then(|a| a.icon.clone()) + .or_else(|| self.default_target_config.icon.clone()), + assets_path: primary_config + .and_then(|a| a.assets.as_ref()) + .or_else(|| self.default_target_config.assets.as_ref()) + .map(|p| self.manifest_path.parent().unwrap().join(p)), + res_path: primary_config + .and_then(|a| a.res.as_ref()) + .or_else(|| self.default_target_config.res.as_ref()) + .map(|p| self.manifest_path.parent().unwrap().join(p)), + fullscreen: primary_config + .and_then(|a| a.fullscreen) + .or_else(|| self.default_target_config.fullscreen) + .unwrap_or(false), + application_attributes: primary_config + .and_then(|a| a.application_attributes.clone()) + .or_else(|| self.default_target_config.application_attributes.clone()) + .map(build_attribute_string), + activity_attributes: primary_config + .and_then(|a| a.activity_attributes.clone()) + .or_else(|| self.default_target_config.activity_attributes.clone()) + .map(build_attribute_string), + opengles_version_major: primary_config + .and_then(|a| a.opengles_version_major) + .or_else(|| self.default_target_config.opengles_version_major) + .unwrap_or(2), + opengles_version_minor: primary_config + .and_then(|a| a.opengles_version_minor) + .or_else(|| self.default_target_config.opengles_version_minor) + .unwrap_or(0), + features: primary_config + .and_then(|a| a.feature.clone()) + .or_else(|| self.default_target_config.feature.clone()) + .unwrap_or_else(Vec::new) + .into_iter() + .map(AndroidFeature::from) + .collect(), + permissions: primary_config + .and_then(|a| a.permission.clone()) + .or_else(|| self.default_target_config.permission.clone()) + .unwrap_or_else(Vec::new) + .into_iter() + .map(AndroidPermission::from) + .collect(), + }) + } +} + +#[derive(Clone)] +pub struct AndroidFeature { + pub name: String, + pub required: bool, + pub version: Option, +} + +impl From for AndroidFeature { + fn from(f: TomlFeature) -> Self { + AndroidFeature { + name: f.name, + required: f.required.unwrap_or(true), + version: f.version, + } + } +} + +#[derive(Clone)] +pub struct AndroidPermission { + pub name: String, + pub max_sdk_version: Option, +} + +impl From for AndroidPermission { + fn from(p: TomlPermission) -> Self { + AndroidPermission { + name: p.name, + max_sdk_version: p.max_sdk_version, + } + } +} + +/// Android build settings for a specific target +pub struct AndroidTargetConfig { /// Name that the package will have on the Android machine. /// This is the key that Android uses to identify your package, so it should be unique for /// for each application and should contain the vendor's name. pub package_name: String, - /// Name of the project to feed to the SDK. This will be the name of the APK file. - /// Should be a "system-ish" name, like `my-project`. - pub project_name: String, + /// Label for the package. pub package_label: String, @@ -34,19 +180,6 @@ pub struct AndroidConfig { /// Versions of this icon with different resolutions have to reside in the res folder pub package_icon: Option, - /// List of targets to build the app for. Eg. `arm-linux-androideabi`. - pub build_targets: Vec, - - /// Version of android for which to compile. TODO: ensure that >=18 because Rustc only supports 18+ - pub android_version: u32, - /// Version of android:targetSdkVersion (optional). Default Value = android_version - pub target_sdk_version: u32, - /// Version of android:minSdkVersion (optional). Default Value = android_version - pub min_sdk_version: u32, - - /// Version of the build tools to use - pub build_tools_version: String, - /// If `Some`, a path that contains the list of assets to ship as part of the package. /// /// The assets can later be loaded with the runtime library. @@ -58,9 +191,6 @@ pub struct AndroidConfig { /// This folder contains for example the launcher icon, the styles and resolution dependent images. pub res_path: Option, - /// Should we build in release mode? - pub release: bool, - /// Should this app be in fullscreen mode (hides the title bar)? pub fullscreen: bool, @@ -75,9 +205,18 @@ pub struct AndroidConfig { /// The OpenGL ES minor version in the AndroidManifest.xml pub opengles_version_minor: u8, + + /// uses-feature in AndroidManifest.xml + pub features: Vec, + + /// uses-permission in AndroidManifest.xml + pub permissions: Vec, } -pub fn load(workspace: &Workspace, flag_package: &Option) -> Result { +pub fn load( + workspace: &Workspace, + flag_package: &Option, +) -> Result { // Find out the package requested by the user. let package = { let packages = Vec::from_iter(flag_package.iter().cloned()); @@ -89,16 +228,19 @@ pub fn load(workspace: &Workspace, flag_package: &Option) -> Result unreachable!("cargo apk supports single package only"), ops::Packages::Packages(xs) => match xs.len() { 0 => workspace.current()?, - 1 => workspace.members() + 1 => workspace + .members() .find(|pkg| *pkg.name() == xs[0]) - .ok_or_else(|| format_err!("package `{}` is not a member of the workspace", xs[0]))?, + .ok_or_else(|| { + format_err!("package `{}` is not a member of the workspace", xs[0]) + })?, _ => unreachable!("cargo apk supports single package only"), - } + }, } }; // Determine the name of the package and the Android-specific metadata from the Cargo.toml - let (package_name, manifest_content) = { + let manifest_content = { // Load Cargo.toml & parse let content = { let mut file = File::open(package.manifest_path()).unwrap(); @@ -106,35 +248,40 @@ pub fn load(workspace: &Workspace, flag_package: &Option) -> Result) -> Result>) -> Option { - // TODO rewrite this in functional style - if let Some(map) = input_map { - let mut result = String::new(); - for (key, val) in map { - result.push_str(&format!("\n{}=\"{}\"", key, val)) - } - Some(result) - } else { - None - } +fn build_attribute_string(input_map: BTreeMap) -> String { + input_map + .iter() + .map(|(key, val)| format!("\n{}=\"{}\"", key, val)) + .join("") +} + +#[derive(Debug, Clone, Deserialize)] +struct TomlConfig { + package: TomlPackage, } -#[derive(Debug, Clone, RustcDecodable)] +#[derive(Debug, Clone, Deserialize)] struct TomlPackage { name: String, metadata: Option, } -#[derive(Debug, Clone, RustcDecodable)] +#[derive(Debug, Clone, Deserialize)] struct TomlMetadata { android: Option, } -#[derive(Debug, Clone, RustcDecodable)] +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] struct TomlAndroid { + android_version: Option, + target_sdk_version: Option, + min_sdk_version: Option, + build_targets: Option>, + + #[serde(flatten)] + default_target_config: TomlAndroidTarget, + + bin: Option>, + example: Option>, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +struct TomlFeature { + name: String, + required: Option, + version: Option, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +struct TomlPermission { + name: String, + max_sdk_version: Option, +} + +/// Configuration specific to a single cargo target +#[derive(Debug, Clone, Deserialize)] +#[serde(deny_unknown_fields)] +struct TomlAndroidSpecificTarget { + name: String, + + #[serde(flatten)] + config: TomlAndroidTarget, +} + +#[derive(Debug, Default, Clone, Deserialize)] +struct TomlAndroidTarget { package_name: Option, label: Option, icon: Option, assets: Option, res: Option, - android_version: Option, - target_sdk_version: Option, - min_sdk_version: Option, fullscreen: Option, application_attributes: Option>, activity_attributes: Option>, - build_targets: Option>, - gradle_command: Option, opengles_version_major: Option, opengles_version_minor: Option, + feature: Option>, + permission: Option>, } diff --git a/cargo-apk/src/main.rs b/cargo-apk/src/main.rs index 5b776df..693986f 100644 --- a/cargo-apk/src/main.rs +++ b/cargo-apk/src/main.rs @@ -1,22 +1,12 @@ -extern crate cargo; -extern crate clap; -extern crate rustc_serialize; -extern crate term; -extern crate toml; - -#[macro_use] -extern crate failure; - -use std::path::PathBuf; - use cargo::core::Workspace; -use cargo::core::compiler::{BuildConfig, CompileMode, MessageFormat}; -use cargo::ops::{CompileFilter, CompileOptions, Packages}; -use cargo::util::Config as CargoConfig; -use cargo::util::important_paths::find_root_manifest_for_wd; use cargo::util::process_builder::process; -use cargo::CargoResult; +use cargo::util::Config as CargoConfig; use clap::{App, AppSettings, Arg, ArgMatches, SubCommand}; +use failure::format_err; + +use cargo::util::command_prelude::opt; +use cargo::util::command_prelude::AppExt; +use cargo::util::command_prelude::ArgMatchesExt; mod config; mod ops; @@ -31,10 +21,10 @@ fn main() { let args = match args.subcommand() { ("apk", Some(subcommand_matches)) => subcommand_matches, - _ => &args + _ => &args, }; - let (command, subcommand_args) = match args.subcommand() { + let (command, subcommand_args) = match args.subcommand() { (command, Some(subcommand_args)) => (command, subcommand_args), _ => { drop(cli().print_help()); @@ -44,81 +34,117 @@ fn main() { let arg_target_dir = &subcommand_args.value_of_path("target-dir", &cargo_config); - cargo_config.configure( - args.occurrences_of("verbose") as u32, - if args.is_present("quiet") { - Some(true) - } else { - None - }, - &args.value_of("color").map(|s| s.to_string()), - args.is_present("frozen"), - args.is_present("locked"), - arg_target_dir, - &args.values_of_lossy("unstable-features") - .unwrap_or_default(), - ).unwrap(); + cargo_config + .configure( + args.occurrences_of("verbose") as u32, + if args.is_present("quiet") { + Some(true) + } else { + None + }, + &args.value_of("color").map(|s| s.to_string()), + args.is_present("frozen"), + args.is_present("locked"), + args.is_present("offline"), + arg_target_dir, + &args + .values_of_lossy("unstable-features") + .unwrap_or_default(), + ) + .unwrap(); let err = match command { "build" => execute_build(&subcommand_args, &cargo_config), "install" => execute_install(&subcommand_args, &cargo_config), "run" => execute_run(&subcommand_args, &cargo_config), "logcat" => execute_logcat(&subcommand_args, &cargo_config), - _ => { - cargo::exit_with_error( - format_err!("Expected `build`, `install`, `run`, or `logcat`. Got {}", command).into(), - &mut *cargo_config.shell()) - } + _ => cargo::exit_with_error( + format_err!( + "Expected `build`, `install`, `run`, or `logcat`. Got {}", + command + ) + .into(), + &mut *cargo_config.shell(), + ), }; match err { Ok(_) => (), - Err(err) => cargo::exit_with_error(err, &mut *cargo_config.shell()) + Err(err) => cargo::exit_with_error(err, &mut *cargo_config.shell()), } } fn cli() -> App<'static, 'static> { - App::new("cargo-apk").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::VersionlessSubcommands, - AppSettings::AllowExternalSubcommands, - ]).subcommands(vec![ - cli_apk(), - cli_build(), - cli_install(), - cli_run(), - cli_logcat(), - ]).arg(opt("verbose", "Verbose output")) + App::new("cargo-apk") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::VersionlessSubcommands, + AppSettings::AllowExternalSubcommands, + ]) + .arg( + opt( + "verbose", + "Use verbose output (-vv very verbose/build.rs output)", + ) + .short("v") + .multiple(true) + .global(true), + ) + .arg(opt("quiet", "No output printed to stdout").short("q")) + .arg( + opt("color", "Coloring: auto, always, never") + .value_name("WHEN") + .global(true), + ) + .arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true)) + .arg(opt("locked", "Require Cargo.lock is up to date").global(true)) + .arg(opt("offline", "Run without accessing the network").global(true)) + .arg( + Arg::with_name("unstable-features") + .help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details") + .short("Z") + .value_name("FLAG") + .multiple(true) + .number_of_values(1) + .global(true), + ) + .subcommands(vec![ + cli_apk(), + cli_build(), + cli_install(), + cli_run(), + cli_logcat(), + ]) } fn cli_apk() -> App<'static, 'static> { - SubCommand::with_name("apk").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]).about("dummy subcommand to allow for calling cargo apk instead of cargo-apk") - .subcommands(vec![ - cli_build(), - cli_install(), - cli_run(), - cli_logcat()]) + SubCommand::with_name("apk") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::DontCollapseArgsInUsage, + ]) + .about("dummy subcommand to allow for calling cargo apk instead of cargo-apk") + .subcommands(vec![cli_build(), cli_install(), cli_run(), cli_logcat()]) } fn cli_build() -> App<'static, 'static> { - SubCommand::with_name("build").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]).alias("b") - .about("Compile a local package and all of its dependencies") - .arg_package_spec( + SubCommand::with_name("build") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::DontCollapseArgsInUsage, + ]) + .alias("b") + .about("Compile a local package and all of its dependencies") + .arg_package_spec( "Package to build (see `cargo help pkgid`)", "Build all packages in the workspace", "Exclude packages from the build", - ) - .arg_jobs() - .arg_targets_all( + ) + .arg_jobs() + .arg_targets_all( "Build only this package's library", "Build only the specified binary", "Build all binaries", @@ -129,16 +155,16 @@ fn cli_build() -> App<'static, 'static> { "Build only the specified bench target", "Build all benches", "Build all targets", - ) - .arg_release("Build artifacts in release mode, with optimizations") - .arg_features() - .arg_target_triple("Build for the target triple") - .arg_target_dir() - .arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH")) - .arg_manifest_path() - .arg_message_format() - .arg_build_plan() - .after_help( + ) + .arg_release("Build artifacts in release mode, with optimizations") + .arg_features() + .arg_target_triple("Build for the target triple") + .arg_target_dir() + .arg(opt("out-dir", "Copy final artifacts to this directory").value_name("PATH")) + .arg_manifest_path() + .arg_message_format() + .arg_build_plan() + .after_help( "\ All packages in the workspace are built if the `--all` flag is supplied. The `--all` flag is automatically assumed for a virtual manifest. @@ -152,40 +178,42 @@ the --release flag will use the `release` profile instead. } fn cli_install() -> App<'static, 'static> { - SubCommand::with_name("install").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]).about("Install a Rust binary") - .arg(Arg::with_name("crate").empty_values(false).multiple(true)) - .arg( + SubCommand::with_name("install") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::DontCollapseArgsInUsage, + ]) + .about("Install a Rust binary") + .arg(Arg::with_name("crate").empty_values(false).multiple(true)) + .arg( opt("version", "Specify a version to install from crates.io") .alias("vers") .value_name("VERSION"), - ) - .arg(opt("git", "Git URL to install the specified crate from").value_name("URL")) - .arg(opt("branch", "Branch to use when installing from git").value_name("BRANCH")) - .arg(opt("tag", "Tag to use when installing from git").value_name("TAG")) - .arg(opt("rev", "Specific commit to use when installing from git").value_name("SHA")) - .arg(opt("path", "Filesystem path to local crate to install").value_name("PATH")) - .arg(opt( + ) + .arg(opt("git", "Git URL to install the specified crate from").value_name("URL")) + .arg(opt("branch", "Branch to use when installing from git").value_name("BRANCH")) + .arg(opt("tag", "Tag to use when installing from git").value_name("TAG")) + .arg(opt("rev", "Specific commit to use when installing from git").value_name("SHA")) + .arg(opt("path", "Filesystem path to local crate to install").value_name("PATH")) + .arg(opt( "list", "list all installed packages and their versions", - )) - .arg_jobs() - .arg(opt("force", "Force overwriting existing crates or binaries").short("f")) - .arg_features() - .arg(opt("debug", "Build in debug mode instead of release mode")) - .arg_targets_bins_examples( + )) + .arg_jobs() + .arg(opt("force", "Force overwriting existing crates or binaries").short("f")) + .arg_features() + .arg(opt("debug", "Build in debug mode instead of release mode")) + .arg_targets_bins_examples( "Install only the specified binary", "Install all binaries", "Install only the specified example", "Install all examples", - ) - .arg_target_triple("Build for the target triple") - .arg(opt("root", "Directory to install packages into").value_name("DIR")) - .arg(opt("registry", "Registry to use").value_name("REGISTRY")) - .after_help( + ) + .arg_target_triple("Build for the target triple") + .arg(opt("root", "Directory to install packages into").value_name("DIR")) + .arg(opt("registry", "Registry to use").value_name("REGISTRY")) + .after_help( "\ This command manages Cargo's local set of installed binary crates. Only packages which have [[bin]] targets can be installed, and all binaries are installed into @@ -221,31 +249,33 @@ in a temporary target directory. To avoid this, the target directory can be specified by setting the `CARGO_TARGET_DIR` environment variable to a relative path. In particular, this can be useful for caching build artifacts on continuous integration systems.", - ) + ) } fn cli_run() -> App<'static, 'static> { - SubCommand::with_name("run").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]).alias("r") - .setting(AppSettings::TrailingVarArg) - .about("Run the main binary of the local package (src/main.rs)") - .arg(Arg::with_name("args").multiple(true)) - .arg_targets_bin_example( + SubCommand::with_name("run") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::DontCollapseArgsInUsage, + ]) + .alias("r") + .setting(AppSettings::TrailingVarArg) + .about("Run the main binary of the local package (src/main.rs)") + .arg(Arg::with_name("args").multiple(true)) + .arg_targets_bin_example( "Name of the bin target to run", "Name of the example target to run", - ) - .arg_package("Package with the target to run") - .arg_jobs() - .arg_release("Build artifacts in release mode, with optimizations") - .arg_features() - .arg_target_triple("Build for the target triple") - .arg_target_dir() - .arg_manifest_path() - .arg_message_format() - .after_help( + ) + .arg_package("Package with the target to run") + .arg_jobs() + .arg_release("Build artifacts in release mode, with optimizations") + .arg_features() + .arg_target_triple("Build for the target triple") + .arg_target_dir() + .arg_manifest_path() + .arg_message_format() + .after_help( "\ If neither `--bin` nor `--example` are given, then if the package only has one bin target it will be run. Otherwise `--bin` specifies the bin target to run, @@ -256,26 +286,30 @@ All the arguments following the two dashes (`--`) are passed to the binary to run. If you're passing arguments to both Cargo and the binary, the ones after `--` go to the binary, the ones before go to Cargo. ", - ) + ) } fn cli_logcat() -> App<'static, 'static> { - SubCommand::with_name("logcat").settings(&[ - AppSettings::UnifiedHelpMessage, - AppSettings::DeriveDisplayOrder, - AppSettings::DontCollapseArgsInUsage, - ]).alias("r") - .about("Print Android log") - .arg_message_format() + SubCommand::with_name("logcat") + .settings(&[ + AppSettings::UnifiedHelpMessage, + AppSettings::DeriveDisplayOrder, + AppSettings::DontCollapseArgsInUsage, + ]) + .alias("r") + .about("Print Android log") + .arg_message_format() } pub fn execute_build(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo::CliResult { - let root_manifest = find_root_manifest_for_wd(&options.manifest_path(cargo_config))?; + let root_manifest = options.root_manifest(&cargo_config)?; let workspace = Workspace::new(&root_manifest, &cargo_config)?; - let mut android_config = config::load(&workspace, - &options.value_of("package").map(|s| s.to_owned()))?; + let mut android_config = config::load( + &workspace, + &options.value_of("package").map(|s| s.to_owned()), + )?; android_config.release = options.is_present("release"); ops::build(&workspace, &android_config, &options)?; @@ -283,12 +317,14 @@ pub fn execute_build(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo: } pub fn execute_install(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo::CliResult { - let root_manifest = find_root_manifest_for_wd(&options.manifest_path(cargo_config))?; + let root_manifest = options.root_manifest(&cargo_config)?; let workspace = Workspace::new(&root_manifest, &cargo_config)?; - let mut android_config = config::load(&workspace, - &options.value_of("package").map(|s| s.to_owned()))?; + let mut android_config = config::load( + &workspace, + &options.value_of("package").map(|s| s.to_owned()), + )?; android_config.release = options.is_present("release"); ops::install(&workspace, &android_config, &options)?; @@ -296,12 +332,14 @@ pub fn execute_install(options: &ArgMatches, cargo_config: &CargoConfig) -> carg } pub fn execute_run(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo::CliResult { - let root_manifest = find_root_manifest_for_wd(&options.manifest_path(cargo_config))?; + let root_manifest = options.root_manifest(&cargo_config)?; let workspace = Workspace::new(&root_manifest, &cargo_config)?; - let mut android_config = config::load(&workspace, - &options.value_of("package").map(|s| s.to_owned()))?; + let mut android_config = config::load( + &workspace, + &options.value_of("package").map(|s| s.to_owned()), + )?; android_config.release = options.is_present("release"); ops::run(&workspace, &android_config, &options)?; @@ -309,321 +347,21 @@ pub fn execute_run(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo::C } pub fn execute_logcat(options: &ArgMatches, cargo_config: &CargoConfig) -> cargo::CliResult { - let root_manifest = find_root_manifest_for_wd(&options.manifest_path(cargo_config))?; + let root_manifest = options.root_manifest(&cargo_config)?; let workspace = Workspace::new(&root_manifest, &cargo_config)?; - let android_config = config::load(&workspace, - &options.value_of("package").map(|s| s.to_owned()))?; - - drop(writeln!(workspace.config().shell().err(), "Starting logcat")); + let android_config = config::load( + &workspace, + &options.value_of("package").map(|s| s.to_owned()), + )?; + + drop(writeln!( + workspace.config().shell().err(), + "Starting logcat" + )); let adb = android_config.sdk_path.join("platform-tools/adb"); - process(&adb) - .arg("logcat") - .exec()?; + process(&adb).arg("logcat").exec()?; Ok(()) } - -// Copied from `cargo/command_prelude.rs` - -pub trait AppExt: Sized { - fn _arg(self, arg: Arg<'static, 'static>) -> Self; - - fn arg_package_spec( - self, - package: &'static str, - all: &'static str, - exclude: &'static str, - ) -> Self { - self.arg_package_spec_simple(package) - ._arg(opt("all", all)) - ._arg(multi_opt("exclude", "SPEC", exclude)) - } - - fn arg_package_spec_simple(self, package: &'static str) -> Self { - self._arg(multi_opt("package", "SPEC", package).short("p")) - } - - fn arg_package(self, package: &'static str) -> Self { - self._arg(opt("package", package).short("p").value_name("SPEC")) - } - - fn arg_jobs(self) -> Self { - self._arg( - opt("jobs", "Number of parallel jobs, defaults to # of CPUs") - .short("j") - .value_name("N"), - ) - } - - fn arg_targets_all( - self, - lib: &'static str, - bin: &'static str, - bins: &'static str, - example: &'static str, - examples: &'static str, - test: &'static str, - tests: &'static str, - bench: &'static str, - benches: &'static str, - all: &'static str, - ) -> Self { - self.arg_targets_lib_bin(lib, bin, bins) - ._arg(multi_opt("example", "NAME", example)) - ._arg(opt("examples", examples)) - ._arg(multi_opt("test", "NAME", test)) - ._arg(opt("tests", tests)) - ._arg(multi_opt("bench", "NAME", bench)) - ._arg(opt("benches", benches)) - ._arg(opt("all-targets", all)) - } - - fn arg_targets_lib_bin(self, lib: &'static str, bin: &'static str, bins: &'static str) -> Self { - self._arg(opt("lib", lib)) - ._arg(multi_opt("bin", "NAME", bin)) - ._arg(opt("bins", bins)) - } - - fn arg_targets_bins_examples( - self, - bin: &'static str, - bins: &'static str, - example: &'static str, - examples: &'static str, - ) -> Self { - self._arg(multi_opt("bin", "NAME", bin)) - ._arg(opt("bins", bins)) - ._arg(multi_opt("example", "NAME", example)) - ._arg(opt("examples", examples)) - } - - fn arg_targets_bin_example(self, bin: &'static str, example: &'static str) -> Self { - self._arg(multi_opt("bin", "NAME", bin)) - ._arg(multi_opt("example", "NAME", example)) - } - - fn arg_features(self) -> Self { - self._arg( - opt("features", "Space-separated list of features to activate").value_name("FEATURES"), - )._arg(opt("all-features", "Activate all available features")) - ._arg(opt( - "no-default-features", - "Do not activate the `default` feature", - )) - } - - fn arg_release(self, release: &'static str) -> Self { - self._arg(opt("release", release)) - } - - fn arg_doc(self, doc: &'static str) -> Self { - self._arg(opt("doc", doc)) - } - - fn arg_target_triple(self, target: &'static str) -> Self { - self._arg(opt("target", target).value_name("TRIPLE")) - } - - fn arg_target_dir(self) -> Self { - self._arg(opt("target-dir", "Directory for all generated artifacts").value_name("DIRECTORY")) - } - - fn arg_manifest_path(self) -> Self { - self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH")) - } - - fn arg_message_format(self) -> Self { - self._arg( - opt("message-format", "Error format") - .value_name("FMT") - .case_insensitive(true) - .possible_values(&["human", "json", "short"]) - .default_value("human"), - ) - } - - fn arg_build_plan(self) -> Self { - self._arg(opt("build-plan", "Output the build plan in JSON")) - } - - fn arg_new_opts(self) -> Self { - self._arg( - opt( - "vcs", - "\ - Initialize a new repository for the given version \ - control system (git, hg, pijul, or fossil) or do not \ - initialize any version control at all (none), overriding \ - a global configuration.", - ).value_name("VCS") - .possible_values(&["git", "hg", "pijul", "fossil", "none"]), - ) - ._arg(opt("bin", "Use a binary (application) template [default]")) - ._arg(opt("lib", "Use a library template")) - ._arg( - opt("edition", "Edition to set for the crate generated") - .possible_values(&["2015", "2018"]) - .value_name("YEAR") - ) - ._arg( - opt( - "name", - "Set the resulting package name, defaults to the directory name", - ).value_name("NAME"), - ) - } - - fn arg_index(self) -> Self { - self._arg(opt("index", "Registry index to upload the package to").value_name("INDEX")) - ._arg( - opt("host", "DEPRECATED, renamed to '--index'") - .value_name("HOST") - .hidden(true), - ) - } -} - -impl AppExt for App<'static, 'static> { - fn _arg(self, arg: Arg<'static, 'static>) -> Self { - self.arg(arg) - } -} - -fn opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> { - Arg::with_name(name).long(name).help(help) -} - -fn multi_opt( - name: &'static str, - value_name: &'static str, - help: &'static str, -) -> Arg<'static, 'static> { - // Note that all `.multiple(true)` arguments in Cargo should specify - // `.number_of_values(1)` as well, so that `--foo val1 val2` is - // **not** parsed as `foo` with values ["val1", "val2"]. - // `number_of_values` should become the default in clap 3. - opt(name, help) - .value_name(value_name) - .multiple(true) - .number_of_values(1) -} - -pub trait ArgMatchesExt { - fn value_of_u32(&self, name: &str) -> CargoResult> { - let arg = match self._value_of(name) { - None => None, - Some(arg) => Some(arg.parse::().map_err(|_| { - clap::Error::value_validation_auto(format!("could not parse `{}` as a number", arg)) - })?), - }; - Ok(arg) - } - - /// Returns value of the `name` command-line argument as an absolute path - fn value_of_path(&self, name: &str, config: &CargoConfig) -> Option { - self._value_of(name).map(|path| config.cwd().join(path)) - } - - fn jobs(&self) -> CargoResult> { - self.value_of_u32("jobs") - } - - fn target(&self) -> Option { - self._value_of("target").map(|s| s.to_string()) - } - - fn manifest_path(&self, cargo_config: &CargoConfig) -> PathBuf { - match self.value_of_path("manifest-path", cargo_config) { - None => cargo_config.cwd().to_owned(), - Some(path) => path.to_owned(), - } - } - - fn compile_options<'a>( - &self, - config: &'a CargoConfig, - mode: CompileMode, - ) -> CargoResult> { - let spec = Packages::from_flags( - self._is_present("all"), - self._values_of("exclude"), - self._values_of("package"), - )?; - - let message_format = match self._value_of("message-format") { - None => MessageFormat::Human, - Some(f) => { - if f.eq_ignore_ascii_case("json") { - MessageFormat::Json - } else if f.eq_ignore_ascii_case("human") { - MessageFormat::Human - } else if f.eq_ignore_ascii_case("short") { - MessageFormat::Short - } else { - panic!("Impossible message format: {:?}", f) - } - } - }; - - let mut build_config = BuildConfig::new(config, self.jobs()?, &self.target(), mode)?; - build_config.message_format = message_format; - build_config.release = self._is_present("release"); - build_config.build_plan = self._is_present("build-plan"); - if build_config.build_plan && !config.cli_unstable().unstable_options { - Err(format_err!( - "`--build-plan` flag is unstable, pass `-Z unstable-options` to enable it" - ))?; - }; - - let opts = CompileOptions { - config, - build_config, - features: self._values_of("features"), - all_features: self._is_present("all-features"), - no_default_features: self._is_present("no-default-features"), - spec, - filter: CompileFilter::new( - self._is_present("lib"), - self._values_of("bin"), - self._is_present("bins"), - self._values_of("test"), - self._is_present("tests"), - self._values_of("example"), - self._is_present("examples"), - self._values_of("bench"), - self._is_present("benches"), - self._is_present("all-targets"), - ), - target_rustdoc_args: None, - target_rustc_args: None, - local_rustdoc_args: None, - export_dir: None, - }; - Ok(opts) - } - - fn _value_of(&self, name: &str) -> Option<&str>; - - fn _values_of(&self, name: &str) -> Vec; - - fn _is_present(&self, name: &str) -> bool; -} - -impl<'a> ArgMatchesExt for ArgMatches<'a> { - fn _value_of(&self, name: &str) -> Option<&str> { - self.value_of(name) - } - - fn _values_of(&self, name: &str) -> Vec { - self.values_of(name) - .unwrap_or_default() - .map(|s| s.to_string()) - .collect() - } - - fn _is_present(&self, name: &str) -> bool { - self.is_present(name) - } -} diff --git a/cargo-apk/src/ops/build.rs b/cargo-apk/src/ops/build.rs index cbde31a..4e860f7 100644 --- a/cargo-apk/src/ops/build.rs +++ b/cargo-apk/src/ops/build.rs @@ -1,672 +1,443 @@ -use std::os; -use std::collections::{HashSet, HashMap}; -use std::env; -use std::fs; +mod compile; +use crate::config::{AndroidConfig, AndroidTargetConfig}; +use cargo::core::{Target, TargetKind, Workspace}; +use cargo::util::process_builder::process; +use cargo::util::CargoResult; +use clap::ArgMatches; +use failure::format_err; +use std::collections::{BTreeMap, HashSet}; use std::fs::File; -use std::io::{self, BufRead, BufReader, Write}; +use std::io::Write; use std::path::Path; use std::path::PathBuf; -use std::process::{Command, Stdio}; -use cargo::ops; -use cargo::core::Workspace; -use cargo::core::compiler::CompileMode; -use cargo::util::errors::CargoError; -use cargo::util::process_builder::process; -use clap::ArgMatches; +use std::{env, fs}; -use ArgMatchesExt; -use config::AndroidConfig; +pub use compile::AndroidAbi; +#[derive(Debug)] pub struct BuildResult { - /// The absolute path where the apk is located. - pub apk_path: PathBuf, + /// Mapping from target kind and target name to the built APK + pub target_to_apk_map: BTreeMap<(TargetKind, String), PathBuf>, } -pub fn build(workspace: &Workspace, config: &AndroidConfig, options: &ArgMatches) - -> Result -{ - // First we detect whether `gradle` works. - match Command::new(&config.gradle_command).arg("-v").stdout(Stdio::null()).status() { - Ok(s) if s.success() => (), - _ => { - return Err(format_err!(r#"Could not execute `gradle`. Did you - install it? (If already installed on windows with `gradle.bat` - in your path, you must customise the gradle command to - `gradle.bat` with the CARGO_APK_GRADLE_COMMAND environment - variable)."#)); - } - } - - // Building the `android-artifacts` directory that will contain all the artifacts. - // FIXME: don't use into_path_unlocked() but pass a Cargo::Filesystem everywhere - let android_artifacts_dir = workspace.target_dir().join("android-artifacts").into_path_unlocked(); - build_android_artifacts_dir(workspace, &android_artifacts_dir, &config)?; - - let mut abi_libs: HashMap<&str, Vec> = HashMap::new(); - - for build_target in config.build_targets.iter() { - assert_ne!(build_target, "app"); - let build_target_dir = android_artifacts_dir.join(build_target); - - // Finding the tools in the NDK. - let (gcc_path, gxx_path, ar_path) = { - let host_os = if cfg!(target_os = "windows") { "windows" } - else if cfg!(target_os = "linux") { "linux" } - else if cfg!(target_os = "macos") { "darwin" } - else { panic!("Unknown or incompatible host OS") }; - - let target_arch = if build_target.starts_with("arm") { "arm-linux-androideabi" } - else if build_target.starts_with("aarch64") { "aarch64-linux-android" } - else if build_target.starts_with("i") { "x86" } - else if build_target.starts_with("x86_64") { "x86_64" } - else if build_target.starts_with("mipsel") { "mipsel-linux-android" } - // TODO: mips64 - else { panic!("Unknown or incompatible build target: {}", build_target) }; - - // Looks like the tools don't always share the prefix of the target arch - // Just a macos issue? - let tool_prefix = if build_target.starts_with("arm") { "arm-linux-androideabi" } - else if build_target.starts_with("aarch64") { "aarch64-linux-android" } - else if build_target.starts_with("i") { "i686-linux-android" } - else if build_target.starts_with("x86_64") { "x86_64-linux-android" } - else if build_target.starts_with("mipsel") { "mipsel-linux-android" } - // TODO: mips64 - else { panic!("Unknown or incompatible build target: {}", build_target) }; - - let base = config.ndk_path.join(format!("toolchains/{}-4.9/prebuilt/{}-x86_64", target_arch, host_os)); - (base.join(format!("bin/{}-gcc", tool_prefix)), - base.join(format!("bin/{}-g++", tool_prefix)), - base.join(format!("bin/{}-ar", tool_prefix))) - }; +pub fn build( + workspace: &Workspace, + config: &AndroidConfig, + options: &ArgMatches, +) -> CargoResult { + let root_build_dir = get_root_build_directory(workspace, config); + let (targets, abis) = + compile::build_static_libraries(workspace, config, options, &root_build_dir)?; + build_apks(config, &root_build_dir, &targets, &abis) +} - let gcc_sysroot_linker = { - let arch = if build_target.starts_with("arm") { "arm" } - else if build_target.starts_with("aarch64") { "arm64" } - else if build_target.starts_with("i") { "x86" } - else if build_target.starts_with("x86_64") { "x86_64" } - else if build_target.starts_with("mips") { "mips" } - // TODO: mips64 - else { panic!("Unknown or incompatible build target: {}", build_target) }; - config.ndk_path.join(format!("platforms/android-{v}/arch-{a}", - v = config.android_version, a = arch)) - }; +/// Returns the directory in which all cargo apk artifacts for the current +/// debug/release configuration should be produced. +fn get_root_build_directory(workspace: &Workspace, config: &AndroidConfig) -> PathBuf { + let android_artifacts_dir = workspace + .target_dir() + .join("android-artifacts") + .into_path_unlocked(); - // TODO Test and make compatible with older android NDKs if needed + if config.release { + android_artifacts_dir.join("release") + } else { + android_artifacts_dir.join("debug") + } +} - let gcc_sysroot = { - config.ndk_path.join("sysroot") +fn build_apks( + config: &AndroidConfig, + root_build_dir: &PathBuf, + targets: &HashSet, + abis: &[AndroidAbi], +) -> CargoResult { + let abis_str = abis.join(" "); + + // Create directory to hold final APKs which are signed using the debug key + let final_apk_dir = root_build_dir.join("apk"); + fs::create_dir_all(&final_apk_dir)?; + + // Paths of created APKs + let mut target_to_apk_map = BTreeMap::new(); + + // Build an APK for each cargo target + for target in targets.iter() { + let target_directory = match target.kind() { + TargetKind::Bin => root_build_dir.join("bin"), + TargetKind::ExampleBin => root_build_dir.join("examples"), + _ => unreachable!("Unexpected target kind"), }; - let gcc_isystem = { - let target_arch = if build_target.starts_with("arm") { "arm-linux-androideabi" } - else if build_target.starts_with("aarch64") { "aarch64-linux-android" } - else if build_target.starts_with("i") { "i686-linux-android" } - else if build_target.starts_with("x86_64") { "x86_64-linux-android" } - else if build_target.starts_with("mipsel") { "mipsel-linux-android" } - // TODO: mips64 - else { panic!("Unknown or incompatible build target: {}", build_target) }; - config.ndk_path.join(format!("sysroot/usr/include/{}", target_arch)) - }; + let target_directory = target_directory.join(target.name()); + fs::create_dir_all(&target_directory)?; - // Create android cpu abi name - let abi = if build_target.starts_with("armv7") { "armeabi-v7a" } - else if build_target.starts_with("arm") { "armeabi" } - else if build_target.starts_with("aarch64") { "arm64-v8a" } - else if build_target.starts_with("i") { "x86" } - else if build_target.starts_with("x86_64") { "x86_64" } - else if build_target.starts_with("mips") { "mips" } - // TODO: mips64 - else { panic!("Unknown or incompatible build target: {}", build_target) }; - - // Compiling android_native_app_glue.c - { - drop(writeln!(workspace.config().shell().err(), - "Compiling android_native_app_glue.c")); - let mut cmd = process(&gcc_path); - cmd.arg(config.ndk_path.join("sources/android/native_app_glue/android_native_app_glue.c")) - .arg("-c"); - if config.release { - cmd.arg("-O3"); - } - cmd.arg("-o").arg(build_target_dir.join("android_native_app_glue.o")) - .arg("--sysroot").arg(&gcc_sysroot) - .arg("-isystem").arg(&gcc_isystem) - .exec()?; - } + // Run ndk-build + build_makefiles(&target_directory, target, &abis_str, config)?; - // Compiling injected-glue - let injected_glue_lib = { - drop(writeln!(workspace.config().shell().err(), "Compiling injected-glue")); - let mut cmd = workspace.config().rustc(None)?.process(); - cmd.arg(android_artifacts_dir.join("injected-glue/lib.rs")) - .arg("--crate-type").arg("rlib"); - if config.release { - cmd.arg("-C") - .arg("opt-level=3"); - } - cmd.arg("--crate-name").arg("cargo_apk_injected_glue") - .arg("--target").arg(build_target) - .arg("--out-dir").arg(&build_target_dir); - - cmd.exec()?; - - let stdout = cmd.arg("--print").arg("file-names") - .exec_with_output()?; - let stdout = String::from_utf8(stdout.stdout).unwrap(); - - build_target_dir.join(stdout.lines().next().unwrap()) + let mut ndk_build_cmd = if cfg!(target_os = "windows") { + let mut pb = process("cmd"); + let ndk_build_path = config.ndk_path.join("build/ndk-build.cmd"); + pb.arg("/C").arg(ndk_build_path); + pb + } else { + let ndk_build_path = config.ndk_path.join("build/ndk-build"); + process(ndk_build_path) }; - // Compiling glue_obj.rs - { - let mut file = File::create(build_target_dir.join("glue_obj.rs")).unwrap(); - file.write_all(&include_bytes!("../../glue_obj.rs")[..]).unwrap(); + ndk_build_cmd + .arg("NDK_LIBS_OUT=./lib") + .cwd(&target_directory) + .exec()?; + + // Determine Target Configuration + let target_config = config.resolve((target.kind().to_owned(), target.name().to_owned()))?; + + // + // Run commands to produce APK + // + build_manifest(&target_directory, &config, &target_config, &target)?; + + let build_tools_path = config + .sdk_path + .join("build-tools") + .join(&config.build_tools_version); + let aapt_path = build_tools_path.join("aapt"); + let aapt2_path = build_tools_path.join("aapt2"); + let zipalign_path = build_tools_path.join("zipalign"); + + // Compile resources + let compiled_resources_filename = "resources.zip"; + if let Some(res_path) = &target_config.res_path { + process(&aapt2_path) + .arg("compile") + .arg("--dir") + .arg(res_path) + .arg("-o") + .arg(compiled_resources_filename) + .cwd(&target_directory) + .exec()?; } - - { - drop(writeln!(workspace.config().shell().err(), "Compiling glue_obj")); - let mut cmd = workspace.config().rustc(None)?.process(); - cmd.arg(build_target_dir.join("glue_obj.rs")) - .arg("--crate-type").arg("staticlib"); - if config.release { - cmd.arg("-C") - .arg("opt-level=3"); - } - cmd.arg("--target").arg(build_target) - .arg("--extern").arg(format!("cargo_apk_injected_glue={}", injected_glue_lib.to_string_lossy())) - .arg("--emit").arg("obj") - .arg("-o").arg(build_target_dir.join("glue_obj.o")) - .exec()?; - } - - // Directory where we will put the native libraries for gradle to pick them up. - let native_libraries_dir = android_artifacts_dir.join(format!("app/lib/{}", abi)); - if fs::metadata(&native_libraries_dir).is_err() { - fs::DirBuilder::new().recursive(true).create(&native_libraries_dir).unwrap(); + // Create unaligned APK which includes resources + let unaligned_apk_name = format!("{}_unaligned.apk", target.name()); + let mut aapt2_link_cmd = process(&aapt2_path); + aapt2_link_cmd + .arg("link") + .arg("-o") + .arg(&unaligned_apk_name) + .arg("--manifest") + .arg("AndroidManifest.xml") + .arg("-I") + .arg(&config.android_jar_path); + + if target_config.res_path.is_some() { + aapt2_link_cmd.arg(compiled_resources_filename); } - // Compiling the crate thanks to `cargo rustc`. We set the linker to `linker_exe`, a hacky - // linker that will tweak the options passed to `gcc`. - { - drop(writeln!(workspace.config().shell().err(), "Compiling crate")); - - // Set the current environment variables so that they are picked up by gcc-rs when - // compiling. - env::set_var(&format!("CC_{}", build_target), gcc_path.as_os_str()); - env::set_var(&format!("CXX_{}", build_target), gxx_path.as_os_str()); - env::set_var(&format!("AR_{}", build_target), ar_path.as_os_str()); - env::set_var(&format!("CFLAGS_{}", build_target), &format!("--sysroot {} -isysroot {} -isystem {}", gcc_sysroot_linker.to_string_lossy(), gcc_sysroot.to_string_lossy(), gcc_isystem.to_string_lossy())); - env::set_var(&format!("CXXFLAGS_{}", build_target), &format!("--sysroot {} -isysroot {} -isystem {}", gcc_sysroot_linker.to_string_lossy(), gcc_sysroot.to_string_lossy(), gcc_isystem.to_string_lossy())); - - let extra_args = vec![ - "-C".to_owned(), format!("linker={}", android_artifacts_dir.join(if cfg!(target_os = "windows") { "linker_exe.exe" } else { "linker_exe" }).to_string_lossy()), - "--extern".to_owned(), format!("cargo_apk_injected_glue={}", injected_glue_lib.to_string_lossy()), - "-C".to_owned(),"link-arg=--cargo-apk-gcc".to_owned(), - "-C".to_owned(), format!("link-arg={}", gcc_path.as_os_str().to_str().unwrap().to_owned()), - "-C".to_owned(),"link-arg=--cargo-apk-gcc-sysroot".to_owned(), - "-C".to_owned(), format!("link-arg={}", gcc_sysroot_linker.as_os_str().to_str().unwrap().to_owned()), - "-C".to_owned(), "link-arg=--cargo-apk-native-app-glue".to_owned(), - "-C".to_owned(), format!("link-arg={}", build_target_dir.join("android_native_app_glue.o").into_os_string().into_string().unwrap()), - "-C".to_owned(), "link-arg=--cargo-apk-glue-obj".to_owned(), - "-C".to_owned(), format!("link-arg={}", build_target_dir.join("glue_obj.o").into_os_string().into_string().unwrap()), - "-C".to_owned(), "link-arg=--cargo-apk-glue-lib".to_owned(), - "-C".to_owned(), format!("link-arg={}", injected_glue_lib.into_os_string().into_string().unwrap()), - "-C".to_owned(), "link-arg=--cargo-apk-linker-output".to_owned(), - "-C".to_owned(), format!("link-arg={}", native_libraries_dir.join("libmain.so").into_os_string().into_string().unwrap()), - "-C".to_owned(), "link-arg=--cargo-apk-libs-path-output".to_owned(), - "-C".to_owned(), format!("link-arg={}", build_target_dir.join("lib_paths").into_os_string().into_string().unwrap()), - "-C".to_owned(), "link-arg=--cargo-apk-libs-output".to_owned(), - "-C".to_owned(), format!("link-arg={}", build_target_dir.join("libs").into_os_string().into_string().unwrap()), - // TODO Test and make compatible with different targets (tested only on armv7-linux-androideabi) - "-C".to_owned(), "relocation-model=pic".to_owned(), - "-C".to_owned(), "link-args=-no-pie".to_owned(), - "-C".to_owned(), "link-args=-Wl,-Bsymbolic".to_owned(), - ]; - - let packages = options.values_of_lossy("package").unwrap_or_default(); - let spec = ops::Packages::Packages(packages); - - let (mut examples, mut bins) = (Vec::new(), Vec::new()); - if let Some(s) = options.values_of_lossy("bin") { - bins.extend(s.into_iter()); - } - if let Some(s) = options.values_of_lossy("example") { - examples.extend(s.into_iter()); - } - if !bins.is_empty() && !examples.is_empty() { - return Err(format_err!("You can only specify either a --bin or an --example but not both")); - } - - let pkg = match spec { - ops::Packages::Default => unreachable!("cargo apk supports single package only"), - ops::Packages::All => unreachable!("cargo apk supports single package only"), - ops::Packages::OptOut(_) => unreachable!("cargo apk supports single package only"), - ops::Packages::Packages(ref xs) => match xs.len() { - 0 => workspace.current()?, - 1 => workspace.members() - .find(|pkg| *pkg.name() == xs[0]) - .ok_or_else(|| - format_err!("package `{}` is not a member of the workspace", xs[0]) - )?, - _ => unreachable!("cargo apk supports single package only"), - } - }; - - if bins.is_empty() && examples.is_empty() { - bins = pkg.manifest().targets().iter().filter(|a| { - !a.is_lib() && !a.is_custom_build() && a.is_bin() - }).map(|a| a.name().to_owned()).collect(); - if bins.len() >= 2 { - return Err(format_err!("`cargo apk` can run at most one executable, but \ - multiple exist")); - } else if bins.is_empty() { - return Err(format_err!("a bin target must be available for `cargo apk`")); - } - } - - let mut opts = options.compile_options(workspace.config(), CompileMode::Build)?; - opts.build_config.requested_target = Some((*build_target).clone()); - opts.target_rustc_args = Some(extra_args); - ops::compile(workspace, &opts)?; + // Link assets + if let Some(assets_path) = &target_config.assets_path { + aapt2_link_cmd.arg("-A").arg(assets_path); } - // Determine the list of library paths and libraries, and copy them to the right location. - let shared_objects_to_load = { - let lib_paths: Vec = { - if let Ok(f) = File::open(build_target_dir.join("lib_paths")) { - let l = BufReader::new(f); - l.lines().map(|l| l.unwrap()).collect() - } else { - vec![] - } - }; - - let libs_list: HashSet = { - if let Ok(f) = File::open(build_target_dir.join("libs")) { - let l = BufReader::new(f); - l.lines().map(|l| l.unwrap()).collect() - } else { - HashSet::new() - } - }; - - let mut shared_objects_to_load = Vec::new(); - - for dir in lib_paths.iter() { - fs::read_dir(&dir).and_then(|paths| { - for path in paths { - let path = path.unwrap().path(); - match (path.file_name(), path.extension()) { - (Some(filename), Some(ext)) => { - let filename = filename.to_str().unwrap(); - if filename.starts_with("lib") && ext == "so" && - libs_list.contains(filename) - { - shared_objects_to_load.push(filename.to_owned()); - fs::copy(&path, native_libraries_dir.join(filename)).unwrap(); - } - } - _ => {} - } - } - - Ok(()) - }).ok(); - } + aapt2_link_cmd.cwd(&target_directory).exec()?; + + // Add binaries + for abi in abis { + let so_path = format!("lib/{}/lib{}.so", abi, target.name()); + process(&aapt_path) + .arg("add") + .arg(&unaligned_apk_name) + .arg(so_path) + .cwd(&target_directory) + .exec()?; + } - shared_objects_to_load + // Determine the directory in which to place the aligned and signed APK + let target_apk_directory = match target.kind() { + TargetKind::Bin => final_apk_dir.clone(), + TargetKind::ExampleBin => final_apk_dir.join("examples"), + _ => unreachable!("Unexpected target kind"), }; - - abi_libs.insert(abi, shared_objects_to_load); - } - - // Write the Java source - build_java_src(workspace, &android_artifacts_dir, &config, &abi_libs)?; - - // Invoking `gradle` from within `android-artifacts` in order to compile the project. - drop(writeln!(workspace.config().shell().err(), "Invoking gradle")); - let mut cmd = process(&config.gradle_command); - if config.release { - cmd.arg("assembleRelease"); - } else { - cmd.arg("assembleDebug"); - } - cmd.cwd(&android_artifacts_dir) - .exec()?; - - Ok(BuildResult { - apk_path: { - let apk_name = if options.is_present("release") { - "app/build/outputs/apk/app-release-unsigned.apk" + fs::create_dir_all(&target_apk_directory)?; + + // Align apk + let final_apk_path = target_apk_directory.join(format!("{}.apk", target.name())); + process(&zipalign_path) + .arg("-f") + .arg("-v") + .arg("4") + .arg(&unaligned_apk_name) + .arg(&final_apk_path) + .cwd(&target_directory) + .exec()?; + + // Find or generate a debug keystore for signing the APK + // We use the same debug keystore as used by the Android SDK. If it does not exist, + // then we create it using keytool which is part of the JRE/JDK + let keystore_path = dirs::home_dir() + .ok_or_else(|| format_err!("Unable to determine home directory"))? + .join(".android/debug.keystore"); + if !keystore_path.exists() { + // Generate key + let keytool_filename = if cfg!(target_os = "windows") { + "keytool.exe" } else { - "app/build/outputs/apk/app-debug.apk" + "keytool" }; - android_artifacts_dir.join(apk_name) - }, - }) -} - -fn build_android_artifacts_dir(workspace: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - fs::create_dir_all(path.join("app").join("src").join("main")).unwrap(); - - { - fs::create_dir_all(path.join("injected-glue")).unwrap(); - - let mut lib = File::create(path.join("injected-glue/lib.rs")).unwrap(); - lib.write_all(&include_bytes!("../../injected-glue/lib.rs")[..]).unwrap(); - - let mut ffi = File::create(path.join("injected-glue/ffi.rs")).unwrap(); - ffi.write_all(&include_bytes!("../../injected-glue/ffi.rs")[..]).unwrap(); - } - - build_linker(workspace, path)?; - build_manifest(workspace, path, config)?; - build_build_gradle_root(workspace, path, config)?; - build_build_gradle_proj(workspace, path, config)?; - build_settings_dot_gradle(workspace, path, config)?; - build_gradle_properties(workspace, path, config)?; - build_local_properties(workspace, path, config)?; - build_assets(workspace, path, config)?; - build_res(workspace, path, config)?; - - for target in config.build_targets.iter() { - if fs::metadata(path.join(target)).is_err() { - fs::DirBuilder::new().recursive(true).create(path.join(target)).unwrap(); + let keytool_path = find_java_executable(keytool_filename)?; + process(keytool_path) + .arg("-genkey") + .arg("-v") + .arg("-keystore") + .arg(&keystore_path) + .arg("-storepass") + .arg("android") + .arg("-alias") + .arg("androidebugkey") + .arg("-keypass") + .arg("android") + .arg("-dname") + .arg("CN=Android Debug,O=Android,C=US") + .arg("-keyalg") + .arg("RSA") + .arg("-keysize") + .arg("2048") + .arg("-validity") + .arg("10000") + .cwd(root_build_dir) + .exec()?; } - } - - Ok(()) -} - -fn build_linker(workspace: &Workspace, path: &Path) -> Result<(), CargoError> { - let exe_file = path.join(if cfg!(target_os = "windows") { "linker_exe.exe" } else { "linker_exe" }); - - /*if fs::metadata(&exe_file).is_ok() { - return; - }*/ - - let mut command = workspace.config() - .rustc(None)? - .process() - .arg("-") - .arg("-o") - .arg(&exe_file) - .build_command(); - - let mut child = command.stdin(Stdio::piped()) - .spawn()?; - child.stdin.take().unwrap().write_all(&include_bytes!("../../linker.rs")[..])?; - - let status = child.wait()?; - assert!(status.success()); - - assert!(fs::metadata(&exe_file).is_ok()); - - Ok(()) -} - -fn build_java_src(_: &Workspace, path: &Path, config: &AndroidConfig, abi_libs: &HashMap<&str, Vec>) -> Result<(), CargoError> -{ - let file = path.join("app/src/main/java/rust").join(config.project_name.replace("-", "_")) - .join("MainActivity.java"); - fs::create_dir_all(file.parent().unwrap())?; - //if fs::metadata(&file).is_ok() { return; } - let mut file = File::create(&file)?; - - let mut libs_string = String::new(); - for (abi, libs) in abi_libs { - - libs_string.push_str(format!(" if (abi.equals(\"{}\")) {{\n",abi).as_str()); - libs_string.push_str(format!(" matched_an_abi = true;\n").as_str()); - - for name in libs { - // Strip off the 'lib' prefix and ".so" suffix. - let line = format!(" System.loadLibrary(\"{}\");\n", - name.trim_left_matches("lib").trim_right_matches(".so")); - libs_string.push_str(&*line); - } + // Sign the APK with the development certificate + let mut apksigner_cmd = if cfg!(target_os = "windows") { + let mut pb = process("cmd"); + let apksigner_path = build_tools_path.join("apksigner.bat"); + pb.arg("/C").arg(apksigner_path); + pb + } else { + let apksigner_path = build_tools_path.join("apksigner"); + process(apksigner_path) + }; - libs_string.push_str(format!(" break;\n").as_str()); - libs_string.push_str(format!(" }}\n").as_str()); + apksigner_cmd + .arg("sign") + .arg("--ks") + .arg(keystore_path) + .arg("--ks-pass") + .arg("pass:android") + .arg(&final_apk_path) + .cwd(&target_directory) + .exec()?; + + target_to_apk_map.insert( + (target.kind().to_owned(), target.name().to_owned()), + final_apk_path, + ); } - write!(file, r#"package rust.{package_name}; - -import java.lang.UnsupportedOperationException; -import android.os.Build; -import android.util.Log; - -public class MainActivity extends android.app.NativeActivity {{ - - static {{ - - String[] supported_abis; - - try {{ - supported_abis = (String[]) Build.class.getField("SUPPORTED_ABIS").get(null); - }} catch (Exception e) {{ - // Assume that this is an older phone; use backwards-compatible targets. - supported_abis = new String[]{{Build.CPU_ABI, Build.CPU_ABI2}}; - }} - - boolean matched_an_abi = false; - - for (String abi : supported_abis) {{ -{libs} - }} - - if (!matched_an_abi) {{ - throw new UnsupportedOperationException("Could not find a native abi target to load"); - }} + Ok(BuildResult { target_to_apk_map }) +} - }} -}}"#, libs = libs_string, package_name = config.project_name.replace("-", "_"))?; - Ok(()) +/// Find an executable that is part of the Java SDK +fn find_java_executable(name: &str) -> CargoResult { + // Look in PATH + env::var_os("PATH") + .and_then(|paths| { + env::split_paths(&paths) + .filter_map(|path| { + let filepath = path.join(name); + if fs::metadata(&filepath).is_ok() { + Some(filepath) + } else { + None + } + }) + .next() + }) + .or_else(|| + // Look in JAVA_HOME + env::var_os("JAVA_HOME").and_then(|java_home| { + let filepath = PathBuf::from(java_home).join("bin").join(name); + if filepath.exists() { + Some(filepath) + } else { + None + } + })) + .ok_or_else(|| { + format_err!( + "Unable to find executable: '{}'. Configure PATH or JAVA_HOME with the path to the JRE or JDK.", + name + ) + }) } -fn build_manifest(_: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - fs::create_dir_all(path.join("app/src/main")).unwrap(); - let file = path.join("app/src/main/AndroidManifest.xml"); - //if fs::metadata(&file).is_ok() { return; } +fn build_manifest( + path: &Path, + config: &AndroidConfig, + target_config: &AndroidTargetConfig, + target: &Target, +) -> CargoResult<()> { + let file = path.join("AndroidManifest.xml"); let mut file = File::create(&file)?; // Building application attributes - let application_attrs = format!(r#" - android:label="{0}"{1}{2}{3}"#, - config.package_label, - config.package_icon.as_ref().map_or(String::new(), |a| format!(r#" - android:icon="{}""#, a)), - if config.fullscreen { r#" + let application_attrs = format!( + r#" + android:hasCode="false" android:label="{0}"{1}{2}{3}"#, + target_config.package_label, + target_config + .package_icon + .as_ref() + .map_or(String::new(), |a| format!( + r#" + android:icon="{}""#, + a + )), + if target_config.fullscreen { + r#" android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen""# - } else { "" }, - config.application_attributes.as_ref().map_or(String::new(), |a| a.replace("\n","\n ")) + } else { + "" + }, + target_config + .application_attributes + .as_ref() + .map_or(String::new(), |a| a.replace("\n", "\n ")) ); - // Buidling activity attributes - let activity_attrs = format!(r#" - android:name="rust.{1}.MainActivity" + // Build activity attributes + let activity_attrs = format!( + r#" + android:name="android.app.NativeActivity" android:label="{0}" - android:configChanges="orientation|keyboardHidden|screenSize" {2}"#, - config.package_label, - config.project_name.replace("-", "_"), - config.activity_attributes.as_ref().map_or(String::new(), |a| a.replace("\n","\n ")) + android:configChanges="orientation|keyboardHidden|screenSize" {1}"#, + target_config.package_label, + target_config + .activity_attributes + .as_ref() + .map_or(String::new(), |a| a.replace("\n", "\n ")) ); + let uses_features = target_config + .features + .iter() + .map(|f| { + format!( + "\n\t", + f.name, + f.required, + f.version + .as_ref() + .map_or(String::new(), |v| format!(r#"android:version="{}""#, v)) + ) + }) + .collect::>() + .join(", "); + + let uses_permissions = target_config + .permissions + .iter() + .map(|f| { + format!( + "\n\t", + f.name, + max_sdk_version = f.max_sdk_version.map_or(String::new(), |v| format!( + r#"android:maxSdkVersion="{}""#, + v + )) + ) + }) + .collect::>() + .join(", "); + // Write final AndroidManifest - write!( + writeln!( file, r#" - - - - - - - - + {uses_features}{uses_permissions} + - - - -"#, - package = config.package_name.replace("-", "_"), +"#, + package = target_config.package_name.replace("-", "_"), targetSdkVersion = config.target_sdk_version, minSdkVersion = config.min_sdk_version, - glEsVersion = format!("0x{:04}{:04}", config.opengles_version_major, config.opengles_version_minor), + glEsVersion = format!("0x{:04}{:04}", target_config.opengles_version_major, target_config.opengles_version_minor), + uses_features = uses_features, + uses_permissions = uses_permissions, application_attrs = application_attrs, - activity_attrs = activity_attrs + activity_attrs = activity_attrs, + target_name = target.name(), )?; - Ok(()) -} -fn build_assets(_: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - let src_path = match config.assets_path { - None => return Ok(()), - Some(ref p) => p, - }; - let dst_path = path.join("app").join("src").join("main").join("assets"); - if !dst_path.exists() { - create_dir_symlink(&src_path, &dst_path)?; - } Ok(()) } -fn build_res(_: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - let src_path = match config.res_path { - None => return Ok(()), - Some(ref p) => p, - }; - - if !src_path.exists() { - return Err(format_err!("Resources directory doesn't exist")); - } - - let dst_path = path.join("app").join("src").join("main").join("res"); - if !dst_path.exists() { - create_dir_symlink(&src_path, &dst_path)?; - } +fn build_makefiles( + target_directory: &Path, + target: &Target, + abis: &str, + config: &AndroidConfig, +) -> CargoResult<()> { + let output_directory = target_directory.join("jni"); + fs::create_dir_all(&output_directory)?; + + // Write Android.mk + let file = output_directory.join("Android.mk"); + let mut file = File::create(&file)?; - Ok(()) -} + writeln!( + file, + r#"LOCAL_PATH := $(call my-dir) -#[cfg(target_os = "windows")] -fn create_dir_symlink(src_path: &Path, dst_path: &Path) -> io::Result<()> { - os::windows::fs::symlink_dir(&src_path, &dst_path) -} +# Define module for static library built by rustc +include $(CLEAR_VARS) +LOCAL_MODULE := rustlib +LOCAL_SRC_FILES := ../../../$(TARGET_ARCH_ABI)/build/lib{target_library_name}.a +include $(PREBUILT_STATIC_LIBRARY) -#[cfg(not(target_os = "windows"))] -fn create_dir_symlink(src_path: &Path, dst_path: &Path) -> io::Result<()> { - os::unix::fs::symlink(&src_path, &dst_path) -} +# Build the application +include $(CLEAR_VARS) -fn build_build_gradle_root(_: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - let file = path.join("build.gradle"); - //if fs::metadata(&file).is_ok() { return; } - let mut file = File::create(&file).unwrap(); - - write!(file, r#" -buildscript {{ - repositories {{ - jcenter() - }} - dependencies {{ - classpath 'com.android.tools.build:gradle:2.3.3' - }} -}} -allprojects {{ - repositories {{ - jcenter() - }} -}} -ext {{ - compileSdkVersion = {android_version} - buildToolsVersion = "{build_tools_version}" -}} -"#, android_version = config.android_version, - build_tools_version = config.build_tools_version)?; - Ok(()) -} +LOCAL_MODULE := {target_name} +LOCAL_SRC_FILES := +LOCAL_LDLIBS := -llog -landroid +LOCAL_STATIC_LIBRARIES := android_native_app_glue rustlib +NDK_LIBS_OUT := ./lib -fn build_build_gradle_proj(_: &Workspace, path: &Path, _config: &AndroidConfig) -> Result<(), CargoError> { - let file = path.join("app/build.gradle"); - //if fs::metadata(&file).is_ok() { return; } - let mut file = File::create(&file).unwrap(); - - write!(file, r#" -apply plugin: 'com.android.application' - -android {{ - compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion - - sourceSets {{ - main {{ - jniLibs.srcDirs 'lib/' - }} - }} -}} -"#)?; - Ok(()) -} +include $(BUILD_SHARED_LIBRARY) -fn build_settings_dot_gradle(_: &Workspace, path: &Path, _: &AndroidConfig) -> Result<(), CargoError> { - let file = path.join("settings.gradle"); - //if fs::metadata(&file).is_ok() { return; } - let mut file = File::create(&file)?; - write!(file, r"include ':app'")?; - Ok(()) -} - -fn build_gradle_properties(_: &Workspace, path: &Path, _: &AndroidConfig) -> Result<(), CargoError> { - let file = path.join("gradle.properties"); - //if fs::metadata(&file).is_ok() { return; } - let mut file = File::create(&file)?; - write!(file, r"android.builder.sdkDownload=false")?; - Ok(()) -} +$(call import-module,android/native_app_glue)"#, + target_library_name = target.name().replace("-", "_"), + target_name = target.name() + )?; -fn build_local_properties(_: &Workspace, path: &Path, config: &AndroidConfig) -> Result<(), CargoError> { - let file = path.join("local.properties"); - //if fs::metadata(&file).is_ok() { return; } + // Write Application.mk + let file = output_directory.join("Application.mk"); let mut file = File::create(&file)?; - let sdk_abs_dir = if config.sdk_path.is_absolute() { - config.sdk_path.clone() - } else { - env::current_dir()?.join(&config.sdk_path) - }; - - let ndk_abs_dir = if config.ndk_path.is_absolute() { - config.ndk_path.clone() - } else { - env::current_dir()?.join(&config.ndk_path) - }; + let app_optim = if config.release { "release" } else { "debug" }; - if cfg!(target_os = "windows") { - writeln!(file, r"sdk.dir={}", sdk_abs_dir.to_str().unwrap().replace("\\", "\\\\"))?; - } else { - writeln!(file, r"sdk.dir={}", sdk_abs_dir.to_str().unwrap())?; - } - - if cfg!(target_os = "windows") { - writeln!(file, r"ndk.dir={}", ndk_abs_dir.to_str().unwrap().replace("\\", "\\\\"))?; - } else { - writeln!(file, r"ndk.dir={}", ndk_abs_dir.to_str().unwrap())?; - } + write!( + file, + r#"APP_ABI := {} +APP_PLATFORM := android-{} +APP_OPTIM := {}"#, + abis, config.min_sdk_version, app_optim + )?; Ok(()) } diff --git a/cargo-apk/src/ops/build/compile.rs b/cargo-apk/src/ops/build/compile.rs new file mode 100644 index 0000000..50fefb4 --- /dev/null +++ b/cargo-apk/src/ops/build/compile.rs @@ -0,0 +1,315 @@ +use crate::config::AndroidConfig; +use cargo::core::compiler::CompileMode; +use cargo::core::compiler::Executor; +use cargo::core::manifest::TargetSourcePath; +use cargo::core::{PackageId, Target, TargetKind, Workspace}; +use cargo::util::command_prelude::ArgMatchesExt; +use cargo::util::{CargoResult, ProcessBuilder}; +use clap::ArgMatches; +use failure::format_err; +use std::collections::HashSet; +use std::ffi::OsString; +use std::fmt; +use std::fs; +use std::fs::File; +use std::io::Write; +use std::path::Path; +use std::path::PathBuf; +use std::sync::{Arc, Mutex}; + +pub type AndroidAbi = String; + +/// For each build target and cargo binary or example target, produce a static library which is named based on the cargo target +pub fn build_static_libraries( + workspace: &Workspace, + config: &AndroidConfig, + options: &ArgMatches, + root_build_dir: &PathBuf, +) -> CargoResult<(HashSet, Vec)> { + let injected_glue_src_path = write_injected_glue_src(&root_build_dir)?; + + let mut abis = Vec::new(); + let targets: Arc>> = Arc::new(Mutex::new(HashSet::new())); // Set of all example and bin cargo targets built + for build_target in config.build_targets.iter() { + // Determine the android ABI + let abi = get_abi(build_target)?; + abis.push(abi.to_owned()); + + let build_target_dir = root_build_dir.join(abi); + + let injected_glue_lib = build_injected_glue( + workspace, + config, + &injected_glue_src_path, + &build_target_dir, + build_target, + )?; + + // Configure compilation options so that we will build the desired build_target + let mut opts = + options.compile_options(workspace.config(), CompileMode::Build, Some(&workspace))?; + opts.build_config.requested_target = Some((*build_target).clone()); + + // Create + let executor: Arc = Arc::new(StaticLibraryExecutor { + root_build_directory: root_build_dir.clone(), + build_target_dir: build_target_dir.clone(), + injected_glue_lib, + targets: targets.clone(), + }); + + // Compile all targets for the requested build target + // Hack to ignore expected error caused by the executor changing the targetkind and other settings. + // "error: failed to stat ... + let compilation_result = cargo::ops::compile_with_exec(workspace, &opts, &executor); + if let Err(err) = &compilation_result { + let mut output = String::new(); + fmt::write(&mut output, format_args!("{}", err))?; + if !output.contains(".fingerprint") { + compilation_result?; + } + } + } + + // Remove the set of targets from the reference counted mutex + let mut targets = targets.lock().unwrap(); + let targets = std::mem::replace(&mut *targets, HashSet::new()); + + Ok((targets, abis)) +} + +/// Executor which builds binary and example targets as static libraries +struct StaticLibraryExecutor { + root_build_directory: PathBuf, + build_target_dir: PathBuf, + injected_glue_lib: PathBuf, + targets: Arc>>, +} + +impl<'a> Executor for StaticLibraryExecutor { + fn exec( + &self, + cmd: ProcessBuilder, + _id: PackageId, + target: &Target, + mode: CompileMode, + on_stdout_line: &mut dyn FnMut(&str) -> CargoResult<()>, + on_stderr_line: &mut dyn FnMut(&str) -> CargoResult<()>, + ) -> CargoResult<()> { + if mode == CompileMode::Build + && (target.kind() == &TargetKind::Bin || target.kind() == &TargetKind::ExampleBin) + { + let mut new_args = cmd.get_args().to_owned(); + + // + // Determine source path + // + let path = if let TargetSourcePath::Path(path) = target.src_path() { + path.to_owned() + } else { + // Ignore other values + return Ok(()); + }; + + let original_src_filepath = path.canonicalize()?; + + // + // Generate source file that will be built + // + let src_gen = self + .root_build_directory + .join("src_gen") + .join(target.name()); + fs::create_dir_all(&src_gen)?; + let lib_filepath = src_gen.join("lib.rs"); + { + let mut lib_src_file = File::create(&lib_filepath)?; + + writeln!( + lib_src_file, + r##" +include!(r#"{original_src_path}"#); + +#[no_mangle] +#[inline(never)] +#[allow(non_snake_case)] +pub extern "C" fn android_main(app: *mut ()) {{ + cargo_apk_injected_glue::android_main2(app as *mut _, move || {{ let _ = main(); }}); +}}"##, + original_src_path = original_src_filepath + .to_str() + .expect("Unable to convert original filepath") + )?; + } + + // + // Replace source argument + // + let filename = path.file_name().unwrap().to_owned(); + let source_arg = new_args.iter_mut().find_map(|arg| { + let path_arg = Path::new(&arg); + let tmp = path_arg.file_name().unwrap(); + + if filename == tmp { + Some(arg) + } else { + None + } + }); + + if let Some(source_arg) = source_arg { + *source_arg = lib_filepath.clone().into(); + } else { + return Err(format_err!( + "Unable to replace source argument when buildin target '{}'", + target.name() + )); + } + + // + // Change target from bin to staticlib + // + for arg in &mut new_args { + if arg == "bin" { + *arg = "staticlib".into(); + } + } + + // + // Replace output directory with one inside the build target directory + // + let build_path = self.build_target_dir.join("build"); + fs::create_dir_all(&build_path).unwrap(); + + let mut iter = new_args.iter_mut().rev().peekable(); + while let Some(arg) = iter.next() { + if let Some(prev_arg) = iter.peek() { + if *prev_arg == "--out-dir" { + *arg = build_path.clone().into(); + } + } + } + + // Remove -C extra-filename argument + { + let mut extra_filename_index = None; + for (i, value) in new_args.iter().enumerate() { + if value.to_string_lossy().starts_with("extra-filename=") { + extra_filename_index = Some(i); + } + } + + if let Some(index) = extra_filename_index { + new_args.remove(index - 1); + new_args.remove(index - 1); + } + } + + // + // Inject crate dependency for injected glue + // + new_args.push("--extern".into()); + let mut arg = OsString::new(); + arg.push("cargo_apk_injected_glue="); + arg.push(&self.injected_glue_lib); + new_args.push(arg); + + // Create new command + let mut cmd = cmd.clone(); + cmd.args_replace(&new_args); + + // + // Execute the command + // + cmd.exec_with_streaming(on_stdout_line, on_stderr_line, false) + .map(drop)?; + + // Add target to target set + let mut targets = self.targets.lock().unwrap(); + + // Track the cargo targets that are built + targets.insert(target.clone()); + } else if mode == CompileMode::Test { + // This occurs when --all-targets is specified + eprintln!("Ignoring CompileMode::Test for target: {}", target.name()); + } else { + cmd.exec_with_streaming(on_stdout_line, on_stderr_line, false) + .map(drop)? + } + + Ok(()) + } +} + +fn write_injected_glue_src(android_artifacts_dir: &Path) -> CargoResult { + let injected_glue_path = android_artifacts_dir.join("injected-glue"); + fs::create_dir_all(&injected_glue_path).unwrap(); + + let src_path = injected_glue_path.join("lib.rs"); + let mut lib = File::create(&src_path).unwrap(); + lib.write_all(&include_bytes!("../../../injected-glue/lib.rs")[..]) + .unwrap(); + + let mut ffi = File::create(injected_glue_path.join("ffi.rs")).unwrap(); + ffi.write_all(&include_bytes!("../../../injected-glue/ffi.rs")[..]) + .unwrap(); + + Ok(src_path) +} + +fn build_injected_glue( + workspace: &Workspace, + config: &AndroidConfig, + injected_glue_src_path: &PathBuf, + build_target_dir: &PathBuf, + build_target: &str, +) -> CargoResult { + let rustc = workspace.config().load_global_rustc(Some(&workspace))?; + let injected_glue_build_path = build_target_dir.join("injected-glue"); + fs::create_dir_all(&injected_glue_build_path)?; + + drop(writeln!( + workspace.config().shell().err(), + "Compiling injected-glue for {}", + build_target + )); + let mut cmd = rustc.process(); + cmd.arg(injected_glue_src_path) + .arg("--edition") + .arg("2018") + .arg("--crate-type") + .arg("rlib"); + if config.release { + cmd.arg("-C").arg("opt-level=3"); + } + cmd.arg("--crate-name") + .arg("cargo_apk_injected_glue") + .arg("--target") + .arg(build_target) + .arg("--out-dir") + .arg(&injected_glue_build_path); + + cmd.exec()?; + + let stdout = cmd.arg("--print").arg("file-names").exec_with_output()?; + let stdout = String::from_utf8(stdout.stdout).unwrap(); + + Ok(injected_glue_build_path.join(stdout.lines().next().unwrap())) +} + +fn get_abi(build_target: &str) -> CargoResult<&str> { + Ok(if build_target == "armv7-linux-androideabi" { + "armeabi-v7a" + } else if build_target == "aarch64-linux-android" { + "arm64-v8a" + } else if build_target == "i686-linux-android" { + "x86" + } else if build_target == "x86_64-linux-android" { + "x86_64" + } else { + return Err(format_err!( + "Unknown or incompatible build target: {}", + build_target + )); + }) +} diff --git a/cargo-apk/src/ops/install.rs b/cargo-apk/src/ops/install.rs index 2c05052..55cd232 100644 --- a/cargo-apk/src/ops/install.rs +++ b/cargo-apk/src/ops/install.rs @@ -1,23 +1,33 @@ +use super::BuildResult; +use crate::config::AndroidConfig; +use crate::ops::build; use cargo::core::Workspace; -use cargo::util::errors::CargoError; use cargo::util::process_builder::process; +use cargo::util::CargoResult; use clap::ArgMatches; -use ops::build; -use config::AndroidConfig; -pub fn install(workspace: &Workspace, config: &AndroidConfig, options: &ArgMatches) - -> Result<(), CargoError> -{ +pub fn install( + workspace: &Workspace, + config: &AndroidConfig, + options: &ArgMatches, +) -> CargoResult { let build_result = build::build(workspace, config, options)?; let adb = config.sdk_path.join("platform-tools/adb"); - drop(writeln!(workspace.config().shell().err(), "Installing apk to the device")); - process(&adb) - .arg("install") - .arg("-r") // TODO: let user choose - .arg(&build_result.apk_path) - .exec()?; + for apk_path in build_result.target_to_apk_map.values() { + drop(writeln!( + workspace.config().shell().err(), + "Installing apk '{}' to the device", + apk_path.file_name().unwrap().to_string_lossy() + )); - Ok(()) + process(&adb) + .arg("install") + .arg("-r") // TODO: let user choose + .arg(apk_path) + .exec()?; + } + + Ok(build_result) } diff --git a/cargo-apk/src/ops/run.rs b/cargo-apk/src/ops/run.rs index 3e446d0..1b7d36c 100644 --- a/cargo-apk/src/ops/run.rs +++ b/cargo-apk/src/ops/run.rs @@ -1,30 +1,64 @@ -use cargo::core::Workspace; -use cargo::util::errors::CargoError; +use crate::config::AndroidConfig; +use crate::ops::install; +use cargo::core::{TargetKind, Workspace}; use cargo::util::process_builder::process; +use cargo::util::CargoResult; use clap::ArgMatches; -use ops::install; -use config::AndroidConfig; +use failure::format_err; -pub fn run(workspace: &Workspace, config: &AndroidConfig, options: &ArgMatches) - -> Result<(), CargoError> -{ - let _build_result = install::install(workspace, config, options)?; +pub fn run(workspace: &Workspace, config: &AndroidConfig, options: &ArgMatches) -> CargoResult<()> { + let build_result = install::install(workspace, config, options)?; + // Determine the target that should be executed + let requested_target = if options.is_present("example") && options.is_present("bin") { + return Err(format_err!( + "Specifying both example and bin targets is not supported" + )); + } else if let Some(bin) = options.value_of("bin") { + (TargetKind::Bin, bin.to_owned()) + } else if let Some(example) = options.value_of("example") { + (TargetKind::ExampleBin, example.to_owned()) + } else { + match build_result.target_to_apk_map.len() { + 1 => build_result + .target_to_apk_map + .keys() + .next() + .unwrap() + .to_owned(), + 0 => return Err(format_err!("No APKs to execute.")), + _ => { + return Err(format_err!( + "Multiple APKs built. Specify which APK to execute using '--bin' or '--example'." + )) + } + } + }; + + // Determine package name + let package_name = config.resolve(requested_target)?.package_name; + + // + // Start the APK using adb + // let adb = config.sdk_path.join("platform-tools/adb"); // Found it by doing this : // adb shell "cmd package resolve-activity --brief com.author.myproject | tail -n 1" let activity_path = format!( - "{}/rust.{}.MainActivity", - config.package_name.replace("-", "_"), - config.project_name.replace("-", "_") + "{}/android.app.NativeActivity", + package_name.replace("-", "_"), ); drop(writeln!(workspace.config().shell().err(), "Running apk")); process(&adb) - .arg("shell").arg("am").arg("start") - .arg("-a").arg("android.intent.action.MAIN") - .arg("-n").arg(&activity_path) + .arg("shell") + .arg("am") + .arg("start") + .arg("-a") + .arg("android.intent.action.MAIN") + .arg("-n") + .arg(&activity_path) .exec()?; Ok(()) diff --git a/cargo-apk/tests/cli.rs b/cargo-apk/tests/cli.rs new file mode 100644 index 0000000..1ceee86 --- /dev/null +++ b/cargo-apk/tests/cli.rs @@ -0,0 +1,36 @@ +use assert_cmd::prelude::*; +use std::process::Command; + +#[test] +fn check_advanced_example() { + build_example("advanced"); +} + +#[test] +fn check_basic_example() { + build_example("basic"); +} + +#[test] +fn check_multiple_targets_example() { + build_example("multiple_targets"); +} + +#[test] +fn check_use_asset_example() { + build_example("use_assets"); +} + +#[test] +fn check_use_icon_example() { + build_example("use_icon"); +} + +fn build_example(directory_name: &str) { + let example_path = format!("../examples/{}/", directory_name); + let mut cmd = Command::cargo_bin("cargo-apk").unwrap(); + cmd.arg("build"); + cmd.arg("--all-targets"); + cmd.current_dir(example_path); + cmd.assert().success(); +} diff --git a/examples/advanced/Cargo.lock b/examples/advanced/Cargo.lock new file mode 100644 index 0000000..a688820 --- /dev/null +++ b/examples/advanced/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "advanced" +version = "0.1.0" + diff --git a/examples/advanced/Cargo.toml b/examples/advanced/Cargo.toml new file mode 100644 index 0000000..d7a8f80 --- /dev/null +++ b/examples/advanced/Cargo.toml @@ -0,0 +1,88 @@ +[package] +name = "advanced" +version = "0.1.0" +authors = ["Philip Alldredge tag : +# android:theme="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen +# Defaults to false. +fullscreen = false + +# The maximum supported OpenGL ES version , as claimed by the manifest. Defaults to 2.0. +# See https://developer.android.com/guide/topics/graphics/opengl.html#manifest +opengles_version_major = 3 +opengles_version_minor = 2 + +# Adds extra arbitrary XML attributes to the tag in the manifest. +# See https://developer.android.com/guide/topics/manifest/application-element.html +[package.metadata.android.application_attributes] +"android:debuggable" = "true" +"android:hardwareAccelerated" = "true" + +# Adds extra arbitrary XML attributes to the tag in the manifest. +# See https://developer.android.com/guide/topics/manifest/activity-element.html +[package.metadata.android.activity_attributes] +"android:screenOrientation" = "unspecified" +"android:uiOptions" = "none" + +# Adds a uses-feature element to the manifest +# Supported keys: name, required, version +# The glEsVersion attribute is not supported using this section. +# It can be specified using the opengles_version_major and opengles_version_minor values +# See https://developer.android.com/guide/topics/manifest/uses-feature-element +[[package.metadata.android.feature]] +name = "android.hardware.camera" + +[[package.metadata.android.feature]] +name = "android.hardware.vulkan.level" +version = "1" +required = false + +# Adds a uses-permission element to the manifest. +# Note that android_version 23 and higher, Android requires the application to request permissions at runtime. +# There is currently no way to do this using a pure NDK based application. +# See https://developer.android.com/guide/topics/manifest/uses-permission-element +[[package.metadata.android.permission]] +name = "android.permission.WRITE_EXTERNAL_STORAGE" +max_sdk_version = 18 + +[[package.metadata.android.permission]] +name = "android.permission.CAMERA" diff --git a/examples/advanced/assets/test_asset b/examples/advanced/assets/test_asset new file mode 100644 index 0000000..44e1b76 --- /dev/null +++ b/examples/advanced/assets/test_asset @@ -0,0 +1,3 @@ +str1 +str2 +str3 diff --git a/examples/advanced/res/mipmap-hdpi/ic_launcher.png b/examples/advanced/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..30ffc5e Binary files /dev/null and b/examples/advanced/res/mipmap-hdpi/ic_launcher.png differ diff --git a/examples/advanced/res/mipmap-mdpi/ic_launcher.png b/examples/advanced/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..7c4fe22 Binary files /dev/null and b/examples/advanced/res/mipmap-mdpi/ic_launcher.png differ diff --git a/examples/advanced/res/mipmap-xhdpi/ic_launcher.png b/examples/advanced/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..172616a Binary files /dev/null and b/examples/advanced/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/examples/advanced/res/mipmap-xxhdpi/ic_launcher.png b/examples/advanced/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..2149348 Binary files /dev/null and b/examples/advanced/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/examples/advanced/res/mipmap-xxxhdpi/ic_launcher.png b/examples/advanced/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..d7e4274 Binary files /dev/null and b/examples/advanced/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/examples/advanced/src/main.rs b/examples/advanced/src/main.rs new file mode 100644 index 0000000..d93b3dd --- /dev/null +++ b/examples/advanced/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("main() has been called from advanced example"); +} diff --git a/examples/basic/Cargo.lock b/examples/basic/Cargo.lock index 488d227..1efb9bd 100644 --- a/examples/basic/Cargo.lock +++ b/examples/basic/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "android_glue" version = "0.2.3" diff --git a/examples/basic/Cargo.toml b/examples/basic/Cargo.toml index ec0b1d4..75ea5fc 100644 --- a/examples/basic/Cargo.toml +++ b/examples/basic/Cargo.toml @@ -1,15 +1,15 @@ -[package] -name = "android_glue_example" -version = "0.1.0" -authors = ["Pierre Krieger "] - -[package.metadata.android] -label = "Basic android-rs-glue example" -build_targets = ["arm-linux-androideabi", "i686-linux-android"] - -[[bin]] -name = "example" -path = "src/basic.rs" - -[dependencies.android_glue] -path = "../../glue" +[package] +name = "android_glue_example" +version = "0.1.0" +authors = ["Pierre Krieger "] +edition = "2018" + +[package.metadata.android] +label = "Basic android-rs-glue example" + +[[bin]] +name = "example" +path = "src/basic.rs" + +[dependencies.android_glue] +path = "../../glue" diff --git a/examples/basic/src/basic.rs b/examples/basic/src/basic.rs index 0ed61c7..3bef5fa 100644 --- a/examples/basic/src/basic.rs +++ b/examples/basic/src/basic.rs @@ -1,6 +1,3 @@ -extern crate android_glue; - fn main() { android_glue::write_log("main() has been called"); - loop {} } diff --git a/examples/multiple_targets/Cargo.lock b/examples/multiple_targets/Cargo.lock new file mode 100644 index 0000000..8b2da99 --- /dev/null +++ b/examples/multiple_targets/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "android_glue" +version = "0.2.3" + +[[package]] +name = "android_primary_bin" +version = "0.1.0" +dependencies = [ + "android_glue 0.2.3", +] + diff --git a/examples/multiple_targets/Cargo.toml b/examples/multiple_targets/Cargo.toml new file mode 100644 index 0000000..f73114a --- /dev/null +++ b/examples/multiple_targets/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "android_primary_bin" +version = "0.1.0" +authors = ["Philip Alldredge "] +publish = false +edition = "2018" + +[dependencies.android_glue] +path = "../../glue" + +[package.metadata.android] +label = "Primary Binary" + +[[package.metadata.android.bin]] +name = "secondary-bin" +label = "Secondary Binary" + +[[package.metadata.android.example]] +name = "example1" +label = "Example 1" diff --git a/examples/multiple_targets/examples/example1.rs b/examples/multiple_targets/examples/example1.rs new file mode 100644 index 0000000..aa6081c --- /dev/null +++ b/examples/multiple_targets/examples/example1.rs @@ -0,0 +1,3 @@ +fn main() { + println!("main() has been called on example1"); +} diff --git a/examples/multiple_targets/src/bin/secondary-bin.rs b/examples/multiple_targets/src/bin/secondary-bin.rs new file mode 100644 index 0000000..97b7e59 --- /dev/null +++ b/examples/multiple_targets/src/bin/secondary-bin.rs @@ -0,0 +1,3 @@ +fn main() { + println!("main() has been called on the secondary binary"); +} diff --git a/examples/multiple_targets/src/main.rs b/examples/multiple_targets/src/main.rs new file mode 100644 index 0000000..aeb380d --- /dev/null +++ b/examples/multiple_targets/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("main() has been called on the primary binary"); +} diff --git a/examples/use_assets/Cargo.lock b/examples/use_assets/Cargo.lock index 224c41c..40222e5 100644 --- a/examples/use_assets/Cargo.lock +++ b/examples/use_assets/Cargo.lock @@ -1,11 +1,13 @@ -[root] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "android_glue" +version = "0.2.3" + +[[package]] name = "android_glue_assets_example" version = "0.1.0" dependencies = [ "android_glue 0.2.3", ] -[[package]] -name = "android_glue" -version = "0.2.3" - diff --git a/examples/use_assets/Cargo.toml b/examples/use_assets/Cargo.toml index 8dd86e1..5599bfb 100644 --- a/examples/use_assets/Cargo.toml +++ b/examples/use_assets/Cargo.toml @@ -1,11 +1,12 @@ -[package] -name = "android_glue_assets_example" -version = "0.1.0" -authors = ["Pierre Krieger "] - -[package.metadata.android] -label = "Using assets android-rs-glue example" -assets = "assets" - -[dependencies.android_glue] -path = "../../glue" +[package] +name = "android_glue_assets_example" +version = "0.1.0" +authors = ["Pierre Krieger "] +edition = "2018" + +[package.metadata.android] +label = "Using assets android-rs-glue example" +assets = "assets" + +[dependencies.android_glue] +path = "../../glue" diff --git a/examples/use_assets/src/main.rs b/examples/use_assets/src/main.rs index 34b389a..904ad5d 100644 --- a/examples/use_assets/src/main.rs +++ b/examples/use_assets/src/main.rs @@ -1,5 +1,3 @@ -extern crate android_glue; - mod fs; use std::io::BufRead; diff --git a/examples/use_icon/Cargo.lock b/examples/use_icon/Cargo.lock index 37f2756..8f7698f 100644 --- a/examples/use_icon/Cargo.lock +++ b/examples/use_icon/Cargo.lock @@ -1,11 +1,13 @@ -[root] +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "android_glue" +version = "0.2.3" + +[[package]] name = "android_glue_icon_example" version = "0.1.0" dependencies = [ "android_glue 0.2.3", ] -[[package]] -name = "android_glue" -version = "0.2.3" - diff --git a/examples/use_icon/Cargo.toml b/examples/use_icon/Cargo.toml index 78d14a1..d2b1937 100644 --- a/examples/use_icon/Cargo.toml +++ b/examples/use_icon/Cargo.toml @@ -2,6 +2,7 @@ name = "android_glue_icon_example" version = "0.1.0" authors = ["Pierre Krieger "] +edition = "2018" [package.metadata.android] label = "Using icon android-rs-glue example" diff --git a/examples/use_icon/src/main.rs b/examples/use_icon/src/main.rs index 0aa524c..b3ca3e6 100644 --- a/examples/use_icon/src/main.rs +++ b/examples/use_icon/src/main.rs @@ -1,6 +1,3 @@ -extern crate android_glue; - fn main() { android_glue::write_log("main() has been called, did you like the icon?"); - loop {} } \ No newline at end of file