Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid clang wrapper scripts and pass --target instead #106

Closed
wants to merge 1 commit into from

Conversation

rib
Copy link
Contributor

@rib rib commented May 18, 2023

I'm just sharing this as a draft PR to show another attempt at solving #92 based on the approach currently used in ndk-build, but as you can see from the description below this actually ends up being a lot more complex that it appears on the surface. I tried to even jump the extra hurdles to parse the cargo config files to read configured rustflags but I think this approach would be too fragile to adopt. Notably, for my own use case this solution doesn't work because our project configures rustflags via .cargo/config.toml, including target.<cfg>.rustflags which are the the most problematic to handle here

Cc: @MarijnS95

--

This is an alternative fix for #92 that avoids hitting command line length limitations and avoids needing to use cargo-ndk as a spring board for running clang, which avoids needing temporary hard links or copying the cargo-ndk binary to the target/ directory.

This takes a similar approach to ndk-build here: rust-mobile/ndk#306 but also tries to be more thorough with reading configured rustflags.

Although this solution initially looked like it would be much simpler it soon became apparent that for it to work reliably it needs to be able to read the user's configured rustflags before adding the required -Clink-arg=--target rustflag (otherwise we would potentially discard rustflags needed by the project).

Unfortunately it turns out to be practically impossible to reliably read configured rustflags from outside cargo!

Rustflags are read by cargo from one of four, mutually-exclusive, places:

  1. CARGO_ENCODED_RUSTFLAGS environment variable.
  2. RUSTFLAGS environment variable.
  3. All matching target..rustflags and target..rustflags config entries joined together.
  4. build.rustflags config value.

(cargo also supports --config command line options that can set these)

Although we can easily handle the first two environment variables, the second two involve:

  • parsing all of Cargo's config files
  • evaluating cfg options and handling a paradox whereby --cfg arguments specified as rustflags need to then also affect which target.rustflags to use! (cargo does this internally with 2 iterations)

This experimental patch handles the first two cases and by adding a dependency on the cargo crate will even attempt to handle the second two options, with these caveats:

  1. --config options on the command line aren't handled
  2. Any use of target..rustflags are treated as an error because we have no way of knowing if these are needed but we can't handle them
  3. It's always possible that future versions of Cargo could add new ways to configure rustflags that we might not handle

This is an alternative fix for bbqsrc#92 that avoids hitting command line
length limitations and avoids needing to use `cargo-ndk` as a spring
board for running `clang`, which avoids needing temporary hard links or
copying the `cargo-ndk` binary to the target/ directory.

This takes a similar approach to `ndk-build` here:
rust-mobile/ndk#306 but also tries to be more
thorough with reading configured rustflags.

Although this solution initially looked like it would be much simpler
it soon became apparent that for it to work reliably it needs to be
able to read the user's configured rustflags before adding the
required `-Clink-arg=--target` rustflag (otherwise we would potentially
discard rustflags needed by the project).

Unfortunately it turns out to be practically impossible to reliably read
configured rustflags from outside cargo!

Rustflags are read by cargo from one of four, mutually-exclusive, places:

1. CARGO_ENCODED_RUSTFLAGS environment variable.
2. RUSTFLAGS environment variable.
3. All matching target.<triple>.rustflags and target.<cfg>.rustflags config entries joined together.
4. build.rustflags config value.

(cargo also supports --config command line options that can set these)

Although we can easily handle the first two environment variables, the
second two involve:
- parsing all of Cargo's config files
- evaluating cfg options and handling a paradox whereby --cfg arguments
  specified as rustflags need to then also affect which
  target.<cfg>rustflags to use! (cargo does this internally with 2
  iterations)

This experimental patch handles the first two cases and by adding a
dependency on the `cargo` crate will even attempt to handle the second
two options, with these caveats:
1. --config options on the command line aren't handled
2. _Any_ use of target.<cfg>.rustflags are treated as an error because
   we have no way of knowing if these are needed but we can't handle
   them
3. It's always possible that future versions of Cargo could add new
   ways to configure rustflags that we might not handle
@rib
Copy link
Contributor Author

rib commented May 18, 2023

I think it's useful to have this PR for posterity, and to document the challenges that arose from trying to parse cargo's config files but I'll close this for now in favor of #108 as a solution instead - can potentially re-open later if it makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant