Revision: 8eaf13b06ce6 Author: Niek Linnenbank <nieklinnenbank@xxxxxxxxx> Date: Fri Jan 23 20:26:37 2015 UTC Log: Rewrote configuration file parser to .conf files. Support for Include() inside .conf files. Added default build.conf for target and host builds. Allow commandline VAR=VALUE overrides. https://code.google.com/p/freenos/source/detail?r=8eaf13b06ce6 Added: /config/host/gcc.conf /config/x86/pc/build.conf /site_scons/config.py Deleted: /build.conf Modified: /.gitignore /SConstruct /config/x86/pc/clang.conf /config/x86/pc/gcc.conf /kernel/x86/pc/SConscript /site_scons/build.py ======================================= --- /dev/null +++ /config/host/gcc.conf Fri Jan 23 20:26:37 2015 UTC @@ -0,0 +1,19 @@ +# +# Copyright (C) 2015 Niek Linnenbank +# +# 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/>. +# + +CPPFLAGS = '-D__HOST__' +CPPPATH = [ '#include' ] ======================================= --- /dev/null +++ /config/x86/pc/build.conf Fri Jan 23 20:26:37 2015 UTC @@ -0,0 +1,24 @@ +# +# Copyright (C) 2015 Niek Linnenbank +# +# 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/>. +# + +ARCH = 'x86' +SYSTEM = 'pc' +COMPILER = 'gcc' +BUILDROOT = 'build/${ARCH}/${SYSTEM}' +VERBOSE = False + +Include('config/${ARCH}/${SYSTEM}/${COMPILER}.conf') ======================================= --- /dev/null +++ /site_scons/config.py Fri Jan 23 20:26:37 2015 UTC @@ -0,0 +1,148 @@ +# +# Copyright (C) 2015 Niek Linnenbank +# +# 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/>. +# + +import os.path +import shutil +from SCons.Script import * +from autoconf import * + +# Then a command: +# scons defconfig SUBCONF=raspberry_model_bplus ARCH=arm SYSTEM=rpi +# which copies raspberry_model_bplus.conf to build.conf +# scons defconfig ARCH=arm SYSTEM=rpi +# which copies config/arm/rpi/build.conf to build.conf +# +# Or if only for the host environment: +# scons HOST:CC=gcc-4.4 HOST:CCFLAGS='-Wall' +# +# Any driver or server can then just do: +# #include <FreeNOS/Config.h> +# #ifdef MY_SETTING +# #endif + +local_dict = {} + +def initialize(target, host, params): + """ + Initialize configuration subsystem. + This will create a build.conf / build.host.conf if already existing. + """ + if not os.path.exists('build.conf'): + shutil.copyfile('config/' + params.get('ARCH', 'x86') + '/' + + params.get('SYSTEM', 'pc') + '/' + + params.get('CONF', 'build') + '.conf', 'build.conf') + + if not os.path.exists('build.host.conf'): + shutil.copyfile('config/host/build.conf', 'build.host.conf') + + # Apply commandline arguments for use in build.conf's + for key in params: + if not key.startswith('HOST:'): + set_value(local_dict, key, params[key]) + apply_file('build.conf', target) + + for key in params: + if key.startswith('HOST:'): + set_value(local_dict, key[5:], params[key]) + apply_file('build.host.conf', host) + + # Apply the current VERSION to the environments. + version = open('VERSION').read().strip() + target['VERSION'] = version + host['VERSION'] = version ++ # Reapply commandline arguments. This overwrites anything from build*.conf
+ for key in params: + if key.startswith('HOST:'): + set_value(host, key[5:], params[key]) + else: + set_value(target, key, params[key]) + +def set_value(env, key, value): + """ + Apply new value to a environment. + """ + if type(value) == bool or value in ('True', 'true', 'False', 'false'): + env[key] = bool(value) + else: + try: + env[key] = int(value) + except: + env[key] = value + +def apply_file(conf_file, env): + """ + Apply a configuration on the given SCons environment + """ + global local_dict + result = parse_file(conf_file) + + for item in result: + if type(result[item]) is list: + env[item] = eval_list(result[item], result) + elif type(result[item]) is str: + env[item] = eval_string(result[item], result) + else: + env[item] = result[item] + + local_dict = {} + + +def parse_file(conf_file): + """ + Parses a configuration file. + Returns a dictionary with the parsed values. + """ + global_dict = { 'Include' : parse_file } + config_file = eval_string(conf_file) + + execfile(config_file, global_dict, local_dict) + return local_dict + +def eval_list(lst, replace_dict = None): + """ + Replace configuration item values in the given list. + """ + new_lst = [] + + for item in lst: + new_lst.append(eval_string(item, replace_dict)) + + return new_lst + +def eval_string(string, replace_dict = None): + """ + Replace configuration item values in the given string or list. + """ + if not replace_dict: + replace_dict = local_dict + + split_string = string.split('}') + final_string = '' + + for substr in split_string: + idx = substr.find('${') + if idx == -1: + final_string += substr + else: + final_string += substr[0:idx] + var_name = substr[idx+2:] + + if var_name in replace_dict: + final_string += replace_dict[var_name] + + return final_string ======================================= --- /build.conf Mon Jan 19 19:58:13 2015 UTC +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (C) 2010 Niek Linnenbank -# -# 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/>. -# - -VERSION = '0.1.0' -ARCH = 'x86' -SYSTEM = 'pc' -COMPILER = 'config/' + ARCH + '/' + SYSTEM + '/gcc.conf' -BUILDROOT = 'build/' + ARCH + '/' + SYSTEM -VERBOSE = 'False' - ======================================= --- /.gitignore Tue Jan 20 18:37:02 2015 UTC +++ /.gitignore Fri Jan 23 20:26:37 2015 UTC @@ -6,7 +6,8 @@ config.log .sconf_temp .sconsign.dblite -boot/boot.* -host/ include/FreeNOS .gdbinit +build.conf +build.host.conf + ======================================= --- /SConstruct Wed Jan 21 18:25:37 2015 UTC +++ /SConstruct Fri Jan 23 20:26:37 2015 UTC @@ -31,13 +31,14 @@ VariantDir(target['BUILDROOT'] + '/bin', '#bin', duplicate = 0) VariantDir(target['BUILDROOT'] + '/srv', '#srv', duplicate = 0) VariantDir(target['BUILDROOT'] + '/kernel', '#kernel', duplicate = 0)-#VariantDir(target['BUILDROOT'] + '/kernel/' + target['ARCH'] + '/' + target['SYSTEM'],
-# '#kernel/' + target['ARCH'] + '/' + target['SYSTEM'], duplicate = 0) SConscript(target['BUILDROOT'] + '/lib/SConscript') SConscript(target['BUILDROOT'] + '/bin/SConscript') SConscript(target['BUILDROOT'] + '/srv/SConscript')SConscript(target['BUILDROOT'] + '/kernel/' + target['ARCH'] + '/' + target['SYSTEM'] + '/SConscript')
+# Install files to the target RootFS +#target.TargetInstall('VERSION') + # # Host build # ======================================= --- /config/x86/pc/clang.conf Thu Jan 22 18:33:49 2015 UTC +++ /config/x86/pc/clang.conf Fri Jan 23 20:26:37 2015 UTC @@ -15,10 +15,10 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -CC = 'clang' -CXX = 'clang' -AS = 'clang' -LD = 'clang' +CC = '${CROSS_COMPILE}clang' +CXX = '${CROSS_COMPILE}clang' +AS = '${CROSS_COMPILE}clang' +LD = '${CROSS_COMPILE}clang' CCFLAGS = [ '-m32', '-Wall', '-nostdinc', '-fno-builtin', '-fno-stack-protector', '-g3', '-Wno-write-strings' ] ======================================= --- /config/x86/pc/gcc.conf Thu Jan 22 18:33:49 2015 UTC +++ /config/x86/pc/gcc.conf Fri Jan 23 20:26:37 2015 UTC @@ -15,18 +15,18 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -CC = 'gcc' -AS = 'gcc' -LD = 'gcc' -CXX = 'g++' +CC = '${CROSS_COMPILE}gcc' +AS = '${CROSS_COMPILE}gcc' +LD = '${CROSS_COMPILE}gcc' +CXX = '${CROSS_COMPILE}g++' CCFLAGS = [ '-m32', '-Wall', '-nostdinc', '-fno-stack-protector', '-fno-builtin', '-g3', '-Wno-write-strings' ] CXXFLAGS = [ '-fno-rtti', '-fno-exceptions' ] ASFLAGS = [ '-m32', '-Wall', '-nostdinc' ] +LINKUSER = [ '-T', 'config/x86/pc/user.ld' ] +LINKKERN = [ '-T', 'config/x86/pc/kernel.ld' ] LINKFLAGS = [ '-m32', '-static', '-nostdlib', '-nostartfiles', '-nodefaultlibs', '-Wl,-whole-archive' ] -LINKUSER = [ '-T', 'config/x86/pc/user.ld' ] -LINKKERN = [ '-T', 'config/x86/pc/kernel.ld' ] +LINKFLAGS += LINKUSER CPPPATH = [ '#include' ] - ======================================= --- /kernel/x86/pc/SConscript Thu Jan 22 18:31:11 2015 UTC +++ /kernel/x86/pc/SConscript Fri Jan 23 20:26:37 2015 UTC @@ -35,7 +35,7 @@ # # Boot Image # -env.BootImage('#${BUILDROOT}/boot.img', '#${BUILDROOT}/kernel/x86/pc/boot.imgdesc') +env.BootImage('#${BUILDROOT}/boot.img', '#kernel/x86/pc/boot.imgdesc') # # RootFS ======================================= --- /site_scons/build.py Thu Jan 22 18:34:13 2015 UTC +++ /site_scons/build.py Fri Jan 23 20:26:37 2015 UTC @@ -16,6 +16,7 @@ # import os.path +import config from SCons.Script import * from autoconf import * @@ -92,7 +93,6 @@ Export('SubDirectories') - # Create target, host and kernel environments. host = Environment() host.AddMethod(HostProgram, "HostProgram") @@ -111,40 +111,8 @@target = host.Clone(tools = ["default", "bootimage", "iso", "binary", "linn"],
toolpath = ["site_scons"]) -# Global top-level configuration. -global_vars = Variables('build.conf') -global_vars.Add('VERSION', 'FreeNOS release version number')-global_vars.Add(EnumVariable('ARCH', 'Target machine CPU architecture', 'x86',
- allowed_values = ("x86",))) -global_vars.Add(EnumVariable('SYSTEM', 'Target machine system type', 'pc', - allowed_values = ("pc",))) -global_vars.Add(PathVariable('COMPILER', 'Target compiler chain', None)) -global_vars.Add('BUILDROOT','Object output directory')-global_vars.Add(BoolVariable('VERBOSE', 'Output verbose compilation commands', False))
-global_vars.Update(target) -global_vars.Update(host) - -# System-specific configuration. -system_vars = Variables(target['COMPILER']) -system_vars.Add('CC', 'C Compiler') -system_vars.Add('CXX', 'C++ Compiler') -system_vars.Add('AS', 'Assembler') -system_vars.Add('LD', 'Linker') -system_vars.Add('CROSS_COMPILE', 'Cross Compiler toolchain prefix', '') -system_vars.Add('CCFLAGS', 'C/C++ Compiler flags') -system_vars.Add('CXXFLAGS', 'C++ Compiler flags') -system_vars.Add('ASFLAGS', 'Assembler flags') -system_vars.Add('LINKFLAGS', 'Linker flags') -system_vars.Add('LINKKERN', 'Linker flags for the kernel linker script') -system_vars.Add('LINKUSER', 'Linker flags for user programs linker script') -system_vars.Add('CPPPATH', 'C Preprocessor include directories') -system_vars.Update(target) - -target.Prepend(CC = target['CROSS_COMPILE'], - CXX = target['CROSS_COMPILE'], - AS = target['CROSS_COMPILE'], - LD = target['CROSS_COMPILE']) -target.Append(LINKFLAGS = target['LINKUSER']) +# Apply configuration +config.initialize(target, host, ARGUMENTS) # Enables verbose compilation command output. if not target['VERBOSE']: @@ -162,17 +130,6 @@ CheckCCFlags(target) CheckCXXFlags(target) -# Host environment uses a different output directory. -host.Replace(ARCH = 'host') -host.Replace(SYSTEM = 'host') -host.Replace(BUILDROOT = 'build/host') -host.Append (CPPFLAGS = '-D__HOST__') -host.Append (CPPPATH = [ '#include' ]) - -# Provide configuration help. -Help(global_vars.GenerateHelpText(target)) -Help(system_vars.GenerateHelpText(target)) - # Make a symbolic link to the system-specific headers. try: os.unlink("include/FreeNOS") @@ -183,4 +140,3 @@ os.symlink(target['ARCH'], "include/FreeNOS") except: pass -