How to Build Tencent's Mars XLog from Source for 16K Alignment and Custom Log Formats
Tencent Mars XLog is a high-performance on-device logging solution. For an introduction and usage guide, see this article: Tencent XLog Logging Framework Android Integration
Tencent's Mars XLog is a great library, but it has basically stopped updating on GitHub. Its latest release version 1.3.0 dates back 7 years. It neither supports 16K alignment for .so files nor allows specifying the log format. However, its codebase had commits as recently as a year ago, so we can modify and compile it on the latest branch to generate 16K-aligned .so files and achieve the log format we want.
Compilation Environment
My compilation environment is WIN11 + WSL2, with Ubuntu 26.04 installed as the Linux distribution. The compilation software used is as follows:
- NDK version R29
- Python version 3.14.4
- CMake version 4.2.3
WSL2 is indeed a good way to use Linux on Windows, much more convenient than installing a virtual machine. For installing WSL2, see this article: The Best Way to Install WSL
After installation, we also need to install some compilation-related software. Thanks to Ubuntu's package manager, we just need to execute the following commands:
sudo apt update
sudo apt install -y make cmake g++ python3 python3-pip openjdk-17-jdk-headless zip unzip
Downloading the Source Code
Mars' source code is hosted on GitHub: Tencent/mars: Mars is a cross-platform network component developed by WeChat
First, download the source code locally, then choose a suitable branch for compilation. The branch I used here is release/android/2024-t2.1:
Use the following command to switch the code to this branch:
git checkout -b release/android/2024-t2.1 origin/release/android/2024-t2.1
Compilation Process
Mars' Android compilation script is located at: ./mars/build_android.py. In earlier compilation scripts, Python 2 was required, but the latest code already supports Python 3.
Navigate to this directory and execute the file with Python:
avril@LenovoPro16:~/code/mars$ cd mars/
avril@LenovoPro16:~/code/mars/mars$ python3 build_android.py
Enter menu:
1. Clean && build mars.
2. Build incrementally mars.
3. Clean && build xlog.
4. Exit
After running the compilation script, you will see 4 options. We only want to compile xlog, so just enter 3 here.
However, the compilation will definitely fail at this point. We need to modify some files and configure environment variables first.
Configuring the NDK Environment Variable
The NDK used for compilation is version r29, which is relatively new and can be downloaded from this URL: NDK Downloads | Android NDK | Android Developers
After downloading, you can unzip it and then configure the environment variable. Because the build_android.py script reads the NDK_ROOT environment variable, we configure it as follows:
Open the ~/.bashrc file and add the following content at the end:
export NDK_ROOT=~/software/android-sdk/android-ndk-r29 # Your NDK path
After configuration, don't forget:
source .bashrc
Modifying the Compilation Script File
Since the official original build_android.py was compiled using an older version of the NDK and references related files within the NDK, the locations of these files have changed in the new version of the NDK. Therefore, we need to modify this configuration file.
There are three changes:
# 1: Change ANDROID_STL_FILE to:
ANDROID_STL_FILE = {
'armeabi': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so',
'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so',
'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so',
}
# 2: Change ANDROID_STRIP_FILE to:
ANDROID_STRIP_FILE = {
'armeabi': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
}
# 3: In the get_android_strip_cmd(arch) method, change
strip_cmd = ANDROID_STRIP_FILE[arch] %(system_str)
# to:
strip_cmd = ANDROID_STRIP_FILE[arch]
After making the above changes, we also need to modify the CMake compilation options.
Modifying Files to Suppress CMake Warnings
The cmake version used in the official build is too old. When we compile with a new cmake, we encounter many deprecated syntaxes or definitions, and encountering such issues causes the compilation to fail. Therefore, we need to modify the following files to suppress warnings.
mars/build_android.py
Still in this file, we need to find the ANDROID_BUILD_CMD variable and add -DCMAKE_CXX_FLAGS="-Wno-error". The final ANDROID_BUILD_CMD result is as follows:
ANDROID_BUILD_CMD = 'cmake "%s" %s -DANDROID_ABI="%s" ' \
'-DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=%s/build/cmake/android.toolchain.cmake '>
'-DANDROID_TOOLCHAIN=clang -DANDROID_NDK=%s ' \
'-DANDROID_PLATFORM=android-21 ' \
'-DANDROID_STL="c++_shared" ' \
'-DCMAKE_CXX_FLAGS="-Wno-error" ' \
'&& cmake --build . %s --config Release -- -j8'
mars/comm/CMakeExtraFlags.txt
Modify the third line of this file:
# Change the original
set(SELF_EXTRA_FLAGS "-Werror -Wall -Werror=sign-compare -Wtype-limits -Wuninitialized -Wempty-body")
# to
set(SELF_EXTRA_FLAGS "-Werror -Wall -Werror=sign-compare -Wtype-limits -Wuninitialized -Wempty-body -Wno-error=deprecated-builtins -Wno-error=deprecated-declarations -Wno-deprecated-builtins -Wno-deprecated-declarations")
Modifying the exp File
Modify the mars/libraries/mars_android_sdk/jni/export.exp file by deleting three lines:
{
global:
__xlogger_Print_impl; # Delete this line
...
local:
_Z22appender_set_console_logb; # Delete this line
_Z24appender_set_console_logb; # Delete this line
*;
}
These three symbols do not exist or have changed when compiling with the new NDK version. Not deleting them will cause undefined symbol errors during linking.
Among them, __xlogger_Print_impl is the core printing function of XLog, and _Z22appender_set_console_logb and _Z24appender_set_console_logb are C++ compiler-mangled console log switch functions. Under the new NDK compilation environment, the implementations of these symbols have changed, and the export declarations do not match the actual compilation results, so they need to be removed from the export list.
After modifying the above 3 files, the compilation should succeed:
Compilation Result: mars_xlog_sdk Library
The compiled .so files will be placed into the mars_xlog_sdk library. Opening this folder, you will find that it is an Android library module. After compilation is complete, the mars_xlog_sdk/ directory becomes a complete Android Library Module, containing libmarsxlog.so and libc++_shared.so under jni/ (for armeabi-v7a and arm64-v8a architectures).
At this point, you can directly copy this library into your project and have your app module depend on it to use XLog:
If you don't want to directly depend on the mars_xlog_sdk library module, you can compile an AAR directly from this module. Use the following command to generate the AAR:
.\gradlew :mars_xlog_sdk:assembleRelease
After using this command, the mars_xlog_sdk-release.aar file will be generated in the mars_xlog_sdk/build/outputs/aar directory.
Additionally, the official XLog does not provide ProGuard rules, but it is recommended to add a ProGuard file when using it:
# Keep XLog's JNI classes, cannot be obfuscated
-keep class com.tencent.mars.** { *; }
-keep class com.tencent.mars.xlog.** { *; }
# Keep native methods (JNI entry points)
-keepclasseswithmembernames class * {
native <methods>;
}
If you have created your own wrapper for XLog, you also need to retain the wrapper class's package name in the wrapper module's consumer-rules.
Modifying the Log Format
The above covers all the content for compiling XLog. If the goal was only to solve the 16K alignment issue for .so files, the .so files compiled this way are already 16K-aligned. However, compiling from source also gives us greater freedom, such as modifying the log printing format.
Modifying the Log Header Format
The log header content is the file header information automatically written each time a new log file is created, including compilation date, version number, disk space, etc.:
^^^^^^^^^^Jul 30 2026^^^16:07:53^^^^^^^^^^[16710,16710][2026-07-30 +0800 17:01:47]
get mmap time: 1
MARS_URL:
MARS_PATH: release/android/2024-t2.1
MARS_REVISION: 041a3c49
MARS_BUILD_TIME: 2026-07-30 16:07:46
MARS_BUILD_JOB:
log appender mode:0, use mmap:1
cache dir space info, capacity:114502369280 free:61877350400 available:61654315008
log dir space info, capacity:114502369280 free:61877350400 available:61654315008
To modify the format of this part, we need to modify the mars/xlog/src/appender.cc file:
Modifying the Log Prefix Format
The default format for logs printed by XLog is:
[I][2026-07-29 +8.0 19:09:42.286][27360, 2*][xlog_tag][:0, ][Log message: time = 1785323382286, count = 1
[D][2026-07-29 +8.0 19:09:42.287][27360, 2*][xlog_tag][:0, ][Log message: time = 1785323382287, count = 2
[W][2026-07-29 +8.0 19:09:42.288][27360, 2*][xlog_tag][:0, ][Log message: time = 1785323382287, count = 3
[E][2026-07-29 +8.0 19:09:42.288][27360, 2*][xlog_tag][:0, ][Log message: time = 1785323382288, count = 4
- Where
[2026-07-29 +8.0 19:09:42.286]is date + timezone offset (+8.0 = UTC+8) + time (milliseconds) - Where
[27360, 2*]is process ID and thread ID,*indicates the thread is the main thread - Where
[:0, ]is filename and line number, which cannot be obtained in Java
If we need to modify the default prefix when printing logs, we need to modify the mars\xlog\src\formater.cc file:
Modifying the Console Log Format
If we also want to modify the format of logs printed to the console, we need to modify the mars/xlog/jni/ConsoleLog.cc file:
After changing the above content to your desired log format, repackage it again to use your own log format.