diff options
-rwxr-xr-x | environment.py | 33 | ||||
-rwxr-xr-x | interpreter.py | 21 | ||||
-rwxr-xr-x | shellgenerator.py | 18 | ||||
-rw-r--r-- | test cases/2 cxx/builder.txt | 2 | ||||
-rw-r--r-- | test cases/3 static/builder.txt | 3 | ||||
-rw-r--r-- | test cases/3 static/libfile.c | 3 |
6 files changed, 74 insertions, 6 deletions
diff --git a/environment.py b/environment.py index 02675fa..daf0e87 100755 --- a/environment.py +++ b/environment.py @@ -40,6 +40,9 @@ class CCompiler(): def get_debug_flags(self): return ['-g'] + + def get_std_link_flags(self): + return [] def can_compile(self, filename): suffix = filename.split('.')[-1] @@ -117,6 +120,20 @@ class GnuCXXCompiler(CXXCompiler): def get_std_opt_flags(self): return GnuCXXCompiler.std_opt_flags +class ArLinker(): + std_flags = ['cr'] + + def __init__(self, exelist): + self.exelist = exelist + + def get_exelist(self): + return self.exelist + + def get_std_link_flags(self): + return self.std_flags + + def get_output_flags(self): + return [] class Environment(): def __init__(self, source_dir, build_dir): @@ -127,6 +144,7 @@ class Environment(): self.default_c = ['cc'] self.default_cxx = ['c++'] + self.default_static_linker = ['ar'] self.exe_suffix = '' self.shared_lib_suffix = 'so' @@ -163,12 +181,27 @@ class Environment(): 'Free Software Foundation' in out: return GnuCXXCompiler(exelist) raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"') + + def detect_static_linker(self): + exelist = self.get_static_linker_exelist() + p = subprocess.Popen(exelist + ['--version'], stdout=subprocess.PIPE) + out = p.communicate()[0] + out = out.decode() + if p.returncode == 0: + return ArLinker(exelist) + raise EnvironmentException('Unknown static linker "' + ' '.join(exelist) + '"') def get_cxx_compiler_exelist(self): evar = 'CXX' if evar in os.environ: return os.environ[evar].split() return self.default_cxx + + def get_static_linker_exelist(self): + evar = 'AR' + if evar in os.environ: + return os.environ[evar].split() + return self.default_static_linker def get_source_dir(self): return self.source_dir diff --git a/interpreter.py b/interpreter.py index 0fa6dfb..6e3fb04 100755 --- a/interpreter.py +++ b/interpreter.py @@ -64,6 +64,9 @@ class BuildTarget(InterpreterObject): class Executable(BuildTarget): pass +class StaticLibrary(BuildTarget): + pass + class Interpreter(): def __init__(self, code, environment): @@ -74,6 +77,7 @@ class Interpreter(): self.targets = {} self.variables = {} self.environment = environment + self.static_linker = self.environment.detect_static_linker() def get_project(self): return self.project @@ -169,6 +173,19 @@ class Interpreter(): name = args[0] dep = environment.find_external_dependency(name) return dep + + def func_static_lib(self, node, args): + for a in args: + if not isinstance(a, str): + raise InvalidArguments('Line %d: Argument %s is not a string.' % (node.lineno(), str(a))) + name= args[0] + sources = args[1:] + if name in self.targets: + raise InvalidCode('Line %d: tried to create static library "%s", but a target of that name already exists.' % (node.lineno(), name)) + l = StaticLibrary(name, sources) + self.targets[name] = l + print('Creating static library "%s" with %d files.' % (name, len(sources))) + return l def function_call(self, node): func_name = node.get_function_name() @@ -183,9 +200,11 @@ class Interpreter(): return self.func_executable(node, args) elif func_name == 'find_dep': return self.func_find_dep(node, args) + elif func_name == 'static_library': + return self.func_static_lib(node, args) else: raise InvalidCode('Unknown function "%s".' % func_name) - + def is_assignable(self, value): if isinstance(value, InterpreterObject) or \ isinstance(value, environment.PkgConfigDependency): diff --git a/shellgenerator.py b/shellgenerator.py index 872b996..d030af5 100755 --- a/shellgenerator.py +++ b/shellgenerator.py @@ -15,6 +15,7 @@ # limitations under the License. import os, stat +import interpreter def shell_quote(cmdlist): return ["'" + x + "'" for x in cmdlist] @@ -68,14 +69,18 @@ class ShellGenerator(): return abs_obj def generate_link(self, target, outfile, outname, obj_list): - linker = self.interpreter.compilers[0] # Fixme. + if isinstance(target, interpreter.StaticLibrary): + linker = self.interpreter.static_linker + else: + linker = self.interpreter.compilers[0] # Fixme. commands = [] commands += linker.get_exelist() - commands += obj_list + commands += linker.get_std_link_flags() for dep in target.get_external_deps(): commands += dep.get_link_flags() commands += linker.get_output_flags() commands.append(outname) + commands += obj_list quoted = shell_quote(commands) outfile.write('\necho Linking \\"%s\\".\n' % target.get_basename()) outfile.write(' '.join(quoted) + ' || exit\n') @@ -91,8 +96,13 @@ class ShellGenerator(): target = i[1] print('Generating target', name) targetdir = self.get_target_dir(target) - outname = os.path.join(targetdir, target.get_basename()) - suffix = self.environment.get_exe_suffix() + if isinstance(target, interpreter.Executable): + prefix = '' + suffix = self.environment.get_exe_suffix() + elif isinstance(target, interpreter.StaticLibrary): + prefix = self.environment.get_static_lib_prefix() + suffix = self.environment.get_static_lib_suffix() + outname = os.path.join(targetdir, prefix + target.get_basename()) if suffix != '': outname = outname + '.' + suffix obj_list = [] diff --git a/test cases/2 cxx/builder.txt b/test cases/2 cxx/builder.txt index 89e9910..724d0e3 100644 --- a/test cases/2 cxx/builder.txt +++ b/test cases/2 cxx/builder.txt @@ -1,3 +1,3 @@ -project('trivial test') +project('c++ test') language('c++') exe = executable('trivialprog', 'trivial.cc') diff --git a/test cases/3 static/builder.txt b/test cases/3 static/builder.txt new file mode 100644 index 0000000..2ae7a36 --- /dev/null +++ b/test cases/3 static/builder.txt @@ -0,0 +1,3 @@ +project('static library test') +language('c') +exe = static_library('mylib', 'libfile.c') diff --git a/test cases/3 static/libfile.c b/test cases/3 static/libfile.c new file mode 100644 index 0000000..80a427b --- /dev/null +++ b/test cases/3 static/libfile.c @@ -0,0 +1,3 @@ +int libfunc() { + return 3; +} |