Skip to content

Build for the target platform, and for Android - #81

Open
trypsynth wants to merge 3 commits into
muja:masterfrom
trypsynth:android-and-cross-compilation
Open

trypsynth wants to merge 3 commits into
muja:masterfrom
trypsynth:android-and-cross-compilation

Conversation

@trypsynth

Copy link
Copy Markdown

The build script decides which sources to compile and which libraries to link from cfg!(windows), which in a build script answers for the machine doing the building rather than the one being built for. Cross compiling reads the wrong answer out of it, and there is no way to tell it otherwise.

Two ways it shows:

  • Windows host, non-Windows target. isnt.cpp is compiled for a platform that has none of what it needs. Building for aarch64-linux-android from Windows stops at vendor/unrar/isnt.cpp:3:1: error: unknown type name 'DWORD' and then fatal error: 'wbemidl.h' file not found.
  • Non-Windows host, Windows target. The other way round: isnt.cpp is left out of a library that needs it, and powrprof and shell32 go unlinked.

CARGO_CFG_TARGET_OS and CARGO_CFG_TARGET_ENV are what a build script has to ask instead, and that is the first commit. Nothing changes for a native build on any platform.

That alone gets an Android build as far as the next stop. A commit of its own carries the rest of what Android needs, three things:

Android has no lutimes. ulinks.cpp restores a symlink's timestamps with it, so a Linux host building for Android fails with error: use of undeclared identifier 'lutimes'; did you mean 'utimes'?. Upstream reaches for lutimes only where it thinks there is no utimensat, which os.hpp decides from _POSIX_C_SOURCE; bionic has utimensat and does not set that macro. Defining UNIX_TIME_NS for Android takes the utimensat path, which is the one that builds there and the more precise of the two. No vendored source is touched.

Android has no libpthread. Its pthread functions live in libc, so the -lpthread the Unix branch emits has nothing to link against. It is not emitted for Android now.

Nothing links a C++ runtime. The NDK does not link one by default, and the cpp_link_stdlib(None) that is there for windows-gnu says not to ask for one, so the link ends in undefined symbol: operator new and __cxa_throw. Android now links c++_static, which keeps a dependent crate from having to ship libc++_shared.so beside its own library, plus c++abi, which libc++_static leaves its ABI symbols to.

One more, unrelated to Android, in a commit of its own; say the word if you would rather it went in a PR of its own: an MSVC link of a crate that depends on this one ends in unresolved external symbol __imp_RegCloseKey, __imp_RegOpenKeyExW, __imp_RegQueryValueExW, __imp_OpenProcessToken, __imp_AdjustTokenPrivileges and friends. pathfn.cpp reads the registry to find the RAR data directory and system.cpp asks about the process token; both are in advapi32, which is not linked. windows-gnu never noticed because its import libraries are pulled in more loosely.

Testing

On a Windows host (x86_64-pc-windows-msvc):

  • cargo build --release and cargo test --release: 46 tests across the 7 binaries, all passing, unchanged from before.
  • cargo ndk -t arm64-v8a -t armeabi-v7a build --release: both compile, where before this they could not be built for Android from a Windows host at all.
  • A binary that lists an archive and reads a member out of it links for both aarch64-linux-android and armv7-linux-androideabi. Linking is where the last two problems showed up, so a build alone was not enough to call it done.

Not tested by me: a Linux or macOS host. The change to the Windows branch there is that it now fires for a Windows target rather than a Windows host, which is the point of the patch, and the non-Windows branch is unchanged for every target except Android.

Found while adding .cbr support to Paperback, a screen-reader-first document reader. Comic archives packed with RAR are a good half of what people have on their shelves, and this crate reads them well; the Android build is the one place it could not follow.

rursache added a commit to rursache/balatro-mod-manager that referenced this pull request Oct 13, 2026
unrar_sys 0.5.8 picks link libraries and sources from the host instead of
the target and its SSE/AES attributes are only enabled for GCC, so building
x86_64-pc-windows-msvc with cargo-xwin from macOS failed. The local copy
fixes both (build.rs mirrors upstream muja/unrar.rs#81), see PATCHED.md

Claude-Session: https://claude.ai/code/session_01VQ2ANcwsfQEPqhrDGSNdeL
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