Changeset 9a0367f in mainline


Ignore:
Timestamp:
2009-01-20T18:38:16Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
27fb3d6
Parents:
b1747a5
Message:

configuration system overhaul (requires newt)

Files:
3 deleted
37 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    rb1747a5 r9a0367f  
    11#
    2 # Copyright (c) 2006 Ondrej Palkovsky 
     2# Copyright (c) 2006 Ondrej Palkovsky
    33# All rights reserved.
    44#
     
    2727#
    2828
    29 ## General configuration directives
    30 
    31 # Platform
     29
     30## General platform options
     31
     32% Platform
    3233@ "amd64" AMD64/Intel EM64T (PC)
    3334@ "arm32" ARM 32-bit
     
    4142! PLATFORM (choice)
    4243
    43 # Machine
     44% Machine type
    4445@ "msim" MSIM
    4546@ "simics" Simics
     
    4849! [PLATFORM=mips32] MACHINE (choice)
    4950
    50 # Machine type
     51% Machine type
    5152@ "i460GX" i460GX chipset machine
    5253@ "ski" Ski ia64 simulator
    5354! [PLATFORM=ia64] MACHINE (choice)
    5455
    55 # Compiler
     56% CPU type
     57@ "pentium4" Pentium 4
     58@ "pentium3" Pentium 3
     59@ "core" Core Solo/Duo
     60@ "athlon-xp" Athlon XP
     61@ "athlon-mp" Athlon MP
     62! [PLATFORM=ia32|PLATFORM=ia32xen] MACHINE (choice)
     63
     64% CPU type
     65@ "opteron" Opteron
     66! [PLATFORM=amd64] MACHINE (choice)
     67
     68% CPU type
     69@ "us" UltraSPARC I-II subarchitecture
     70@ "us3" UltraSPARC III-IV subarchitecture
     71! [PLATFORM=sparc64] MACHINE (choice)
     72
     73% Ramdisk format
     74@ "tmpfs" TMPFS image
     75@ "fat" FAT16 image
     76! RDFMT (choice)
     77
     78
     79## Compiler options
     80
     81% Compiler
    5682@ "gcc_cross" GCC Cross-compiler
    5783@ "gcc_native" GCC Native
     
    6086! [PLATFORM=amd64|PLATFORM=ia32|PLATFORM=ia32xen] COMPILER (choice)
    6187
    62 # Compiler
     88% Compiler
    6389@ "gcc_cross" GCC Cross-compiler
    6490@ "gcc_native" GCC Native
     
    6692! [PLATFORM=ia64] COMPILER (choice)
    6793
    68 # Compiler
     94% Compiler
    6995@ "gcc_cross" GCC Cross-compiler
    7096@ "gcc_native" GCC Native
     
    7298! [PLATFORM=sparc64] COMPILER (choice)
    7399
    74 # Compiler
     100% Compiler
    75101@ "gcc_cross" GCC Cross-compiler
    76102@ "gcc_native" GCC Native
    77103! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=ppc64] COMPILER (choice)
    78104
    79 # Debug build
     105
     106## Debug build options
     107
     108% Debug build
    80109! CONFIG_DEBUG (y/n)
     110
     111
     112## Kernel features options
     113
     114% Support for SMP
     115! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia32xen|PLATFORM=sparc64|PLATFORM=ia64] CONFIG_SMP (y/n)
     116
     117% Improved support for hyperthreading
     118! [(PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n)
     119
     120% Simics BIOS AP boot fix
     121! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_SMP=y] CONFIG_SIMICS_FIX (y/n)
     122
     123% Lazy FPU context switching
     124! [(PLATFORM=mips32&MACHINE!=msim&MACHINE!=simics)|PLATFORM=amd64|PLATFORM=ia32|PLATFORM=ia64|PLATFORM=sparc64|PLATFORM=ia32xen] CONFIG_FPU_LAZY (y/n)
     125
     126% Use VHPT
     127! [PLATFORM=ia64] CONFIG_VHPT (n/y)
     128
     129% Use TSB
     130! [PLATFORM=sparc64] CONFIG_TSB (y/n)
     131
     132% Support for Z8530 serial port
     133! [PLATFORM=sparc64] CONFIG_Z8530 (y/n)
     134
     135% Support for NS16550 serial port
     136! [PLATFORM=sparc64|(PLATFORM=ia64&MACHINE!=ski)] CONFIG_NS16550 (n/y)
     137
     138% Support for Serengeti console
     139! [PLATFORM=sparc64] CONFIG_SGCN (y/n)
     140
     141% IOSapic on default address support
     142! [PLATFORM=ia64&MACHINE!=ski] CONFIG_IOSAPIC (y/n)
     143
     144% Interrupt-driven driver for Legacy Keyboard?
     145! [CONFIG_NS16550=n&CONFIG_IOSAPIC=y&MACHINE!=ski] CONFIG_I8042_INTERRUPT_DRIVEN (y/n)
     146
     147% Interrupt-driven driver for NS16550?
     148! [CONFIG_NS16550=y&((PLATFORM!=ia64)|CONFIG_IOSAPIC=y)&MACHINE!=ski] CONFIG_NS16550_INTERRUPT_DRIVEN (y/n)
     149
     150% Virtually indexed D-cache support
     151! [PLATFORM=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n)
     152
     153% Support for userspace debuggers
     154! CONFIG_UDEBUG (n/y)
     155
     156% Kernel console support
     157! CONFIG_KCONSOLE (y/n)
     158
     159% Detailed kernel logging
     160! CONFIG_LOG (n/y)
     161
     162% Deadlock detection support for spinlocks
     163! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n)
     164
     165% Watchpoint on rewriting AS with zero
     166! [CONFIG_DEBUG=y&(PLATFORM=amd64|PLATFORM=ia32|PLATFORM=ia32xen)] CONFIG_DEBUG_AS_WATCHPOINT (y/n)
     167
     168% Save all interrupt registers
     169! [CONFIG_DEBUG=y&(PLATFORM=amd64|PLATFORM=mips32|PLATFORM=ia32|PLATFORM=ia32xen)] CONFIG_DEBUG_ALLREGS (y/n)
     170
     171% Compile kernel tests
     172! CONFIG_TEST (y/n)
     173
     174
     175## Hardware support
     176
     177% Framebuffer support
     178! [(PLATFORM=mips32&MACHINE=lgxemul)|(PLATFORM=mips32&MACHINE=bgxemul)|(PLATFORM=ia32)|(PLATFORM=amd64)|(PLATFORM=arm32)] CONFIG_FB (y/n)
     179
     180% Framebuffer width
     181@ "640"
     182@ "800"
     183@ "1024"
     184@ "1152"
     185@ "1280"
     186@ "1400"
     187@ "1440"
     188@ "1600"
     189@ "2048"
     190! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_WIDTH (choice)
     191
     192% Framebuffer height
     193@ "480"
     194@ "600"
     195@ "768"
     196@ "852"
     197@ "900"
     198@ "960"
     199@ "1024"
     200@ "1050"
     201@ "1200"
     202@ "1536"
     203! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_HEIGHT (choice)
     204
     205% Framebuffer depth
     206@ "8"
     207@ "16"
     208@ "24"
     209! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice)
     210
     211% Start AP processors by the loader
     212! [PLATFORM=sparc64] CONFIG_SMP (y/n)
     213
     214% Use Block Address Translation by the loader
     215! [PLATFORM=ppc32] CONFIG_BAT (y/n)
     216
     217% Preserve A.OUT header in isofs.b
     218! [PLATFORM=sparc64] CONFIG_AOUT_ISOFS_B (y/n)
     219
     220% External ramdisk
     221! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n)
  • Makefile

    rb1747a5 r9a0367f  
    3737ifeq ($(PLATFORM),amd64)
    3838        KARCH = amd64
    39         MACHINE = opteron
    4039        UARCH = amd64
    4140        BARCH = amd64
     
    112111
    113112all:
    114         tools/config.py HelenOS.config default $(PLATFORM) $(COMPILER) $(CONFIG_DEBUG)
     113        tools/config.py HelenOS.config default
    115114        $(MAKE) -C . build
    116115
    117 build:
    118 ifneq ($(MACHINE),)
    119         $(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) MACHINE=$(MACHINE)
    120 else
    121         $(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG)
    122 endif
    123         $(MAKE) -C uspace ARCH=$(UARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG)
    124 ifneq ($(IMAGE),)
    125         $(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) IMAGE=$(IMAGE)
    126 else
    127         $(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG)
    128 endif
     116build: Makefile.config
     117        $(MAKE) -C kernel ARCH=$(KARCH)
     118        $(MAKE) -C uspace ARCH=$(UARCH)
     119        $(MAKE) -C boot ARCH=$(BARCH) IMAGE=$(IMAGE)
    129120
    130 config:
     121config: HelenOS.config
    131122        tools/config.py HelenOS.config
    132123
    133 distclean:
    134         -$(MAKE) -C kernel distclean
    135         -$(MAKE) -C uspace distclean
    136         -$(MAKE) -C boot distclean
     124distclean: clean
    137125        rm -f Makefile.config tools/*.pyc
    138126
    139127clean:
    140         -$(MAKE) -C kernel clean
    141         -$(MAKE) -C uspace clean
    142         -$(MAKE) -C boot clean
     128        -$(MAKE) -C kernel clean ARCH=$(KARCH)
     129        -$(MAKE) -C uspace clean ARCH=$(UARCH)
     130        -$(MAKE) -C boot clean ARCH=$(BARCH) IMAGE=$(IMAGE)
    143131
    144132cscope:
  • boot/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 -include Makefile.config
     32-include ../Makefile.config
    3333
    3434## Paths
     
    5151endif
    5252
    53 .PHONY: all build config distclean clean generic_clean
     53.PHONY: all build clean generic_clean
    5454
    55 all:
    56         ../tools/config.py boot.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(IMAGE)
    57         $(MAKE) -C . build
     55all: ../Makefile.config build
    5856
    5957-include arch/$(ARCH)/Makefile.inc
    6058
    61 config:
    62         ../tools/config.py boot.config
    63 
    64 distclean: clean
    65         -rm Makefile.config
    66 
    6759generic_clean:
    6860        -rm generic/*.o genarch/*.o
  • boot/arch/arm32/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • boot/arch/ia64/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • boot/arch/mips32/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • boot/arch/ppc32/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • boot/arch/ppc64/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • boot/arch/sparc64/loader/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../../version
    30 include ../../../Makefile.config
     30include ../../../../Makefile.config
    3131
    3232## Toolchain configuration
  • kernel/Makefile

    rb1747a5 r9a0367f  
    3131#
    3232
    33 -include ../version
    34 -include Makefile.config
     33include ../version
     34-include ../Makefile.config
    3535
    3636INCLUDES = generic/include
     
    360360GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
    361361
    362 .PHONY: all build config distclean clean archlinks depend disasm
    363 
    364 all:
    365         ../tools/config.py kernel.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(MACHINE)
     362.PHONY: all build clean archlinks depend disasm
     363
     364all: ../Makefile.config
     365        -rm Makefile.depend
    366366        $(MAKE) -C . build
    367367
    368368build: kernel.bin disasm
    369369
    370 config:
    371         -rm Makefile.depend
    372         ../tools/config.py kernel.config
    373 
    374370-include Makefile.depend
    375 
    376 distclean: clean
    377         -rm Makefile.config
    378371
    379372clean:
  • tools/config.py

    rb1747a5 r9a0367f  
    22#
    33# Copyright (c) 2006 Ondrej Palkovsky
     4# Copyright (c) 2009 Martin Decky
    45# All rights reserved.
    56#
     
    2829#
    2930"""
    30 HelenOS configuration script
     31HelenOS configuration system
    3132"""
    3233import sys
     
    3435import re
    3536import commands
     37import snack
    3638
    3739INPUT = sys.argv[1]
    3840OUTPUT = 'Makefile.config'
    39 TMPOUTPUT = 'Makefile.config.tmp'
    40 
    41 class DefaultDialog:
    42     "Wrapper dialog that tries to return default values"
    43     def __init__(self, dlg):
    44         self.dlg = dlg
    45 
    46     def set_title(self,text):
    47         self.dlg.set_title(text)
    48        
    49     def yesno(self, text, default=None):
    50         if default is not None:
    51             return default
    52         return self.dlg.yesno(text, default)
    53     def noyes(self, text, default=None):
    54         if default is not None:
    55             return default
    56         return self.dlg.noyes(text, default)
    57    
    58     def choice(self, text, choices, defopt=None):
    59         if defopt is not None:
    60             return choices[defopt][0]
    61         return self.dlg.choice(text, choices, defopt)
    62 
    63 class NoDialog:
    64     def __init__(self):
    65         self.printed = None
    66         self.title = 'HelenOS Configuration'
    67 
    68     def print_title(self):
    69         if not self.printed:
    70             sys.stdout.write("\n*** %s ***\n" % self.title)
    71             self.printed = True
    72 
    73     def set_title(self, text):
    74         self.title = text
    75         self.printed = False
    76    
    77     def noyes(self, text, default=None):
    78         if not default:
    79             default = 'n'
    80         return self.yesno(text, default)
    81    
    82     def yesno(self, text, default=None):
    83         self.print_title()
    84        
    85         if default != 'n':
    86             default = 'y'
    87         while 1:
    88             sys.stdout.write("%s (y/n)[%s]: " % (text,default))
    89             inp = sys.stdin.readline()
    90             if not inp:
    91                 raise EOFError
    92             inp = inp.strip().lower()
    93             if not inp:
    94                 return default
    95             if inp == 'y':
    96                 return 'y'
    97             elif inp == 'n':
    98                 return 'n'
    99 
    100     def _print_choice(self, text, choices, defopt):
    101         sys.stdout.write('%s:\n' % text)
    102         for i,(text,descr) in enumerate(choices):
    103             if descr is '':
    104                 sys.stdout.write('\t%2d. %s\n' % (i, text))
    105             else:
    106                 sys.stdout.write('\t%2d. %s\n' % (i, descr))
    107         if defopt is not None:
    108             sys.stdout.write('Enter choice number[%d]: ' % defopt)
    109         else:
    110             sys.stdout.write('Enter choice number: ')
    111 
    112     def menu(self, text, choices, button, defopt=None):
    113         self.title = 'Main menu'
    114         menu = []
    115         for key, descr in choices:
    116             txt = key + (45-len(key))*' ' + ': ' + descr
    117             menu.append((key, txt))
    118            
    119         return self.choice(text, [button] + menu)
    120        
    121     def choice(self, text, choices, defopt=None):
    122         self.print_title()
    123         while 1:
    124             self._print_choice(text, choices, defopt)
    125             inp = sys.stdin.readline()
    126             if not inp:
    127                 raise EOFError
    128             if not inp.strip():
    129                 if defopt is not None:
    130                     return choices[defopt][0]
    131                 continue
    132             try:
    133                 number = int(inp.strip())
    134             except ValueError:
    135                 continue
    136             if number < 0 or number >= len(choices):
    137                 continue
    138             return choices[number][0]
    139 
    140 
    141 def eof_checker(fnc):
    142     def wrapper(self, *args, **kw):
    143         try:
    144             return fnc(self, *args, **kw)
    145         except EOFError:
    146             return getattr(self.bckdialog,fnc.func_name)(*args, **kw)
    147     return wrapper
    148 
    149 class Dialog(NoDialog):
    150     def __init__(self):
    151         NoDialog.__init__(self)
    152         self.dlgcmd = os.environ.get('DIALOG','dialog')
    153         self.title = ''
    154         self.backtitle = 'HelenOS Configuration'
    155        
    156         if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0:
    157             raise NotImplementedError
    158        
    159         self.bckdialog = NoDialog()
    160 
    161     def set_title(self,text):
    162         self.title = text
    163         self.bckdialog.set_title(text)
    164        
    165     def calldlg(self,*args,**kw):
    166         "Wrapper for calling 'dialog' program"
    167         indesc, outdesc = os.pipe()
    168         pid = os.fork()
    169         if not pid:
    170             os.close(2)
    171             os.dup(outdesc)
    172             os.close(indesc)
    173            
    174             dlgargs = [self.dlgcmd,'--title',self.title,
    175                        '--backtitle', self.backtitle]
    176             for key,val in kw.items():
    177                 dlgargs.append('--'+key)
    178                 dlgargs.append(val)
    179             dlgargs += args           
    180             os.execlp(self.dlgcmd,*dlgargs)
    181 
    182         os.close(outdesc)
    183        
    184         try:
    185             errout = os.fdopen(indesc,'r')
    186             data = errout.read()
    187             errout.close()
    188             pid,status = os.wait()
    189         except:
    190             os.system('reset') # Reset terminal
    191             raise
    192        
    193         if not os.WIFEXITED(status):
    194             os.system('reset') # Reset terminal
    195             raise EOFError
    196        
    197         status = os.WEXITSTATUS(status)
    198         if status == 255:
    199             raise EOFError
    200         return status,data
    201        
    202     def yesno(self, text, default=None):
    203         if text[-1] not in ('?',':'):
    204             text = text + ':'
    205         width = '50'
    206         height = '5'
    207         if len(text) < 48:
    208             text = ' '*int(((48-len(text))/2)) + text
    209         else:
    210             width = '0'
    211             height = '0'
    212         if default == 'n':
    213             res,data = self.calldlg('--defaultno','--yesno',text,height,width)
    214         else:
    215             res,data = self.calldlg('--yesno',text,height,width)
    216 
    217         if res == 0:
    218             return 'y'
    219         return 'n'
    220     yesno = eof_checker(yesno)
    221 
    222     def menu(self, text, choices, button, defopt=None):
    223         self.title = 'Main menu'
    224         text = text + ':'
    225         width = '70'
    226         height = str(8 + len(choices))
    227         args = []
    228         for key,val in choices:
    229             args.append(key)
    230             args.append(val)
    231 
    232         kw = {}
    233         if defopt:
    234             kw['default-item'] = choices[defopt][0]
    235         res,data = self.calldlg('--ok-label','Change',
    236                                 '--extra-label',button[1],
    237                                 '--extra-button',
    238                                 '--menu',text,height,width,
    239                                 str(len(choices)),*args,**kw)
    240         if res == 3:
    241             return button[0]
    242         if res == 1: # Cancel
    243             sys.exit(1)
    244         elif res:
    245             print data
    246             raise EOFError
    247         return data
    248     menu = eof_checker(menu)
    249    
    250     def choice(self, text, choices, defopt=None):
    251         text = text + ':'
    252         width = '50'
    253         height = str(8 + len(choices))
    254         args = []
    255         for key,val in choices:
    256             args.append(key)
    257             args.append(val)
    258 
    259         kw = {}
    260         if defopt:
    261             kw['default-item'] = choices[defopt][0]
    262         res,data = self.calldlg('--nocancel','--menu',text,height,width,
    263                                 str(len(choices)),*args, **kw)
    264         if res:
    265             print data
    266             raise EOFError
    267         return data
    268     choice = eof_checker(choice)
    269    
    270 def read_defaults(fname,defaults):
    271     "Read saved values from last configuration run"
    272     f = file(fname,'r')
    273     for line in f:
    274         res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
    275         if res:
    276             defaults[res.group(1)] = res.group(2)
    277     f.close()
    278 
    279 def check_condition(text, defaults, asked_names):
    280     seen_vars = [ x[0] for x in asked_names ]
    281     ctype = 'cnf'
    282     if ')|' in text or '|(' in text:
    283         ctype = 'dnf'
    284    
    285     if ctype == 'cnf':
    286         conds = text.split('&')
    287     else:
    288         conds = text.split('|')
    289 
    290     for cond in conds:
    291         if cond.startswith('(') and cond.endswith(')'):
    292             cond = cond[1:-1]
    293            
    294         inside = check_inside(cond, defaults, ctype, seen_vars)
    295        
    296         if ctype == 'cnf' and not inside:
    297             return False
    298         if ctype == 'dnf' and inside:
    299             return True
    300 
    301     if ctype == 'cnf':
    302         return True
    303     return False
    304 
    305 def check_inside(text, defaults, ctype, seen_vars):
    306     """
    307     Check that the condition specified on input line is True
    308 
    309     only CNF is supported
    310     """
    311     if ctype == 'cnf':
    312         conds = text.split('|')
    313     else:
    314         conds = text.split('&')
    315     for cond in conds:
    316         res = re.match(r'^(.*?)(!?=)(.*)$', cond)
    317         if not res:
    318             raise RuntimeError("Invalid condition: %s" % cond)
    319         condname = res.group(1)
    320         oper = res.group(2)
    321         condval = res.group(3)
    322         if condname not in seen_vars:
    323             varval = ''
    324 ##             raise RuntimeError("Variable %s not defined before being asked." %\
    325 ##                                condname)
    326         elif not defaults.has_key(condname):
    327             raise RuntimeError("Condition var %s does not exist: %s" % \
    328                                (condname,text))
    329         else:
    330             varval = defaults[condname]
    331         if ctype == 'cnf':
    332             if oper == '=' and  condval == varval:
    333                 return True
    334             if oper == '!=' and condval != varval:
    335                 return True
    336         else:
    337             if oper== '=' and condval != varval:
    338                 return False
    339             if oper== '!=' and condval == varval:
    340                 return False
    341     if ctype=='cnf':
    342         return False
    343     return True
    344 
    345 def parse_config(input, output, dlg, defaults={}, askonly=None):
    346     "Parse configuration file and create Makefile.config on the fly"
    347     def ask_the_question(dialog):
    348         "Ask question based on the type of variables to ask"
    349         # This is quite a hack, this thingy is written just to
    350         # have access to local variables..
    351         if vartype == 'y/n':
    352             return dialog.yesno(comment, default)
    353         elif vartype == 'n/y':
    354             return dialog.noyes(comment, default)
    355         elif vartype == 'choice':
    356             defopt = None
    357             if default is not None:
    358                 for i,(key,val) in enumerate(choices):
    359                     if key == default:
    360                         defopt = i
    361                         break
    362             return dialog.choice(comment, choices, defopt)
    363         else:
    364             raise RuntimeError("Bad method: %s" % vartype)
    365 
    366    
    367     f = file(input, 'r')
    368     outf = file(output, 'w')
    369 
    370     outf.write('#########################################\n')
    371     outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
    372     outf.write('#########################################\n\n')
    373 
    374     asked_names = []
    375 
    376     comment = ''
    377     default = None
    378     choices = []
    379     for line in f:
    380         if line.startswith('%'):
    381             res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line)
    382             if not res:
    383                 raise RuntimeError('Invalid command: %s' % line)
    384             if res.group(1):
    385                 if not check_condition(res.group(1), defaults,
    386                                        asked_names):
    387                     continue
    388             args = res.group(2).strip().split(' ')
    389             cmd = args[0].lower()
    390             args = args[1:]
    391             if cmd == 'saveas':
    392                 outf.write('%s = %s\n' % (args[1],defaults[args[0]]))
    393             elif cmd == 'shellcmd':
    394                 varname = args[0]
    395                 args = args[1:]
    396                 for i,arg in enumerate(args):
    397                     if arg.startswith('$'):
    398                         args[i] = defaults[arg[1:]]
    399                 data,status = commands.getstatusoutput(' '.join(args))
    400                 if status:
    401                     raise RuntimeError('Error running: %s' % ' '.join(args))
    402                 outf.write('%s = %s\n' % (varname,data.strip()))
    403             continue
    404            
    405         if line.startswith('!'):
    406             # Ask a question
    407             res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
    408             if not res:
    409                 raise RuntimeError("Weird line: %s" % line)
    410             varname = res.group(2)
    411             vartype = res.group(3)
    412 
    413             default = defaults.get(varname,None)
    414            
    415             if res.group(1):
    416                 if not check_condition(res.group(1), defaults,
    417                                        asked_names):
    418                     if default is not None:
    419                         outf.write('#!# %s = %s\n' % (varname, default))
    420                     # Clear cumulated values
    421                     comment = ''
    422                     default = None
    423                     choices = []
    424                     continue
    425                
    426             asked_names.append((varname,comment))
    427 
    428             if default is None or not askonly or askonly == varname:
    429                 default = ask_the_question(dlg)
    430             else:
    431                 default = ask_the_question(DefaultDialog(dlg))
    432 
    433             outf.write('%s = %s\n' % (varname, default))
    434             # Remeber the selected value
    435             defaults[varname] = default
    436             # Clear cumulated values
    437             comment = ''
    438             default = None
    439             choices = []
    440             continue
    441        
    442         if line.startswith('@'):
    443             # Add new line into the 'choice array'
    444             res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
    445             if not res:
    446                 raise RuntimeError("Bad line: %s" % line)
    447             if res.group(1):
    448                 if not check_condition(res.group(1),defaults,
    449                                        asked_names):
    450                     continue
    451             choices.append((res.group(2), res.group(3)))
    452             continue
    453 
    454         # All other things print to output file
    455         outf.write(line)
    456         if re.match(r'^#[^#]', line):
    457             # Last comment before question will be displayed to the user
    458             comment = line[1:].strip()
    459         elif line.startswith('## '):
    460             # Set title of the dialog window
    461             dlg.set_title(line[2:].strip())
    462 
    463     outf.write('\n')
    464     outf.write('REVISION = %s\n' % commands.getoutput('svnversion . 2> /dev/null'))
    465     outf.write('TIMESTAMP = %s\n' % commands.getoutput('date "+%Y-%m-%d %H:%M:%S"'))
    466     outf.close()
    467     f.close()
    468     return asked_names
     41
     42def read_defaults(fname, defaults):
     43        "Read saved values from last configuration run"
     44       
     45        inf = file(fname,'r')
     46       
     47        for line in inf:
     48                res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line)
     49                if (res):
     50                        defaults[res.group(1)] = res.group(2)
     51       
     52        inf.close()
     53
     54def check_condition(text, defaults, ask_names):
     55        "Check for condition"
     56       
     57        ctype = 'cnf'
     58       
     59        if ((')|' in text) or ('|(' in text)):
     60                ctype = 'dnf'
     61       
     62        if (ctype == 'cnf'):
     63                conds = text.split('&')
     64        else:
     65                conds = text.split('|')
     66       
     67        for cond in conds:
     68                if (cond.startswith('(')) and (cond.endswith(')')):
     69                        cond = cond[1:-1]
     70               
     71                inside = check_inside(cond, defaults, ctype)
     72               
     73                if (ctype == 'cnf') and (not inside):
     74                        return False
     75               
     76                if (ctype == 'dnf') and (inside):
     77                        return True
     78       
     79        if (ctype == 'cnf'):
     80                return True
     81        return False
     82
     83def check_inside(text, defaults, ctype):
     84        "Check that the condition specified on input line is True (only CNF is supported)"
     85       
     86        if (ctype == 'cnf'):
     87                conds = text.split('|')
     88        else:
     89                conds = text.split('&')
     90       
     91        for cond in conds:
     92                res = re.match(r'^(.*?)(!?=)(.*)$', cond)
     93                if (not res):
     94                        raise RuntimeError("Invalid condition: %s" % cond)
     95               
     96                condname = res.group(1)
     97                oper = res.group(2)
     98                condval = res.group(3)
     99               
     100                if (not defaults.has_key(condname)):
     101                        varval = ''
     102                else:
     103                        varval = defaults[condname]
     104               
     105                if (ctype == 'cnf'):
     106                        if (oper == '=') and (condval == varval):
     107                                return True
     108               
     109                        if (oper == '!=') and (condval != varval):
     110                                return True
     111                else:
     112                        if (oper == '=') and (condval != varval):
     113                                return False
     114                       
     115                        if (oper == '!=') and (condval == varval):
     116                                return False
     117       
     118        if (ctype == 'cnf'):
     119                return False
     120       
     121        return True
     122
     123def parse_config(fname, ask_names):
     124        "Parse configuration file"
     125       
     126        inf = file(fname, 'r')
     127       
     128        name = ''
     129        choices = []
     130       
     131        for line in inf:
     132               
     133                if (line.startswith('!')):
     134                        # Ask a question
     135                        res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line)
     136                       
     137                        if (not res):
     138                                raise RuntimeError("Weird line: %s" % line)
     139                       
     140                        cond = res.group(1)
     141                        varname = res.group(2)
     142                        vartype = res.group(3)
     143                       
     144                        ask_names.append((varname, vartype, name, choices, cond))
     145                        name = ''
     146                        choices = []
     147                        continue
     148               
     149                if (line.startswith('@')):
     150                        # Add new line into the 'choices' array
     151                        res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line)
     152                       
     153                        if not res:
     154                                raise RuntimeError("Bad line: %s" % line)
     155                       
     156                        choices.append((res.group(2), res.group(3)))
     157                        continue
     158               
     159                if (line.startswith('%')):
     160                        # Name of the option
     161                        name = line[1:].strip()
     162                        continue
     163               
     164                if ((line.startswith('#')) or (line == '\n')):
     165                        # Comment or empty line
     166                        continue
     167               
     168               
     169                raise RuntimeError("Unknown syntax: %s" % line)
     170       
     171        inf.close()
     172
     173def yes_no(default):
     174        "Return '*' if yes, ' ' if no"
     175       
     176        if (default == 'y'):
     177                return '*'
     178       
     179        return ' '
     180
     181def subchoice(screen, name, choices):
     182        "Return choice of choices"
     183       
     184        maxlen = 0
     185        for choice in choices:
     186                length = len(choice[0])
     187                if (length > maxlen):
     188                        maxlen = length
     189       
     190        options = []
     191        for choice in choices:
     192                options.append(" %-*s  %s " % (maxlen, choice[0], choice[1]))
     193       
     194        retval = snack.ListboxChoiceWindow(screen, name, 'Choose value', options)
     195       
     196        if (retval[0] == 'cancel'):
     197                return None
     198       
     199        return choices[retval[1]][0]
     200
     201def check_choices(defaults, ask_names):
     202        "Check whether all accessible variables have a default"
     203       
     204        for row in ask_names:
     205                varname = row[0]
     206                cond = row[4]
     207               
     208                if ((cond) and (not check_condition(cond, defaults, ask_names))):
     209                        continue
     210               
     211                if (not defaults.has_key(varname)):
     212                        return False
     213       
     214        return True
     215
     216def create_output(fname, defaults, ask_names):
     217        "Create output configuration"
     218       
     219        outf = file(fname, 'w')
     220       
     221        outf.write('#########################################\n')
     222        outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n')
     223        outf.write('#########################################\n\n')
     224       
     225        for row in ask_names:
     226                varname = row[0]
     227                name = row[2]
     228                cond = row[4]
     229               
     230                if ((cond) and (not check_condition(cond, defaults, ask_names))):
     231                        continue
     232               
     233                if (not defaults.has_key(varname)):
     234                        default = ''
     235                else:
     236                        default = defaults[varname]
     237               
     238                outf.write('# %s\n%s = %s\n\n' % (name, varname, default))
     239       
     240        outf.write('REVISION = %s\n' % commands.getoutput('svnversion . 2> /dev/null'))
     241        outf.write('TIMESTAMP = %s\n' % commands.getoutput('date "+%Y-%m-%d %H:%M:%S"'))
     242        outf.close()
    469243
    470244def main():
    471     defaults = {}
    472     try:
    473         dlg = Dialog()
    474     except NotImplementedError:
    475         dlg = NoDialog()
    476 
    477     if len(sys.argv) >= 3 and sys.argv[2]=='default':
    478         defmode = True
    479     else:
    480         defmode = False
    481 
    482     # Default run will update the configuration file
    483     # with newest options
    484     if os.path.exists(OUTPUT):
    485         read_defaults(OUTPUT, defaults)
    486 
    487         # Get ARCH from command line if specified
    488     if len(sys.argv) >= 4:
    489         defaults['ARCH'] = sys.argv[3]
    490         defaults['PLATFORM'] = sys.argv[3]
    491        
    492         # Get COMPILER from command line if specified
    493     if len(sys.argv) >= 5:
    494         defaults['COMPILER'] = sys.argv[4]
    495        
    496         # Get CONFIG_DEBUG from command line if specified
    497     if len(sys.argv) >= 6:
    498         defaults['CONFIG_DEBUG'] = sys.argv[5]
    499        
    500         # Get MACHINE/IMAGE from command line if specified
    501     if len(sys.argv) >= 7:
    502         defaults['MACHINE'] = sys.argv[6]
    503         defaults['IMAGE'] = sys.argv[6]
    504 
    505     # Dry run only with defaults
    506     varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
    507     # If not in default mode, present selection of all possibilities
    508     if not defmode:
    509         defopt = 0
    510         while 1:
    511             # varnames contains variable names that were in the
    512             # last question set
    513             choices = [ (x[1],defaults[x[0]]) for x in varnames ]
    514             res = dlg.menu('Configuration',choices,('save','Save'),defopt)
    515             if res == 'save':
    516                 parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults)
    517                 break
    518             # transfer description back to varname
    519             for i,(vname,descr) in enumerate(varnames):
    520                 if res == descr:
    521                     defopt = i
    522                     break
    523             # Ask the user a simple question, produce output
    524             # as if the user answered all the other questions
    525             # with default answer
    526             varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults,
    527                                     askonly=varnames[i][0])
    528        
    529    
    530     if os.path.exists(OUTPUT):
    531         os.unlink(OUTPUT)
    532     os.rename(TMPOUTPUT, OUTPUT)
    533    
    534     if not defmode and dlg.yesno('Rebuild everything?') == 'y':
    535         os.execlp('make','make','clean','build')
     245        defaults = {}
     246        ask_names = []
     247       
     248        # Parse configuration file
     249        parse_config(INPUT, ask_names)
     250       
     251        # Read defaults from previous run
     252        if os.path.exists(OUTPUT):
     253                read_defaults(OUTPUT, defaults)
     254       
     255        # Default mode: only check defaults and regenerate configuration
     256        if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')):
     257                if (check_choices(defaults, ask_names)):
     258                        create_output(OUTPUT, defaults, ask_names)
     259                        return 0
     260       
     261        screen = snack.SnackScreen()
     262        try:
     263                selname = None
     264                while True:
     265                       
     266                        options = []
     267                        opt2row = {}
     268                        position = None
     269                        cnt = 0
     270                        for row in ask_names:
     271                               
     272                                varname = row[0]
     273                                vartype = row[1]
     274                                name = row[2]
     275                                choices = row[3]
     276                                cond = row[4]
     277                               
     278                                if ((cond) and (not check_condition(cond, defaults, ask_names))):
     279                                        continue
     280                               
     281                                if (varname == selname):
     282                                        position = cnt
     283                               
     284                                if (not defaults.has_key(varname)):
     285                                        default = None
     286                                else:
     287                                        default = defaults[varname]
     288                               
     289                                if (vartype == 'choice'):
     290                                        # Check if the default is an acceptable value
     291                                        if ((default) and (not default in [choice[0] for choice in choices])):
     292                                                default = None
     293                                                defaults.pop(varname)
     294                                       
     295                                        # If there is just one option, use it
     296                                        if (len(choices) == 1):
     297                                                default = choices[0][0]
     298                                                defaults[varname] = default
     299                                       
     300                                        options.append("     %s [%s] --> " % (name, default))
     301                                elif (vartype == 'y/n'):
     302                                        if (default == None):
     303                                                default = 'y'
     304                                                defaults[varname] = default
     305                                        options.append(" <%s> %s " % (yes_no(default), name))
     306                                elif (vartype == 'n/y'):
     307                                        if (default == None):
     308                                                default = 'n'
     309                                                defaults[varname] = default
     310                                        options.append(" <%s> %s " % (yes_no(default), name))
     311                                else:
     312                                        raise RuntimeError("Unknown variable type: %s" % vartype)
     313                               
     314                                opt2row[cnt] = row
     315                               
     316                                cnt += 1
     317                       
     318                        retval = snack.ListboxChoiceWindow(screen, 'HelenOS configuration', 'Choose configuration option', options, default = position)
     319                       
     320                        if (retval[0] == 'cancel'):
     321                                return 'Configuration canceled'
     322                       
     323                        row = opt2row[retval[1]]
     324                        if (row == None):
     325                                raise RuntimeError("Error selecting value: %s" % retval[1])
     326                       
     327                        selname = row[0]
     328                        seltype = row[1]
     329                        name = row[2]
     330                        choices = row[3]
     331                       
     332                        if (retval[0] == 'ok'):
     333                                if (check_choices(defaults, ask_names)):
     334                                        break
     335                                else:
     336                                        snack.ButtonChoiceWindow(screen, 'Error', 'Some options have still undefined values.', ['Ok']);
     337                                        continue
     338                       
     339                        if (seltype == 'choice'):
     340                                defaults[selname] = subchoice(screen, name, choices)
     341                        elif ((seltype == 'y/n') or (seltype == 'n/y')):
     342                                if (defaults[selname] == 'y'):
     343                                        defaults[selname] = 'n'
     344                                else:
     345                                        defaults[selname] = 'y'
     346        finally:
     347                screen.finish()
     348       
     349        create_output(OUTPUT, defaults, ask_names)
     350        return 0
    536351
    537352if __name__ == '__main__':
    538     main()
     353    exit(main())
  • uspace/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 -include Makefile.config
     32-include ../Makefile.config
    3333
    3434DIRS = \
     
    7474CLEANS := $(addsuffix .clean,$(DIRS))
    7575
    76 .PHONY: all config build $(BUILDS) $(CLEANS) clean distclean
     76.PHONY: all $(BUILDS) $(CLEANS) clean
    7777
    78 all:
    79         ../tools/config.py uspace.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG)
    80         $(MAKE) -C . build
    81 
    82 config:
    83         ../tools/config.py uspace.config
    84 
    85 build: $(BUILDS)
     78all: ../Makefile.config $(BUILDS)
    8679
    8780clean: $(CLEANS)
    88 
    89 distclean: clean
    90         -rm Makefile.config
    9181
    9282$(CLEANS):
  • uspace/app/bdsh/Makefile

    rb1747a5 r9a0367f  
    3131
    3232include ../../../version
    33 include ../../Makefile.config
     33-include ../../../Makefile.config
    3434
    3535LIBC_PREFIX = ../../lib/libc
  • uspace/app/init/Makefile

    rb1747a5 r9a0367f  
    2828
    2929include ../../../version
    30 include ../../Makefile.config
     30-include ../../../Makefile.config
    3131
    3232## Setup toolchain
  • uspace/app/klog/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/app/tester/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/app/tetris/Makefile

    rb1747a5 r9a0367f  
    1 include ../../Makefile.config
     1-include ../../../Makefile.config
    22
    33LIBC_PREFIX = ../../lib/libc
  • uspace/app/trace/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/lib/libblock/Makefile

    rb1747a5 r9a0367f  
    3131#
    3232
    33 include ../../Makefile.config
     33-include ../../../Makefile.config
    3434
    3535LIBC_PREFIX = ../libc
  • uspace/lib/libc/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = $(shell pwd)
  • uspace/lib/libc/Makefile.toolchain

    rb1747a5 r9a0367f  
    3131LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a
    3232AFLAGS =
    33 #-Werror
    3433
    3534## Setup platform configuration
    3635#
    3736
    38 include $(LIBC_PREFIX)/arch/$(ARCH)/Makefile.inc
     37-include $(LIBC_PREFIX)/arch/$(ARCH)/Makefile.inc
    3938
    4039## Simple detection of the host system
  • uspace/lib/libc/arch/mips32/Makefile.inc

    rb1747a5 r9a0367f  
    3838CFLAGS += -mips3
    3939
    40 -include ../../Makefile.config
     40-include ../../../Makefile.config
    4141ifeq ($(CONFIG_MIPS_FPU),y)
    4242        CFLAGS += -DCONFIG_MIPS_FPU
  • uspace/lib/libfs/Makefile

    rb1747a5 r9a0367f  
    3131#
    3232
    33 include ../../Makefile.config
     33-include ../../../Makefile.config
    3434
    3535LIBC_PREFIX = ../libc
  • uspace/lib/softfloat/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../libc
  • uspace/lib/softint/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../libc
  • uspace/srv/console/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/devmap/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/fb/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/fs/fat/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../../Makefile.config
     32-include ../../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../../lib/libc
  • uspace/srv/fs/tmpfs/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../../Makefile.config
     32-include ../../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../../lib/libc
  • uspace/srv/kbd/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
    3535SOFTINT_PREFIX = ../../lib/softint
    36 include $(LIBC_PREFIX)/Makefile.toolchain
    37 include ../../../Makefile.config
     36include $(LIBC_PREFIX)/Makefile.toolchain
    3837
    3938CFLAGS += -Iinclude -I../libadt/include
  • uspace/srv/loader/Makefile

    rb1747a5 r9a0367f  
    2828#
    2929
    30 include ../../Makefile.config
     30-include ../../../Makefile.config
    3131
    3232## Setup toolchain
  • uspace/srv/ns/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/pci/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/pci/libpci/Makefile

    rb1747a5 r9a0367f  
    44# Modified and ported to HelenOS by Jakub Jermar
    55
    6 include ../../../Makefile.config
     6-include ../../../../Makefile.config
    77
    88LIBC_PREFIX=$(shell cd ../../../lib/libc; pwd)
  • uspace/srv/rd/Makefile

    rb1747a5 r9a0367f  
    3030#
    3131
    32 include ../../Makefile.config
     32-include ../../../Makefile.config
    3333
    3434LIBC_PREFIX = ../../lib/libc
  • uspace/srv/vfs/Makefile

    rb1747a5 r9a0367f  
    3131#
    3232
    33 include ../../Makefile.config
     33-include ../../../Makefile.config
    3434
    3535LIBC_PREFIX = ../../lib/libc
Note: See TracChangeset for help on using the changeset viewer.