aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xenvironment.py33
-rwxr-xr-xinterpreter.py21
-rwxr-xr-xshellgenerator.py18
-rw-r--r--test cases/2 cxx/builder.txt2
-rw-r--r--test cases/3 static/builder.txt3
-rw-r--r--test cases/3 static/libfile.c3
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;
+}