summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatalin Rebhan <me@dblsaiko.net>2025-02-17 18:25:40 +0100
committerJussi Pakkanen <jussi.pakkanen@mailbox.org>2025-07-24 13:54:53 +0300
commitf34d2c3aa3047562f7ecb4174c5d513b9d6ebe74 (patch)
tree05ed2151baa5b34863ceb0848cacc161e75e5169
parentc07eb44c2b54025a98162e0ccd4c70c0f9b2d244 (diff)
downloadmeson-f34d2c3aa3047562f7ecb4174c5d513b9d6ebe74.tar.gz
Add -parse-as-library to Swift library targets
-rw-r--r--docs/markdown/snippets/swift-parse-as-library.md8
-rw-r--r--mesonbuild/backend/ninjabackend.py7
-rw-r--r--mesonbuild/compilers/swift.py3
-rw-r--r--test cases/swift/14 single-file library/main.swift3
-rw-r--r--test cases/swift/14 single-file library/meson.build4
-rw-r--r--test cases/swift/14 single-file library/singlefile.swift1
-rw-r--r--test cases/swift/15 main in single-file library/main.swift3
-rw-r--r--test cases/swift/15 main in single-file library/meson.build4
-rw-r--r--test cases/swift/15 main in single-file library/module.modulemap3
-rw-r--r--test cases/swift/15 main in single-file library/program.c5
-rw-r--r--test cases/swift/15 main in single-file library/program.h1
-rw-r--r--test cases/swift/16 main in multi-file library/main.swift4
-rw-r--r--test cases/swift/16 main in multi-file library/meson.build4
-rw-r--r--test cases/swift/16 main in multi-file library/module.modulemap3
-rw-r--r--test cases/swift/16 main in multi-file library/more.swift3
-rw-r--r--test cases/swift/16 main in multi-file library/program.c5
-rw-r--r--test cases/swift/16 main in multi-file library/program.h1
-rw-r--r--test cases/swift/8 extra args/lib.swift3
-rw-r--r--test cases/swift/8 extra args/main.swift1
-rw-r--r--test cases/swift/8 extra args/meson.build4
20 files changed, 67 insertions, 3 deletions
diff --git a/docs/markdown/snippets/swift-parse-as-library.md b/docs/markdown/snippets/swift-parse-as-library.md
new file mode 100644
index 000000000..5208899bc
--- /dev/null
+++ b/docs/markdown/snippets/swift-parse-as-library.md
@@ -0,0 +1,8 @@
+## Top-level statement handling in Swift libraries
+
+The Swift compiler normally treats modules with a single source
+file (and files named main.swift) to run top-level code at program
+start. This emits a main symbol which is usually undesirable in a
+library target. Meson now automatically passes the *-parse-as-library*
+flag to the Swift compiler in case of single-file library targets to
+disable this behavior unless the source file is called main.swift.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index ba75ce737..82411b0e6 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2288,6 +2288,13 @@ class NinjaBackend(backends.Backend):
compile_args += swiftc.get_cxx_interoperability_args(target.compilers)
compile_args += self.build.get_project_args(swiftc, target.subproject, target.for_machine)
compile_args += self.build.get_global_args(swiftc, target.for_machine)
+ if isinstance(target, (build.StaticLibrary, build.SharedLibrary)):
+ # swiftc treats modules with a single source file, and the main.swift file in multi-source file modules
+ # as top-level code. This is undesirable in library targets since it emits a main function. Add the
+ # -parse-as-library option as necessary to prevent emitting the main function while keeping files explicitly
+ # named main.swift treated as the entrypoint of the module in case this is desired.
+ if len(abssrc) == 1 and os.path.basename(abssrc[0]) != 'main.swift':
+ compile_args += swiftc.get_library_args()
for i in reversed(target.get_include_dirs()):
basedir = i.get_curdir()
for d in i.get_incdirs():
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index 47d254be5..3fff7a1ff 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -159,6 +159,9 @@ class SwiftCompiler(Compiler):
else:
return ['-cxx-interoperability-mode=off']
+ def get_library_args(self) -> T.List[str]:
+ return ['-parse-as-library']
+
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
build_dir: str) -> T.List[str]:
for idx, i in enumerate(parameter_list):
diff --git a/test cases/swift/14 single-file library/main.swift b/test cases/swift/14 single-file library/main.swift
new file mode 100644
index 000000000..ccc8fb98b
--- /dev/null
+++ b/test cases/swift/14 single-file library/main.swift
@@ -0,0 +1,3 @@
+import SingleFile
+
+callMe()
diff --git a/test cases/swift/14 single-file library/meson.build b/test cases/swift/14 single-file library/meson.build
new file mode 100644
index 000000000..8eda1d59d
--- /dev/null
+++ b/test cases/swift/14 single-file library/meson.build
@@ -0,0 +1,4 @@
+project('single-file library', 'swift')
+
+lib = static_library('SingleFile', 'singlefile.swift')
+executable('program', 'main.swift', link_with: [lib])
diff --git a/test cases/swift/14 single-file library/singlefile.swift b/test cases/swift/14 single-file library/singlefile.swift
new file mode 100644
index 000000000..617952f4e
--- /dev/null
+++ b/test cases/swift/14 single-file library/singlefile.swift
@@ -0,0 +1 @@
+public func callMe() {}
diff --git a/test cases/swift/15 main in single-file library/main.swift b/test cases/swift/15 main in single-file library/main.swift
new file mode 100644
index 000000000..0d95abbcf
--- /dev/null
+++ b/test cases/swift/15 main in single-file library/main.swift
@@ -0,0 +1,3 @@
+import CProgram
+
+precondition(callMe() == 4)
diff --git a/test cases/swift/15 main in single-file library/meson.build b/test cases/swift/15 main in single-file library/meson.build
new file mode 100644
index 000000000..2e1202e34
--- /dev/null
+++ b/test cases/swift/15 main in single-file library/meson.build
@@ -0,0 +1,4 @@
+project('main in single-file library', 'swift', 'c')
+
+lib = static_library('Library', 'main.swift', include_directories: ['.'])
+executable('program', 'program.c', link_with: [lib])
diff --git a/test cases/swift/15 main in single-file library/module.modulemap b/test cases/swift/15 main in single-file library/module.modulemap
new file mode 100644
index 000000000..3c1817a32
--- /dev/null
+++ b/test cases/swift/15 main in single-file library/module.modulemap
@@ -0,0 +1,3 @@
+module CProgram [extern_c] {
+ header "program.h"
+}
diff --git a/test cases/swift/15 main in single-file library/program.c b/test cases/swift/15 main in single-file library/program.c
new file mode 100644
index 000000000..8959daee5
--- /dev/null
+++ b/test cases/swift/15 main in single-file library/program.c
@@ -0,0 +1,5 @@
+#include "program.h"
+
+int callMe() {
+ return 4;
+}
diff --git a/test cases/swift/15 main in single-file library/program.h b/test cases/swift/15 main in single-file library/program.h
new file mode 100644
index 000000000..5058be393
--- /dev/null
+++ b/test cases/swift/15 main in single-file library/program.h
@@ -0,0 +1 @@
+int callMe(void);
diff --git a/test cases/swift/16 main in multi-file library/main.swift b/test cases/swift/16 main in multi-file library/main.swift
new file mode 100644
index 000000000..3682e8d40
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/main.swift
@@ -0,0 +1,4 @@
+import CProgram
+
+precondition(callMe() == 4)
+precondition(callMe2() == 6)
diff --git a/test cases/swift/16 main in multi-file library/meson.build b/test cases/swift/16 main in multi-file library/meson.build
new file mode 100644
index 000000000..4d287f3a3
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/meson.build
@@ -0,0 +1,4 @@
+project('main in multi-file library', 'swift', 'c')
+
+lib = static_library('Library', 'main.swift', 'more.swift', include_directories: ['.'])
+executable('program', 'program.c', link_with: [lib])
diff --git a/test cases/swift/16 main in multi-file library/module.modulemap b/test cases/swift/16 main in multi-file library/module.modulemap
new file mode 100644
index 000000000..3c1817a32
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/module.modulemap
@@ -0,0 +1,3 @@
+module CProgram [extern_c] {
+ header "program.h"
+}
diff --git a/test cases/swift/16 main in multi-file library/more.swift b/test cases/swift/16 main in multi-file library/more.swift
new file mode 100644
index 000000000..716500f6f
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/more.swift
@@ -0,0 +1,3 @@
+func callMe2() -> Int {
+ 6
+}
diff --git a/test cases/swift/16 main in multi-file library/program.c b/test cases/swift/16 main in multi-file library/program.c
new file mode 100644
index 000000000..8959daee5
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/program.c
@@ -0,0 +1,5 @@
+#include "program.h"
+
+int callMe() {
+ return 4;
+}
diff --git a/test cases/swift/16 main in multi-file library/program.h b/test cases/swift/16 main in multi-file library/program.h
new file mode 100644
index 000000000..5058be393
--- /dev/null
+++ b/test cases/swift/16 main in multi-file library/program.h
@@ -0,0 +1 @@
+int callMe(void);
diff --git a/test cases/swift/8 extra args/lib.swift b/test cases/swift/8 extra args/lib.swift
new file mode 100644
index 000000000..f8167ad45
--- /dev/null
+++ b/test cases/swift/8 extra args/lib.swift
@@ -0,0 +1,3 @@
+public func callMe() {
+ print("test")
+}
diff --git a/test cases/swift/8 extra args/main.swift b/test cases/swift/8 extra args/main.swift
deleted file mode 100644
index 1ff8e07c7..000000000
--- a/test cases/swift/8 extra args/main.swift
+++ /dev/null
@@ -1 +0,0 @@
-print("test")
diff --git a/test cases/swift/8 extra args/meson.build b/test cases/swift/8 extra args/meson.build
index ead2ff509..d243e3646 100644
--- a/test cases/swift/8 extra args/meson.build
+++ b/test cases/swift/8 extra args/meson.build
@@ -2,8 +2,8 @@ project('extra args', 'swift')
trace_fname = 'trace.json'
-lib = static_library('main',
- 'main.swift',
+lib = static_library('lib',
+ 'lib.swift',
swift_args: [
'-emit-loaded-module-trace',
'-emit-loaded-module-trace-path', '../' + trace_fname