Skip to content

Commit 44b2137

Browse files
authored
feat: add support for Android in MLC script (#130)
* feat: add support for Android in MLC script * fix
1 parent a749481 commit 44b2137

1 file changed

Lines changed: 132 additions & 3 deletions

File tree

packages/mlc/scripts/build-runtime.sh

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,19 @@ while [[ $# -gt 0 ]]; do
3333
echo " brew install git-lfs && git lfs install"
3434
echo " 2. For iOS builds - Install Metal toolchain:"
3535
echo " xcodebuild -downloadComponent MetalToolchain"
36-
echo " 3. Clone MLC LLM repository with submodules:"
36+
echo " 3. For Android builds - Install additional dependencies:"
37+
echo " - Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
38+
echo " - Android Studio with NDK 27.0.11718014"
39+
echo " - JDK >= 17 (preferably Android Studio's bundled JBR)"
40+
echo " - Set environment variables: ANDROID_NDK, TVM_NDK_CC, JAVA_HOME, TVM_SOURCE_DIR"
41+
echo " 4. Clone MLC LLM repository with submodules:"
3742
echo " # Fresh clone (recommended):"
3843
echo " git clone --recursive https://github.com/mlc-ai/mlc-llm.git"
3944
echo " # Or if already cloned without --recursive:"
4045
echo " cd mlc-llm && git submodule update --init --recursive"
41-
echo " 4. Set environment variable:"
46+
echo " 5. Set environment variable:"
4247
echo " export MLC_LLM_SOURCE_DIR=/path/to/mlc-llm"
43-
echo " 5. Install MLC Python package:"
48+
echo " 6. Install MLC Python package:"
4449
echo " pip install --pre -U -f https://mlc.ai/wheels mlc-llm-cpu mlc-ai-cpu"
4550
exit 0
4651
;;
@@ -67,6 +72,7 @@ fi
6772
# Get script directory
6873
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6974
PACKAGE_DIR="$(dirname "$SCRIPT_DIR")"
75+
BUILD_DIR="$PACKAGE_DIR/build"
7076
CONFIG_FILE="$PACKAGE_DIR/mlc-package-config-$PLATFORM.json"
7177
OUTPUT_DIR="$PACKAGE_DIR/prebuilt/$PLATFORM"
7278

@@ -122,6 +128,109 @@ if [ ! -d "$MLC_LLM_SOURCE_DIR" ]; then
122128
exit 1
123129
fi
124130

131+
# Android-specific checks
132+
if [ "$PLATFORM" = "android" ]; then
133+
echo "Checking Android prerequisites..."
134+
135+
# Check for Rust
136+
if ! command -v rustc > /dev/null 2>&1 || ! command -v cargo > /dev/null 2>&1 || ! command -v rustup > /dev/null 2>&1; then
137+
echo -e "${RED}Error: Rust toolchain not found${NC}"
138+
echo ""
139+
echo "Rust is required to cross-compile HuggingFace tokenizers to Android."
140+
echo "Please install Rust from https://rustup.rs/ and ensure rustc, cargo, and rustup are in \$PATH"
141+
exit 1
142+
fi
143+
144+
# Check for ANDROID_NDK
145+
if [ -z "$ANDROID_NDK" ]; then
146+
echo -e "${RED}Error: ANDROID_NDK environment variable not set${NC}"
147+
echo ""
148+
echo "Please install Android Studio with NDK and set up environment variables:"
149+
echo " 1. Install Android Studio from https://developer.android.com/studio"
150+
echo " 2. Install NDK via SDK Manager → SDK Tools → NDK"
151+
echo " 3. Set ANDROID_NDK environment variable:"
152+
echo ""
153+
echo "Example paths:"
154+
echo " macOS: export ANDROID_NDK=\$HOME/Library/Android/sdk/ndk/27.0.11718014"
155+
echo " Linux: export ANDROID_NDK=\$HOME/Android/Sdk/ndk/27.0.11718014"
156+
echo " Windows: export ANDROID_NDK=%HOME%/AppData/Local/Android/Sdk/ndk/27.0.11718014"
157+
exit 1
158+
fi
159+
160+
if [ ! -d "$ANDROID_NDK" ]; then
161+
echo -e "${RED}Error: ANDROID_NDK directory does not exist: $ANDROID_NDK${NC}"
162+
exit 1
163+
fi
164+
165+
if [ ! -f "$ANDROID_NDK/build/cmake/android.toolchain.cmake" ]; then
166+
echo -e "${RED}Error: Android NDK toolchain not found at: $ANDROID_NDK/build/cmake/android.toolchain.cmake${NC}"
167+
echo "Please ensure you have installed the correct NDK version."
168+
exit 1
169+
fi
170+
171+
# Check for TVM_NDK_CC
172+
if [ -z "$TVM_NDK_CC" ]; then
173+
echo -e "${RED}Error: TVM_NDK_CC environment variable not set${NC}"
174+
echo ""
175+
echo "Please set TVM_NDK_CC to point to NDK's clang compiler:"
176+
echo ""
177+
echo "Example paths:"
178+
echo " macOS: export TVM_NDK_CC=\$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android24-clang"
179+
echo " Linux: export TVM_NDK_CC=\$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang"
180+
echo " Windows: export TVM_NDK_CC=\$ANDROID_NDK/toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android24-clang"
181+
exit 1
182+
fi
183+
184+
if [ ! -f "$TVM_NDK_CC" ]; then
185+
echo -e "${RED}Error: TVM_NDK_CC compiler not found: $TVM_NDK_CC${NC}"
186+
exit 1
187+
fi
188+
189+
# Check for JAVA_HOME
190+
if [ -z "$JAVA_HOME" ]; then
191+
echo -e "${RED}Error: JAVA_HOME environment variable not set${NC}"
192+
echo ""
193+
echo "Please install JDK >= 17 and set JAVA_HOME:"
194+
echo "We recommend using the JDK bundled with Android Studio:"
195+
echo ""
196+
echo "Example paths:"
197+
echo " macOS: export JAVA_HOME=/Applications/Android\\ Studio.app/Contents/jbr/Contents/Home"
198+
echo " Linux: export JAVA_HOME=/opt/android-studio/jbr"
199+
echo ""
200+
echo "Make sure \$JAVA_HOME/bin/java exists and JDK version matches Android Studio's JBR."
201+
exit 1
202+
fi
203+
204+
if [ ! -f "$JAVA_HOME/bin/java" ]; then
205+
echo -e "${RED}Error: Java binary not found: $JAVA_HOME/bin/java${NC}"
206+
echo "Please verify your JAVA_HOME path is correct."
207+
exit 1
208+
fi
209+
210+
# Check Java version (should be >= 17)
211+
JAVA_VERSION=$("$JAVA_HOME/bin/java" -version 2>&1 | grep -oP 'version "([0-9]+)' | grep -oP '[0-9]+' | head -1)
212+
if [ -n "$JAVA_VERSION" ] && [ "$JAVA_VERSION" -gt 0 ] 2>/dev/null && [ "$JAVA_VERSION" -lt 17 ]; then
213+
echo -e "${YELLOW}Warning: Java version is $JAVA_VERSION, but >= 17 is recommended${NC}"
214+
fi
215+
216+
# Check for TVM_SOURCE_DIR
217+
if [ -z "$TVM_SOURCE_DIR" ]; then
218+
echo -e "${RED}Error: TVM_SOURCE_DIR environment variable not set${NC}"
219+
echo ""
220+
echo "Please set TVM_SOURCE_DIR to point to the TVM runtime:"
221+
echo " export TVM_SOURCE_DIR=$MLC_LLM_SOURCE_DIR/3rdparty/tvm"
222+
exit 1
223+
fi
224+
225+
if [ ! -d "$TVM_SOURCE_DIR" ]; then
226+
echo -e "${RED}Error: TVM_SOURCE_DIR directory does not exist: $TVM_SOURCE_DIR${NC}"
227+
echo "Expected path: $MLC_LLM_SOURCE_DIR/3rdparty/tvm"
228+
exit 1
229+
fi
230+
231+
echo -e "${GREEN}✅ Android prerequisites verified${NC}"
232+
fi
233+
125234
# Check for submodules
126235
if [ ! -f "$MLC_LLM_SOURCE_DIR/3rdparty/tvm/CMakeLists.txt" ] || [ ! -f "$MLC_LLM_SOURCE_DIR/3rdparty/tokenizers-cpp/CMakeLists.txt" ]; then
127236
echo -e "${RED}Error: MLC LLM submodules not initialized${NC}"
@@ -145,6 +254,26 @@ if ! python3 -m mlc_llm --help > /dev/null 2>&1; then
145254
exit 1
146255
fi
147256

257+
# Check for conflicting build artifacts from other platforms
258+
if [ -f "$BUILD_DIR/CMakeCache.txt" ]; then
259+
# Check if this is an Xcode/iOS build when building for Android
260+
if [ "$PLATFORM" = "android" ] && grep -q "Xcode" "$BUILD_DIR/CMakeCache.txt" 2>/dev/null; then
261+
echo -e "${YELLOW}Warning: Detected Xcode/iOS build artifacts in $BUILD_DIR${NC}"
262+
echo "This can cause CMake cache conflicts for Android builds."
263+
echo "Cleaning build directory..."
264+
rm -rf "$BUILD_DIR"
265+
echo -e "${GREEN}Build directory cleaned${NC}"
266+
fi
267+
# Check if this is an Android build when building for iOS
268+
if [ "$PLATFORM" = "ios" ] && grep -q "Android" "$BUILD_DIR/CMakeCache.txt" 2>/dev/null; then
269+
echo -e "${YELLOW}Warning: Detected Android build artifacts in $BUILD_DIR${NC}"
270+
echo "This can cause CMake cache conflicts for iOS builds."
271+
echo "Cleaning build directory..."
272+
rm -rf "$BUILD_DIR"
273+
echo -e "${GREEN}Build directory cleaned${NC}"
274+
fi
275+
fi
276+
148277
# Create output directory
149278
mkdir -p "$OUTPUT_DIR"
150279

0 commit comments

Comments
 (0)