安卓so下,cmake编译系统,如何仅导出指定符号

安卓下的so,由于需要链接第三方lib库,导出符号时,总是会将第三方的符号也导出了。

根据LD链接,可以指定相应的version_script,简化的version_script为如下格式:

{
global:
XXXXXXXXXXX;
YYYYYYYYYYYY;
local:*;
};
XXXXXXXXXXX与YYYYYYYYYYYY即需要导出的符号。
研究了一下,利用nm.exe与awk.exe,实现了在windows下交叉编译时,只导出指定符号

关键代码行:
add_custom_command(TARGET abcd PRE_LINK
            COMMAND ${ANDROID_NDK}/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-nm.exe -g "\$(abcd_OBJECTS)"  > ${CMAKE_CURRENT_BINARY_DIR}/cwCrypt_${ANDROID_ABI}.txt
            COMMAND ..\\..\\..\\..\\awk.exe \"BEGIN{print(\\"{\\nglobal\:\\")} / T /{print $$NF,\\"\;\\"} END {print(\\"local\:\*\;}\\\;\\")}\" ${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.txt > ${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.def
            COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.txt )

这儿的abcd,即将要链接出来的so文件,默认只导出编译abcd时指定的目标文件中的符号;

利用awk的/ T /过滤掉非导出的符号

这儿会生成一个abcd_armv8.txt及abcd_armv8.def

此命令后会删除txt文件,相应def文件则使用如下命令来删除

add_custom_command(TARGET abcd POST_BUILD COMMAND ${CMAKE_COMMAND} -E remove -f ${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.def)

使用相应的def文件可以有两种实现方式,如下:

#set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.def\" ${CMAKE_SHARED_LINKER_FLAGS}")
set_target_properties(abcd PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_BINARY_DIR}/abcd_${ANDROID_ABI}.def\"")

如此后,编译出来的so文件,将只剩下编译库时中指定导出的符号,其余符号均会被隐藏为内部符号

 

 



 

posted @ 2020-05-19 11:15  日月王  阅读(1162)  评论(5编辑  收藏  举报