aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2015-12-10 21:49:41 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2015-12-10 21:49:41 +0200
commit43b07729aa058ce8af1aa4d7f3c445f61f39c42a (patch)
treea3784e2b3f5fdf0dbde333cdeaeb20ead1889a15
parent7ed515dacc726b6413ff720b7c125670b60543a1 (diff)
downloadmeson-43b07729aa058ce8af1aa4d7f3c445f61f39c42a.zip
meson-43b07729aa058ce8af1aa4d7f3c445f61f39c42a.tar.gz
meson-43b07729aa058ce8af1aa4d7f3c445f61f39c42a.tar.bz2
Reworked swift code so now can use multiple source files in one target.
-rw-r--r--backends.py20
-rw-r--r--compilers.py3
-rwxr-xr-xdirchanger.py24
-rw-r--r--ninjabackend.py58
-rw-r--r--test cases/swift/2 multifile/libfile.swift3
-rw-r--r--test cases/swift/2 multifile/main.swift1
-rw-r--r--test cases/swift/2 multifile/meson.build3
7 files changed, 101 insertions, 11 deletions
diff --git a/backends.py b/backends.py
index 03ecd4b..70b206a 100644
--- a/backends.py
+++ b/backends.py
@@ -132,23 +132,23 @@ class Backend():
self.write_benchmark_file(datafile)
datafile.close()
- def has_vala(self, target):
+ def has_source_suffix(self, target, suffix):
for s in target.get_sources():
- if s.endswith('.vala'):
+ if s.endswith(suffix):
return True
return False
+ def has_vala(self, target):
+ return self.has_source_suffix(target, '.vala')
+
def has_rust(self, target):
- for s in target.get_sources():
- if s.endswith('.rs'):
- return True
- return False
+ return self.has_source_suffix(target, '.rs')
def has_cs(self, target):
- for s in target.get_sources():
- if s.endswith('.cs'):
- return True
- return False
+ return self.has_source_suffix(target, '.cs')
+
+ def has_swift(self, target):
+ return self.has_source_suffix(target, '.swift')
def determine_linker(self, target, src):
if isinstance(target, build.StaticLibrary):
diff --git a/compilers.py b/compilers.py
index 41c4ecd..c496a5d 100644
--- a/compilers.py
+++ b/compilers.py
@@ -1012,6 +1012,9 @@ class SwiftCompiler(Compiler):
def get_std_exe_link_args(self):
return ['-emit-executable']
+ def get_module_args(self, modname):
+ return ['-module-name', modname]
+
def build_rpath_args(self, *args):
return [] # FIXME
diff --git a/dirchanger.py b/dirchanger.py
new file mode 100755
index 0000000..4cc863a
--- /dev/null
+++ b/dirchanger.py
@@ -0,0 +1,24 @@
+# Copyright 2015 The Meson development team
+
+# 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.
+
+'''CD into dir given as first argument and execute
+the command given in the rest of the arguments.'''
+
+import os, subprocess, sys
+
+dirname = sys.argv[1]
+command = sys.argv[2:]
+
+os.chdir(dirname)
+sys.exit(subprocess.call(command))
diff --git a/ninjabackend.py b/ninjabackend.py
index c8134d7..9a8aa0b 100644
--- a/ninjabackend.py
+++ b/ninjabackend.py
@@ -195,6 +195,9 @@ class NinjaBackend(backends.Backend):
return
if 'vala' in self.environment.coredata.compilers.keys() and self.has_vala(target):
gen_src_deps += self.generate_vala_compile(target, outfile)
+ if 'swift' in self.environment.coredata.compilers.keys() and self.has_swift(target):
+ self.generate_swift_target(target, outfile)
+ return
self.scan_fortran_module_outputs(target)
# The following deals with C/C++ compilation.
(gen_src, gen_other_deps) = self.process_dep_gens(outfile, target)
@@ -834,6 +837,42 @@ class NinjaBackend(backends.Backend):
element.write(outfile)
self.check_outputs(element)
+ def generate_swift_target(self, target, outfile):
+ swiftc = self.environment.coredata.compilers['swift']
+ abssrc = []
+ for i in target.get_sources():
+ if not swiftc.can_compile(i):
+ raise InvalidArguments('Swift target %s contains a non-swift source file.' % target.get_basename())
+ relsrc = i.rel_to_builddir(self.build_to_src)
+ abss = os.path.normpath(os.path.join(self.environment.get_build_dir(), relsrc))
+ abssrc.append(abss)
+ os.makedirs(os.path.join(self.get_target_private_dir_abs(target)), exist_ok=True)
+ # We need absolute paths because swiftc needs to be invoked in a subdir
+ # and this is the easiest way about it.
+ objects = [] # Relative to swift invocation dir
+ rel_objects = [] # Relative to build.ninja
+ for i in abssrc:
+ base = os.path.split(i)[1]
+ oname = os.path.splitext(base)[0] + '.o'
+ objects.append(oname)
+ rel_objects.append(os.path.join(self.get_target_private_dir(target), oname))
+ compile_args = swiftc.get_compile_only_args()
+ compile_args += swiftc.get_module_args(target.name)
+ link_args = swiftc.get_output_args(self.get_target_filename(target))
+ rundir = self.get_target_private_dir(target)
+
+ elem = NinjaBuildElement(rel_objects, 'swift_COMPILER', abssrc)
+ elem.add_item('ARGS', compile_args)
+ elem.add_item('RUNDIR', rundir)
+ elem.write(outfile)
+ self.check_outputs(elem)
+ elem = NinjaBuildElement(self.get_target_filename(target), 'swift_COMPILER', [])
+ elem.add_dep(rel_objects)
+ elem.add_item('ARGS', link_args + objects)
+ elem.add_item('RUNDIR', rundir)
+ elem.write(outfile)
+ self.check_outputs(elem)
+
def generate_static_link_rules(self, is_cross, outfile):
if self.build.has_language('java'):
if not is_cross:
@@ -958,7 +997,10 @@ class NinjaBackend(backends.Backend):
def generate_rust_compile_rules(self, compiler, outfile):
rule = 'rule %s_COMPILER\n' % compiler.get_language()
- invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()])
+ full_exe = [sys.executable,
+ os.path.join(self.environment.get_script_root(), 'dirchanger'),
+ '$RUNDIR'] + compiler.get_exelist()
+ invoc = ' '.join([ninja_quote(i) for i in full_exe])
command = ' command = %s $ARGS $in\n' % invoc
description = ' description = Compiling Rust source $in.\n'
depfile = ' depfile = $targetdep\n'
@@ -971,6 +1013,16 @@ class NinjaBackend(backends.Backend):
outfile.write(depstyle)
outfile.write('\n')
+ def generate_swift_compile_rules(self, compiler, outfile):
+ rule = 'rule %s_COMPILER\n' % compiler.get_language()
+ invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()])
+ command = ' command = %s $ARGS $in\n' % invoc
+ description = ' description = Compiling Swift source $in.\n'
+ outfile.write(rule)
+ outfile.write(command)
+ outfile.write(description)
+ outfile.write('\n')
+
def generate_fortran_dep_hack(self, outfile):
if mesonlib.is_windows():
cmd = 'cmd /C ""'
@@ -1004,6 +1056,10 @@ rule FORTRAN_DEP_HACK
if not is_cross:
self.generate_rust_compile_rules(compiler, outfile)
return
+ if langname == 'swift':
+ if not is_cross:
+ self.generate_swift_compile_rules(compiler, outfile)
+ return
if langname == 'fortran':
self.generate_fortran_dep_hack(outfile)
if is_cross:
diff --git a/test cases/swift/2 multifile/libfile.swift b/test cases/swift/2 multifile/libfile.swift
new file mode 100644
index 0000000..45f941c
--- /dev/null
+++ b/test cases/swift/2 multifile/libfile.swift
@@ -0,0 +1,3 @@
+func printSomething(text: String) {
+ print("Got this: \(text)")
+}
diff --git a/test cases/swift/2 multifile/main.swift b/test cases/swift/2 multifile/main.swift
new file mode 100644
index 0000000..61d67e2
--- /dev/null
+++ b/test cases/swift/2 multifile/main.swift
@@ -0,0 +1 @@
+printSomething("String from main")
diff --git a/test cases/swift/2 multifile/meson.build b/test cases/swift/2 multifile/meson.build
new file mode 100644
index 0000000..9012f3d
--- /dev/null
+++ b/test cases/swift/2 multifile/meson.build
@@ -0,0 +1,3 @@
+project('2 files', 'swift')
+
+test('2files', executable('twofiles', 'main.swift', 'libfile.swift'))