summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-02-25 17:07:10 +0800
committerGitHub <[email protected]>2025-02-25 17:07:10 +0800
commite789f102f3963a471c94e6da4df1ad70adfa8f9f (patch)
tree48f8961deb103b7152fdac18dd8761955c303d0e
parentfdca3b2904d158ab22f402f647fb9c34eaf2e587 (diff)
parent87693d5c7c360b3218032bc2bff4253a27ad0425 (diff)
Merge pull request #6170 from xmake-io/kotlin
Add kotlin native package support
-rw-r--r--tests/projects/kotlin-native/package/cli-parser/src/main.kt10
-rw-r--r--tests/projects/kotlin-native/package/cli-parser/xmake.lua10
-rw-r--r--tests/projects/kotlin-native/package/json/src/main.kt23
-rw-r--r--tests/projects/kotlin-native/package/json/xmake.lua11
-rw-r--r--xmake/languages/kotlin/load.lua9
-rw-r--r--xmake/languages/kotlin/xmake.lua4
-rw-r--r--xmake/modules/core/tools/kotlinc_native.lua5
-rw-r--r--xmake/modules/package/manager/kotlin-native/configurations.lua58
-rw-r--r--xmake/modules/package/manager/kotlin-native/find_package.lua42
-rw-r--r--xmake/modules/package/manager/kotlin-native/install_package.lua115
-rw-r--r--xmake/rules/kotlin-native/xmake.lua1
11 files changed, 280 insertions, 8 deletions
diff --git a/tests/projects/kotlin-native/package/cli-parser/src/main.kt b/tests/projects/kotlin-native/package/cli-parser/src/main.kt
new file mode 100644
index 000000000..dae11c45c
--- /dev/null
+++ b/tests/projects/kotlin-native/package/cli-parser/src/main.kt
@@ -0,0 +1,10 @@
+import kotlinx.cli.ArgParser
+import kotlinx.cli.ArgType
+import kotlinx.cli.default
+
+fun main(args: Array<String>) {
+ val parser = ArgParser("example")
+ val name by parser.option(ArgType.String, shortName = "n", description = "Your name").default("World")
+ parser.parse(args)
+ println("Hello, $name!")
+}
diff --git a/tests/projects/kotlin-native/package/cli-parser/xmake.lua b/tests/projects/kotlin-native/package/cli-parser/xmake.lua
new file mode 100644
index 000000000..f2cfdac2b
--- /dev/null
+++ b/tests/projects/kotlin-native/package/cli-parser/xmake.lua
@@ -0,0 +1,10 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("kotlin-native")
+add_requires("kotlin-native::org.jetbrains.kotlinx:kotlinx-cli 0.3.6", {alias = "kotlinx-cli"})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.kt")
+ add_packages("kotlinx-cli")
+ set_toolchains("@kotlin-native")
diff --git a/tests/projects/kotlin-native/package/json/src/main.kt b/tests/projects/kotlin-native/package/json/src/main.kt
new file mode 100644
index 000000000..ec15ce26d
--- /dev/null
+++ b/tests/projects/kotlin-native/package/json/src/main.kt
@@ -0,0 +1,23 @@
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+
+@Serializable
+private data class Message(
+ val topic: String,
+ val content: String,
+)
+
+private val PrettyPrintJson = Json {
+ prettyPrint = true
+}
+
+fun main() {
+ val message = Message(
+ topic = "Kotlin/Native",
+ content = "Hello!"
+ )
+ println(PrettyPrintJson.encodeToString(message))
+}
+
+
diff --git a/tests/projects/kotlin-native/package/json/xmake.lua b/tests/projects/kotlin-native/package/json/xmake.lua
new file mode 100644
index 000000000..2f085de15
--- /dev/null
+++ b/tests/projects/kotlin-native/package/json/xmake.lua
@@ -0,0 +1,11 @@
+add_rules("mode.debug", "mode.release")
+
+add_requires("kotlin-native")
+add_requires("kotlin-native::org.jetbrains.kotlinx:kotlinx-serialization-json 1.8.0", {alias = "json"})
+add_requires("kotlin-native::org.jetbrains.kotlinx:kotlinx-serialization-core 1.8.0", {alias = "core"})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.kt")
+ add_packages("json", "core")
+ set_toolchains("@kotlin-native")
diff --git a/xmake/languages/kotlin/load.lua b/xmake/languages/kotlin/load.lua
index 8d7ad0430..7964351ec 100644
--- a/xmake/languages/kotlin/load.lua
+++ b/xmake/languages/kotlin/load.lua
@@ -26,25 +26,26 @@ function _get_apis()
, "target.add_ldflags"
, "target.add_arflags"
, "target.add_shflags"
- , "target.add_rpathdirs" -- @note do not translate path, it's usually an absolute path or contains $ORIGIN/@loader_path
+ , "target.add_links"
-- option.add_xxx
, "option.add_kcflags"
, "option.add_ldflags"
, "option.add_arflags"
, "option.add_shflags"
- , "option.add_rpathdirs"
+ , "option.add_links"
-- toolchain.add_xxx
, "toolchain.add_kcflags"
, "toolchain.add_ldflags"
, "toolchain.add_arflags"
- , "toolchain.add_shflags"
- , "toolchain.add_rpathdirs"
+ , "toolchain.add_links"
}
apis.paths = {
-- target.add_xxx
"target.add_linkdirs"
-- option.add_xxx
, "option.add_linkdirs"
+ -- toolchain.add_xxx
+ , "toolchain.add_linkdirs"
}
return apis
end
diff --git a/xmake/languages/kotlin/xmake.lua b/xmake/languages/kotlin/xmake.lua
index 3269ea6cd..9820531b8 100644
--- a/xmake/languages/kotlin/xmake.lua
+++ b/xmake/languages/kotlin/xmake.lua
@@ -42,12 +42,10 @@ language("kotlin")
, "config.frameworkdirs"
, "target.linkdirs"
, "target.frameworkdirs"
- , "target.rpathdirs"
, "target.strip"
, "target.symbols"
, "toolchain.linkdirs"
, "toolchain.frameworkdirs"
- , "toolchain.rpathdirs"
, "config.frameworks"
, "target.frameworks"
, "toolchain.frameworks"
@@ -63,12 +61,10 @@ language("kotlin")
, "config.frameworkdirs"
, "target.linkdirs"
, "target.frameworkdirs"
- , "target.rpathdirs"
, "target.strip"
, "target.symbols"
, "toolchain.linkdirs"
, "toolchain.frameworkdirs"
- , "toolchain.rpathdirs"
, "config.frameworks"
, "target.frameworks"
, "toolchain.frameworks"
diff --git a/xmake/modules/core/tools/kotlinc_native.lua b/xmake/modules/core/tools/kotlinc_native.lua
index 8c703477c..c785f646f 100644
--- a/xmake/modules/core/tools/kotlinc_native.lua
+++ b/xmake/modules/core/tools/kotlinc_native.lua
@@ -30,6 +30,11 @@ import("lib.detect.find_tool")
function init(self)
end
+-- make the link flag
+function nf_link(self, lib)
+ return {"-l", lib}
+end
+
-- make the build arguments list
function buildargv(self, sourcefiles, targetkind, targetfile, flags, opt)
return self:program(), table.join(flags, sourcefiles, "-o", targetfile)
diff --git a/xmake/modules/package/manager/kotlin-native/configurations.lua b/xmake/modules/package/manager/kotlin-native/configurations.lua
new file mode 100644
index 000000000..ef9a70f38
--- /dev/null
+++ b/xmake/modules/package/manager/kotlin-native/configurations.lua
@@ -0,0 +1,58 @@
+--!A cross-platform build utility based on Lua
+--
+-- 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.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file configurations.lua
+--
+
+-- get architecture for kotlin-native
+function arch(arch)
+ local archs = {
+ x86_64 = "x64",
+ i386 = "x86",
+ ["armeabi-v7a"] = "arm32",
+ ["arm64-v8a"] = "arm64",
+ armv7 = "arm32",
+ armv7s = "arm32"
+ }
+ return archs[arch] or arch
+end
+
+-- get platform for kotlin-native
+function plat(plat)
+ local plats = {
+ macosx = "macos",
+ iphoneos = "ios",
+ appletvos = "tvos",
+ windows = "mingw"
+ }
+ return plats[plat] or plat
+end
+
+-- get triplet
+function triplet(plat, arch)
+ return plat .. arch
+end
+
+-- get configurations
+function main()
+ return {
+ repositories = {description = "set the maven repositories", default = {
+ "https://repo.maven.apache.org/maven2"
+ }}
+ }
+end
+
diff --git a/xmake/modules/package/manager/kotlin-native/find_package.lua b/xmake/modules/package/manager/kotlin-native/find_package.lua
new file mode 100644
index 000000000..da2768306
--- /dev/null
+++ b/xmake/modules/package/manager/kotlin-native/find_package.lua
@@ -0,0 +1,42 @@
+--!A cross-platform build utility based on Lua
+--
+-- 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.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file find_package.lua
+--
+
+-- imports
+import("lib.detect.find_file")
+import("lib.detect.find_tool")
+import("core.base.option")
+import("core.project.config")
+import("core.project.target")
+import("package.manager.kotlin-native.configurations")
+
+-- find package from the kotlin-native package manager
+--
+-- @param name the package name, e.g. org.jetbrains.kotlinx:kotlinx-serialization-json 1.8.0
+-- @param opt the options, e.g. {verbose = true)
+--
+function main(name, opt)
+ opt = opt or {}
+ local result = {}
+ local installdir = assert(opt.installdir, "installdir not found!")
+ local manifest_file = path.join(installdir, "installed_manifest.txt")
+ if os.isfile(manifest_file) then
+ return io.load(manifest_file)
+ end
+end
diff --git a/xmake/modules/package/manager/kotlin-native/install_package.lua b/xmake/modules/package/manager/kotlin-native/install_package.lua
new file mode 100644
index 000000000..ed9cb4ab9
--- /dev/null
+++ b/xmake/modules/package/manager/kotlin-native/install_package.lua
@@ -0,0 +1,115 @@
+--!A cross-platform build utility based on Lua
+--
+-- 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.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file install_package.lua
+--
+
+-- imports
+import("core.base.option")
+import("core.base.global")
+import("core.base.json")
+import("core.base.semver")
+import("lib.detect.find_tool")
+import("package.manager.kotlin-native.configurations")
+import("net.http")
+import("core.base.semver")
+
+-- select package version
+-- e.g. https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json-iosarm64/maven-metadata.xml
+function _select_package_version(name, opt)
+ local installdir = opt.installdir
+ local require_version = opt.require_version
+ local metadata_file = path.join(installdir, "maven-metadata.xml")
+ for _, repository in ipairs(opt.repositories) do
+ local metadata_url = ("%s/%s-%s/maven-metadata.xml"):format(repository, (name:gsub("%.", "/"):gsub(":", "/")), opt.triplet)
+ local ok = try {
+ function()
+ http.download(metadata_url, metadata_file, {
+ insecure = global.get("insecure-ssl")})
+ return true
+ end
+ }
+ if ok and os.isfile(metadata_file) then
+ local metadata = io.readfile(metadata_file)
+ local versions = {}
+ for _, line in ipairs(metadata:split("\n")) do
+ local v = line:match("<version>(.*)</version>")
+ if v then
+ table.insert(versions, v)
+ end
+ end
+ local version = semver.select(require_version, versions)
+ if version then
+ return version, repository
+ end
+ end
+ end
+end
+
+-- install package
+-- e.g. https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-json-iosarm64/1.8.0/kotlinx-serialization-json-iosarm64-1.8.0.klib
+function _install_package(name, opt)
+ local installdir = opt.installdir
+ local basename = name:split(":")[2] .. "-" .. opt.triplet
+ local library_file = path.join(installdir, "klib", "platform", opt.plat .. "_" .. opt.arch, basename .. ".klib")
+ local library_url = ("%s/%s-%s/%s/%s-%s.klib"):format(opt.repository, (name:gsub("%.", "/"):gsub(":", "/")), opt.triplet, opt.version, basename, opt.version)
+ http.download(library_url, library_file, {
+ insecure = global.get("insecure-ssl")})
+
+ local manifest_file = path.join(installdir, "installed_manifest.txt")
+ io.save(manifest_file, {
+ links = library_file,
+ libfiles = library_file,
+ version = opt.version})
+end
+
+-- install package
+--
+-- @param name the package name, e.g. org.jetbrains.kotlinx:kotlinx-serialization-json 1.8.0
+-- @param opt the options, e.g. {verbose = true}
+--
+function main(name, opt)
+ opt = opt or {}
+ local configs = opt.configs or {}
+ local repositories = configs.repositories
+
+ -- init triplet
+ local arch = opt.arch
+ local plat = opt.plat
+ plat = configurations.plat(plat)
+ arch = configurations.arch(arch)
+ local triplet = configurations.triplet(plat, arch)
+
+ -- select version
+ local installdir = assert(opt.installdir, "installdir not found!")
+ local require_version = opt.require_version
+ local version, repository = _select_package_version(name, {
+ triplet = triplet,
+ installdir = installdir,
+ require_version = require_version,
+ repositories = repositories})
+ assert(version and repository, "package(%s): %s not found for %s!", name, require_version, triplet)
+
+ -- do install
+ _install_package(name, {
+ plat = plat,
+ arch = arch,
+ triplet = triplet,
+ installdir = installdir,
+ version = version,
+ repository = repository})
+end
diff --git a/xmake/rules/kotlin-native/xmake.lua b/xmake/rules/kotlin-native/xmake.lua
index 386c85677..f2bd9ed5c 100644
--- a/xmake/rules/kotlin-native/xmake.lua
+++ b/xmake/rules/kotlin-native/xmake.lua
@@ -21,6 +21,7 @@
rule("kotlin-native.build")
set_sourcekinds("kc")
on_load(function (target)
+ target:add("kcflags", "-opt-in=kotlinx.cinterop.ExperimentalForeignApi", {force = true})
if target:is_static() then
target:add("arflags", {"-produce", "static"}, {force = true})
target:add("includedirs", target:targetdir(), {interface = true})