diff options
| author | ruki <[email protected]> | 2025-10-28 10:39:48 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-28 10:39:48 +0800 |
| commit | 961a7f0fe0c630ddc6e56ab192e3035c9479f0fa (patch) | |
| tree | 7468347e0c6e7310aa0ae7b5bde23307bc8a1ee7 | |
| parent | d2c54e27de9eb98bd96c262909d31528f44f45cb (diff) | |
| parent | 2c373c8daa2c916fb24ac1411eb61f828e3bfd2e (diff) | |
Merge pull request #6967 from Arthapz/add-swift-cxxinterop
feat(swift) add swift to C++ and objective-C interop
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 |
