From 5987773f3c32f209b951e41764c9cca432607612 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 29 Aug 2009 08:07:50 +0100 Subject: [PATCH 1/3] First attempt at splitting out the containers build from the SConstruct. This creates a runnable final.axf, but the load is not correct and the tests fail to execute. --- SConstruct | 132 +++++++++++++++--------------------------- containers/SConscript | 103 ++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 containers/SConscript diff --git a/SConstruct b/SConstruct index 3158618..40bd9c6 100644 --- a/SConstruct +++ b/SConstruct @@ -26,7 +26,6 @@ import os includeDirectory = 'include' containersDirectory = 'containers' -posixServicesDirectory = containersDirectory + '/posix' toolsDirectory = 'tools' cml2ToolsDirectory = toolsDirectory + '/cml2-tools' buildDirectory = 'build' @@ -35,6 +34,8 @@ cml2CompileRulesFile = buildDirectory + '/cml2Rules.out' cml2ConfigPropertiesFile = buildDirectory + '/cml2Config.out' cml2ConfigHeaderFile = buildDirectory + '/cml2Config.h' +configureHelpEntry = 'configure the build.' + # The choice of which parts of the kernel to compile and include in the build depends on the configuration # which is managed using CML2. CML2 uses a base configuration file (currently #configs/arm.cml) to drive # an interaction with the user which results in a trio of files that specify the user choice. @@ -59,14 +60,26 @@ if 'configure' in COMMAND_LINE_TARGETS : os.system(toolsDirectory + '/cml2header.py -o ' + cml2ConfigHeaderFile + ' -i ' + cml2ConfigPropertiesFile) if len(COMMAND_LINE_TARGETS) != 1: - print '#### Warning####: configure is part of the command line, all the other targets are being ignored as this is a configure step.' + print '#### Warning ####: configure is a target on the command line, all the other targets are being ignored as this is a configure step.' Command('configure', ['#configs/arm.cml'], performCML2Configuration) Clean('configure', buildDirectory) + baseEnvironment = Environment(tools=[], + targetHelpEntries = {'configure': configureHelpEntry}, + ) + else : if not os.path.exists(cml2ConfigPropertiesFile): - print "####\n#### Configuration has not been undertaken, please run 'scons configure'.\n####" + if GetOption('help'): + print ''' +The project has to be configured even to get the help on the project. +Running 'scons configure' starts the configuration system. Typing x +causes the configuration system to terminate and write all the +configuration data. 'scons -h' will then print the project help. +''' + else: + print "####\n#### Configuration has not been undertaken, please run 'scons configure'.\n####" Exit() ########## Create the base environment and process the configuration ######################## @@ -95,10 +108,10 @@ else : }, includeDirectory = includeDirectory, containersDirectory = containersDirectory, - posixServicesDirectory = posixServicesDirectory, toolsDirectory = toolsDirectory, cml2ToolsDirectory = cml2ToolsDirectory, buildDirectory = buildDirectory, + targetHelpEntries = {'configure': configureHelpEntry}, ) # It is assumed that the C code is assuming that the configuration file will be found at l4/config.h so create it there. @@ -153,84 +166,29 @@ else : libelf = SConscript('libs/elf/SConscript', variant_dir = buildDirectory + '/lib/elf', duplicate = 0, exports = {'environment': baseEnvironment}) Alias('libs', crts.values() + libs.values() + [libelf]) + baseEnvironment['targetHelpEntries']['libs'] = 'build the support libraries.' ########## Build the kernel ######################## - startAxf = SConscript('src/SConscript' , variant_dir = buildDirectory + '/kernel' , duplicate = 0, exports = {'environment': baseEnvironment}) + startAxf = SConscript('src/SConscript', variant_dir = buildDirectory + '/kernel', duplicate = 0, exports = {'environment': baseEnvironment}) Alias('kernel', startAxf) + baseEnvironment['targetHelpEntries']['kernel'] = 'build the kernel itself.' -########## Build the task libraries ######################## +########## Handle all the container creation ####################### - taskSupportLibraryEnvironment = baseEnvironment.Clone() - taskSupportLibraryEnvironment.Append(CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory]) + containers = SConscript('containers/SConscript', variant_dir = buildDirectory + '/containers', duplicate = 0, exports = {'environment': baseEnvironment, 'startAxf': startAxf}) - taskLibraryNames = [f.name for f in Glob(posixServicesDirectory + '/lib*')] - - taskLibraries = [] - for library in taskLibraryNames: - taskLibraries.append(SConscript(posixServicesDirectory + '/' + library + '/SConscript', variant_dir = buildDirectory + '/' + posixServicesDirectory + '/' + library, - duplicate = 0, exports = {'environment': taskSupportLibraryEnvironment})) - - Alias ('tasklibs', taskLibraries) - -########## Build the tasks ######################## - - def buildTask(programName, sources, environment, previousImage, extraCppPath=None): - e = environment.Clone() - e.Append(LINKFLAGS=['-T' + e['posixServicesDirectory'] + '/' + programName + '/include/linker.lds']) - e.Append(LIBPATH=['#build/' + e['posixServicesDirectory'] + '/' + programName]) - if extraCppPath: e.Append(CPPPATH=extraCppPath) - objects = e.StaticObject(sources) - Depends(objects, e['configFiles']) - program = e.Program(programName, objects) - environment['physicalBaseLinkerScript'] = Command('include/physical_base.lds', previousImage, 'tools/pyelf/readelf.py --first-free-page ' + previousImage[0].path + ' >> $TARGET') - Depends(program, [environment['physicalBaseLinkerScript']]) - return program - - tasksEnvironment = baseEnvironment.Clone() - tasksEnvironment.Append(LIBS = taskLibraries + ['gcc'] + taskLibraries) - tasksEnvironment.Append(CPPDEFINES = ['__USERSPACE__']) - tasksEnvironment.Append(CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory, 'include', \ - '#' + posixServicesDirectory + '/libl4/include', '#' + posixServicesDirectory + '/libc/include', \ - '#' + posixServicesDirectory + '/libmem', '#' + posixServicesDirectory + '/libposix/include']) - tasksEnvironment.Append(buildTask = buildTask) - -#### -#### TODO: Why does the linker require crt0.o to be in the current directory and named as such. Is it -#### because of the text in the linker script? -#### - - #### taskNameList = [ f.name for f in Glob(posixServicesDirectory + '*') if f.name not in taskLibraryNames + ['bootdesc'] ] - #### imageOrderData = [(taskName, []) for taskName in taskNameList] - execfile(posixServicesDirectory + '/taskOrder.py') - imageOrderData = [(taskName, []) for taskName in taskOrder] - imageOrderData[0][1].append(startAxf) - tasks = [] - for i in range(len(imageOrderData)): - taskName = imageOrderData[i][0] - dependency = imageOrderData[i][1] - program = SConscript(posixServicesDirectory + '/' + taskName + '/SConscript', variant_dir = buildDirectory + '/' + posixServicesDirectory + '/' + taskName, - duplicate = 0, exports = {'environment': tasksEnvironment, 'previousImage': dependency[0]}) - tasks.append(program) - if i < len(imageOrderData) - 1: - imageOrderData[i+1][1].append(program) - - Alias ('tasks', tasks) - -########## Create the boot description ######################## - - bootdesc = SConscript(posixServicesDirectory + '/bootdesc/SConscript', variant_dir = buildDirectory + '/' + posixServicesDirectory + '/bootdesc', - duplicate = 0, exports = {'environment': baseEnvironment, 'images': [startAxf] + tasks}) - - Alias('bootdesc', bootdesc) + Alias('containers', containers) + baseEnvironment['targetHelpEntries']['containers'] = 'build all the containers.' ########## Do the packing / create loadable ######################## loader = SConscript('loader/SConscript', variant_dir = buildDirectory + '/loader', duplicate = 0, - exports = {'environment': baseEnvironment, 'images': [startAxf, bootdesc] + tasks, 'libsInOrder': [libelf, libs['baremetal'], 'gcc', libs['baremetal']]}) + exports = {'environment': baseEnvironment, 'images': [startAxf] + containers, 'libsInOrder': [libelf, libs['baremetal'], 'gcc', libs['baremetal']]}) Alias('final', loader) + baseEnvironment['targetHelpEntries']['final'] = 'build all components and the final loadable.' # The test does not terminate and Ctrl-C and Ctrl-Z have no effect. Run the job in the background so # the initiating terminal retains control and allows the process to be killed from this terminal. Add @@ -241,25 +199,31 @@ else : ########## Other rules. ######################## - Default(crts.values() + libs.values() + [libelf, startAxf] + tasks + bootdesc + loader) + Default(loader) Clean('.', [buildDirectory]) ########## Be helpful ######################## -Help(''' -Explicit targets are: - - configure -- configure the build area ready for a build. - - libs -- build the support library. - kernel -- build the kernel. - tasklibs -- build all the support libraries for the tasks. - tasks -- build all the tasks. - bootdesc -- build the tasks and the boot descriptor. - final -- build the loadable. - -The default target is to compile everything and to do a final link. - -Compilation can only be undertaken after a configuration. +if len(COMMAND_LINE_TARGETS) != 0: + Help('\n') + for item in COMMAND_LINE_TARGETS: + if baseEnvironment['targetHelpEntries'].has_key(item): + Help(' ' + item + ' -- ' + baseEnvironment['targetHelpEntries'][item] + '\n') + elif FindFile(item, '.'): + Help(' ' + item + ' is a file that exists or can be created.\n') + else: + Help(' ' + item + ' is not a possible target.\n') +else: + Help(''' +Possible targets are: +''') + targetList = baseEnvironment['targetHelpEntries'].keys() + targetList.sort() + for item in targetList: + Help(' ' + item + ' -- ' + baseEnvironment['targetHelpEntries'][item] + '\n') + Help(''' +The default target is 'final'. + +A configure must have been executed before any other target is possible. ''') diff --git a/containers/SConscript b/containers/SConscript new file mode 100644 index 0000000..571bc61 --- /dev/null +++ b/containers/SConscript @@ -0,0 +1,103 @@ +# -*- mode: python; coding: utf-8; -*- + +# Codezero -- a microkernel for embedded systems. +# +# Copyright © 2009 B Labs Ltd +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU +# General Public License as published by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +# License for more details. +# +# You should have received a copy of the GNU General Public License along with this program. If not, see +# . +# +# Author: Russel Winder + +Import('environment', 'startAxf') + +posixServicesDirectory = 'posix' + +compilationProducts = [] + +########## Build the task libraries ######################## + +taskSupportLibraryEnvironment = environment.Clone() +taskSupportLibraryEnvironment.Append(CPPPATH = ['#' + environment['buildDirectory'], '#' + environment['buildDirectory'] + '/l4', '#' + environment['includeDirectory']]) + +taskSupportLibraryEnvironment['posixServicesDirectory'] = 'containers/' + posixServicesDirectory + +taskLibraryNames = [f.name for f in Glob(posixServicesDirectory + '/lib*')] + +taskLibraries = [] +for library in taskLibraryNames: + taskLibraries.append(SConscript(posixServicesDirectory + '/' + library + '/SConscript', exports = {'environment': taskSupportLibraryEnvironment})) + +Alias ('tasklibs', taskLibraries) +environment['targetHelpEntries']['tasklibs'] = 'build the support libraries for the tasks in the containers.' + +########## Build the tasks ######################## + +def buildTask(programName, sources, environment, previousImage, extraCppPath=None): + e = environment.Clone() + e.Append(LINKFLAGS=['-T' + e['posixServicesDirectory'] + '/' + programName + '/include/linker.lds']) + e.Append(LIBPATH=['#' + e['buildDirectory'] + '/' + e['posixServicesDirectory'] + '/' + programName]) + if extraCppPath: e.Append(CPPPATH=extraCppPath) + objects = e.StaticObject(sources) + Depends(objects, e['configFiles']) + program = e.Program(programName, objects) + environment['physicalBaseLinkerScript'] = Command('include/physical_base.lds', previousImage, 'tools/pyelf/readelf.py --first-free-page ' + previousImage[0].path + ' >> $TARGET') + Depends(program, [environment['physicalBaseLinkerScript']]) + return program + +tasksEnvironment = environment.Clone() +tasksEnvironment.Append(LIBS = taskLibraries + ['gcc'] + taskLibraries) +tasksEnvironment.Append(CPPDEFINES = ['__USERSPACE__']) +tasksEnvironment.Append(CPPPATH = ['#' + environment['buildDirectory'], '#' + environment['buildDirectory'] + '/l4', '#' + environment['includeDirectory'], 'include', \ + '#containers/' +posixServicesDirectory + '/libl4/include', '#containers/' + posixServicesDirectory + '/libc/include', \ + '#containers/' + posixServicesDirectory + '/libmem', '#containers/' + posixServicesDirectory + '/libposix/include']) +tasksEnvironment.Append(buildTask = buildTask) + +tasksEnvironment['posixServicesDirectory'] = 'containers/' + posixServicesDirectory + +#### +#### TODO: Why does the linker require crt0.o to be in the current directory and named as such. Is it +#### because of the text in the linker script? +#### + +#### taskNameList = [ f.name for f in Glob(posixServicesDirectory + '*') if f.name not in taskLibraryNames + ['bootdesc'] ] +#### imageOrderData = [(taskName, []) for taskName in taskNameList] + +taskOrder = ('mm0', 'fs0', 'test0') + +#execfile('containers/' + posixServicesDirectory + '/taskOrder.py') +imageOrderData = [(taskName, []) for taskName in taskOrder] +imageOrderData[0][1].append(startAxf) +tasks = [] +for i in range(len(imageOrderData)): + taskName = imageOrderData[i][0] + dependency = imageOrderData[i][1] + program = SConscript(posixServicesDirectory + '/' + taskName + '/SConscript', exports = {'environment': tasksEnvironment, 'previousImage': dependency[0]}) + tasks.append(program) + if i < len(imageOrderData) - 1: + imageOrderData[i+1][1].append(program) + +Alias ('tasks', tasks) +environment['targetHelpEntries']['tasks'] = 'build the tasks for the containers.' + +########## Create the boot description ######################## + +bootdescEnvironment = environment.Clone() + +bootdescEnvironment['posixServicesDirectory'] = 'containers/' + posixServicesDirectory + +bootdesc = SConscript(posixServicesDirectory + '/bootdesc/SConscript', exports = {'environment': bootdescEnvironment, 'images': [startAxf] + tasks}) + +Alias('bootdesc', bootdesc) +environment['targetHelpEntries']['bootdesc'] = 'build the boot descriptions of the tasks for the containers.' + + +Return('compilationProducts') From 68f299088520f8ff5394a2365d1c71fc68a8ac24 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 29 Aug 2009 08:24:56 +0100 Subject: [PATCH 2/3] Return the compilation products from the containers build so they get loaded in. --- containers/SConscript | 1 + 1 file changed, 1 insertion(+) diff --git a/containers/SConscript b/containers/SConscript index 571bc61..ee976ff 100644 --- a/containers/SConscript +++ b/containers/SConscript @@ -99,5 +99,6 @@ bootdesc = SConscript(posixServicesDirectory + '/bootdesc/SConscript', exports = Alias('bootdesc', bootdesc) environment['targetHelpEntries']['bootdesc'] = 'build the boot descriptions of the tasks for the containers.' +compilationProducts = tasks + [bootdesc] Return('compilationProducts') From 98ca32779c2cf3496b7fb3c16b63f63bf6aa80b2 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sat, 29 Aug 2009 12:35:29 +0100 Subject: [PATCH 3/3] Make using the task order file work again. There are serious problems with the build in that the link order is crucial and should not be. --- containers/SConscript | 5 ++--- containers/posix/taskOrder.py | 7 +++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/containers/SConscript b/containers/SConscript index ee976ff..f8e0351 100644 --- a/containers/SConscript +++ b/containers/SConscript @@ -71,9 +71,8 @@ tasksEnvironment['posixServicesDirectory'] = 'containers/' + posixServicesDirect #### taskNameList = [ f.name for f in Glob(posixServicesDirectory + '*') if f.name not in taskLibraryNames + ['bootdesc'] ] #### imageOrderData = [(taskName, []) for taskName in taskNameList] -taskOrder = ('mm0', 'fs0', 'test0') - -#execfile('containers/' + posixServicesDirectory + '/taskOrder.py') +# Have to know the build is in build/containers, can't use '#' here. +execfile('../../containers/' + posixServicesDirectory + '/taskOrder.py') imageOrderData = [(taskName, []) for taskName in taskOrder] imageOrderData[0][1].append(startAxf) tasks = [] diff --git a/containers/posix/taskOrder.py b/containers/posix/taskOrder.py index b6550ec..34a8a13 100644 --- a/containers/posix/taskOrder.py +++ b/containers/posix/taskOrder.py @@ -19,4 +19,11 @@ # A sequence determining the order of tasks in the packing. +#### +#### TODO: Why do the tests only run when the load order is mm0, fs0, test0 -- any other order and the tests +#### do not run. Worse if test0 is not last then there are problems with the compilation du to issues with +#### linker scripts. +#### + taskOrder = ('mm0', 'fs0', 'test0') +#taskOrder = ('fs0', 'mm0', 'test0')