Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 32 additions & 15 deletions cmake/onnxruntime.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,25 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
set(OUTPUT_STYLE xcode)
endif()

# This macro is to get the path of header files for mobile packaging, for iOS and Android
macro(get_mobile_api_headers _HEADERS)
# include both c and cxx api
set(${_HEADERS}
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_c_api.h"
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_api.h"
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_inline.h"
)

# need to add header files for enabled EPs
foreach(f ${ONNXRUNTIME_PROVIDER_NAMES})
file(GLOB _provider_headers CONFIGURE_DEPENDS
"${REPO_ROOT}/include/onnxruntime/core/providers/${f}/*.h"
)
list(APPEND ${_HEADERS} "${_provider_headers}")
unset(_provider_headers)
endforeach()
endmacro()

#If you want to verify if there is any extra line in symbols.txt, run
# nm -C -g --defined libonnxruntime.so |grep -v '\sA\s' | cut -f 3 -d ' ' | sort
# after build
Expand All @@ -39,21 +58,7 @@ if(WIN32)
"${ONNXRUNTIME_ROOT}/core/dll/onnxruntime.rc"
)
elseif(onnxruntime_BUILD_APPLE_FRAMEWORK)
# include both c and cxx api
set(APPLE_FRAMEWORK_HEADERS
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_c_api.h"
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_api.h"
"${REPO_ROOT}/include/onnxruntime/core/session/onnxruntime_cxx_inline.h"
)

# need to add header files for enabled EPs
foreach(f ${ONNXRUNTIME_PROVIDER_NAMES})
file(GLOB _provider_headers CONFIGURE_DEPENDS
"${REPO_ROOT}/include/onnxruntime/core/providers/${f}/*.h"
)
list(APPEND APPLE_FRAMEWORK_HEADERS "${_provider_headers}")
unset(_provider_headers)
endforeach()
get_mobile_api_headers(APPLE_FRAMEWORK_HEADERS)

# apple framework requires the header file be part of the library
onnxruntime_add_shared_library(onnxruntime
Expand Down Expand Up @@ -132,6 +137,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android" OR (onnxruntime_MINIMAL_BUILD AND UNIX))
endif()
endif()

# we need to copy C/C++ API headers to be packed into Android AAR package
if(CMAKE_SYSTEM_NAME STREQUAL "Android" AND onnxruntime_BUILD_JAVA)
get_mobile_api_headers(ANDROID_AAR_HEADERS)
set(ANDROID_HEADERS_DIR ${CMAKE_CURRENT_BINARY_DIR}/android/headers)
file(MAKE_DIRECTORY ${ANDROID_HEADERS_DIR})
# copy the header files one by one
foreach(h_ ${ANDROID_AAR_HEADERS})
get_filename_component(HEADER_NAME_ ${h_} NAME)
configure_file(${h_} ${ANDROID_HEADERS_DIR}/${HEADER_NAME_} COPYONLY)
endforeach()
endif()

target_link_libraries(onnxruntime PRIVATE
onnxruntime_session
${onnxruntime_libs}
Expand Down
33 changes: 33 additions & 0 deletions tools/ci_build/github/android/build_aar_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ def _parse_build_settings(args):
return build_settings


# Add ORT C and C++ API headers to the AAR package (in fact a zip file)
# Such that developers using ORT native API can extract libraries and header from AAR package without building ORT
# TODO, see if we can use Gradle to add headers to AAR package directly, which is necessary if we want to
# publish the packagee directly using Gradle in the pipeline
def _add_headers_to_aar(aar_file_path, header_files_path):
import shutil
import tempfile
with tempfile.TemporaryDirectory() as temp_dir:
aar_content = os.path.join(temp_dir, 'aar_content')
shutil.unpack_archive(aar_file_path, aar_content, 'zip')

# copy necessary header files
shutil.copytree(header_files_path, os.path.join(aar_content, 'headers'))

# create the zip archive
zip_base_filename = os.path.join(temp_dir, 'aar_with_headers')
zip_filename = zip_base_filename + '.zip'
shutil.make_archive(zip_base_filename, 'zip', root_dir=aar_content)

# overwrite the existing AAR package
shutil.move(zip_filename, aar_file_path)


def _build_aar(args):
build_settings = _parse_build_settings(args)
build_dir = os.path.abspath(args.build_dir)
Expand All @@ -89,6 +112,7 @@ def _build_aar(args):
_base_build_command = [
sys.executable, BUILD_PY, '--config=' + _build_config
] + build_settings['build_params']
header_files_path = ''

# Build binary for each ABI, one by one
for abi in build_settings['build_abis']:
Expand Down Expand Up @@ -116,6 +140,10 @@ def _build_aar(args):
os.remove(_target_lib_name)
os.symlink(os.path.join(_build_dir, _build_config, lib_name), _target_lib_name)

# we only need to define the header files path once
if not header_files_path:
header_files_path = os.path.join(_build_dir, _build_config, 'android', 'headers')

# The directory to publish final AAR
_aar_publish_dir = os.path.join(build_dir, 'aar_out', _build_config)
os.makedirs(_aar_publish_dir, exist_ok=True)
Expand All @@ -139,6 +167,11 @@ def _build_aar(args):
# clean, build, and publish to a local directory
subprocess.run(_gradle_command + ['clean'], env=_env, shell=_shell, check=True, cwd=JAVA_ROOT)
subprocess.run(_gradle_command + ['build'], env=_env, shell=_shell, check=True, cwd=JAVA_ROOT)

# add C and C++ API headers to the intermediate aar package
aar_file_path = os.path.join(_aar_dir, 'outputs', 'aar', 'onnxruntime-release.aar')
_add_headers_to_aar(aar_file_path, header_files_path)

subprocess.run(_gradle_command + ['publish'], env=_env, shell=_shell, check=True, cwd=JAVA_ROOT)


Expand Down