Android 16KB 腾讯Mars XLog适配

文章目录

发现网上基本上很少有给出Android16k的XLog相关适配,记录一下windows环境从xlog编译到适配16k相关过程。

编译XLog

本地安装Python3

首先下载Python3.14.2

可以在控制台判断Python是否安装成功

安装NDK

现在xlog官方文档写的是下载ndk-r20,我这边下载安装的是ndk-25,可以去Android官方下载,也可以在AndroidStudio下载(路径在sdk目录的ndk文件夹里)

在环境变量中新建NDK_ROOT,值为NDK目录

然后将NDK_ROOT添加到PATH中

验证NDK安装是否成功

安装CMake

这里可以去CMake官网下载,也可以在AndroidStudio下载,这里选择的版本是3.22.1。

验证安装是否成功

安装cygwin

windows还需要cygwin,从 https://cygwin.com 上下载 setup-x86.exe 或 setup-x86_64.exe。

选择Install from Internet

然后下一步下一步,在"User URL"处输入以下地址:

这里选择阿里云的即可

接着点击下一步

接着选择Full

可以选择自己需要的包进行安装,这里需要make, gcc gdb


最后,点击下一步,即可安装成功。

然后还需要在cygwin下的bin目录配置到环境变量PATH中

进行编译

使用cmd进入mars/mars项目,所有的编译脚本都在mars/mars 目录。

执行下面指令

bash 复制代码
Python build_android.py  

这里有4个选项

如果选择编译Mars,选择1或2,如果仅编译XLog,选择3

这里选择3,稍微等一会,就编译成功了

接着,在mars\libraries\mars_xlog_sdk\libs\armeabi-v7a路径下,就可以看到,我们编译后的so文件了。

因为脚本指定了armeabi-v7a和arm64-v8a所有生成了两个so文件,你可以指定具体生成的文件。

注意事项(会导致编译不过)

  • build_android.py文件中的ANDROID_STL_FILE需要换成你ndk不同cpu架构的so文件路径
  • ANDROID_STRIP_FILE用于指定不同CPU架构(ABI)对应的strip工具路径,目的在于编译完.so动态库之后,剥离调试符号、减小文件体积。你可以发现不执行strip和执行strip,so文件体积大小还是差别挺大的。NDK r19+移除了独立的GCC/Clang toolchain目录结构,NDK 19+所有架构的strip工具都统一为llvm-strip( D:\AndroidSDK\ndk\25.1.8937393\toolchains\llvm\prebuilt\windows-x86_64\bin\llvm-strip.exe)

主要修改代码

py 复制代码
#!/usr/bin/env python3
import os
import sys
import glob
import time
import shutil
import platform

from mars_utils import *


SCRIPT_PATH = os.path.split(os.path.realpath(__file__))[0]

def system_is_windows():
    return platform.system() == 'Windows'

def system_architecture_is64():
    return platform.machine().endswith('64')


if system_is_windows():
    ANDROID_GENERATOR = '-G "Unix Makefiles"'
else:
    ANDROID_GENERATOR = ''

try:
    NDK_ROOT = os.environ['NDK_ROOT']
except KeyError as identifier:
    NDK_ROOT = ''


BUILD_OUT_PATH = 'cmake_build/Android'
ANDROID_LIBS_INSTALL_PATH = BUILD_OUT_PATH + '/'
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" ' \
                    '&& cmake --build . %s --config Release -- -j8'
ANDROID_SYMBOL_PATH = 'libraries/mars_android_sdk/obj/local/'
ANDROID_LIBS_PATH = 'libraries/mars_android_sdk/libs/'
ANDROID_XLOG_SYMBOL_PATH = 'libraries/mars_xlog_sdk/obj/local/'
ANDROID_XLOG_LIBS_PATH = 'libraries/mars_xlog_sdk/libs/'


ANDROID_STRIP_FILE = NDK_ROOT + '/toolchains/llvm/prebuilt/%s/bin/llvm-strip'


ANDROID_STL_FILE = {
        'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
        'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so',
        'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/i686-linux-android/libc++_shared.so',
        'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/%s/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so',
        }


def get_android_strip_cmd():

    system_str = platform.system().lower()
    if (system_architecture_is64()):
        system_str = system_str + '-x86_64'
    else:
        pass

    strip_cmd = ANDROID_STRIP_FILE %(system_str)
    print('Android strip cmd:%s' %(strip_cmd))
    return strip_cmd

def get_android_stl_cmd(arch):

    system_str = platform.system().lower()
    if (system_architecture_is64()):
        system_str = system_str + '-x86_64'
    else:
        pass

    stl_cmd = ANDROID_STL_FILE[arch] %(system_str)
    print('Android stl cmd:%s' %(stl_cmd))
    return stl_cmd

def build_android(incremental, arch, target_option=''):

    before_time = time.time()
    
    clean(BUILD_OUT_PATH, incremental)
    os.chdir(BUILD_OUT_PATH)
    
    build_cmd = ANDROID_BUILD_CMD %(SCRIPT_PATH, ANDROID_GENERATOR, arch, NDK_ROOT, NDK_ROOT, target_option)
    print("build cmd:" + build_cmd)
    ret = os.system(build_cmd)
    os.chdir(SCRIPT_PATH)

    if 0 != ret:
        print('!!!!!!!!!!!!!!!!!!build fail!!!!!!!!!!!!!!!!!!!!')
        return False

    if len(target_option) > 0:
        symbol_path = ANDROID_XLOG_SYMBOL_PATH
        lib_path = ANDROID_XLOG_LIBS_PATH
    else:
        symbol_path = ANDROID_SYMBOL_PATH
        lib_path = ANDROID_LIBS_PATH

    if not os.path.exists(symbol_path):
        os.makedirs(symbol_path)

    symbol_path = symbol_path + arch
    if os.path.exists(symbol_path):
        shutil.rmtree(symbol_path)

    os.mkdir(symbol_path)

    
    if not os.path.exists(lib_path):
        os.makedirs(lib_path)

    lib_path = lib_path + arch
    if os.path.exists(lib_path):
        shutil.rmtree(lib_path)

    os.mkdir(lib_path)


    for f in glob.glob(ANDROID_LIBS_INSTALL_PATH + "*.so"):
        shutil.copy(f, symbol_path)
        shutil.copy(f, lib_path)

    # copy stl
    stl_cmd = get_android_stl_cmd(arch)
    shutil.copy(stl_cmd, symbol_path)
    shutil.copy(stl_cmd, lib_path)


    #strip
    strip_cmd = get_android_strip_cmd()
    for f in glob.glob('%s/*.so' %(lib_path)):
        os.system('%s %s' %(strip_cmd, f))

    print('==================Output========================')
    print('libs(release): %s' %(lib_path))
    print('symbols(must store permanently): %s' %(symbol_path))


    after_time = time.time()

    print("use time:%d s" % (int(after_time - before_time)))
    return True

def main(incremental, archs, target_option='', tag=''):
    if not check_ndk_env():
        return

    gen_mars_revision_file(SCRIPT_PATH + '/comm', tag)

    # if os.path.exists(ANDROID_LIBS_PATH):
    #     shutil.rmtree(ANDROID_LIBS_PATH)

    # if os.path.exists(ANDROID_SYMBOL_PATH):
    #     shutil.rmtree(ANDROID_SYMBOL_PATH)

    for arch in archs:
        if not build_android(incremental, arch, target_option):
            return

if __name__ == '__main__':

    while True:
        if len(sys.argv) >= 3:
            archs = sys.argv[2:]
            main(False, archs, tag=sys.argv[1])
            break
        else:
            archs = {'armeabi-v7a', 'arm64-v8a'}
            num = input('Enter menu:\n1. Clean && build mars.\n2. Build incrementally mars.\n3. Clean && build xlog.\n4. Exit\n')
            if num == '1':
                main(False, archs)
                break
            elif num == '2':
                main(True, archs)
                break
            elif num == '3':
                main(False, archs, '--target libzstd_static marsxlog')
                break
            elif num == '4':
                break
            else:
                main(False, archs)
                break

16k适配

可以参考官方16kB适配地址

Android NDK r28 及更高版本

NDK 版本 r28 及更高版本默认编译为 16 KB 对齐。

Android NDK r27

为了支持使用 Android NDK 版本 r27 及更高版本编译 16 KB 对齐的共享库,您需要按如下方式更新 ndk-build、build.gradle、build.gradle.kts 或链接器标志:

在 build.gradle 文件中,设置实参 -DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON:

bash 复制代码
android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {
      // For ndk-build, instead use the ndkBuild block.
      cmake {
        // Passes optional arguments to CMake.
        arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
      }
    }
  }
}

Android NDK r26 及更低版本

请务必始终更新 NDK。此功能仅应在万不得已时使用,且不保证提供支持。

如需支持使用 Android NDK 版本 r26 或更低版本编译 16 KB 对齐的共享库,您需要按如下方式更新 ndk-build 或 cmake 配置:

更新 CMakeLists.txt 以启用 16 KB ELF 对齐:

c 复制代码
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")

这里使用的是NDK25

c 复制代码
cmake_minimum_required (VERSION 3.6)

set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "Installation directory" FORCE)
message(STATUS "CMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}")

include_directories(openssl/include)

add_subdirectory(comm comm)
add_subdirectory(boot boot)
add_subdirectory(boost boost)
add_subdirectory(app app)
add_subdirectory(baseevent baseevent)
add_subdirectory(xlog xlog)
add_subdirectory(sdt sdt)
add_subdirectory(stn stn)

# for zstd
option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
option(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" OFF)
set(ZSTD_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zstd")
set(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib)
include(GNUInstallDirs)
add_subdirectory(zstd/build/cmake/lib zstd)

project (mars)
#target_link_options(${CMAKE_PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384")
#[[if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    add_compile_options(-Wno-deprecated-builtins)
    add_compile_options(-Wno-error=deprecated-builtins)
    add_compile_options(-Wno-error=deprecated-declarations)
endif()]]

include(comm/CMakeUtils.txt)

include_directories(.)
include_directories(..)

set(SELF_LIBS_OUT ${CMAKE_SYSTEM_NAME}.out)

if(ANDROID)

    if(NATIVE_CALLBACK)
        message("common native callback")
        add_definitions(-DNATIVE_CALLBACK)
    endif()

    find_library(log-lib log)
    find_library(z-lib z)

    link_directories(app baseevent xlog sdt stn comm boost zstd)

    # marsxlog
    set(SELF_LIB_NAME marsxlog)
    file(GLOB SELF_SRC_FILES libraries/mars_android_sdk/jni/JNI_OnLoad.cc
            libraries/mars_xlog_sdk/jni/import.cc)
    add_library(${SELF_LIB_NAME} SHARED ${SELF_SRC_FILES})
    set_target_properties(${SELF_LIB_NAME} PROPERTIES LINK_FLAGS "-Wl,-z,max-page-size=16384")
    install(TARGETS ${SELF_LIB_NAME} LIBRARY DESTINATION ${SELF_LIBS_OUT} ARCHIVE DESTINATION ${SELF_LIBS_OUT})
    get_filename_component(EXPORT_XLOG_EXP_FILE libraries/mars_android_sdk/jni/export.exp ABSOLUTE)
    set(SELF_XLOG_LINKER_FLAG "-Wl,--gc-sections -Wl,--version-script='${EXPORT_XLOG_EXP_FILE}'") 
    if(ANDROID_ABI STREQUAL "x86_64" OR ANDROID_ABI STREQUAL "x86")
        set(SELF_XLOG_LINKER_FLAG "-Wl,--gc-sections -Wl,--version-script='${EXPORT_XLOG_EXP_FILE}' -Wl,--no-warn-shared-textrel") 
    endif()
    target_link_libraries(${SELF_LIB_NAME} "${SELF_XLOG_LINKER_FLAG}"
                            xlog
                            mars-boost
                            comm
                            libzstd_static
                            ${log-lib}
                            ${z-lib}
                            )
 
    # marsstn
    set(SELF_LIB_NAME marsstn)
    file(GLOB SELF_SRC_FILES libraries/mars_android_sdk/jni/*.cc)
    add_library(${SELF_LIB_NAME} SHARED ${SELF_SRC_FILES})
    set_target_properties(${SELF_LIB_NAME} PROPERTIES LINK_FLAGS "-Wl,-z,max-page-size=16384")
    install(TARGETS ${SELF_LIB_NAME} LIBRARY DESTINATION ${SELF_LIBS_OUT} ARCHIVE DESTINATION ${SELF_LIBS_OUT})
    link_directories(${SELF_LIBS_OUT})
    find_library(CRYPT_LIB crypto PATHS openssl/openssl_lib_android/${ANDROID_ABI} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
    find_library(SSL_LIB ssl PATHS openssl/openssl_lib_android/${ANDROID_ABI} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
    target_link_libraries(${SELF_LIB_NAME} "-Wl,--gc-sections"
                        ${log-lib}
                        stn
                        sdt
                        app
                        baseevent
                        comm
                        boot
                        mars-boost
                        marsxlog
                        libzstd_static
                        ${SSL_LIB}
                        ${CRYPT_LIB})
endif()

这里在marsxlog和marsstn里的add_library之后加上了 set_target_properties(${SELF_LIB_NAME} PROPERTIES LINK_FLAGS "-Wl,-z,max-page-size=16384")

为什么用 set_target_properties(... LINK_FLAGS ...) 而不是target_link_options?

  • 声明了 cmake_minimum_required(VERSION 3.6)
  • target_link_options() 是 CMake 3.13+ 才引入的
  • 在 CMake 3.6 中使用它会导致 配置失败
  • set_target_properties(... LINK_FLAGS ...) 是 CMake 2.8+ 就支持的旧式方法,完全兼容

实际上如果你使用的是NDK28基本上按官网说的就一步到位了。

最后可以通过在google应用市场下载Libcheker,可以帮忙分析我们的app支不支持16kb,比较方便快捷。

看到标有16kb标签的so文件说明适配好了

相关推荐
2501_915921432 小时前
不用 Xcode 上架 iOS,拆分流程多工具协作完成 iOS 应用的发布准备与提交流程
android·macos·ios·小程序·uni-app·iphone·xcode
子木鑫2 小时前
[SUCTF2019 & GXYCTF2019] 文件上传绕过实战:图片马 + .user.ini / .htaccess 构造 PHP 后门
android·开发语言·安全·php
一起养小猫2 小时前
Flutter for OpenHarmony 实战:打造功能完整的记账助手应用
android·前端·flutter·游戏·harmonyos
_乐无2 小时前
Unity 发布 Android 安卓端所有文件可读写
android·unity·游戏引擎
User_芊芊君子3 小时前
【LeetCode原地复写零】:双指针+逆向填充,O(n)时间O(1)空间最优解!
android·linux·leetcode
2501_944448005 小时前
Flutter for OpenHarmony衣橱管家App实战:支持我们功能实现
android·javascript·flutter
2601_9498333914 小时前
flutter_for_openharmony口腔护理app实战+预约管理实现
android·javascript·flutter
2603_9494621016 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
王泰虎18 小时前
安卓开发日记,因为JCenter 关闭导致加载不了三方库应该怎么办
android