跪拜 Guibai
← Back to the summary

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:

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

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.