Android: build/runtime fixes for modern Clang + ETDump path override#19293
Android: build/runtime fixes for modern Clang + ETDump path override#19293jgibson2 wants to merge 4 commits intopytorch:mainfrom
Conversation
Three small fixes needed to build and run ExecuTorch Android on hosts with Apple Clang 21 and on devices where /data/local/tmp isn't app-writable: 1. Workaround flatcc's vendored CMakeLists.txt hitting -Werror on new Clang warnings (-Wimplicit-int-conversion-on-negation, -Wunterminated-string-initialization). Passes FLATCC_ALLOW_WERROR=OFF into both the top-level flatcc CMake build and the flatcc_ep ExternalProject. 2. scripts/build_android_library.sh was setting EXECUTORCH_ENABLE_EVENT_TRACER from $EXECUTORCH_ANDROID_PROFILING but never forwarding the separate -DEXECUTORCH_ANDROID_PROFILING define that gates ETDumpGen allocation in extension/android/jni/jni_layer.cpp. As a result, the event tracer was compiled in but the JNI never attached it, and Module.etdump() always returned false. 3. Add Module.etdump(String outputPath) / etdumpTo() JNI method so apps can write the ETDump into their own filesDir. The existing etdump() hardcodes /data/local/tmp/result.etdump, which is not app-writable on modern Android (Pixel 9 / API 36 returns EACCES). The new overload factors the write path through a shared etdump_to_path() helper; etdump() now delegates to it with the legacy path.
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/19293
Note: Links to docs will display an error until the docs builds have been completed. ❗ 1 Active SEVsThere are 1 currently active SEVs. If your PR is affected, please view them below: ❌ 2 New Failures, 1 Cancelled Job, 4 Unrelated FailuresAs of commit dc1bcb3 with merge base 8a397b4 ( NEW FAILURES - The following jobs have failed:
BROKEN TRUNK - The following jobs failed but were present on the merge base:👉 Rebase onto the `viable/strict` branch to avoid these failures
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@pytorchbot label "release notes: android" |
|
@claude Review these changes |
|
Claude finished @SS-JIA's task in 2m 8s —— View job Code Review for PR #19293
SummaryOverall this is a solid, well-scoped PR that fixes real issues. The three changes are logically independent and each solves a clear problem. A few items to consider: 1.
|
The set(..CACHE TYPE DOCSTRING [FORCE]) form treats the docstring as a
single argument, but `${DESCRIPTION}` was being expanded unquoted, so
multi-word descriptions were spilling their trailing words into
subsequent set() arguments. This is latent for the common case because
most existing STRING options are driven by the else-branch (not overridden
via -D), but any STRING option overridden on the cmake command line with
a multi-word description hits it — for example:
cmake -DEXECUTORCH_VULKAN_FP16_PRECISION=mediump ...
fails with the description text being fed to the downstream shader
generator as CLI args.
One-char fix: quote "${DESCRIPTION}" in both set() calls. Correct for
both single- and multi-word descriptions.
The script defaults `PYTHON_EXECUTABLE=python3` (and honors any value the
caller sets in the env), but never passed it to the `cmake` invocation. As
a result, cmake's `find_package(Python3)` picked up whatever interpreter
came first on PATH, which on macOS is typically Homebrew's `python3` rather
than the project's torch-equipped venv. The build then failed at
`find_package_torch_headers` (`tools/cmake/Utils.cmake:118`) with:
AttributeError: 'NoneType' object has no attribute 'submodule_search_locations'
(i.e. `import torch` in the wrong interpreter, returning None.)
One-line fix: pass `-DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}"` so the
script's documented behavior — that the caller can pin the interpreter —
actually flows through to the cmake configure step.
* Null-guard module_->event_tracer() before casting to ETDumpGen*. If the tracer is unset (e.g. ANDROID_PROFILING was compiled in but the module was constructed without an ETDumpGen on some path), we'd previously segfault on get_etdump_data(). Switch the C-style cast to a static_cast while we're here. * Move etdump_to_path() into a private: section at the end of the class, rather than splicing private:/public: visibility blocks into the middle of the public method group. * Reject null outputPath in etdumpTo() before calling toStdString(); a null jstring would otherwise crash.
|
Addressed review |
SS-JIA
left a comment
There was a problem hiding this comment.
Changes LGTM, but will defer to @kirklandsign or @psiddh for the final stamp.
Summary
Five small fixes needed to build and run ExecuTorch Android on hosts with Apple Clang 21, on devices where
/data/local/tmpisn't app-writable, and to make the Android build script behave correctly on hosts with multiple Python interpreters:flatcc
-Werroron modern Clang. flatcc's vendoredCMakeLists.txthits-Wimplicit-int-conversion-on-negationand-Wunterminated-string-initializationon new Clang. PassFLATCC_ALLOW_WERROR=OFFinto theflatcc_epExternalProject so the third-party build doesn't fail.EXECUTORCH_ANDROID_PROFILINGwas never forwarded.scripts/build_android_library.shsetEXECUTORCH_ENABLE_EVENT_TRACERfrom$EXECUTORCH_ANDROID_PROFILINGbut never forwarded the separate-DEXECUTORCH_ANDROID_PROFILINGdefine that gatesETDumpGenallocation inextension/android/jni/jni_layer.cpp. As a result the event tracer was compiled in but the JNI never attached it, andModule.etdump()always returnedfalse.Module.etdump(String outputPath)overload. Add a JNI method (etdumpToNative) and Java wrapper so apps can write the ETDump into their ownfilesDir. The existingetdump()hardcodes/data/local/tmp/result.etdump, which is not app-writable on modern Android (Pixel 9 / API 36 returnsEACCES). The new overload factors the write path through a sharedetdump_to_path()helper;etdump()now delegates to it with the legacy path.define_overridable_optionwas expanding${DESCRIPTION}unquoted. Theset(... CACHE TYPE DOCSTRING [FORCE])form expects the docstring as a single argument, but${DESCRIPTION}was unquoted, so anySTRINGoption with a multi-word description that the user overrides on the cmake command line had its description text spill into subsequentset()arguments. One-character fix: quote"${DESCRIPTION}"in bothset()calls.scripts/build_android_library.shnever forwardedPYTHON_EXECUTABLEto cmake. The script defaultsPYTHON_EXECUTABLE=python3and honors a caller override, but only used it forwhich. cmake'sfind_package(Python3)then picked up whatever interpreter came first on PATH (e.g. Homebrew'spython3on macOS) instead of the project's torch-equipped venv, failing atfind_package_torch_headerswith'NoneType' object has no attribute 'submodule_search_locations'. Pass-DPYTHON_EXECUTABLE="${PYTHON_EXECUTABLE}"so the script's documented behavior actually flows through.Test plan
scripts/build_android_library.shnow succeeds (flatcc no longer fails-Werror).EXECUTORCH_ANDROID_PROFILING=1:-DEXECUTORCH_ANDROID_PROFILINGreaches the JNI compile,ETDumpGenis attached,Module.etdump()returnstrueand writes a valid.etdump.Module.etdump(context.getFilesDir() + "/result.etdump")succeeds; legacyModule.etdump()still works on devices where/data/local/tmpis writable.EXECUTORCH_ANDROID_PROFILINGunset): unchanged —etdump()returnsfalseas before.cmake -DEXECUTORCH_VULKAN_FP16_PRECISION=mediump …(multi-word description STRING option) now configures cleanly.python3and a torch-equipped venv:PYTHON_EXECUTABLE=$VENV/bin/python scripts/build_android_library.shconfigures correctly.🤖 Authored with Claude Code
cc @kirklandsign @cbilgin