Add example of building TDLib for Android with JSON interface.

This commit is contained in:
levlam 2024-05-13 21:54:55 +03:00
parent 2ede408570
commit f28fa6a860
4 changed files with 62 additions and 30 deletions

View File

@ -2,10 +2,19 @@ cmake_minimum_required(VERSION 3.4.1 FATAL_ERROR)
project(TdAndroid VERSION 1.0 LANGUAGES CXX) project(TdAndroid VERSION 1.0 LANGUAGES CXX)
option(TD_ENABLE_JNI "Enable JNI-compatible TDLib API" ON)
set(TD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..) set(TD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../..)
if (TD_ANDROID_JSON)
if (CMAKE_CROSSCOMPILING)
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -flto=thin -Oz")
list(APPEND CMAKE_FIND_ROOT_PATH "${OPENSSL_ROOT_DIR}")
endif()
add_subdirectory(${TD_DIR} td)
return()
endif()
option(TD_ENABLE_JNI "Enable JNI-compatible TDLib API" ON)
if (CMAKE_CROSSCOMPILING) if (CMAKE_CROSSCOMPILING)
set(CMAKE_MODULE_PATH "${TD_DIR}/CMake") set(CMAKE_MODULE_PATH "${TD_DIR}/CMake")

View File

@ -18,7 +18,8 @@ RUN git clone https://github.com/tdlib/td.git && cd td && git checkout "$COMMIT_
RUN cd td && git merge-base --is-ancestor bcd89728c3b93b67448b93b4863dc5bd4e122a4c "$COMMIT_HASH" RUN cd td && git merge-base --is-ancestor bcd89728c3b93b67448b93b4863dc5bd4e122a4c "$COMMIT_HASH"
ARG ANDROID_STL=c++_static ARG ANDROID_STL=c++_static
RUN td/example/android/build-tdlib.sh SDK "$ANDROID_NDK_VERSION" openssl "$ANDROID_STL" && rm -rf td/example/android/build-* ARG TDLIB_INTERFACE=Java
RUN td/example/android/build-tdlib.sh SDK "$ANDROID_NDK_VERSION" openssl "$ANDROID_STL" "$TDLIB_INTERFACE" && rm -rf td/example/android/build-*
FROM scratch FROM scratch

View File

@ -9,7 +9,7 @@ You need a Bash shell on Linux, macOS, or Windows with some common tools, a C++
* Run the script `./fetch-sdk.sh` to download Android SDK to a local directory. * Run the script `./fetch-sdk.sh` to download Android SDK to a local directory.
* Run the script `./build-openssl.sh` to download and build OpenSSL for Android. * Run the script `./build-openssl.sh` to download and build OpenSSL for Android.
* Run the script `./build-tdlib.sh` to build TDLib for Android. * Run the script `./build-tdlib.sh` to build TDLib for Android.
* The built libraries are now located in the `tdlib/libs` directory, corresponding Java code is located in the `tdlib/java` directory, and standalone Java documentation can be found in the `tdlib/javadoc` directory. You can also use archives `tdlib/tdlib.zip` and `tdlib/tdlib-debug.zip`, which contain all aforementioned data. * The built libraries are now located in the `tdlib/libs` directory. If [Java](https://github.com/tdlib/td#using-java) interface was built, then corresponding Java code is located in the `tdlib/java` directory, and standalone Java documentation can be found in the `tdlib/javadoc` directory. You can also use archives `tdlib/tdlib.zip` and `tdlib/tdlib-debug.zip`, which contain all aforementioned data.
If you already have installed Android SDK and NDK, you can skip the second step and specify existing Android SDK root path and Android NDK version as the first and the second parameters to the subsequent scripts. Make sure that the SDK includes android-34 platform and CMake 3.22.1. If you already have installed Android SDK and NDK, you can skip the second step and specify existing Android SDK root path and Android NDK version as the first and the second parameters to the subsequent scripts. Make sure that the SDK includes android-34 platform and CMake 3.22.1.
@ -21,4 +21,8 @@ You can specify different OpenSSL version as the fourth parameter to the script
You can build TDLib against shared standard C++ library by specifying "c++_shared" as the fourth parameter to the script `./build-tdlib.sh`. This can reduce total application size if you have a lot of other C++ code and want it to use the same shared library. You can build TDLib against shared standard C++ library by specifying "c++_shared" as the fourth parameter to the script `./build-tdlib.sh`. This can reduce total application size if you have a lot of other C++ code and want it to use the same shared library.
Alternatively, you can use Docker to build TDLib for Android. Use `docker build --output tdlib .` to build the latest TDLib commit from Github, or `docker build --build-arg COMMIT_HASH=<commit-hash> --output tdlib .` to build specific commit. The output archives will be placed in the directory "tdlib" as specified. You can build TDLib with [JSON interface](https://github.com/tdlib/td#using-json) instead of [Java](https://github.com/tdlib/td#using-java) interface by passing "JSON" as the fifth parameter to the script `./build-tdlib.sh`.
You can pass an empty string instead of any script parameter to use its default value. For example, you can use the command `./build-tdlib.sh '' '' '' '' 'JSON'` to build TDLib with [JSON interface](https://github.com/tdlib/td#using-json) using default values for other parameters.
Alternatively, you can use Docker to build TDLib for Android. Use `docker build --output tdlib .` to build the latest TDLib commit from Github, or `docker build --build-arg COMMIT_HASH=<commit-hash> --output tdlib .` to build specific commit. The output archives will be placed in the directory "tdlib" as specified. Additionally, you can specify build arguments "TDLIB_INTERFACE", "ANDROID_NDK_VERSION", "OPENSSL_VERSION", and "ANDROID_STL" to the provided Dockerfile. For example, use `docker build --build-arg TDLIB_INTERFACE=JSON --output tdlib .` to build the latest TDLib with JSON interface.

View File

@ -4,12 +4,18 @@ ANDROID_SDK_ROOT=${1:-SDK}
ANDROID_NDK_VERSION=${2:-23.2.8568313} ANDROID_NDK_VERSION=${2:-23.2.8568313}
OPENSSL_INSTALL_DIR=${3:-third-party/openssl} OPENSSL_INSTALL_DIR=${3:-third-party/openssl}
ANDROID_STL=${4:-c++_static} ANDROID_STL=${4:-c++_static}
TDLIB_INTERFACE=${5:-Java}
if [ "$ANDROID_STL" != "c++_static" ] && [ "$ANDROID_STL" != "c++_shared" ] ; then if [ "$ANDROID_STL" != "c++_static" ] && [ "$ANDROID_STL" != "c++_shared" ] ; then
echo 'Error: ANDROID_STL must be either "c++_static" or "c++_shared".' echo 'Error: ANDROID_STL must be either "c++_static" or "c++_shared".'
exit 1 exit 1
fi fi
if [ "$TDLIB_INTERFACE" != "Java" ] && [ "$TDLIB_INTERFACE" != "JSON" ] ; then
echo 'Error: TDLIB_INTERFACE must be either "Java" or "JSON".'
exit 1
fi
source ./check-environment.sh || exit 1 source ./check-environment.sh || exit 1
if [ ! -d "$ANDROID_SDK_ROOT" ] ; then if [ ! -d "$ANDROID_SDK_ROOT" ] ; then
@ -26,45 +32,57 @@ ANDROID_SDK_ROOT="$(cd "$(dirname -- "$ANDROID_SDK_ROOT")" >/dev/null; pwd -P)/$
ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION" ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/ndk/$ANDROID_NDK_VERSION"
OPENSSL_INSTALL_DIR="$(cd "$(dirname -- "$OPENSSL_INSTALL_DIR")" >/dev/null; pwd -P)/$(basename -- "$OPENSSL_INSTALL_DIR")" OPENSSL_INSTALL_DIR="$(cd "$(dirname -- "$OPENSSL_INSTALL_DIR")" >/dev/null; pwd -P)/$(basename -- "$OPENSSL_INSTALL_DIR")"
PATH=$ANDROID_SDK_ROOT/cmake/3.22.1/bin:$PATH PATH=$ANDROID_SDK_ROOT/cmake/3.22.1/bin:$PATH
TDLIB_INTERFACE_OPTION=$([ "$TDLIB_INTERFACE" == "JSON" ] && echo "-DTD_ANDROID_JSON=ON" || echo "")
cd $(dirname $0) cd $(dirname $0)
echo "Downloading annotation Java package..."
rm -f android.jar annotation-1.4.0.jar || exit 1
$WGET https://maven.google.com/androidx/annotation/annotation/1.4.0/annotation-1.4.0.jar || exit 1
echo "Generating TDLib source files..." echo "Generating TDLib source files..."
mkdir -p build-native || exit 1 mkdir -p build-native-$TDLIB_INTERFACE || exit 1
cd build-native cd build-native-$TDLIB_INTERFACE
cmake .. || exit 1 cmake $TDLIB_INTERFACE_OPTION .. || exit 1
cmake --build . --target prepare_cross_compiling || exit 1 cmake --build . --target prepare_cross_compiling || exit 1
cmake --build . --target tl_generate_java || exit 1
cd .. cd ..
php AddIntDef.php org/drinkless/tdlib/TdApi.java || exit 1
echo "Copying Java source files..."
rm -rf tdlib || exit 1 rm -rf tdlib || exit 1
mkdir -p tdlib/java/org/drinkless/tdlib || exit 1
cp -p {../../example,tdlib}/java/org/drinkless/tdlib/Client.java || exit 1
mv {,tdlib/java/}org/drinkless/tdlib/TdApi.java || exit 1
rm -rf org || exit 1
echo "Generating Javadoc documentation..." if [ "$TDLIB_INTERFACE" == "Java" ] ; then
cp "$ANDROID_SDK_ROOT/platforms/android-34/android.jar" . || exit 1 echo "Downloading annotation Java package..."
JAVADOC_SEPARATOR=$([ "$OS_NAME" == "win" ] && echo ";" || echo ":") rm -f android.jar annotation-1.4.0.jar || exit 1
javadoc -d tdlib/javadoc -encoding UTF-8 -charset UTF-8 -classpath "android.jar${JAVADOC_SEPARATOR}annotation-1.4.0.jar" -quiet -sourcepath tdlib/java org.drinkless.tdlib || exit 1 $WGET https://maven.google.com/androidx/annotation/annotation/1.4.0/annotation-1.4.0.jar || exit 1
rm android.jar annotation-1.4.0.jar || exit 1
echo "Generating Java source files..."
cmake --build build-native-$TDLIB_INTERFACE --target tl_generate_java || exit 1
php AddIntDef.php org/drinkless/tdlib/TdApi.java || exit 1
mkdir -p tdlib/java/org/drinkless/tdlib || exit 1
cp -p {../../example,tdlib}/java/org/drinkless/tdlib/Client.java || exit 1
mv {,tdlib/java/}org/drinkless/tdlib/TdApi.java || exit 1
rm -rf org || exit 1
echo "Generating Javadoc documentation..."
cp "$ANDROID_SDK_ROOT/platforms/android-34/android.jar" . || exit 1
JAVADOC_SEPARATOR=$([ "$OS_NAME" == "win" ] && echo ";" || echo ":")
javadoc -d tdlib/javadoc -encoding UTF-8 -charset UTF-8 -classpath "android.jar${JAVADOC_SEPARATOR}annotation-1.4.0.jar" -quiet -sourcepath tdlib/java org.drinkless.tdlib || exit 1
rm android.jar annotation-1.4.0.jar || exit 1
fi
echo "Building TDLib..." echo "Building TDLib..."
for ABI in arm64-v8a armeabi-v7a x86_64 x86 ; do for ABI in arm64-v8a armeabi-v7a x86_64 x86 ; do
mkdir -p build-$ABI || exit 1 mkdir -p tdlib/libs/$ABI/ || exit 1
cd build-$ABI
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake" -DOPENSSL_ROOT_DIR="$OPENSSL_INSTALL_DIR/$ABI" -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja -DANDROID_ABI=$ABI -DANDROID_STL=$ANDROID_STL -DANDROID_PLATFORM=android-16 .. || exit 1 mkdir -p build-$ABI-$TDLIB_INTERFACE || exit 1
cmake --build . || exit 1 cd build-$ABI-$TDLIB_INTERFACE
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake" -DOPENSSL_ROOT_DIR="$OPENSSL_INSTALL_DIR/$ABI" -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja -DANDROID_ABI=$ABI -DANDROID_STL=$ANDROID_STL -DANDROID_PLATFORM=android-16 $TDLIB_INTERFACE_OPTION .. || exit 1
if [ "$TDLIB_INTERFACE" == "Java" ] ; then
cmake --build . --target tdjni || exit 1
cp -p libtd*.so* ../tdlib/libs/$ABI/ || exit 1
fi
if [ "$TDLIB_INTERFACE" == "JSON" ] ; then
cmake --build . --target tdjson || exit 1
cp -p td/libtdjson.so ../tdlib/libs/$ABI/libtdjson.so.debug || exit 1
"$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_ARCH/bin/llvm-strip" --strip-debug --strip-unneeded ../tdlib/libs/$ABI/libtdjson.so.debug -o ../tdlib/libs/$ABI/libtdjson.so || exit 1
fi
cd .. cd ..
mkdir -p tdlib/libs/$ABI/ || exit 1
cp -p build-$ABI/libtd*.so* tdlib/libs/$ABI/ || exit 1
if [[ "$ANDROID_STL" == "c++_shared" ]] ; then if [[ "$ANDROID_STL" == "c++_shared" ]] ; then
if [[ "$ABI" == "arm64-v8a" ]] ; then if [[ "$ABI" == "arm64-v8a" ]] ; then
FULL_ABI="aarch64-linux-android" FULL_ABI="aarch64-linux-android"