Open bes opened 3 years ago
I was looking forward to testing this project to see if I could get Rust running as an ACAP app. […] Which commits of cargo-acap and vapix should I use for building?
I will look into this later tonight, probably including cutting a release of each.
You might also want to know that I had been working on Rust bindings to the ACAP libraries. I don't remember exactly the status of that but I'll see if I can't push what I have without being too embarrassed 😄
Furthermore I could not find any version of
cargo-acap-build
on docker hub?
There's a variety of tags on trunnion/cargo-acap
. cargo-acap
ought to pull the version corresponding to your usual rustc
automatically… once you have a working copy of cargo-acap
.
I am kind of surprised that there isn't an easier way of doing this than building Rust from scratch?
rustc
supports custom targets on nightly. I like Rust's release cycle and didn't want to require nightly just for a MIPS target that's smack in the middle of the supported MIPS targets, so I figured building stable rustc
with an extra target would be a better fit. By duplicating some of the existing target triples, this can also enable #[cfg(target_vendor = "axis")]
.
Suppose the other way: use nightly with custom targets. That avoids needing build rustc
, but does not avoid needing to build std
, which is rather lengthy. It also doesn't avoid needing a GNU toolchain for each target, which for the MIPS target is either a) an exciting adventure in cross-compiler installation or b) usage of the Linux toolchain provided by Axis in SDK2.
Building a rustc
+std
for each stable release (extended to support extra targets) and packaging everything into a container image along with the appropriate toolchains seemed like the best solution.
Thanks for the explanation! I would be really happy to have a look at your Rust bindings 👍
You write "Axis SDK2", how does that relate to "ACAP 3" as mentioned here https://hub.docker.com/r/axisecp/acap-toolchain ?
Axis changed a bunch of stuff when they released ACAP 3. If you had a C/C++ application, you'd have to make significant changes to your build process to transition from building ACAP 2 to ACAP 3.
ACAP 3 dropped support for the CRIS cameras (ARTPEC 1-3) which haven't been sold in ages, but also dropped support for MIPS cameras (ARTPEC 4-5) some of which aren't even EOL. The runtime environment isn't all that different, though – it's perfectly possible to make an application which works in either platform – leading to a situation where most ACAP software vendors use both SDKs to avoid unnecessarily reducing compatibility.
cargo-acap
replaces the entire Axis ACAP build process anyway, and it doesn't care about the runtime environment at all, so for building an .eap
from Rust there's really no need to distinguish. Unlike either ACAP SDK 2 or ACAP 3, cargo-acap
can build executables for every camera Axis sells.
The ACAP bindings I was working on are similarly indifferent. Everything is dlopen()
ed at runtime, so if you try to use an interface not supported on this camera, you get an Err()
you can handle – usually by falling back to a different interface – rather than having to build two different executables.
So if I were to build an ACAP application using cargo-acap
, but I also had a bunch of legacy code in C, then I would have to call into the C code using FFI, instead of my initial plan which was to call Rust from C over FFI?
cargo acap build
is certainly intended to get you to an .eap
. You could probably use the pieces to make a .a
against which you could statically link a C application, and hooking that up with ACAP 2 and/or 3 would be… fun.
Another alternative would be to make -sys
crate for your C code, write an application in Rust, and let cargo acap build
build that Rust application into a bunch of .eap
s. The containerized build environment has a C compiler for every target and Rust build scripts work as normal. I'm not exactly sure what the header situation is so you might have some #include
-related problems, but depending on your circumstances that might be a smaller hurdle. I've definitely used Rust crates that build and link against bundled C libraries via cargo acap build
.
Given a Cargo workspace:
[workspace]
members = [
"cargo-acap",
"vapix",
]
[patch.crates-io]
vapix = { path = "./vapix" }
…where ./cargo-acap
is 76edea1
and ./vapix
is eac61ce
, I'm able to reproduce the cargo-0.47
build failure you reported with cargo install --path ./cargo-acap
, but I'm also able to get a working executable with cargo install --locked --path ./cargo-acap
.
Unfortunately I still get that build failure when using cargo install --locked --path ./cargo-acap
Given this directory structure:
axis% exa -T -L 1
.
├── cargo-acap
├── Cargo.toml
├── target
└── vapix
This Cargo.toml
in axis
:
[workspace]
members = [
"cargo-acap",
"vapix",
]
[patch.crates-io]
vapix = { path = "./vapix" }
And these commits from cargo-acap
axis/cargo-acap% git show --summary
commit 76edea1ef13017ddf202deee14ef3bcd98d0dc7d (HEAD -> master, origin/master, origin/HEAD)
Author: Will Glynn <will@willglynn.com>
Date: Thu Nov 19 09:58:26 2020 -0600
1.48.0: search for compiler/rustc_target/src/spec too
and vapix
:
axis/vapix% git show --summary
commit eac61ce0bbf80e6c4ab3b9ad55960aab46fc39b1 (HEAD -> master, origin/master, origin/HEAD)
Author: Will Glynn <will@willglynn.com>
Date: Fri Sep 3 23:45:47 2021 -0500
Add ARTPEC-2
Running this command fails:
axis% cargo install --locked --path ./cargo-acap
warning: no Cargo.lock file published in cargo-acap v0.1.0 (/Users/bes/repos/github/axis/cargo-acap)
Installing cargo-acap v0.1.0 (/Users/bes/repos/github/axis/cargo-acap)
Updating crates.io index
Updating git repository `https://github.com/willglynn/goblin.git`
warning: field is never read: `device`
--> vapix/src/v3/recordings.rs:16:5
|
16 | device: &'a Client<T>,
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: field is never read: `supports_continuous_recording`
--> vapix/src/v3/recordings.rs:17:5
|
17 | supports_continuous_recording: bool,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: field is never read: `supports_playback_over_rtsp`
--> vapix/src/v3/recordings.rs:18:5
|
18 | supports_playback_over_rtsp: bool,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: field is never read: `supports_exporting`
--> vapix/src/v3/recordings.rs:19:5
|
19 | supports_exporting: bool,
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: associated function is never used: `new`
--> vapix/src/v3/recordings.rs:23:25
|
23 | pub(crate) async fn new(device: &'a Client<T>) -> Result<Option<Recordings<'a, T>>> {
| ^^^
warning: 5 warnings emitted
Compiling cargo v0.47.0
error[E0283]: type annotations needed
--> /Users/bes/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-0.47.0/src/cargo/util/config/de.rs:491:63
|
491 | seed.deserialize(Tuple2Deserializer(1i32, env.as_ref()))
| ----^^^^^^--
| | |
| | cannot infer type for type parameter `T` declared on the trait `AsRef`
| this method call resolves to `&T`
|
= note: cannot satisfy `std::string::String: AsRef<_>`
help: use the fully qualified path for the potential candidates
|
491 | seed.deserialize(Tuple2Deserializer(1i32, <std::string::String as AsRef<OsStr>>::as_ref(env)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
491 | seed.deserialize(Tuple2Deserializer(1i32, <std::string::String as AsRef<std::path::Path>>::as_ref(env)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
491 | seed.deserialize(Tuple2Deserializer(1i32, <std::string::String as AsRef<[u8]>>::as_ref(env)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
491 | seed.deserialize(Tuple2Deserializer(1i32, <std::string::String as AsRef<str>>::as_ref(env)))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0283`.
error: failed to compile `cargo-acap v0.1.0 (/Users/bes/repos/github/axis/cargo-acap)`, intermediate artifacts can be found at `/Users/bes/repos/github/axis/target`
Caused by:
could not compile `cargo`
To learn more, run the command again with --verbose.
I wonder if warning: no Cargo.lock file published in cargo-acap v0.1.0 (/Users/bes/repos/github/axis/cargo-acap)
might be a hint?
Ah, the Cargo.lock
in my checkout was .gitignore
d. Try cargo-acap
as of 671a5da.
Great! No dice using the workspace configuration (same error, missing Cargo.lock
), but modifying Cargo.toml
in cargo-acap
like this worked:
vapix = { path = "../vapix", version = "0.1.1-alpha.0", features = ["goblin"] }
I would love to have a peek at those fabled Rust bindings to the ACAP libraries
you mentioned ;)
@willglynn Don't want to take up any of your time unnecessarily (I know how precious one's time is) - but if you have the chance & are willing, I would love to take a look at your ACAP bindings <3
I'm planning to return to that sometime in the next week or two.
Hey! Did you ever return to it? ❤️
The README instructions seem to be fixed, both the crate and docker image are published on crates.io and dockerhub respectively.
The rust bindings for ACAPs do sound very useful too though!
Hi,
I was looking forward to testing this project to see if I could get Rust running as an ACAP app.
I had some troubles getting this up and running, mainly that
cargo install cargo-acap
doesn't work since there is nocargo-acap
on crates.io.I tried building
cargo-acap
from source but after cloningcargo-acap
andvapix
, updatingCargo.toml
withvapix = { path = "../vapix", version = "0.1.1-alpha.0", features = ["goblin"] }
and runningcargo install --path cargo-acap
I got a build error:Which commits of
cargo-acap
andvapix
should I use for building?Furthermore I could not find any version of
cargo-acap-build
on docker hub? Maybe the files are on another registry, or do I have build the image (and multiple versions of rust) manually using theDockerfile
incargo-acap-build
. I am kind of surprised that there isn't an easier way of doing this than building Rust from scratch?Thanks.