Added target install option.
This commit is contained in:
parent
1bfae39a9d
commit
b6886b2c27
|
@ -24,6 +24,7 @@ parser = OptionParser()
|
|||
|
||||
parser.add_option('--prefix', default='/usr/local', dest='prefix')
|
||||
parser.add_option('--libdir', default='lib', dest='libdir')
|
||||
parser.add_option('--bindir', default='bin', dest='bindir')
|
||||
parser.add_option('--includedir', default='include', dest='includedir')
|
||||
parser.add_option('--datadir', default='share', dest='datadir')
|
||||
|
||||
|
@ -32,6 +33,8 @@ class BuilderApp():
|
|||
|
||||
def __init__(self, dir1, dir2, options):
|
||||
(self.source_dir, self.build_dir) = self.validate_dirs(dir1, dir2)
|
||||
if options.prefix[0] != '/':
|
||||
raise RuntimeError('--prefix must be an absolute path.')
|
||||
self.options = options
|
||||
|
||||
def has_builder_file(self, dirname):
|
||||
|
@ -66,7 +69,7 @@ class BuilderApp():
|
|||
if len(code.strip()) == 0:
|
||||
raise interpreter.InvalidCode('Builder file is empty.')
|
||||
assert(isinstance(code, str))
|
||||
env = environment.Environment(self.source_dir, self.build_dir)
|
||||
env = environment.Environment(self.source_dir, self.build_dir, options)
|
||||
b = build.Build(env)
|
||||
intr = interpreter.Interpreter(code, b)
|
||||
intr.run()
|
||||
|
|
|
@ -142,9 +142,10 @@ class ArLinker():
|
|||
return []
|
||||
|
||||
class Environment():
|
||||
def __init__(self, source_dir, build_dir):
|
||||
def __init__(self, source_dir, build_dir, options):
|
||||
self.source_dir = source_dir
|
||||
self.build_dir = build_dir
|
||||
self.options = options
|
||||
self.scratch_dir = os.path.join(build_dir, 'builder-private')
|
||||
os.makedirs(self.scratch_dir, exist_ok=True)
|
||||
|
||||
|
@ -232,6 +233,15 @@ class Environment():
|
|||
|
||||
def get_object_suffix(self):
|
||||
return self.object_suffix
|
||||
|
||||
def get_prefix(self):
|
||||
return self.options.prefix
|
||||
|
||||
def get_libdir(self):
|
||||
return self.options.libdir
|
||||
|
||||
def get_bindir(self):
|
||||
return self.options.bindir
|
||||
|
||||
# This should be an InterpreterObject. Fix it.
|
||||
class PkgConfigDependency():
|
||||
|
|
|
@ -39,9 +39,11 @@ class BuildTarget(InterpreterObject):
|
|||
self.sources = sources
|
||||
self.external_deps = []
|
||||
self.methods = {'add_dep': self.add_dep_method,
|
||||
'link' : self.link_method}
|
||||
'link' : self.link_method,
|
||||
'install': self.install}
|
||||
self.link_targets = []
|
||||
self.filename = 'no_name'
|
||||
self.need_install = False
|
||||
|
||||
def get_filename(self):
|
||||
return self.filename
|
||||
|
@ -54,7 +56,10 @@ class BuildTarget(InterpreterObject):
|
|||
|
||||
def get_sources(self):
|
||||
return self.sources
|
||||
|
||||
|
||||
def should_install(self):
|
||||
return self.need_install
|
||||
|
||||
def add_external_dep(self, dep):
|
||||
if not isinstance(dep, environment.PkgConfigDependency):
|
||||
raise InvalidArguments('Argument is not an external dependency')
|
||||
|
@ -78,6 +83,10 @@ class BuildTarget(InterpreterObject):
|
|||
return self.methods[method_name](args)
|
||||
raise InvalidCode('Unknown method "%s" in BuildTarget.' % method_name)
|
||||
|
||||
def install(self, args):
|
||||
if len(args) != 0:
|
||||
raise InvalidArguments('Install() takes no arguments.')
|
||||
self.need_install = True
|
||||
|
||||
class Executable(BuildTarget):
|
||||
def __init__(self, name, sources, environment):
|
||||
|
@ -95,6 +104,7 @@ class StaticLibrary(BuildTarget):
|
|||
suffix = environment.get_static_lib_suffix()
|
||||
self.filename = prefix + self.name + '.' + suffix
|
||||
|
||||
|
||||
class SharedLibrary(BuildTarget):
|
||||
def __init__(self, name, sources, environment):
|
||||
BuildTarget.__init__(self, name, sources)
|
||||
|
@ -102,6 +112,7 @@ class SharedLibrary(BuildTarget):
|
|||
suffix = environment.get_shared_lib_suffix()
|
||||
self.filename = prefix + self.name + '.' + suffix
|
||||
|
||||
|
||||
class Test(InterpreterObject):
|
||||
def __init__(self, name, exe):
|
||||
InterpreterObject.__init__(self)
|
||||
|
@ -229,6 +240,8 @@ class Interpreter():
|
|||
raise InvalidArguments('Line %d: Argument %s is not a string.' % (node.lineno(), str(a)))
|
||||
name= args[0]
|
||||
sources = args[1:]
|
||||
if len(sources) == 0:
|
||||
raise InvalidArguments('Line %d: target has no source files.' % node.lineno())
|
||||
if name in self.build.targets:
|
||||
raise InvalidCode('Line %d: tried to create target "%s", but a target of that name already exists.' % (node.lineno(), name))
|
||||
l = targetclass(name, sources, self.environment)
|
||||
|
|
10
run_tests.py
10
run_tests.py
|
@ -18,15 +18,19 @@ from glob import glob
|
|||
import os, subprocess, shutil
|
||||
|
||||
test_build_dir = 'work area'
|
||||
install_dir = os.path.join(os.path.split(os.path.abspath(__file__))[0], 'install dir')
|
||||
builder_command = './builder.py'
|
||||
compile_command = os.path.join(test_build_dir, 'compile.sh')
|
||||
test_command = os.path.join(test_build_dir, 'run_tests.sh')
|
||||
install_command = os.path.join(test_build_dir, 'install.sh')
|
||||
|
||||
def run_test(testdir):
|
||||
shutil.rmtree(test_build_dir)
|
||||
shutil.rmtree(install_dir)
|
||||
os.mkdir(test_build_dir)
|
||||
os.mkdir(install_dir)
|
||||
print('Running test: ' + testdir)
|
||||
p = subprocess.Popen([builder_command, testdir, test_build_dir])
|
||||
p = subprocess.Popen([builder_command, '--prefix', install_dir, testdir, test_build_dir])
|
||||
p.wait()
|
||||
if p.returncode != 0:
|
||||
raise RuntimeError('Generating the build system failed.')
|
||||
|
@ -38,6 +42,10 @@ def run_test(testdir):
|
|||
pt.wait()
|
||||
if pt.returncode != 0:
|
||||
raise RuntimeError('Running unit tests failed.')
|
||||
pi = subprocess.Popen([install_command])
|
||||
pi.wait()
|
||||
if pi.returncode != 0:
|
||||
raise RuntimeError('Running install failed.')
|
||||
|
||||
def run_tests():
|
||||
tests = glob('test cases/*')
|
||||
|
|
|
@ -27,39 +27,70 @@ class ShellGenerator():
|
|||
self.environment = build.environment
|
||||
self.build_filename = 'compile.sh'
|
||||
self.test_filename = 'run_tests.sh'
|
||||
self.install_filename = 'install.sh'
|
||||
self.processed_targets = {}
|
||||
|
||||
def generate(self):
|
||||
self.generate_compile_script()
|
||||
self.generate_test_script()
|
||||
self.generate_install_script()
|
||||
|
||||
def create_shfile(self, outfilename, message):
|
||||
outfile = open(outfilename, 'w')
|
||||
outfile.write('#!/bin/sh\n\n')
|
||||
outfile.write(message)
|
||||
cdcmd = ['cd', self.environment.get_build_dir()]
|
||||
outfile.write(' '.join(shell_quote(cdcmd)) + '\n')
|
||||
os.chmod(outfilename, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\
|
||||
stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
|
||||
return outfile
|
||||
|
||||
def generate_compile_script(self):
|
||||
outfilename = os.path.join(self.environment.get_build_dir(), self.build_filename)
|
||||
outfile = open(outfilename, 'w')
|
||||
outfile.write('#!/bin/sh\n\n')
|
||||
outfile.write('echo This is an autogenerated shell script build file for project \\"%s\\".\n'
|
||||
% self.build.get_project())
|
||||
outfile.write('echo This is experimental and most likely will not work!\n')
|
||||
cdcmd = ['cd', self.environment.get_build_dir()]
|
||||
outfile.write(' '.join(shell_quote(cdcmd)) + '\n')
|
||||
message = """echo This is an autogenerated shell script build file for project \\"%s\\"
|
||||
echo This is experimental and most likely will not work!
|
||||
""" % self.build.get_project()
|
||||
outfile = self.create_shfile(outfilename, message)
|
||||
self.generate_commands(outfile)
|
||||
outfile.close()
|
||||
os.chmod(outfilename, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\
|
||||
stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
|
||||
|
||||
def generate_test_script(self):
|
||||
outfilename = os.path.join(self.environment.get_build_dir(), self.test_filename)
|
||||
outfile = open(outfilename, 'w')
|
||||
outfile.write('#!/bin/sh\n\n')
|
||||
outfile.write('echo This is an autogenerated shell script test file for project \\"%s\\".\n'
|
||||
% self.build.get_project())
|
||||
outfile.write('echo Run the compile script before this one or bad things will happen!\n')
|
||||
cdcmd = ['cd', self.environment.get_build_dir()]
|
||||
outfile.write(' '.join(shell_quote(cdcmd)) + '\n')
|
||||
message = """echo This is an autogenerated test script for project \\"%s\\"
|
||||
echo This is experimental and most likely will not work!
|
||||
echo Run compile.sh before this or bad things will happen.
|
||||
""" % self.build.get_project()
|
||||
outfile = self.create_shfile(outfilename, message)
|
||||
self.generate_tests(outfile)
|
||||
outfile.close()
|
||||
os.chmod(outfilename, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |\
|
||||
stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
|
||||
|
||||
def generate_install_script(self):
|
||||
outfilename = os.path.join(self.environment.get_build_dir(), self.install_filename)
|
||||
message = """echo This is an autogenerated install script for project \\"%s\\"
|
||||
echo This is experimental and most likely will not work!
|
||||
echo Run compile.sh before this or bad things will happen.
|
||||
""" % self.build.get_project()
|
||||
outfile = self.create_shfile(outfilename, message)
|
||||
self.generate_install(outfile)
|
||||
outfile.close()
|
||||
|
||||
def generate_install(self, outfile):
|
||||
prefix = self.environment.get_prefix()
|
||||
libdir = os.path.join(prefix, self.environment.get_libdir())
|
||||
bindir = os.path.join(prefix, self.environment.get_bindir())
|
||||
outfile.write("mkdir -p '%s'\n" % libdir)
|
||||
outfile.write("mkdir -p '%s'\n" % bindir)
|
||||
for tmp in self.build.get_targets().items():
|
||||
(name, t) = tmp
|
||||
if t.should_install():
|
||||
if isinstance(t, interpreter.Executable):
|
||||
outdir = bindir
|
||||
else:
|
||||
outdir = libdir
|
||||
outfile.write('echo Installing "%s".\n' % name)
|
||||
cpcommand = ['cp', self.get_target_filename(t), outdir]
|
||||
cpcommand = ' '.join(shell_quote(cpcommand)) + '\n'
|
||||
outfile.write(cpcommand)
|
||||
|
||||
def generate_tests(self, outfile):
|
||||
for t in self.build.get_tests():
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
project('install test', 'c')
|
||||
|
||||
stlib = static_library('stat', 'stat.c')
|
||||
shlib = shared_library('shar', 'shar.c')
|
||||
exe = executable('prog', 'prog.c')
|
||||
|
||||
stlib.install()
|
||||
shlib.install()
|
||||
exe.install()
|
|
@ -0,0 +1,3 @@
|
|||
int main(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int func() { return 15; }
|
|
@ -0,0 +1 @@
|
|||
int func() { return 933; }
|
Loading…
Reference in New Issue