From 7ed515dacc726b6413ff720b7c125670b60543a1 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Mon, 7 Dec 2015 21:52:08 +0200 Subject: Refactored dep file name so Swift dependency tracking works. --- ninjabackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 7d72e06..c8134d7 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -1269,7 +1269,7 @@ rule FORTRAN_DEP_HACK obj_basename = src_filename.replace('/', '_').replace('\\', '_') rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename) rel_obj += '.' + self.environment.get_object_suffix() - dep_file = rel_obj + '.' + compiler.get_depfile_suffix() + dep_file = compiler.depfile_for_object(rel_obj) if self.environment.coredata.get_builtin_option('use_pch'): pchlist = target.get_pch(compiler.language) else: -- cgit v1.1 From 43b07729aa058ce8af1aa4d7f3c445f61f39c42a Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Thu, 10 Dec 2015 21:49:41 +0200 Subject: Reworked swift code so now can use multiple source files in one target. --- ninjabackend.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'ninjabackend.py') 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: -- cgit v1.1 From d531f915b12ad648c1ae08749548233882087f12 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Dec 2015 00:19:25 +0200 Subject: Can build Swift libraries and link them. --- ninjabackend.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 9a8aa0b..2230b1f 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -837,7 +837,33 @@ class NinjaBackend(backends.Backend): element.write(outfile) self.check_outputs(element) + def swift_module_file_name(self, target): + return os.path.join(self.get_target_private_dir(target), + self.target_swift_modulename(target) + '.swiftmodule') + + def target_swift_modulename(self, target): + return target.name + + def determine_swift_dep_modules(self, target): + result = [] + for l in target.link_targets: + result.append(self.swift_module_file_name(l)) + return result + + def determine_swift_dep_dirs(self, target): + result = [] + for l in target.link_targets: + result.append(self.get_target_private_dir_abs_v2(l)) + return result + + def get_swift_link_deps(self, target): + result = [] + for l in target.link_targets: + result.append(self.get_target_filename(l)) + return result + def generate_swift_target(self, target, outfile): + module_name = self.target_swift_modulename(target) swiftc = self.environment.coredata.compilers['swift'] abssrc = [] for i in target.get_sources(): @@ -857,21 +883,49 @@ class NinjaBackend(backends.Backend): 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)) + compile_args += swiftc.get_module_args(module_name) + link_args = swiftc.get_output_args(os.path.join(self.environment.get_build_dir(), 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) + out_module_name = self.swift_module_file_name(target) + in_module_files = self.determine_swift_dep_modules(target) + abs_module_dirs = self.determine_swift_dep_dirs(target) + module_includes = [] + for x in abs_module_dirs: + module_includes += swiftc.get_include_args(x) + link_deps = self.get_swift_link_deps(target) + abs_link_deps = [os.path.join(self.environment.get_build_dir(), x) for x in link_deps] + + # Swiftc does not seem to be able to emit objects and module files in one go. + elem = NinjaBuildElement(rel_objects, + 'swift_COMPILER', + abssrc) + elem.add_dep(in_module_files) + elem.add_item('ARGS', compile_args + module_includes) 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 = NinjaBuildElement(out_module_name, + 'swift_COMPILER', + abssrc) + elem.add_dep(in_module_files) + elem.add_item('ARGS', compile_args + module_includes + swiftc.get_mod_gen_args()) elem.add_item('RUNDIR', rundir) elem.write(outfile) self.check_outputs(elem) + if isinstance(target, build.StaticLibrary): + elem = self.generate_link(target, outfile, self.get_target_filename(target), + rel_objects, self.build.static_linker) + elem.write(outfile) + elif isinstance(target, build.Executable): + elem = NinjaBuildElement(self.get_target_filename(target), 'swift_COMPILER', []) + elem.add_dep(rel_objects) + elem.add_dep(link_deps) + elem.add_item('ARGS', link_args + swiftc.get_std_exe_link_args() + objects + abs_link_deps) + elem.add_item('RUNDIR', rundir) + elem.write(outfile) + self.check_outputs(elem) + else: + raise MesonException('Swift supports only executable and static library targets.') def generate_static_link_rules(self, is_cross, outfile): if self.build.has_language('java'): @@ -997,10 +1051,7 @@ class NinjaBackend(backends.Backend): def generate_rust_compile_rules(self, compiler, outfile): rule = 'rule %s_COMPILER\n' % compiler.get_language() - 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]) + invoc = ' '.join([ninja_quote(i) for i in compiler.get_exelist()]) command = ' command = %s $ARGS $in\n' % invoc description = ' description = Compiling Rust source $in.\n' depfile = ' depfile = $targetdep\n' @@ -1015,7 +1066,10 @@ class NinjaBackend(backends.Backend): 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()]) + full_exe = [sys.executable, + os.path.join(self.environment.get_script_dir(), 'dirchanger.py'), + '$RUNDIR'] + compiler.get_exelist() + invoc = ' '.join([ninja_quote(i) for i in full_exe]) command = ' command = %s $ARGS $in\n' % invoc description = ' description = Compiling Swift source $in.\n' outfile.write(rule) -- cgit v1.1 From 961b000090e01a1eb3647c6b16d951ca419b13cb Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Dec 2015 23:14:16 +0200 Subject: Can generate swift sources with custom target. --- ninjabackend.py | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 2230b1f..b91250c 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -862,6 +862,26 @@ class NinjaBackend(backends.Backend): result.append(self.get_target_filename(l)) return result + def split_swift_generated_sources(self, target): + all_srcs = [] + for genlist in target.get_generated_sources(): + if isinstance(genlist, build.CustomTarget): + for ifile in genlist.get_filename(): + rel = os.path.join(self.get_target_dir(genlist), ifile) + all_srcs.append(rel) + else: + for ifile in genlist.get_outfilelist(): + rel = os.path.join(self.get_target_private_dir(target), ifile) + all_srcs.append(rel) + srcs = [] + others = [] + for i in all_srcs: + if i.endswith('.swift'): + srcs.append(i) + else: + others.append(i) + return (srcs, others) + def generate_swift_target(self, target, outfile): module_name = self.target_swift_modulename(target) swiftc = self.environment.coredata.compilers['swift'] @@ -873,15 +893,6 @@ class NinjaBackend(backends.Backend): 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(module_name) link_args = swiftc.get_output_args(os.path.join(self.environment.get_build_dir(), self.get_target_filename(target))) @@ -894,21 +905,32 @@ class NinjaBackend(backends.Backend): module_includes += swiftc.get_include_args(x) link_deps = self.get_swift_link_deps(target) abs_link_deps = [os.path.join(self.environment.get_build_dir(), x) for x in link_deps] + (rel_generated, _) = self.split_swift_generated_sources(target) + abs_generated = [os.path.join(self.environment.get_build_dir(), x) for x in rel_generated] + # 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 + abs_generated: + 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)) # Swiftc does not seem to be able to emit objects and module files in one go. elem = NinjaBuildElement(rel_objects, 'swift_COMPILER', abssrc) - elem.add_dep(in_module_files) - elem.add_item('ARGS', compile_args + module_includes) + elem.add_dep(in_module_files + rel_generated) + elem.add_item('ARGS', compile_args + abs_generated + module_includes) elem.add_item('RUNDIR', rundir) elem.write(outfile) self.check_outputs(elem) elem = NinjaBuildElement(out_module_name, 'swift_COMPILER', abssrc) - elem.add_dep(in_module_files) - elem.add_item('ARGS', compile_args + module_includes + swiftc.get_mod_gen_args()) + elem.add_dep(in_module_files + rel_generated) + elem.add_item('ARGS', compile_args + abs_generated + module_includes + swiftc.get_mod_gen_args()) elem.add_item('RUNDIR', rundir) elem.write(outfile) self.check_outputs(elem) -- cgit v1.1 From 161d633f362a316e4711b8ab524d3688cd6847ef Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 12 Dec 2015 00:17:44 +0200 Subject: Added support for calling into C. --- ninjabackend.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index b91250c..1258f07 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -844,10 +844,17 @@ class NinjaBackend(backends.Backend): def target_swift_modulename(self, target): return target.name + def is_swift_target(self, target): + for s in target.sources: + if s.endswith('swift'): + return True + return False + def determine_swift_dep_modules(self, target): result = [] for l in target.link_targets: - result.append(self.swift_module_file_name(l)) + if self.is_swift_target(l): + result.append(self.swift_module_file_name(l)) return result def determine_swift_dep_dirs(self, target): @@ -886,12 +893,20 @@ class NinjaBackend(backends.Backend): module_name = self.target_swift_modulename(target) swiftc = self.environment.coredata.compilers['swift'] abssrc = [] + abs_headers = [] + header_imports = [] for i in target.get_sources(): - if not swiftc.can_compile(i): + if swiftc.can_compile(i): + 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) + elif self.environment.is_header(i): + relh = i.rel_to_builddir(self.build_to_src) + absh = os.path.normpath(os.path.join(self.environment.get_build_dir(), relh)) + abs_headers.append(absh) + header_imports += swiftc.get_header_import_args(absh) + else: 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) compile_args = swiftc.get_compile_only_args() compile_args += swiftc.get_module_args(module_name) @@ -922,7 +937,8 @@ class NinjaBackend(backends.Backend): 'swift_COMPILER', abssrc) elem.add_dep(in_module_files + rel_generated) - elem.add_item('ARGS', compile_args + abs_generated + module_includes) + elem.add_dep(abs_headers) + elem.add_item('ARGS', compile_args + header_imports + abs_generated + module_includes) elem.add_item('RUNDIR', rundir) elem.write(outfile) self.check_outputs(elem) -- cgit v1.1