diff options
-rw-r--r-- | backends.py | 3 | ||||
-rw-r--r-- | compilers.py | 7 | ||||
-rw-r--r-- | environment.py | 3 | ||||
-rw-r--r-- | ninjabackend.py | 16 | ||||
-rw-r--r-- | test cases/common/103 manygen/depuser.c | 8 | ||||
-rw-r--r-- | test cases/common/103 manygen/meson.build | 8 | ||||
-rw-r--r-- | test cases/common/103 manygen/subdir/funcinfo.def | 1 | ||||
-rwxr-xr-x | test cases/common/103 manygen/subdir/manygen.py | 69 | ||||
-rw-r--r-- | test cases/common/103 manygen/subdir/meson.build | 7 |
9 files changed, 121 insertions, 1 deletions
diff --git a/backends.py b/backends.py index c996cb8..64d3860 100644 --- a/backends.py +++ b/backends.py @@ -358,6 +358,9 @@ class Backend(): ofilenames = [os.path.join(self.get_target_dir(target), i) for i in target.output] srcs = [] outdir = self.get_target_dir(target) + # Many external programs fail on empty arguments. + if outdir == '': + outdir = '.' if absolute_paths: outdir = os.path.join(self.environment.get_build_dir(), outdir) for i in target.sources: diff --git a/compilers.py b/compilers.py index 06dd1d0..73fd8cd 100644 --- a/compilers.py +++ b/compilers.py @@ -28,6 +28,7 @@ cpp_suffixes = ['cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx', 'c++'] c_suffixes = ['c'] clike_suffixes = c_suffixes + cpp_suffixes obj_suffixes = ['o', 'obj', 'res'] +lib_suffixes = ['a', 'lib', 'dll', 'dylib', 'so'] def is_header(fname): if hasattr(fname, 'fname'): @@ -47,6 +48,12 @@ def is_object(fname): suffix = fname.split('.')[-1] return suffix in obj_suffixes +def is_library(fname): + if hasattr(fname, 'fname'): + fname = fname.fname + suffix = fname.split('.')[-1] + return suffix in lib_suffixes + gnulike_buildtype_args = {'plain' : [], 'debug' : ['-g'], 'debugoptimized' : ['-O2', '-g'], diff --git a/environment.py b/environment.py index e09f6ae..e905b2f 100644 --- a/environment.py +++ b/environment.py @@ -145,6 +145,9 @@ class Environment(): def is_object(self, fname): return is_object(fname) + def is_library(self, fname): + return is_library(fname) + def merge_options(self, options): for (name, value) in options.items(): if name not in self.coredata.user_options: diff --git a/ninjabackend.py b/ninjabackend.py index c465f7c..8fc1772 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -264,6 +264,8 @@ int dummy; header_deps)) elif self.environment.is_object(src): obj_list.append(src) + elif self.environment.is_library(src): + pass else: # Assume anything not specifically a source file is a header. This is because # people generate files with weird suffixes (.inc, .fh) that they then include @@ -1674,17 +1676,29 @@ rule FORTRAN_DEP_HACK self.determine_rpath_dirs(target), target.install_rpath) if self.environment.coredata.get_builtin_option('coverage'): commands += linker.get_coverage_link_args() + custom_target_libraries = self.get_custom_target_provided_libraries(target) commands += extra_args + commands += custom_target_libraries commands = linker.unixtype_flags_to_native(commands) dep_targets = [self.get_dependency_filename(t) for t in dependencies] dep_targets += [os.path.join(self.environment.source_dir, target.subdir, t) for t in target.link_depends] elem = NinjaBuildElement(outname, linker_rule, obj_list) - elem.add_dep(dep_targets) + elem.add_dep(dep_targets + custom_target_libraries) elem.add_item('LINK_ARGS', commands) self.check_outputs(elem) return elem + def get_custom_target_provided_libraries(self, target): + libs = [] + for t in target.get_generated_sources(): + if not isinstance(t, build.CustomTarget): + continue + for f in t.output: + if self.environment.is_library(f): + libs.append(os.path.join(self.get_target_dir(t), f)) + return libs + def determine_rpath_dirs(self, target): link_deps = target.get_all_link_deps() result = [] diff --git a/test cases/common/103 manygen/depuser.c b/test cases/common/103 manygen/depuser.c new file mode 100644 index 0000000..1a825e0 --- /dev/null +++ b/test cases/common/103 manygen/depuser.c @@ -0,0 +1,8 @@ +#include"gen_func.h" + +int main(int argc, char **argv) { + unsigned int i = (unsigned int) gen_func_in_lib(); + unsigned int j = (unsigned int) gen_func_in_obj(); + unsigned int k = (unsigned int) gen_func_in_src(); + return (int)(i + j + k); +} diff --git a/test cases/common/103 manygen/meson.build b/test cases/common/103 manygen/meson.build new file mode 100644 index 0000000..5079d1b --- /dev/null +++ b/test cases/common/103 manygen/meson.build @@ -0,0 +1,8 @@ +project('manygen', 'c') + +subdir('subdir') + +exe = executable('depuser', 'depuser.c', + generated) + +test('depuser test', exe) diff --git a/test cases/common/103 manygen/subdir/funcinfo.def b/test cases/common/103 manygen/subdir/funcinfo.def new file mode 100644 index 0000000..b074186 --- /dev/null +++ b/test cases/common/103 manygen/subdir/funcinfo.def @@ -0,0 +1 @@ +gen_func diff --git a/test cases/common/103 manygen/subdir/manygen.py b/test cases/common/103 manygen/subdir/manygen.py new file mode 100755 index 0000000..fbf2eae --- /dev/null +++ b/test cases/common/103 manygen/subdir/manygen.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 + +# Generates a static library, object file, source +# file and a header file. + +import sys, os +import shutil, subprocess + +funcname = open(sys.argv[1]).readline().strip() +outdir = sys.argv[2] + +if not os.path.isdir(outdir): + print('Outdir does not exist.') + sys.exit(1) + +if shutil.which('cl'): + print('VS support not yet added.') + sys.exit(1) + +objsuffix = '.o' +libsuffix = '.a' + +outo = os.path.join(outdir, funcname + objsuffix) +outa = os.path.join(outdir, funcname + libsuffix) +outh = os.path.join(outdir, funcname + '.h') +outc = os.path.join(outdir, funcname + '.c') + +compiler = shutil.which('gcc') +if compiler is None: + compiler = shutil.which('clang') +if compiler is None: + compiler = shutil.which('cc') +if compiler is None: + print('No known compilers found.') + sys.exit(1) +linker = 'ar' + +tmpc = 'diibadaaba.c' +tmpo = 'diibadaaba' + objsuffix + +open(outc, 'w').write('''#include"%s.h" +int %s_in_src() { + return 0; +} +''' % (funcname, funcname)) + +open(outh, 'w').write('''#pragma once +int %s_in_lib(); +int %s_in_obj(); +int %s_in_src(); +''' % (funcname, funcname, funcname)) + +open(tmpc, 'w').write('''int %s_in_obj() { + return 0; +} +''' % funcname) + +subprocess.check_call([compiler, '-c', '-o', outo, tmpc]) + +open(tmpc, 'w').write('''int %s_in_lib() { + return 0; +} +''' % funcname) + +subprocess.check_call([compiler, '-c', '-o', tmpo, tmpc]) +subprocess.check_call([linker, 'csr', outa, tmpo]) +os.unlink(tmpo) +os.unlink(tmpc) + diff --git a/test cases/common/103 manygen/subdir/meson.build b/test cases/common/103 manygen/subdir/meson.build new file mode 100644 index 0000000..4470d1a --- /dev/null +++ b/test cases/common/103 manygen/subdir/meson.build @@ -0,0 +1,7 @@ +gen = find_program('manygen.py') + +generated = custom_target('manygen', + output : ['gen_func.a', 'gen_func.c', 'gen_func.h', 'gen_func.o'], + input : ['funcinfo.def'], + command : [gen, '@INPUT@', '@OUTDIR@'], +) |