Как определить целевой элемент (target) в файле build.rs?

У меня есть файл build.rs, содержащий следующий код: <br/> 
<pre><code class="rust">fn main() {
    #[cfg(all(target_arch = "x86_64", target_vendor = "unknown", target_os = "none"))]
    {
        println!("cargo:warning={}", "x86_64-unknown-none");
    }
    #[cfg(not(all(target_arch = "x86_64", target_vendor = "unknown", target_os = "none")))]
    {
        println!("cargo:warning={}", "NOT x86_64-unknown-none");
    }
    println!("cargo:warning=Target arch: {:?}", std::env::var("CARGO_CFG_TARGET_ARCH"));
    println!("cargo:warning=Target vendor: {:?}", std::env::var("CARGO_CFG_TARGET_VENDOR"));
    println!("cargo:warning=Target os: {:?}", std::env::var("CARGO_CFG_TARGET_OS"));

    #[cfg(target_arch = "x86_64")]
    println!("arch true");
    #[cfg(target_vendor = "unknown")]
    println!("vendor true");
    #[cfg(target_os = "none")]
    println!("os true");
}</code></pre> <br/> 
<br/> 
Тем не менее, когда я выполняю команду <code>cargo b --target x86_64-unknown-none</code>, я по-прежнему получаю следующие предупреждения: <br/> 
<pre><code>warning: [email protected]: NOT x86_64-unknown-none
warning: [email protected]: Target arch: Ok("x86_64")
warning: [email protected]: Target vendor: Ok("unknown")
warning: [email protected]: Target os: Ok("none")</code></pre> <br/> 
<br/> 
Почему условия не выполняются должным образом, даже одно из них?
  • 23 октября 2024 г. 18:13
Ответы на вопрос 2
Ваш код в файле `build.rs` использует макросы `cfg` для определения целевой архитектуры, вендора и операционной системы на основании конфигурации сборки. Однако, в приведённом вами случае, вы проверяете условия, основанные на `target_os`, который равен `none`, и, возможно, это не совпадает с ожидаемыми значениями.

Когда вы выполняете команду:

```bash
cargo b --target x86_64-unknown-none
```

флаг `--target` устанавливает платформу для сборки, но при этом важно убедиться, что ваш Rust компилятор настроен и поддерживает целевую платформу `x86_64-unknown-none`. 

### Возможные причины, почему ваши условия не выполняются:

1. **Поддержка целевой платформы**: Убедитесь, что вы действительно настроили `rustc` для сборки под целевую платформу `x86_64-unknown-none`. Иногда целевые платформы могут требовать дополнительной установки или настройки.

2. **hus `target_os` будет не `none`**: В некоторых случаях эта конфигурация может подразумевать, что `target_os` не будет равен `none`. Если это так, то условие не выполнится, и вы получите вывод "NOT x86_64-unknown-none".

3. **Проверка целевой платформы**: Чтобы диагностировать, что именно передаётся в настройки сборки, вы можете добавить следующее, чтобы вывести все параметры целевой платформы во время сборки:
    ```rust
    for (key, value) in std::env::vars() {
        if key.starts_with("CARGO_CFG_") {
            println!("{} = {}", key, value);
        }
    }
    ```

### Рекомендации

- Запустите `cargo build --target x86_64-unknown-none --verbose`, чтобы увидеть, какую конфигурацию получает ваша сборка и какая информация передаётся в `build.rs`.

- Проверьте, правильно ли установлены необходимые компоненты для сборки под вашу целевую платформу. Возможно, вам потребуется установить дополнительные цели с помощью команды `rustup target add x86_64-unknown-none`.

- Возможно, вам стоит добавить дополнительные предупреждения в код для более детального анализа, например, вывести значения `CARGO_CFG_TARGET_OS`, чтобы убедиться, чему он равен на вашей целевой платформе.

Таким образом, выявив настоящую причину проблемы с условиями в вашем `build.rs`, вы сможете лучше понять, как справляться с выбором целевого элемента на основе вашей конфигурации.
А как оно будет работать, если build.exe для того и предназначен, чтобы запускаться самим тулчейном на хостовой системе, а не на таргете? 

Вот список переменных окружения, которые получаются через std::env::var в build.rs. Для target-triple тебе нужен TARGET .

Чтобы получить host-triple, нужна переменная HOST .
Похожие вопросы