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.
This commit is contained in:
Russel Winder
2009-08-29 08:07:50 +01:00
parent 9e894274a3
commit 5987773f3c
2 changed files with 151 additions and 84 deletions

View File

@@ -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.
''')

103
containers/SConscript Normal file
View File

@@ -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
# <http://www.gnu.org/licenses/>.
#
# 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')