mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Add OpenHarmony support to mach and CI (#32507)
* Add ohos to mach Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> * Add OpenHarmony build to CI * Rename ohos sdk action I decided to rename the upstream ohos sdk action to setup-ohos-sdk, making it clearer that is a github action repository. Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> * Remove commented line Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> --------- Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com> Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
parent
bea181f5d5
commit
3381f2a704
6 changed files with 250 additions and 2 deletions
7
.github/workflows/dispatch-workflow.yml
vendored
7
.github/workflows/dispatch-workflow.yml
vendored
|
@ -57,3 +57,10 @@ jobs:
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
with:
|
with:
|
||||||
profile: ${{ inputs.profile }}
|
profile: ${{ inputs.profile }}
|
||||||
|
|
||||||
|
ohos:
|
||||||
|
if: ${{ inputs.workflow == 'ohos' }}
|
||||||
|
name: OpenHarmony
|
||||||
|
uses: ./.github/workflows/ohos.yml
|
||||||
|
with:
|
||||||
|
profile: ${{ inputs.profile }}
|
||||||
|
|
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
|
@ -46,6 +46,13 @@ jobs:
|
||||||
profile: "release"
|
profile: "release"
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
|
build-ohos:
|
||||||
|
name: OpenHarmony
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
uses: ./.github/workflows/ohos.yml
|
||||||
|
with:
|
||||||
|
profile: "release"
|
||||||
|
|
||||||
build-result:
|
build-result:
|
||||||
name: Result
|
name: Result
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -56,6 +63,7 @@ jobs:
|
||||||
- "build-mac"
|
- "build-mac"
|
||||||
- "build-linux"
|
- "build-linux"
|
||||||
- "build-android"
|
- "build-android"
|
||||||
|
- "build-ohos"
|
||||||
steps:
|
steps:
|
||||||
- name: Merge build timings
|
- name: Merge build timings
|
||||||
uses: actions/upload-artifact/merge@v4
|
uses: actions/upload-artifact/merge@v4
|
||||||
|
|
72
.github/workflows/ohos.yml
vendored
Normal file
72
.github/workflows/ohos.yml
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
name: OpenHarmony
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
profile:
|
||||||
|
required: false
|
||||||
|
default: "release"
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
profile:
|
||||||
|
required: false
|
||||||
|
default: "release"
|
||||||
|
type: choice
|
||||||
|
description: "Cargo build profile"
|
||||||
|
options: [ "release", "debug", "production"]
|
||||||
|
|
||||||
|
env:
|
||||||
|
RUST_BACKTRACE: 1
|
||||||
|
SHELL: /bin/bash
|
||||||
|
SCCACHE_GHA_ENABLED: "true"
|
||||||
|
RUSTC_WRAPPER: "sccache"
|
||||||
|
CCACHE: "sccache"
|
||||||
|
CARGO_INCREMENTAL: 0
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: OpenHarmony Build
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch: ['aarch64-unknown-linux-ohos']
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
if: github.event_name != 'issue_comment' && github.event_name != 'pull_request_target'
|
||||||
|
with:
|
||||||
|
fetch-depth: 2
|
||||||
|
# This is necessary to checkout the pull request if this run was triggered
|
||||||
|
# via an `issue_comment` action on a pull request.
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
if: github.event_name == 'issue_comment' || github.event_name == 'pull_request_target'
|
||||||
|
with:
|
||||||
|
ref: refs/pull/${{ github.event.issue.number || github.event.number }}/head
|
||||||
|
fetch-depth: 2
|
||||||
|
- name: Run sccache-cache
|
||||||
|
uses: mozilla-actions/sccache-action@v0.0.4
|
||||||
|
- name: Install taplo
|
||||||
|
uses: baptiste0928/cargo-install@v3
|
||||||
|
with:
|
||||||
|
crate: taplo-cli
|
||||||
|
locked: true
|
||||||
|
- name: Bootstrap Python
|
||||||
|
run: python3 -m pip install --upgrade pip virtualenv
|
||||||
|
- name: Bootstrap dependencies
|
||||||
|
run: sudo apt update && python3 ./mach bootstrap
|
||||||
|
- name: Setup OpenHarmony SDK
|
||||||
|
id: setup_sdk
|
||||||
|
uses: openharmony-rs/setup-ohos-sdk@v0.1
|
||||||
|
with:
|
||||||
|
version: "4.1"
|
||||||
|
- name: Build (arch ${{ matrix.arch }} profile ${{ inputs.profile }})
|
||||||
|
env:
|
||||||
|
OHOS_SDK_NATIVE: ${{ steps.setup_sdk.outputs.ohos_sdk_native }}
|
||||||
|
run: |
|
||||||
|
python3 ./mach build --locked --target ${{ matrix.arch }} --${{ inputs.profile }}
|
||||||
|
cp -r target/cargo-timings target/cargo-timings-ohos-${{ matrix.arch }}
|
||||||
|
- name: Archive build timing
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: cargo-timings-ohos-${{ matrix.arch }}
|
||||||
|
# Using a wildcard here ensures that the archive includes the path.
|
||||||
|
path: target/cargo-timings-*
|
|
@ -10,6 +10,9 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import errno
|
||||||
|
import json
|
||||||
|
import pathlib
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
import functools
|
import functools
|
||||||
|
@ -32,6 +35,7 @@ from glob import glob
|
||||||
from os import path
|
from os import path
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
from xml.etree.ElementTree import XML
|
from xml.etree.ElementTree import XML
|
||||||
|
from packaging.version import parse as parse_version
|
||||||
|
|
||||||
import toml
|
import toml
|
||||||
|
|
||||||
|
@ -310,6 +314,9 @@ class CommandBase(object):
|
||||||
self.config["android"].setdefault("ndk", "")
|
self.config["android"].setdefault("ndk", "")
|
||||||
self.config["android"].setdefault("toolchain", "")
|
self.config["android"].setdefault("toolchain", "")
|
||||||
|
|
||||||
|
self.config.setdefault("ohos", {})
|
||||||
|
self.config["ohos"].setdefault("ndk", "")
|
||||||
|
|
||||||
# Set default android target
|
# Set default android target
|
||||||
self.setup_configuration_for_android_target("armv7-linux-androideabi")
|
self.setup_configuration_for_android_target("armv7-linux-androideabi")
|
||||||
|
|
||||||
|
@ -343,6 +350,9 @@ class CommandBase(object):
|
||||||
elif target:
|
elif target:
|
||||||
base_path = path.join(base_path, target)
|
base_path = path.join(base_path, target)
|
||||||
|
|
||||||
|
if target is not None and "-ohos" in target:
|
||||||
|
return path.join(base_path, build_type.directory_name(), "libservoshell.so")
|
||||||
|
|
||||||
binary_name = f"servo{servo.platform.get().executable_suffix()}"
|
binary_name = f"servo{servo.platform.get().executable_suffix()}"
|
||||||
binary_path = path.join(base_path, build_type.directory_name(), binary_name)
|
binary_path = path.join(base_path, build_type.directory_name(), binary_name)
|
||||||
|
|
||||||
|
@ -524,6 +534,7 @@ class CommandBase(object):
|
||||||
env["LSAN_OPTIONS"] = f"{env.get('LSAN_OPTIONS', '')}:suppressions={ASAN_LEAK_SUPPRESSION_FILE}"
|
env["LSAN_OPTIONS"] = f"{env.get('LSAN_OPTIONS', '')}:suppressions={ASAN_LEAK_SUPPRESSION_FILE}"
|
||||||
|
|
||||||
self.build_android_env_if_needed(env)
|
self.build_android_env_if_needed(env)
|
||||||
|
self.build_ohos_env_if_needed(env)
|
||||||
|
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
@ -658,6 +669,134 @@ class CommandBase(object):
|
||||||
|
|
||||||
env['PKG_CONFIG_SYSROOT_DIR'] = path.join(llvm_toolchain, 'sysroot')
|
env['PKG_CONFIG_SYSROOT_DIR'] = path.join(llvm_toolchain, 'sysroot')
|
||||||
|
|
||||||
|
def build_ohos_env_if_needed(self, env: Dict[str, str]):
|
||||||
|
if not (self.cross_compile_target and self.cross_compile_target.endswith('-ohos')):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Paths to OpenHarmony SDK and build tools:
|
||||||
|
# Note: `OHOS_SDK_NATIVE` is the CMake variable name the `hvigor` build-system
|
||||||
|
# uses for the native directory of the SDK, so we use the same name to be consistent.
|
||||||
|
if "OHOS_SDK_NATIVE" not in env and self.config["ohos"]["ndk"]:
|
||||||
|
env["OHOS_SDK_NATIVE"] = self.config["ohos"]["ndk"]
|
||||||
|
|
||||||
|
if "OHOS_SDK_NATIVE" not in env:
|
||||||
|
print("Please set the OHOS_SDK_NATIVE environment variable to the location of the `native` directory "
|
||||||
|
"in the OpenHarmony SDK.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
ndk_root = pathlib.Path(env["OHOS_SDK_NATIVE"])
|
||||||
|
|
||||||
|
if not ndk_root.is_dir():
|
||||||
|
print(f"OHOS_SDK_NATIVE is not set to a valid directory: `{ndk_root}`")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
ndk_root = ndk_root.resolve()
|
||||||
|
package_info = ndk_root.joinpath("oh-uni-package.json")
|
||||||
|
try:
|
||||||
|
with open(package_info) as meta_file:
|
||||||
|
meta = json.load(meta_file)
|
||||||
|
ohos_api_version = int(meta['apiVersion'])
|
||||||
|
ohos_sdk_version = parse_version(meta['version'])
|
||||||
|
if ohos_sdk_version < parse_version('4.0'):
|
||||||
|
print("Warning: mach build currently assumes at least the OpenHarmony 4.0 SDK is used.")
|
||||||
|
print(f"Info: The OpenHarmony SDK {ohos_sdk_version} is targeting API-level {ohos_api_version}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to read metadata information from {package_info}")
|
||||||
|
print(f"Exception: {e}")
|
||||||
|
|
||||||
|
# The OpenHarmony SDK for Windows hosts currently does not contain a libclang shared library,
|
||||||
|
# which is required by `bindgen` (see issue
|
||||||
|
# https://gitee.com/openharmony/third_party_llvm-project/issues/I8H50W). Using upstream `clang` is currently
|
||||||
|
# also not easily possible, since `libcxx` support still needs to be upstreamed (
|
||||||
|
# https://github.com/llvm/llvm-project/pull/73114).
|
||||||
|
os_type = platform.system().lower()
|
||||||
|
if os_type not in ["linux", "darwin"]:
|
||||||
|
raise Exception("OpenHarmony builds are currently only supported on Linux and macOS Hosts.")
|
||||||
|
|
||||||
|
llvm_toolchain = ndk_root.joinpath("llvm")
|
||||||
|
llvm_bin = llvm_toolchain.joinpath("bin")
|
||||||
|
ohos_sysroot = ndk_root.joinpath("sysroot")
|
||||||
|
if not (llvm_toolchain.is_dir() and llvm_bin.is_dir()):
|
||||||
|
print(f"Expected to find `llvm` and `llvm/bin` folder under $OHOS_SDK_NATIVE at `{llvm_toolchain}`")
|
||||||
|
sys.exit(1)
|
||||||
|
if not ohos_sysroot.is_dir():
|
||||||
|
print(f"Could not find OpenHarmony sysroot in {ndk_root}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Note: We don't use the `<target_triple>-clang` wrappers on purpose, since
|
||||||
|
# a) the OH 4.0 SDK does not have them yet AND
|
||||||
|
# b) the wrappers in the newer SDKs are bash scripts, which can cause problems
|
||||||
|
# on windows, depending on how the wrapper is called.
|
||||||
|
# Instead, we ensure that all the necessary flags for the c-compiler are set
|
||||||
|
# via environment variables such as `TARGET_CFLAGS`.
|
||||||
|
def to_sdk_llvm_bin(prog: str):
|
||||||
|
if is_windows():
|
||||||
|
prog = prog + '.exe'
|
||||||
|
llvm_prog = llvm_bin.joinpath(prog)
|
||||||
|
if not llvm_prog.is_file():
|
||||||
|
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), llvm_prog)
|
||||||
|
return str(llvm_bin.joinpath(prog))
|
||||||
|
|
||||||
|
# CC and CXX should already be set to appropriate host compilers by `build_env()`
|
||||||
|
env['HOST_CC'] = env['CC']
|
||||||
|
env['HOST_CXX'] = env['CXX']
|
||||||
|
env['TARGET_AR'] = to_sdk_llvm_bin("llvm-ar")
|
||||||
|
env['TARGET_RANLIB'] = to_sdk_llvm_bin("llvm-ranlib")
|
||||||
|
env['TARGET_READELF'] = to_sdk_llvm_bin("llvm-readelf")
|
||||||
|
env['TARGET_OBJCOPY'] = to_sdk_llvm_bin("llvm-objcopy")
|
||||||
|
env['TARGET_STRIP'] = to_sdk_llvm_bin("llvm-strip")
|
||||||
|
|
||||||
|
rust_target_triple = str(self.cross_compile_target).replace('-', '_')
|
||||||
|
ndk_clang = to_sdk_llvm_bin("clang")
|
||||||
|
ndk_clangxx = to_sdk_llvm_bin("clang++")
|
||||||
|
env[f'CC_{rust_target_triple}'] = ndk_clang
|
||||||
|
env[f'CXX_{rust_target_triple}'] = ndk_clangxx
|
||||||
|
# The clang target name is different from the LLVM target name
|
||||||
|
clang_target_triple = str(self.cross_compile_target).replace('-unknown-', '-')
|
||||||
|
clang_target_triple_underscore = clang_target_triple.replace('-', '_')
|
||||||
|
env[f'CC_{clang_target_triple_underscore}'] = ndk_clang
|
||||||
|
env[f'CXX_{clang_target_triple_underscore}'] = ndk_clangxx
|
||||||
|
# rustc linker
|
||||||
|
env[f'CARGO_TARGET_{rust_target_triple.upper()}_LINKER'] = ndk_clang
|
||||||
|
# We could also use a cross-compile wrapper
|
||||||
|
env["RUSTFLAGS"] += f' -Clink-arg=--target={clang_target_triple}'
|
||||||
|
env["RUSTFLAGS"] += f' -Clink-arg=--sysroot={ohos_sysroot}'
|
||||||
|
|
||||||
|
env['HOST_CFLAGS'] = ''
|
||||||
|
env['HOST_CXXFLAGS'] = ''
|
||||||
|
ohos_cflags = ['-D__MUSL__', f' --target={clang_target_triple}', f' --sysroot={ohos_sysroot}']
|
||||||
|
if clang_target_triple.startswith('armv7-'):
|
||||||
|
ohos_cflags.extend(['-march=armv7-a', '-mfloat-abi=softfp', '-mtune=generic-armv7-a', '-mthumb'])
|
||||||
|
ohos_cflags_str = " ".join(ohos_cflags)
|
||||||
|
env['TARGET_CFLAGS'] = ohos_cflags_str
|
||||||
|
env['TARGET_CPPFLAGS'] = '-D__MUSL__'
|
||||||
|
env['TARGET_CXXFLAGS'] = ohos_cflags_str
|
||||||
|
|
||||||
|
# CMake related flags
|
||||||
|
cmake_toolchain_file = ndk_root.joinpath("build", "cmake", "ohos.toolchain.cmake")
|
||||||
|
if cmake_toolchain_file.is_file():
|
||||||
|
env[f'CMAKE_TOOLCHAIN_FILE_{rust_target_triple}'] = str(cmake_toolchain_file)
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"Warning: Failed to find the OpenHarmony CMake Toolchain file - Expected it at {cmake_toolchain_file}")
|
||||||
|
env[f'CMAKE_C_COMPILER_{rust_target_triple}'] = ndk_clang
|
||||||
|
env[f'CMAKE_CXX_COMPILER_{rust_target_triple}'] = ndk_clangxx
|
||||||
|
|
||||||
|
# pkg-config
|
||||||
|
pkg_config_path = '{}:{}'.format(str(ohos_sysroot.joinpath("usr", "lib", "pkgconfig")),
|
||||||
|
str(ohos_sysroot.joinpath("usr", "share", "pkgconfig")))
|
||||||
|
env[f'PKG_CONFIG_SYSROOT_DIR_{rust_target_triple}'] = str(ohos_sysroot)
|
||||||
|
env[f'PKG_CONFIG_PATH_{rust_target_triple}'] = pkg_config_path
|
||||||
|
|
||||||
|
# bindgen / libclang-sys
|
||||||
|
env["LIBCLANG_PATH"] = path.join(llvm_toolchain, "lib")
|
||||||
|
env["CLANG_PATH"] = ndk_clangxx
|
||||||
|
env[f'CXXSTDLIB_{clang_target_triple_underscore}'] = "c++"
|
||||||
|
bindgen_extra_clangs_args_var = f'BINDGEN_EXTRA_CLANG_ARGS_{rust_target_triple}'
|
||||||
|
bindgen_extra_clangs_args = env.get(bindgen_extra_clangs_args_var, "")
|
||||||
|
bindgen_extra_clangs_args = bindgen_extra_clangs_args + " " + ohos_cflags_str
|
||||||
|
env[bindgen_extra_clangs_args_var] = bindgen_extra_clangs_args
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def common_command_arguments(build_configuration=False, build_type=False):
|
def common_command_arguments(build_configuration=False, build_type=False):
|
||||||
decorators = []
|
decorators = []
|
||||||
|
@ -867,6 +1006,12 @@ class CommandBase(object):
|
||||||
args += ["--target", target_override]
|
args += ["--target", target_override]
|
||||||
elif self.cross_compile_target:
|
elif self.cross_compile_target:
|
||||||
args += ["--target", self.cross_compile_target]
|
args += ["--target", self.cross_compile_target]
|
||||||
|
# The same would apply to android once we merge the jniapi into servoshell
|
||||||
|
if '-ohos' in self.cross_compile_target:
|
||||||
|
# Note: in practice `cargo rustc` should just be used unconditionally.
|
||||||
|
assert command != 'build', "For Android / OpenHarmony `cargo rustc` must be used instead of cargo build"
|
||||||
|
if command == 'rustc':
|
||||||
|
args += ["--lib", "--crate-type=cdylib"]
|
||||||
|
|
||||||
if "-p" not in cargo_args: # We're building specific package, that may not have features
|
if "-p" not in cargo_args: # We're building specific package, that may not have features
|
||||||
features = list(self.features)
|
features = list(self.features)
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Workflow(str, Enum):
|
||||||
MACOS = "macos"
|
MACOS = "macos"
|
||||||
WINDOWS = "windows"
|
WINDOWS = "windows"
|
||||||
ANDROID = "android"
|
ANDROID = "android"
|
||||||
|
OHOS = "ohos"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -95,6 +96,8 @@ def handle_preset(s: str) -> Optional[JobConfig]:
|
||||||
return JobConfig("MacOS WPT", Workflow.MACOS, wpt_layout=Layout.layout2020)
|
return JobConfig("MacOS WPT", Workflow.MACOS, wpt_layout=Layout.layout2020)
|
||||||
elif s == "android":
|
elif s == "android":
|
||||||
return JobConfig("Android", Workflow.ANDROID)
|
return JobConfig("Android", Workflow.ANDROID)
|
||||||
|
elif s in ["ohos", "openharmony"]:
|
||||||
|
return JobConfig("OpenHarmony", Workflow.OHOS)
|
||||||
elif s == "webgpu":
|
elif s == "webgpu":
|
||||||
return JobConfig("WebGPU CTS", Workflow.LINUX,
|
return JobConfig("WebGPU CTS", Workflow.LINUX,
|
||||||
wpt_layout=Layout.layout2020, # reftests are mode for new layout
|
wpt_layout=Layout.layout2020, # reftests are mode for new layout
|
||||||
|
@ -135,7 +138,7 @@ class Config(object):
|
||||||
self.fail_fast = True
|
self.fail_fast = True
|
||||||
continue # skip over keyword
|
continue # skip over keyword
|
||||||
if word == "full":
|
if word == "full":
|
||||||
words.extend(["linux-wpt", "macos", "windows", "android"])
|
words.extend(["linux-wpt", "macos", "windows", "android", "ohos"])
|
||||||
continue # skip over keyword
|
continue # skip over keyword
|
||||||
|
|
||||||
job = handle_preset(word)
|
job = handle_preset(word)
|
||||||
|
@ -211,6 +214,14 @@ class TestParser(unittest.TestCase):
|
||||||
"profile": "release",
|
"profile": "release",
|
||||||
"unit_tests": False,
|
"unit_tests": False,
|
||||||
"wpt_tests_to_run": ""
|
"wpt_tests_to_run": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OpenHarmony",
|
||||||
|
"workflow": "ohos",
|
||||||
|
"wpt_layout": "none",
|
||||||
|
"profile": "release",
|
||||||
|
"unit_tests": False,
|
||||||
|
"wpt_tests_to_run": ""
|
||||||
}
|
}
|
||||||
]})
|
]})
|
||||||
|
|
||||||
|
@ -248,7 +259,7 @@ class TestParser(unittest.TestCase):
|
||||||
self.assertEqual(a, JobConfig("Linux", Workflow.LINUX, unit_tests=True))
|
self.assertEqual(a, JobConfig("Linux", Workflow.LINUX, unit_tests=True))
|
||||||
|
|
||||||
def test_full(self):
|
def test_full(self):
|
||||||
self.assertDictEqual(json.loads(Config("linux-wpt macos windows android").to_json()),
|
self.assertDictEqual(json.loads(Config("linux-wpt macos windows android ohos").to_json()),
|
||||||
json.loads(Config("").to_json()))
|
json.loads(Config("").to_json()))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -59,3 +59,8 @@ media-stack = "auto"
|
||||||
# Defaults to the value of $ANDROID_SDK_ROOT, $ANDROID_NDK_ROOT respectively
|
# Defaults to the value of $ANDROID_SDK_ROOT, $ANDROID_NDK_ROOT respectively
|
||||||
#sdk = "/opt/android-sdk"
|
#sdk = "/opt/android-sdk"
|
||||||
#ndk = "/opt/android-ndk"
|
#ndk = "/opt/android-ndk"
|
||||||
|
|
||||||
|
# OpenHarmony
|
||||||
|
[ohos]
|
||||||
|
# Defaults to the value of $OHOS_SDK_NATIVE
|
||||||
|
#ndk = "/path/to/ohos-sdk/<host-os>/native"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue