#! /bin/python3 import sys import configparser import os.path import os import shutil help_string = f""" usage: config [options...] Configuration script for the Vhex unikernel. You should build out-of-tree by creating a build directory and configuring from there. Options: -h,--help display this message --verbose display more information during the compilation step --format=FORMAT[,format[,...]] select the format of the library generation. You can use two format: <> static - generate a static library <> dynamic - generate a dynamic library <> all - same behaviour as "--format=static,dynamic" By default, only "dynamic" is used. --board[=BOARD,board[,...]] select boards. If no board name is given, a list of all available board will be printed. --prefix=PATH installation path for all generated libraries """.strip() # # create and apply the arguments parser # def parse_arguments(): """ The objectif of this function is to generate the "arguments object" with all arguments passed throuth this script correctly isolated. """ args = { 'board' : [], 'format' : [], 'verbose': False, 'prefix': '' } arg_name = [ "-h", "--help", "--format", "--verbose", "--board", "--prefix" ] for arg in sys.argv[1:]: info = arg.split("=") if (info[0] in arg_name) == False: print("%s: unreconized option '%s'" % (sys.argv[0],info[0])) print("Try '%s --help' for more information" % sys.argv[0]) exit(84) if (info[0] in ["-h", "--help"]) == True: print(help_string) exit(0) if info[0] == "--verbose": args["verbose"] = True continue if info[0] == "--prefix": args["prefix"] = info[1] continue if len(info) > 1: args[info[0][2:]] = info[1].split(",") return args # # part handlers # def board_check(file, board_list): boards = list(os.walk('../board'))[0][1] archs = list(os.walk('../src/drivers/mpu'))[0][1] if not board_list: print('board available:') for board in boards: path = '../board/%s/board.ini' % board if not os.path.exists(path): print('board \'%s\' does not exists' % board) continue conf = configparser.ConfigParser() conf.read(path) if not ('meta' in conf) or not ('description' in conf['meta']): print('<> %s\t\tNo description available' % board) continue print('<> %s\t\t%s' % (board, conf['meta']['description'])) exit(0) valid_board_list = [] for board in board_list: if not (board in boards): print("board '%s' does not exist" % board) continue path = '../board/%s/board.ini' % board if not os.path.exists(path): print("board '%s' does not have INI descriptor file" % board) continue conf = configparser.ConfigParser() conf.read(path) if not ('drivers' in conf) or not ('mpu' in conf['drivers']): print("board '%s' does not have MPU information" % board) continue arch = '' mpu = conf['drivers']['mpu'] for _arch in archs: if not os.path.exists('../src/drivers/mpu/%s/%s' % (_arch,mpu)): continue arch = _arch break if not arch: print("board '%s': unreconized MPU '%s'" % (board,mpu)) continue pathlist = [ '../board/%s' % board, '../src/drivers/mpu/%s/%s' % (_arch,mpu) ] for driver in conf['drivers']: if driver == 'mpu': continue dpath = '../src/drivers/%s' % driver if not os.path.exists(dpath): print("board '%s': unreconized driver \'%s\'" % (board, dpath)) continue for t in conf['drivers'][driver].split(','): tpath = dpath + '/' + t if not os.path.exists(tpath): print("board '%s': unreconized driver \'%s\'" % (board, t)) continue pathlist.append(tpath) tpath = tpath + '/target/' + arch if os.path.exists(tpath): pathlist.append(tpath) for dirent in os.listdir('../src'): if not (dirent in ['drivers', 'arch']): pathlist.append('../src/' + dirent) ldflags,cflags,prefix,libs = [],[],[],[] if 'toolchain' in conf: if 'prefix' in conf['toolchain']: prefix = conf['toolchain']['prefix'] if 'cflags' in conf['toolchain']: cflags = conf['toolchain']['cflags'].split(',') if 'libs' in conf['toolchain']: libs = conf['toolchain']['libs'].split(',') confstr = 'CONFIG.' + board; file.write( confstr + '.SRC-MODULE-PATH :=' + ' '.join(pathlist) + '\n' + confstr + '.TOOLCHAIN.LDFLAGS :=' + ' '.join(ldflags) + '\n' + confstr + '.TOOLCHAIN.CFLAGS :=' + ' '.join(cflags) + '\n' + confstr + '.TOOLCHAIN.PREFIX :=' + prefix + '\n' + confstr + '.LIBS :=' + ' '.join(libs) + '\n' ) if not os.path.exists(board): os.mkdir(board) os.symlink( '../../board/%s/%s.ld' % (board,board), '%s/%s.ld' % (board,board) ) valid_board_list.append(board) file.write('CONFIG.BOARD-LIST := ' + ' '.join(valid_board_list) + '\n') def format_check(file, format_list): file.write('CONFIG.FORMAT-LIST :=') for _format in format_list: if not (_format in ["static", "dynamic", "all"]): print("%s: unreconized format '%s'" % (sys.argv[0], _format)) exit(84) if _format == 'all': file.write(' dynamic static\n') return file.write(' ' + _format) if not format_list: file.write(' dynamic') file.write('\n') def prefix_check(file, prefix): file.write('CONFIG.INSTALL-PREFIX :=' + prefix + '\n') def verbose_check(file, verbose): file.write(f"CONFIG.VERBOSE := {'true' if verbose else 'false'}\n") # # "real" entry of the script # def main(): args = parse_arguments() if os.path.exists('../src') == False: print('error: you should configure from a build directory, like this:') print(' mkdir build && cd build && ../configure [options..]') exit(84) file = open('kernel.cfg', 'w') board_check(file, args['board']) format_check(file, args['format']) prefix_check(file, args['prefix']) verbose_check(file, args['verbose']) if os.path.exists('Makefile'): os.remove('Makefile') os.symlink('../make/Makefile', 'Makefile') main()