# Copyright (c) 2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/config/ohos/musl.gni")
import("cjc_toolchain.gni")
declare_args() {
# Enable cjc Source-based Code Coverage.
use_cjc_coverage = false
enable_cjc_mock = false
}
template("_cj_target") {
forward_variables_from(invoker,
[
"cjc_args",
"cj_deps",
"cj_external_deps",
"sources",
"part_name",
"subsystem_name",
"data_deps",
])
if (!defined(invoker.output_type)) {
assert(false && "output_type is required")
}
if (!defined(sources)) {
assert(false && "'sources' is required")
}
output_type = invoker.output_type
if (output_type != "test" && output_type != "macro" &&
output_type != "dylib" && output_type != "staticlib" &&
output_type != "exe") {
assert(false &&
"output_type must be one of [test, macro, dylib, staticlib, exe]")
}
is_cj_test_ = output_type == "test"
if (!defined(cjc_args)) {
cjc_args = []
}
cjc_args_ = []
if (output_type == "dylib") {
cjc_args_ += [
"--dy-std",
]
}
sources_ = sources
sources = []
foreach(src, sources_) {
cjc_args_ += [ rebase_path(src) ]
}
if (enable_cjc_mock == true) {
cjc_args_ += [ "--mock=on" ]
}
# coverage support
if (use_cjc_coverage) {
cjc_args_ += [
"-O0",
"--coverage",
]
} else {
trimpath = rebase_path(get_path_info(sources_[0], "dir"))
cjc_args_ += [
"--trimpath",
trimpath,
]
# cjc only support O0 on arm
if (current_cpu == "arm") {
cjc_args_ += [
"-O0",
"--disable-reflection",
]
} else {
cjc_args_ += [ "-O2" ]
}
if (use_clang_coverage) {
cjc_args_ += [ "-lclang_rt.profile" ]
}
}
package_name = target_name
outname_ = target_name
if (defined(invoker.output_name)) {
outname_ = invoker.output_name
}
base_outdir = "${root_out_dir}/cangjie_libraries"
base_outdir_abs = rebase_path(base_outdir)
outdir = base_outdir
if (package_name != "ohos") {
module_name = string_split(package_name, ".")
outdir = "${base_outdir}/${module_name[0]}"
}
outdir_abs = rebase_path(outdir)
is_library = false
if (output_type == "macro") {
cjc_args_ += [ "--compile-macro" ]
outfile_name = "lib-macro_${outname_}${cjc_toolchain.dyn_extension}"
cjc_args_ += [
"--output-dir",
outdir_abs,
]
is_library = true
} else if (output_type == "test") {
cjc_args_ += [ "--test" ]
outfile_name = "${outname_}${cjc_toolchain.exe_extension}"
cjc_args_ += [
"-o",
"${outdir_abs}/${outfile_name}",
]
} else {
cjc_args_ += [ "--output-type=${output_type}" ]
if (output_type == "dylib") {
is_library = true
outfile_name = "lib${outname_}${cjc_toolchain.dyn_extension}"
} else if (output_type == "staticlib") {
is_library = true
outfile_name = "lib${outname_}${cjc_toolchain.static_extension}"
} else if (output_type == "exe") {
outfile_name = "${outname_}${cjc_toolchain.exe_extension}"
}
cjc_args_ += [
"-o",
"${outdir_abs}/${outfile_name}",
]
}
outputs_ = [ "${outdir}/${outfile_name}" ]
if (is_library) {
outputs_ += [ "${outdir}/${package_name}.cjo" ]
}
cjc_args_ += [ "--target=${cjc_toolchain.target_platform}" ]
if (defined(cjc_toolchain.cjc_args)) {
cjc_args_ += cjc_toolchain.cjc_args
}
deps_ = []
external_deps_ = []
if (defined(invoker.deps)) {
deps_ += invoker.deps
}
if (!defined(cj_deps)) {
cj_deps = []
}
if (!defined(cj_external_deps)) {
cj_external_deps = []
}
# external_deps support
if (defined(invoker.external_deps)) {
external_deps_ += invoker.external_deps
}
cjc_args_ += cjc_args
_cangjie_deps_config = "${target_out_dir}/${target_name}__deps_config.json"
generated_file("${target_name}__deps_config") {
deps = invoker.deps
output_conversion = "json"
outputs = [ _cangjie_deps_config ]
data_keys = [ "cangjie_deps" ]
}
save_config = {
package_name = package_name
outname = outname_
output_type = output_type
cjc_toolchain_config = cjc_toolchain
cangjie_deps_config = rebase_path(_cangjie_deps_config)
outfile = "${outdir_abs}/${outfile_name}"
import_path = base_outdir_abs
args = cjc_args_
native_deps = []
foreach(dep, deps_) {
t_name = get_label_info(dep, "name")
t_out_dir = get_label_info(dep, "target_out_dir")
t_config = rebase_path("${t_out_dir}/${t_name}_module_info.json")
native_deps += [ t_config ]
}
if (external_deps_ != []) {
external_deps = external_deps_
}
cjc_deps = []
foreach(dep, cj_deps) {
t_name = get_label_info(dep, "name")
t_out_dir = get_label_info(dep, "target_out_dir")
t_config = rebase_path("${t_out_dir}/${t_name}_cjc_config.json")
cjc_deps += [ t_config ]
}
foreach(dep, cj_external_deps) {
t_name = get_label_info(dep, "name")
t_out_dir = get_label_info(dep, "target_out_dir")
t_config = rebase_path("${t_out_dir}/${t_name}_cjc_config.json")
cjc_deps += [ t_config ]
}
}
config_path = "${target_out_dir}/${target_name}_cjc_config.json"
config_path_abs = rebase_path(config_path)
write_file(config_path, save_config, "json")
compile_target_name = "compile_cj_target_${target_name}"
action(compile_target_name) {
sources = sources_
depfile = "${target_gen_dir}/${compile_target_name}.d"
script = cjc_wrapper
root_dir_abs = rebase_path(root_build_dir)
args = [
"--config=${config_path_abs}",
"--cjc=${cjc_bin}",
"--root_out_dir=${root_dir_abs}",
]
if (is_mac) {
args += [ "--is_mac=true" ]
}
outputs = outputs_
deps = deps_
if (defined(data_deps)) {
deps += data_deps
}
external_deps = external_deps_
deps += cj_deps
external_deps += cj_external_deps
}
ohos_copy(target_name) {
deps = [ ":${compile_target_name}" ]
sources = [ outputs_[0] ]
if (defined(invoker.part_name)) {
part_name = invoker.part_name
subsystem_name = invoker.subsystem_name
}
prebuilt = true
install_enable = false
if (!is_cj_test_) {
if (output_type == "dylib" || output_type == "exe") {
install_enable = true
}
if (output_type == "exe") {
module_type = "exe"
} else {
module_type = "lib"
}
}
if (is_cj_test_) {
testonly = true
test_out_path =
"${root_out_dir}/tests/unittest/${subsystem_name}/${part_name}"
outputs = [ "${test_out_path}/${outfile_name}" ]
write_file("$test_out_path/${target_name}_path.txt",
get_label_info(":$target_name", "dir"),
"string")
bypass_module_info_generation = true
} else {
outputs = [ "${target_out_dir}/${outfile_name}" ]
}
if (install_enable) {
relative_install_dir = "platformsdk/cjsdk"
innerapi_tags = [ "platformsdk/cjsdk" ]
install_images = [ "system" ]
}
}
if (is_library) {
ohos_copy("${target_name}_cjo") {
prebuilt = true
deps = [ ":${compile_target_name}" ]
sources = [ outputs_[1] ]
outputs = [ "${target_out_dir}/${package_name}.cjo" ]
}
}
}
template("cj_target") {
target("_cj_target", target_name) {
forward_variables_from(invoker, "*", [ "no_default_deps" ])
if (!defined(deps)) {
deps = []
}
if (is_ohos) {
deps += [ "//build/config:common_deps" ]
}
}
}