summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-10-28 10:39:48 +0800
committerGitHub <[email protected]>2025-10-28 10:39:48 +0800
commit961a7f0fe0c630ddc6e56ab192e3035c9479f0fa (patch)
tree7468347e0c6e7310aa0ae7b5bde23307bc8a1ee7
parentd2c54e27de9eb98bd96c262909d31528f44f45cb (diff)
parent2c373c8daa2c916fb24ac1411eb61f828e3bfd2e (diff)
Merge pull request #6967 from Arthapz/add-swift-cxxinterop
feat(swift) add swift to C++ and objective-C interop
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/fibonacci.h6
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/module.modulemap3
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.cpp9
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.swift7
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.cpp7
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.swift3
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/test.lua7
-rw-r--r--tests/projects/swift/bidirectional_cxx_interop_lib/xmake.lua23
-rw-r--r--tests/projects/swift/cxx_interop/lib/fibonacci/fibonacci.swift7
-rw-r--r--tests/projects/swift/cxx_interop/src/fibonacci.cpp7
-rw-r--r--tests/projects/swift/cxx_interop/test.lua7
-rw-r--r--tests/projects/swift/cxx_interop/xmake.lua9
-rw-r--r--tests/projects/swift/cxx_interop_lib/lib/fibonacci/fibonacci.swift7
-rw-r--r--tests/projects/swift/cxx_interop_lib/src/fibonacci.cpp7
-rw-r--r--tests/projects/swift/cxx_interop_lib/test.lua7
-rw-r--r--tests/projects/swift/cxx_interop_lib/xmake.lua12
-rw-r--r--xmake/core/tool/toolchain.lua1
-rw-r--r--xmake/languages/swift/load.lua6
-rw-r--r--xmake/languages/swift/xmake.lua5
-rw-r--r--xmake/modules/core/tools/swift_frontend.lua10
-rw-r--r--xmake/modules/core/tools/swiftc.lua10
-rw-r--r--xmake/modules/core/tools/swiftc/has_flags.lua4
-rw-r--r--xmake/rules/swift/xmake.lua183
-rw-r--r--xmake/toolchains/llvm/xmake.lua56
-rw-r--r--xmake/toolchains/swift/xmake.lua17
-rw-r--r--xmake/toolchains/xcode/load_appletvos.lua5
-rw-r--r--xmake/toolchains/xcode/load_applexros.lua8
-rw-r--r--xmake/toolchains/xcode/load_iphoneos.lua5
-rw-r--r--xmake/toolchains/xcode/load_macosx.lua7
-rw-r--r--xmake/toolchains/xcode/load_watchos.lua5
-rw-r--r--xmake/toolchains/xcode/xmake.lua1
31 files changed, 413 insertions, 38 deletions
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/fibonacci.h b/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/fibonacci.h
new file mode 100644
index 000000000..009ea2f3b
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/fibonacci.h
@@ -0,0 +1,6 @@
+#ifndef FIBONACCI_FIBONACCI_H
+#define FIBONACCI_FIBONACCI_H
+
+extern "C" int fibonacci_cpp(int x);
+
+#endif // FIBONACCI_FIBONACCI_H
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/module.modulemap b/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/module.modulemap
new file mode 100644
index 000000000..6d39a1953
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/include/fibonacci/module.modulemap
@@ -0,0 +1,3 @@
+module Fibonacci {
+ header "fibonacci.h"
+}
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.cpp b/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.cpp
new file mode 100644
index 000000000..64ba4bba7
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.cpp
@@ -0,0 +1,9 @@
+#include <fibonacci/fibonacci.h>
+#include <fibonacci-Swift.h>
+#include <iostream>
+
+extern "C" int fibonacci_cpp(int x) {
+ std::cout << "x [cpp]: " << x << std::endl;
+ if (x <= 1) return 1;
+ return SwiftFibonacci::fibonacciSwift(x - 1) + SwiftFibonacci::fibonacciSwift(x - 2);
+}
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.swift b/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.swift
new file mode 100644
index 000000000..9ade2bc48
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/lib/fibonacci.swift
@@ -0,0 +1,7 @@
+public func fibonacciSwift(_ x: CInt) -> CInt {
+ print("x [swift]: \(x)")
+ if x <= 1 {
+ return 1
+ }
+ return fibonacciSwift(x - 1) + fibonacciSwift(x - 2)
+}
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.cpp b/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.cpp
new file mode 100644
index 000000000..f6077d6e1
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.cpp
@@ -0,0 +1,7 @@
+#include <fibonacci-Swift.h>
+#include <iostream>
+
+int main(int argc, char ** argv) {
+ std::cout << SwiftFibonacci::fibonacciSwift(5) << std::endl;
+ return 0;
+}
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.swift b/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.swift
new file mode 100644
index 000000000..aaa192db1
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/src/fibonacci.swift
@@ -0,0 +1,3 @@
+import Fibonacci
+
+print(fibonacci_cpp(5))
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/test.lua b/tests/projects/swift/bidirectional_cxx_interop_lib/test.lua
new file mode 100644
index 000000000..149a15ed0
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/test.lua
@@ -0,0 +1,7 @@
+function main(t)
+ if os.host() == "macosx" then
+ t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
+ end
+end
diff --git a/tests/projects/swift/bidirectional_cxx_interop_lib/xmake.lua b/tests/projects/swift/bidirectional_cxx_interop_lib/xmake.lua
new file mode 100644
index 000000000..b2840f1fd
--- /dev/null
+++ b/tests/projects/swift/bidirectional_cxx_interop_lib/xmake.lua
@@ -0,0 +1,23 @@
+target("fibonacci")
+ set_kind("$(kind)")
+ set_languages("cxx20")
+ add_files("lib/**.swift", {public = true})
+ add_files("lib/**.cpp")
+ set_values("swift.modulename", "SwiftFibonacci")
+ set_values("swift.interop", "cxx")
+ -- for automatic clang modulemap
+ add_includedirs("include/fibonacci", {public = true})
+ add_includedirs("include")
+ add_headerfiles("include/**.h")
+
+target("cxx_interop_lib")
+ set_kind("binary")
+ set_languages("cxx20")
+ add_files("src/**.cpp")
+ add_deps("fibonacci")
+
+target("swift_interop_lib")
+ set_kind("binary")
+ add_files("src/**.swift")
+ add_deps("fibonacci")
+ set_values("swift.interop", "cxx")
diff --git a/tests/projects/swift/cxx_interop/lib/fibonacci/fibonacci.swift b/tests/projects/swift/cxx_interop/lib/fibonacci/fibonacci.swift
new file mode 100644
index 000000000..9ade2bc48
--- /dev/null
+++ b/tests/projects/swift/cxx_interop/lib/fibonacci/fibonacci.swift
@@ -0,0 +1,7 @@
+public func fibonacciSwift(_ x: CInt) -> CInt {
+ print("x [swift]: \(x)")
+ if x <= 1 {
+ return 1
+ }
+ return fibonacciSwift(x - 1) + fibonacciSwift(x - 2)
+}
diff --git a/tests/projects/swift/cxx_interop/src/fibonacci.cpp b/tests/projects/swift/cxx_interop/src/fibonacci.cpp
new file mode 100644
index 000000000..f6077d6e1
--- /dev/null
+++ b/tests/projects/swift/cxx_interop/src/fibonacci.cpp
@@ -0,0 +1,7 @@
+#include <fibonacci-Swift.h>
+#include <iostream>
+
+int main(int argc, char ** argv) {
+ std::cout << SwiftFibonacci::fibonacciSwift(5) << std::endl;
+ return 0;
+}
diff --git a/tests/projects/swift/cxx_interop/test.lua b/tests/projects/swift/cxx_interop/test.lua
new file mode 100644
index 000000000..149a15ed0
--- /dev/null
+++ b/tests/projects/swift/cxx_interop/test.lua
@@ -0,0 +1,7 @@
+function main(t)
+ if os.host() == "macosx" then
+ t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
+ end
+end
diff --git a/tests/projects/swift/cxx_interop/xmake.lua b/tests/projects/swift/cxx_interop/xmake.lua
new file mode 100644
index 000000000..68f7ede78
--- /dev/null
+++ b/tests/projects/swift/cxx_interop/xmake.lua
@@ -0,0 +1,9 @@
+target("cxx_interop")
+ set_kind("binary")
+ set_languages("cxx20")
+ add_files("lib/**.swift", {public = true})
+ add_files("src/**.cpp")
+ set_values("swift.modulename", "SwiftFibonacci")
+ set_values("swift.interop", "cxx")
+ set_values("swift.interop.headername", "fibonacci-Swift.h")
+ set_values("swift.interop.cxxmain", true)
diff --git a/tests/projects/swift/cxx_interop_lib/lib/fibonacci/fibonacci.swift b/tests/projects/swift/cxx_interop_lib/lib/fibonacci/fibonacci.swift
new file mode 100644
index 000000000..9ade2bc48
--- /dev/null
+++ b/tests/projects/swift/cxx_interop_lib/lib/fibonacci/fibonacci.swift
@@ -0,0 +1,7 @@
+public func fibonacciSwift(_ x: CInt) -> CInt {
+ print("x [swift]: \(x)")
+ if x <= 1 {
+ return 1
+ }
+ return fibonacciSwift(x - 1) + fibonacciSwift(x - 2)
+}
diff --git a/tests/projects/swift/cxx_interop_lib/src/fibonacci.cpp b/tests/projects/swift/cxx_interop_lib/src/fibonacci.cpp
new file mode 100644
index 000000000..f6077d6e1
--- /dev/null
+++ b/tests/projects/swift/cxx_interop_lib/src/fibonacci.cpp
@@ -0,0 +1,7 @@
+#include <fibonacci-Swift.h>
+#include <iostream>
+
+int main(int argc, char ** argv) {
+ std::cout << SwiftFibonacci::fibonacciSwift(5) << std::endl;
+ return 0;
+}
diff --git a/tests/projects/swift/cxx_interop_lib/test.lua b/tests/projects/swift/cxx_interop_lib/test.lua
new file mode 100644
index 000000000..149a15ed0
--- /dev/null
+++ b/tests/projects/swift/cxx_interop_lib/test.lua
@@ -0,0 +1,7 @@
+function main(t)
+ if os.host() == "macosx" then
+ t:build({iphoneos = true})
+ else
+ return t:skip("wrong host platform")
+ end
+end
diff --git a/tests/projects/swift/cxx_interop_lib/xmake.lua b/tests/projects/swift/cxx_interop_lib/xmake.lua
new file mode 100644
index 000000000..f1de85d13
--- /dev/null
+++ b/tests/projects/swift/cxx_interop_lib/xmake.lua
@@ -0,0 +1,12 @@
+target("fibonacci")
+ set_kind("$(kind)")
+ set_languages("cxx20")
+ add_files("lib/**.swift", {public = true})
+ set_values("swift.modulename", "SwiftFibonacci")
+ set_values("swift.interop", "cxx")
+
+target("cxx_interop_lib")
+ set_kind("binary")
+ set_languages("cxx20")
+ add_files("src/**.cpp")
+ add_deps("fibonacci")
diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua
index 57b2f5073..2230aae9e 100644
--- a/xmake/core/tool/toolchain.lua
+++ b/xmake/core/tool/toolchain.lua
@@ -442,6 +442,7 @@ function _instance:_description(toolkind)
sc = "the swift compiler",
scld = "the swift linker",
scsh = "the swift shared library linker",
+ scar = "the swift static library archiver",
gc = "the golang compiler",
gcld = "the golang linker",
gcar = "the golang static library archiver",
diff --git a/xmake/languages/swift/load.lua b/xmake/languages/swift/load.lua
index 90277ed90..08e7efde8 100644
--- a/xmake/languages/swift/load.lua
+++ b/xmake/languages/swift/load.lua
@@ -51,9 +51,13 @@ function _get_apis()
}
apis.paths = {
-- target.add_xxx
- "target.add_linkdirs"
+ "target.add_includedirs"
+ , "target.add_sysincludedirs"
+ , "target.add_linkdirs"
, "target.add_frameworkdirs"
-- option.add_xxx
+ , "option.add_includedirs"
+ , "option.add_sysincludedirs"
, "option.add_linkdirs"
, "option.add_frameworkdirs"
}
diff --git a/xmake/languages/swift/xmake.lua b/xmake/languages/swift/xmake.lua
index 8048966f9..a00810111 100644
--- a/xmake/languages/swift/xmake.lua
+++ b/xmake/languages/swift/xmake.lua
@@ -22,8 +22,8 @@ language("swift")
add_rules("swift")
set_sourcekinds {sc = ".swift"}
set_sourceflags {sc = "scflags"}
- set_targetkinds {binary = "scld", static = "ar", shared = "scsh"}
- set_targetflags {binary = "ldflags", static = "arflags", shared = "shflags"}
+ set_targetkinds {binary = "scld", static = "scar", shared = "scsh"}
+ set_targetflags {binary = "ldflags", static = "scarflags", shared = "shflags"}
set_langkinds {swift = "sc"}
set_mixingkinds("sc", "mm", "mxx", "cc", "cxx")
@@ -105,6 +105,7 @@ language("swift")
, {category = "Cross Complation Configuration/Linker Configuration" }
, { nil, "scld", "kv", nil, "The Swift Linker" }
, { nil, "scsh", "kv", nil, "The Swift Shared Library Linker" }
+ , { nil, "scar", "kv", nil, "The Swift Static Library Archiver" }
, { category = "Cross Complation Configuration/Builtin Flags Configuration" }
, { nil, "links", "kv", nil, "The Link Libraries" }
diff --git a/xmake/modules/core/tools/swift_frontend.lua b/xmake/modules/core/tools/swift_frontend.lua
index 002e323d7..66a0c488b 100644
--- a/xmake/modules/core/tools/swift_frontend.lua
+++ b/xmake/modules/core/tools/swift_frontend.lua
@@ -110,6 +110,16 @@ function nf_vectorext(self, extension)
return maps[extension]
end
+-- make the includedir flag
+function nf_includedir(self, includedir)
+ return "-I" .. includedir
+end
+
+-- make the sysincludedir flag
+function nf_sysincludedir(self, dir)
+ return nf_includedir(self, dir)
+end
+
-- make the define flag
function nf_define(self, macro)
return {"-Xcc", "-D" .. macro}
diff --git a/xmake/modules/core/tools/swiftc.lua b/xmake/modules/core/tools/swiftc.lua
index c19072fd7..109d461d2 100644
--- a/xmake/modules/core/tools/swiftc.lua
+++ b/xmake/modules/core/tools/swiftc.lua
@@ -120,6 +120,16 @@ function nf_vectorext(self, extension)
return maps[extension]
end
+-- make the includedir flag
+function nf_includedir(self, includedir)
+ return "-I" .. includedir
+end
+
+-- make the sysincludedir flag
+function nf_sysincludedir(self, dir)
+ return nf_includedir(self, dir)
+end
+
-- make the define flag
function nf_define(self, macro)
return {"-Xcc", "-D" .. macro}
diff --git a/xmake/modules/core/tools/swiftc/has_flags.lua b/xmake/modules/core/tools/swiftc/has_flags.lua
index 290a6de83..0f65e0604 100644
--- a/xmake/modules/core/tools/swiftc/has_flags.lua
+++ b/xmake/modules/core/tools/swiftc/has_flags.lua
@@ -73,6 +73,10 @@ function _check_try_running(flags, opt)
-- check it
local objectfile = os.tmpfile() .. ".o"
local ok, errors = _try_running(opt.program, table.join(flags, "-o", objectfile, sourcefile))
+ if errors and not errors:match("unknown argument") then
+ ok = true
+ errors = nil
+ end
-- remove files
os.tryrm(objectfile)
diff --git a/xmake/rules/swift/xmake.lua b/xmake/rules/swift/xmake.lua
index 3ab44c600..10434968b 100644
--- a/xmake/rules/swift/xmake.lua
+++ b/xmake/rules/swift/xmake.lua
@@ -18,15 +18,186 @@
-- @file xmake.lua
--
+rule("swift.interop", function()
+ set_sourcekinds("sc")
+ add_orders("swift.interop", "swift.build")
+ add_orders("swift.interop", "c++.build")
+ on_config(function(target)
+ import("core.base.json")
+
+ if not target:values("swift.interop") then
+ target:rule_enable("swift.interop", false)
+ return
+ end
+
+ local sourcebatches = target:sourcebatches()
+ local sourcebatch = sourcebatches and sourcebatches["swift.interop"]
+ local sourcefiles = sourcebatch and sourcebatch.sourcefiles
+ sourcefiles = sourcefiles or {}
+ local enabled = false
+ for _, sourcefile in ipairs(sourcefiles) do
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig and fileconfig.public then
+ enabled = true
+ break
+ end
+ end
+ if not enabled then
+ target:rule_enable("swift.interop", false)
+ return
+ end
+
+ local sc = target:tool("sc")
+ assert(sc, "No swift compiler found!")
+ local outdata, errdata = os.iorunv(sc, {"-print-target-info"})
+ assert(outdata, errdata)
+
+ local target_info = json.decode(outdata)
+ assert(target_info and target_info.paths and target_info.paths.runtimeResourcePath, "Failed to get swift resource path")
+ target:add("includedirs", target_info.paths.runtimeResourcePath, {public = true})
+
+ local outdir = target:autogendir("swift.interop")
+ target:add("includedirs", outdir, {public = true})
+
+ local mode = (type(target:values("swift.interop")) == "string") and target:values("swift.interop") or "objc"
+
+ local headername = (target:values("swift.interop.headername") or (target:name() .. "-Swift.h"))
+ local header = path.join(outdir, headername)
+ target:add("headerfiles", header)
+
+ target:data_set("swift.interop", mode)
+ target:data_set("swift.interop.outdir", outdir)
+ end)
+
+ on_prepare_files(function(target, jobgraph, sourcebatch, opt)
+ import("utils.progress")
+ import("core.base.option")
+ import("core.tool.compiler")
+ import("core.language.language")
+ import("core.project.depend")
+
+ local function _get_target_cpp_langflags()
+ local cpp_langflags = _g.cpp_langflags
+ if cpp_langflags == nil then
+ local languages = target:get("languages")
+ for _, language in ipairs(languages) do
+ if language:startswith("c++")
+ or language:startswith("cxx")
+ or language:startswith("gnu++")
+ or language:startswith("gnuxx") then
+ -- c++26 currently prevent compilation of swift modules
+ language = language:gsub("26", "23"):gsub("latest", "23")
+ cpp_langflags = compiler.map_flags("cxx", "language", language, {target = target})
+ _g.cpp_langflags = cpp_langflags or false
+ end
+ end
+ end
+ return cpp_langflags or nil
+ end
+
+ local mode = target:data("swift.interop")
+ local sc = target:tool("sc")
+ assert(sc, "No swift compiler found!")
+ local outdir = target:data("swift.interop.outdir")
+ if not os.isdir(outdir) then os.mkdir(outdir) end
+ assert(outdir)
+
+ local sourcefiles = sourcebatch.sourcefiles
+ local public_sourcefiles
+ for _, sourcefile in ipairs(sourcefiles) do
+ local fileconfig = target:fileconfig(sourcefile)
+ if fileconfig and fileconfig.public then
+ public_sourcefiles = public_sourcefiles or {}
+ table.insert(public_sourcefiles, sourcefile)
+ end
+ end
+
+ if public_sourcefiles then
+ local modulename = target:values("swift.modulename") or target:name()
+ local headername = (target:values("swift.interop.headername") or (target:name() .. "-Swift.h"))
+ local header = path.join(outdir, headername)
+
+ jobgraph:add(target:fullname() .. "/gen_swift_header", function(index, total, opt)
+ depend.on_changed(function()
+ local stdflag
+ if mode == "cxx" then
+ local cpp_langflags = _get_target_cpp_langflags()
+ if cpp_langflags then
+ for _, flag in ipairs(cpp_langflags) do
+ stdflag = stdflag or {}
+ table.join2(stdflag, {"-Xcc", flag})
+ end
+ end
+ end
+
+ if opt.progress then
+ progress.show(
+ opt.progress,
+ "${clear}${color.build.target}<%s> generating.swift.header %s",
+ target:fullname(),
+ headername
+ )
+ end
+
+ local compinst = import("core.tool.compiler").load("sc")
+ local _scflags = compinst:compflags({target = target, sourcekind = "sc"})
+ local scflags
+ if target:has_tool("sc", "swift_frontend") then
+ for _, scflag in ipairs(_scflags) do
+ scflags = scflags or {}
+ if not os.isfile(scflag) then
+ table.insert(scflags, scflag)
+ end
+ end
+ else
+ scflags = _scflags
+ end
+
+ local emit_flag = mode == "cxx" and "-emit-clang-header-path" or "-emit-objc-header-path"
+
+ local flags = table.join({
+ "-frontend",
+ "-typecheck",
+ emit_flag,
+ header,
+ },
+ scflags or {},
+ stdflag or {},
+ public_sourcefiles)
+ if option.get("verbose") then
+ print(os.args(table.join(sc, flags)))
+ end
+
+ os.tryrm(header)
+ local outdata, errdata = os.iorunv(sc, flags)
+ assert(outdata, errdata)
+ end, {
+ files = public_sourcefiles,
+ changed = target:is_rebuilt() or not os.isfile(header),
+ })
+ end)
+ end
+ end, { jobgraph = true })
+end)
+
-- define rule: swift.build
rule("swift.build")
set_sourcekinds("sc")
on_build_files("private.action.build.object", {jobgraph = true, batch = true})
on_config(function (target)
+ local mode = (type(target:values("swift.interop")) == "string") and target:values("swift.interop") or "objc"
+ if mode == "cxx" then
+ target:add("scflags", "-cxx-interoperability-mode=default")
+ end
+
+ if target:is_library() or target:values("swift.interop.cxxmain") then
+ target:add("scflags", "-parse-as-library")
+ end
+ local modulename = target:values("swift.modulename") or target:name()
+ target:add("scflags", "-module-name", modulename, {force = true})
-- we use swift-frontend to support multiple modules
-- @see https://github.com/xmake-io/xmake/issues/3916
if target:has_tool("sc", "swift_frontend") then
- target:add("scflags", "-module-name", target:name(), {force = true})
local sourcebatch = target:sourcebatches()["swift.build"]
if sourcebatch then
for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
@@ -38,10 +209,20 @@ rule("swift.build")
-- define rule: swift
rule("swift")
+ -- add build rules
+ add_deps("swift.interop")
-- add build rules
add_deps("swift.build")
+ -- set compiler runtime, e.g. vs runtime
+ add_deps("utils.compiler.runtime")
+
+ -- inherit links and linkdirs of all dependent targets by default
+ add_deps("utils.inherit.links")
+
-- support `add_files("src/*.o")` to merge object files to target
add_deps("utils.merge.object")
+ -- add linker rules
+ add_deps("linker")
diff --git a/xmake/toolchains/llvm/xmake.lua b/xmake/toolchains/llvm/xmake.lua
index de2e775d7..3dce6bff4 100644
--- a/xmake/toolchains/llvm/xmake.lua
+++ b/xmake/toolchains/llvm/xmake.lua
@@ -39,6 +39,11 @@ toolchain("llvm")
set_toolset("mrc", "llvm-rc")
set_toolset("dlltool", "llvm-dlltool")
+ set_toolset("sc", "$(env SC)", "swift-frontend", "swiftc")
+ set_toolset("scsh", "$(env SC)", "swiftc")
+ set_toolset("scar", "$(env SC)", "swiftc")
+ set_toolset("scld", "$(env SC)", "swiftc")
+
on_check("check")
on_load(function (toolchain)
@@ -56,16 +61,6 @@ toolchain("llvm")
else
target = "x86_64-pc-windows-msvc"
end
- elseif toolchain:is_plat("macosx") then
- local arch = toolchain:arch()
- local target_minver = toolchain:config("target_minver")
- local appledev = toolchain:config("appledev")
- if target_minver then
- target = ("%s-apple-macos%s"):format(arch, target_minver)
- if appledev == "catalyst" then
- target = ("%s-apple-ios%s-macabi"):format(arch, target_minver)
- end
- end
elseif toolchain:is_plat("cross") then
target = toolchain:cross():gsub("(.*)%-$", "%1")
end
@@ -83,6 +78,9 @@ toolchain("llvm")
toolchain:add("asflags", target_flags)
toolchain:add("ldflags", target_flags)
toolchain:add("shflags", target_flags)
+ toolchain:add("scasflags", "--target=" .. target_flags)
+ toolchain:add("scldflags", "--target=" .. target_flags)
+ toolchain:add("scshflags", "--target=" .. target_flags)
end
-- init flags for platform
@@ -90,26 +88,28 @@ toolchain("llvm")
toolchain:add("ldflags", "-fuse-ld=lld")
toolchain:add("shflags", "-fuse-ld=lld")
elseif toolchain:is_plat("macosx") then
- local xcode_dir = get_config("xcode")
- local xcode_sdkver = toolchain:config("xcode_sdkver")
- local xcode_sdkdir = nil
- if xcode_dir and xcode_sdkver then
- xcode_sdkdir = xcode_dir .. "/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk"
- toolchain:add("cxflags", {"-isysroot", xcode_sdkdir})
- toolchain:add("mxflags", {"-isysroot", xcode_sdkdir})
- toolchain:add("ldflags", {"-isysroot", xcode_sdkdir})
- toolchain:add("shflags", {"-isysroot", xcode_sdkdir})
- else
- -- @see https://github.com/xmake-io/xmake/issues/1179
- local macsdk = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
- if os.exists(macsdk) then
- toolchain:add("cxflags", {"-isysroot", macsdk})
- toolchain:add("mxflags", {"-isysroot", macsdk})
- toolchain:add("ldflags", {"-isysroot", macsdk})
- toolchain:add("shflags", {"-isysroot", macsdk})
+ if not toolchain:config("xcode_sysroot") then
+ local xcode_dir = get_config("xcode")
+ local xcode_sdkver = toolchain:config("xcode_sdkver")
+ local xcode_sdkdir
+ if xcode_dir and xcode_sdkver then
+ local macsdk = path.join(xcode_dir, "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk")
+ if os.isdir(macsdk) then
+ xcode_sdkdir = macsdk
+ end
+ else
+ -- @see https://github.com/xmake-io/xmake/issues/1179
+ local macsdk = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
+ if os.isdir(macsdk) then
+ xcode_sdkdir = macsdk
+ end
+ end
+ if os.isdir(xcode_sdkdir) then
+ toolchain:config_set("xcode_sysroot", xcode_sdkdir)
end
end
- toolchain:add("mxflags", "-fobjc-arc")
+ -- load configurations
+ import(".xcode.load_" .. toolchain:plat())(toolchain)
elseif toolchain:is_plat("cross") then
local sysroot
local sdkdir = toolchain:sdkdir()
diff --git a/xmake/toolchains/swift/xmake.lua b/xmake/toolchains/swift/xmake.lua
index 2dec302bf..ff433b04c 100644
--- a/xmake/toolchains/swift/xmake.lua
+++ b/xmake/toolchains/swift/xmake.lua
@@ -27,11 +27,22 @@ toolchain("swift")
-- set toolset
set_toolset("sc", "$(env SC)", "swift-frontend", "swiftc")
- set_toolset("scld", "$(env SC)", "swiftc")
set_toolset("scsh", "$(env SC)", "swiftc")
+ set_toolset("scar", "$(env SC)", "swiftc")
+ set_toolset("scld", "$(env SC)", "swiftc")
-- on load
on_load(function (toolchain)
- toolchain:set("scshflags", "")
- toolchain:set("scldflags", "")
+ if toolchain:is_plat("macosx") then
+ if not toolchain:config("xcode_sysroot") then
+ local xcode_dir = get_config("xcode")
+ local xcode_sdkver = toolchain:config("xcode_sdkver")
+ local xcode_sdkdir = path.join(xcode_dir, "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX" .. xcode_sdkver .. ".sdk")
+ if os.isdir(xcode_sdkdir) then
+ toolchain:config_set("xcode_sysroot", xcode_sdkdir)
+ end
+ end
+ -- load configurations
+ import(".xcode.load_" .. toolchain:plat())(toolchain)
+ end
end)
diff --git a/xmake/toolchains/xcode/load_appletvos.lua b/xmake/toolchains/xcode/load_appletvos.lua
index c4aea5953..446177cab 100644
--- a/xmake/toolchains/xcode/load_appletvos.lua
+++ b/xmake/toolchains/xcode/load_appletvos.lua
@@ -48,6 +48,11 @@ function main(toolchain)
-- init flags for swift (with toolchain:add("ldflags and toolchain:add("shflags)
toolchain:add("scflags", format("-target %s-apple-tvos%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scshflags", format("-target %s-apple-tvos%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+ toolchain:add("scarflags", format("-target %s-apple-tvos%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scldflags", format("-target %s-apple-tvos%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+
+ toolchain:add("scshflags", "-sdk " .. xcode_sysroot, "-emit-library")
+ toolchain:add("scarflags", "-sdk " .. xcode_sysroot, "-emit-library", "-static")
+ toolchain:add("scldflags", "-sdk " .. xcode_sysroot, "-emit-executable")
end
diff --git a/xmake/toolchains/xcode/load_applexros.lua b/xmake/toolchains/xcode/load_applexros.lua
index 9f1702ba5..6a74abaf7 100644
--- a/xmake/toolchains/xcode/load_applexros.lua
+++ b/xmake/toolchains/xcode/load_applexros.lua
@@ -37,6 +37,7 @@ function main(toolchain)
toolchain:add("scflags", "-target", target)
toolchain:add("scldflags", "-target", target)
toolchain:add("scshflags", "-target", target)
+ toolchain:add("scarflags", "-target", target)
end
-- init flags for c/c++
@@ -52,9 +53,10 @@ function main(toolchain)
-- init flags for asm
toolchain:add("asflags", "-isysroot", xcode_sysroot)
- -- init flags for swift (with toolchain:add("ldflags and toolchain:add("shflags)
+ -- init flags for swift (with toolchain:add("ldflags") and toolchain:add("shflags") and toolchain:add("arflags"))
toolchain:add("scflags", "-sdk " .. xcode_sysroot)
- toolchain:add("scshflags", "-sdk " .. xcode_sysroot)
- toolchain:add("scldflags", "-sdk " .. xcode_sysroot)
+ toolchain:add("scshflags", "-sdk " .. xcode_sysroot, "-emit-library")
+ toolchain:add("scarflags", "-sdk " .. xcode_sysroot, "-emit-library", "-static")
+ toolchain:add("scldflags", "-sdk " .. xcode_sysroot, "-emit-executable")
end
diff --git a/xmake/toolchains/xcode/load_iphoneos.lua b/xmake/toolchains/xcode/load_iphoneos.lua
index fd4cd4548..4f3fb1293 100644
--- a/xmake/toolchains/xcode/load_iphoneos.lua
+++ b/xmake/toolchains/xcode/load_iphoneos.lua
@@ -51,6 +51,11 @@ function main(toolchain)
-- init flags for swift (with toolchain:add("ldflags and toolchain:add("shflags)
toolchain:add("scflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scshflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+ toolchain:add("scarflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scldflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+
+ toolchain:add("scshflags", "-emit-library")
+ toolchain:add("scarflags", "-emit-library", "-static")
+ toolchain:add("scldflags", "-emit-executable")
end
diff --git a/xmake/toolchains/xcode/load_macosx.lua b/xmake/toolchains/xcode/load_macosx.lua
index 702d721f4..c88680644 100644
--- a/xmake/toolchains/xcode/load_macosx.lua
+++ b/xmake/toolchains/xcode/load_macosx.lua
@@ -39,6 +39,7 @@ function main(toolchain)
toolchain:add("scflags", "-target", target)
toolchain:add("scldflags", "-target", target)
toolchain:add("scshflags", "-target", target)
+ toolchain:add("scarflags", "-target", target)
end
-- add sysroot flags
@@ -50,6 +51,7 @@ function main(toolchain)
toolchain:add("mxflags", "-isysroot", xcode_sysroot)
toolchain:add("scflags", "-sdk " .. xcode_sysroot)
toolchain:add("scshflags", "-sdk " .. xcode_sysroot)
+ toolchain:add("scarflags", "-sdk " .. xcode_sysroot)
toolchain:add("scldflags", "-sdk " .. xcode_sysroot)
if appledev == "catalyst" then
toolchain:add("cxflags", {"-I", path.join(xcode_sysroot, "System/iOSSupport/usr/include")})
@@ -66,6 +68,7 @@ function main(toolchain)
toolchain:add("mxflags", {"-iframework", path.join(xcode_sysroot, "System/iOSSupport/System/Library/Frameworks")})
toolchain:add("scflags", {"-iframework", path.join(xcode_sysroot, "System/iOSSupport/System/Library/Frameworks")})
toolchain:add("scshflags", {"-iframework", path.join(xcode_sysroot, "System/iOSSupport/System/Library/Frameworks")})
+ toolchain:add("scarflags", {"-iframework", path.join(xcode_sysroot, "System/iOSSupport/System/Library/Frameworks")})
toolchain:add("scldflags", {"-iframework", path.join(xcode_sysroot, "System/iOSSupport/System/Library/Frameworks")})
end
end
@@ -77,4 +80,8 @@ function main(toolchain)
-- init flags for objc/c++ (with ldflags and shflags)
-- we can use `add_mxflags("-fno-objc-arc")` to override it in xmake.lua
toolchain:add("mxflags", "-fobjc-arc")
+
+ toolchain:add("scshflags", "-emit-library")
+ toolchain:add("scarflags", "-emit-library", "-static")
+ toolchain:add("scldflags", "-emit-executable")
end
diff --git a/xmake/toolchains/xcode/load_watchos.lua b/xmake/toolchains/xcode/load_watchos.lua
index 91503ff80..99fc12313 100644
--- a/xmake/toolchains/xcode/load_watchos.lua
+++ b/xmake/toolchains/xcode/load_watchos.lua
@@ -49,5 +49,10 @@ function main(toolchain)
toolchain:add("scflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scshflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
toolchain:add("scldflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+ toolchain:add("scarflags", format("-target %s-apple-ios%s", arch, target_minver) , "-sdk " .. xcode_sysroot)
+
+ toolchain:add("scshflags", "-emit-library")
+ toolchain:add("scarflags", "-emit-library", "-static")
+ toolchain:add("scldflags", "-emit-executable")
end
diff --git a/xmake/toolchains/xcode/xmake.lua b/xmake/toolchains/xcode/xmake.lua
index dfe224d29..482fbaf7e 100644
--- a/xmake/toolchains/xcode/xmake.lua
+++ b/xmake/toolchains/xcode/xmake.lua
@@ -51,6 +51,7 @@ toolchain("xcode")
toolchain:set("toolset", "sc", xc_swift_frontend, "swift_frontend", xc_swiftc, "swiftc")
toolchain:set("toolset", "scld", xc_swiftc, "swiftc")
toolchain:set("toolset", "scsh", xc_swiftc, "swiftc")
+ toolchain:set("toolset", "scar", xc_swiftc, "swiftc")
if arch then
toolchain:set("toolset", "cpp", xc_clang .. " -arch " .. arch .. " -E")
end