Skip to content

Target configuration for binaries #9208

Open
@MichaelMcDonnell

Description

I would like to be able to specify different main files depending on the operating system. I ran into this problem in Servo where there are two main files. The main.rs file is for Android and includes the main2.rs file for the desktop using the include macro:

#[cfg(not(target_os = "android"))]
include!("main2.rs");

#[cfg(target_os = "android")]
pub fn main() {
    println!(
        "Cannot start /ports/servo/ on Android. \
         Use /support/android/apk/ + /ports/libsimpleservo/ instead"
    );
}

Using the include macro is not great because it breaks my IDE. I am not able to easily jump to the code. I also suspect using macros adds a small compile time overhead.

It could be solved using cfg_if crate (see my Servo cfg_if-main branch), and the code is not that nested, but it could be simpler with cargo support.

Another use case could be something like BusyBox but where certain system binaries are only needed on specific platforms. For example, something that queries Linux settings would only be compiled for Linux.

The Cargo.toml file shows how I would like the feature to work:

[package]
name = "target-cfg-bin-example"
version = "0.2.0"
authors = ["Michael Mc Donnell <michael@mcdonnell.dk>"]
edition = "2018"
autobins = false

# Use the standard `main.rs` for all operating systems except Android.
[[bin]]
name = "target-cfg-bin-example"
path = "src/main.rs"
target = "cfg(not(android))"

# Use the `main_android.rs` main file on Android
[[bin]]
name = "target-cfg-bin-example"
path = "src/main_android.rs"
target = "cfg(android)"

[dependencies]

It currently results in the following error message:

error: failed to parse manifest at `/home/michael/src/target-cfg-bin-example/Cargo.toml`

Caused by:
  found duplicate binary name target-cfg-bin-example, but all binary targets must have a unique name

You can clone the example from https://github.com/MichaelMcDonnell/target-cfg-bin-example

UPDATE 1: I changed the Cargo.toml proposal to add a target key/value pair on the binary definition instead of using the target array. Thanks to @ehuss for the suggestions. It became apparent to me too when I tried to implement it. For dependencies the target has to be applied to each dependency key/value pair so it make sense it is defined for the table/array that has them. For binaries it needs to be applied to the table but not to each key/value pair, so having it as a key/value pair makes sense.

UPDATE 2: I tried getting rid of the include macro using the cfg_if crate (see my Servo cfg_if-main branch), and the code is not that nested, but it could be simpler with cargo support. I've updated issue description with this information.

See also

Metadata

Assignees

No one assigned

    Labels

    A-cargo-targetsArea: selection and definition of targets (lib, bins, examples, tests, benches)A-manifestArea: Cargo.toml issuesC-feature-requestCategory: proposal for a feature. Before PR, ping rust-lang/cargo if this is not `Feature accepted`S-needs-designStatus: Needs someone to work further on the design for the feature or fix. NOT YET accepted.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions