make rule for user header file install
[lunaix-os.git] / lunaix-os / scripts / build-tools / luna_build.py
1 #!/usr/bin/env python 
2
3 from lbuild.contract import LunaBuildFile
4 from lbuild.common import BuildEnvironment
5
6 from lcfg.common import LConfigEnvironment
7 from integration.config_io import CHeaderConfigProvider
8 from integration.lbuild_bridge import LConfigProvider
9 from integration.render_ishell import InteractiveShell
10 from integration.build_gen import MakefileBuildGen, install_lbuild_functions
11 from integration.lunamenu import menuconfig, TerminalSizeCheckFailed
12
13 import lcfg.types as lcfg_type
14 import lcfg.builtins as builtin
15
16 from os import getcwd
17 from os import mkdir
18 from os.path import abspath, basename, dirname, exists
19 from argparse import ArgumentParser
20 from lib.utils import join_path
21
22 def prepare_lconfig_env(out_dir):
23     provider = CHeaderConfigProvider(join_path(out_dir, "configs.h"))
24     env = LConfigEnvironment(getcwd(), provider)
25
26     env.register_builtin_func(builtin.v)
27     env.register_builtin_func(builtin.term_type)
28     env.register_builtin_func(builtin.parent)
29     env.register_builtin_func(builtin.default)
30     env.register_builtin_func(builtin.include)
31     env.register_builtin_func(builtin.env)
32     env.register_builtin_func(builtin.set_value)
33
34     env.type_factory().regitser(lcfg_type.PrimitiveType)
35     env.type_factory().regitser(lcfg_type.MultipleChoiceType)
36
37     return env
38
39 def do_config(opt, lcfg_env):
40     redo_config = not exists(opt.config_save) or opt.force
41     if not redo_config or opt.quiet:
42         return
43
44     try:
45         clean_quit = menuconfig(lcfg_env)
46     except TerminalSizeCheckFailed as e:
47         least = e.args[0]
48         current = e.args[1]
49         print(
50             f"Your terminal size: {current} is less than minimum requirement of {least}.\n"
51             "menuconfig will not function properly, switch to prompt based.\n")
52
53         shell = InteractiveShell(lcfg_env)
54         clean_quit = shell.render_loop()
55     
56     if not clean_quit:
57         print("Configuration aborted. Nothing has been saved.")
58         exit(-1)
59
60 def do_buildfile_gen(opts, lcfg_env):
61     root_path = abspath(opts.root)
62     ws_path = dirname(root_path)
63     root_name = basename(root_path)
64
65     mkgen = MakefileBuildGen(opts.out_dir)
66     env = BuildEnvironment(ws_path, mkgen)
67
68     install_lbuild_functions(env)
69
70     cfg_provider = LConfigProvider(lcfg_env)
71     env.set_config_provider(cfg_provider)
72
73     root = LunaBuildFile(env, root_name)
74
75     try:
76         root.resolve()
77     except Exception as err:
78         print("failed to resolve root build file")
79         raise err
80     
81     env.export()
82
83 def main():
84     parser = ArgumentParser()
85     parser.add_argument("--config", action="store_true", default=False)
86     parser.add_argument("--quiet", action="store_true", default=False)
87     parser.add_argument("--lconfig-file", default="LConfig")
88     parser.add_argument("--config-save", default=".config.json")
89     parser.add_argument("--force", action="store_true", default=False)
90     parser.add_argument("root", nargs="?", default="LBuild")
91     parser.add_argument("-o", "--out-dir", required=True)
92
93     opts = parser.parse_args()
94     out_dir = opts.out_dir
95     if not exists(out_dir):
96         mkdir(out_dir)
97     
98     lcfg_env = prepare_lconfig_env(out_dir)
99     require_config = exists(opts.lconfig_file)
100     try:
101         if require_config:
102             lcfg_env.resolve_module(opts.lconfig_file)
103             lcfg_env.update()
104             lcfg_env.load()
105     except Exception as e:
106         print(e)
107     
108     if opts.config:
109         if require_config:
110             do_config(opts, lcfg_env)
111         else:
112             print("No configuration file detected, skipping...")
113         
114         lcfg_env.update()
115         lcfg_env.save(opts.config_save)
116         lcfg_env.export()
117
118     do_buildfile_gen(opts, lcfg_env)
119
120 if __name__ == "__main__":
121     main()