Skip to content

dx fails to link for Android on Windows hosts: backslashes stripped from linker response file #5847

Description

@mariustz

Problem

On a Windows host, dx serve --android / dx build --android fails at the link step. Every path
in the linker arguments loses its backslashes:

clang: error: no such file or directory: 'C:devdioxus-datagridtargetx86_64-linux-androidandroid-releasedepsplayground-2cbced1493db4974.playground.7c43d7eef16e4b50-cgu.0.rcgu.o'
clang: error: no such file or directory: 'C:UsersME.rustuptoolchainsstable-x86_64-pc-windows-msvclibrustlibx86_64-linux-androidliblibcompiler_builtins-7964d93d152b97aa.rlib'

Cause

When dx runs as the linker, packages/cli/src/build/link.rs writes the arguments to a command
file on Windows and passes @file to the real linker:

if cfg!(windows) {
    let cmd_contents: String = out_args
        .iter()
        .map(|s| format!("\"{}\"", s.to_string_lossy()))
        .join(" ");
    std::fs::write(self.windows_command_file(), cmd_contents)
    // ...
    out_args = vec![format!("@{}", self.windows_command_file().display()).into()];
}

The arguments are quoted but not escaped. That fits MSVC link.exe, which reads response files with
Windows quoting rules. For Android the linker is the NDK's clang
(x86_64-linux-android28-clang.cmd), and clang reads response files with GNU quoting rules
whenever the target is not MSVC. Under GNU rules a backslash inside double quotes is an escape
character, so "C:\dev\foo.o" becomes C:devfoo.o.

The code is the same in v0.7.10 and on main.

Steps To Reproduce

  1. On Windows, install the Android SDK and NDK and run rustup target add x86_64-linux-android.
  2. dx new any app (or use an existing one with a mobile feature).
  3. Run dx serve --android --release.
  4. The build fails at the link step with the error above.

The clang behaviour on its own, without dx:

> type a.rsp
"C:\Users\me\AppData\Local\Temp\rsptest\m.c" "-o" "C:\Users\me\AppData\Local\Temp\rsptest\m.out"

> clang.exe --target=x86_64-linux-android28 @a.rsp
clang: error: no such file or directory: 'C:UsersmeAppDataLocalTemprsptestm.c'

> clang.exe --target=x86_64-linux-android28 --rsp-quoting=windows @a.rsp
(succeeds)

Expected behavior

The Android build links on a Windows host.

Workaround

Add --rsp-quoting=windows to the NDK wrapper scripts, for example in
ndk\<version>\toolchains\llvm\prebuilt\windows-x86_64\bin\x86_64-linux-android28-clang.cmd:

"%_BIN_DIR%clang.exe" --target=x86_64-linux-android28 --rsp-quoting=windows %*

With that change the build links and the app runs in the emulator.

Possible fix

When the target is not MSVC, either escape backslashes and double quotes while writing the command
file (\\\, "\"), as rustc does for GNU-style linkers, or pass
--rsp-quoting=windows before the @file argument when the linker is clang.

Environment:

  • Dioxus version: 0.7.10 (dioxus-cli 0.7.10)
  • Rust version: 1.96.1
  • OS info: Windows 11 Pro 10.0.26200
  • App platform: android (x86_64-linux-android, emulator)
  • Android NDK: 30.0.16248370

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions