Rewrite build script in python, use JSON5 for configuration

This commit is contained in:
flysand7 2023-07-27 09:17:57 +11:00
parent 7329ca1f92
commit 7e6066ff85
10 changed files with 318 additions and 574 deletions

6
.gitignore vendored
View File

@ -1,4 +1,5 @@
bin /bin
/lib
/a /a
/src/ciabatta.c /src/ciabatta.c
a.out a.out
@ -13,6 +14,7 @@ a.out
*.o *.o
*.4coder *.4coder
*.rdbg *.rdbg
*.iface.h /.venv
tinyrt-iface.h
test/ test/
test_folder/ test_folder/

228
build.lua
View File

@ -1,228 +0,0 @@
#!/usr/bin/env lua
local path = require 'path'
local argparse = require 'argparse'
local mf_parser = require 'scripts.manifest-parser'
-- Parse command line arguments
local parser = argparse('build.lua', 'Ciabatta build script')
parser:flag('-c --clean', 'Remove all the binaries before recompiling')
parser:flag('-o --only', 'Do not compile ciabatta')
parser:flag('-r --release', 'Compile the release version (without it will compile everything in debug mode)')
parser:option('-p --platform', 'OS to compile for (linux, windows)')
parser:option('-l --library', 'Type of library to compile (static, shared)')
parser:option('-t --test', 'Compile a C file and link the library against it')
parser:option('--options', 'Additional options to provide to the executable')
local args = parser:parse()
local is_clean = args.clean or false
local is_only = args.only or false
local is_release = args.release or false
local platform = args.platform or 'linux'
local library_type = args.library or 'static'
local test_file = args.test
local compiler_options = args.options or ''
-- Clean the build files if needed
function rmdir(p)
if not path.exists(p) then
return
end
path.each(path.join(p,"*"), function(P) path.remove(P) end,
{param = "f",delay = true,recurse = true,reverse = true})
path.remove(p)
end
if is_clean then
print('Cleaning files..')
rmdir('lib')
rmdir('bin')
os.remove('a')
os.remove('a.exe')
end
-- If we only needed to clean the build files, just exit here
if is_only then
os.exit(0)
end
local assembler = 'nasm'
local compiler = 'clang'
local linker = 'ld'
local includes = {'./include'}
local compiler_defines = {}
local compiler_flags = {'-nostdlib'}
local ciabatta_lib = ''
-- Figure out additional flags
if is_release then
table.insert(compiler_flags, '-O2')
table.insert(compiler_defines, 'NDEBUG')
else
table.insert(compiler_flags, '-g')
table.insert(compiler_flags, '-O0')
table.insert(compiler_defines, 'CIA_DEBUG')
end
if library_type == 'static' then
ciabatta_lib = 'ciabatta.a'
if platform == 'windows' then
ciabatta_lib = 'ciabatta.lib'
end
elseif library_type == 'shared' then
ciabatta_lib = 'ciabatta.so'
if platform == 'windows' then
ciabatta_lib = 'ciabatta.dll'
end
else
print('Invalid library type: ' .. library_type)
end
-- Turn flags into table
function map(t, f)
local t1 = {}
local t_len = #t
for i = 1, t_len do
t1[i] = f(t[i])
end
return t1
end
function quote(str)
return '"'..str..'"'
end
function prefix(prefix)
return function(str)
return prefix..str
end
end
function prefix_quote(prefix)
return function(str)
return prefix..'"'..str..'"'
end
end
-- Generate TinyRT interface file for the platform
print('==> Generating TinyRT interface definitions')
local tinyrt_manifest_path = path.join('src', platform, 'tinyrt.mf')
if not path.exists(tinyrt_manifest_path) then
print('ERROR: tinyrt manifest wasnt found: '..tinyrt_manifest_path)
end
tinyrt_iface_hdr = io.open(path.join('src', platform, 'tinyrt.iface.h'), 'wb')
tinyrt_iface_hdr:write('\n')
tinyrt_iface_hdr:write('// This file is AUTO-GENERATED\n')
tinyrt_iface_hdr:write('// See tinyrt.mf\n')
tinyrt_iface_hdr:write('\n')
n = 1
tinyrt_apis = {}
for line in io.lines(tinyrt_manifest_path) do
if line:len() ~= 0 and line:sub(1,1) ~= '#' and line:gsub('%s+', '') ~= '' then
local line_it = line:gmatch('[_a-zA-Z0-9]+')
local api_name = line_it()
local has_impl = line_it()
if has_impl == '0' or has_impl == '1' then
local api_define = '#define ' .. (api_name:upper()) .. ' '..has_impl..'\n'
tinyrt_iface_hdr:write(api_define)
table.insert(tinyrt_apis, api_name)
else
print('SYNTAX ERROR AT LINE '..n..': Expected 1 or 0 for the value')
end
end
n = n+1
end
io.close(tinyrt_iface_hdr)
-- Parse manifest and generate ciabatta.c
local function has_value(tab, val)
for index, value in ipairs(tab) do
if value == val then
return true
end
end
return false
end
print('==> Generating ciabatta.c')
cia_h = io.open(path.join('src', 'ciabatta.c'), 'wb')
mf = parse_mf(path.join('src', 'library.mf'))
cia_h:write('\n')
cia_h:write('// THIS FILE IS AUTO-GENERATED. SEE library.mf FOR DETAILS\n')
cia_h:write('\n// global includes\n')
for index,include in ipairs(mf.includes) do
cia_h:write('#include <'..include..'>\n')
end
for index,decl_platform in ipairs(mf.platforms) do
if decl_platform.name == platform then
cia_h:write(('\n// platform %s\n'):format(decl_platform.name))
for index,include in ipairs(decl_platform.includes) do
cia_h:write('#include "'..include..'"\n')
end
end
end
for index, api in ipairs(mf.apis) do
supported = true
for index, dep in ipairs(api.deps) do
if not has_value(tinyrt_apis, dep) then
supported = false
end
end
if supported then
cia_h:write(('\n// module %s\n'):format(api.name))
print(' - Exporting module: ' .. api.name)
for index, include in ipairs(api.includes) do
cia_h:write('#include "'..include..'"\n')
end
end
end
io.close(cia_h)
-- Figure out compiler flags
local cflags = table.concat(compiler_flags, ' ')..' '..
table.concat(map(compiler_defines, prefix('-D ')), ' ')..' '..
table.concat(map(includes, prefix_quote('-I ')), ' ')..' '
print('==> Compiling ciabatta')
print('Flags: ' .. cflags)
-- Functions for compiling, linking and assembling individual files
function assemble(src, out)
local format = 'elf64'
if platform == 'windows' then
format = 'win64'
end
local cmdline = 'nasm -f '..format..' "'..src..'" -o "'..out..'"'
print('> '..cmdline)
os.execute(cmdline)
end
function compile(srcs, out, additional_flags)
local flags = (additional_flags or '')..' '..cflags
local inputs = table.concat(map(srcs, quote), ' ')
local cmdline = 'clang '..flags..' '..inputs..' -o '..quote(out)..''
print('> '..cmdline)
os.execute(cmdline)
end
function archive(srcs, out)
os.remove(out)
local inputs = table.concat(map(srcs, quote), ' ')
local cmdline = 'llvm-ar -rcs '..quote(out)..' '..inputs
print('> '..cmdline)
os.execute(cmdline)
end
-- Build ciabatta
path.mkdir('lib')
path.mkdir('bin')
assemble('src/linux/crt-entry.asm', 'bin/crt-entry.o')
compile({'src/linux/crt-ctors.c'}, 'bin/crt-ctors.o', '-fpic -c')
compile({'src/ciabatta.c'}, 'bin/ciabatta.o', '-fpic -c')
if library_type == 'static' then
archive({'bin/ciabatta.o', 'bin/crt-ctors.o', 'bin/crt-entry.o'}, 'lib/'..ciabatta_lib)
elseif library_type == 'shared' then
print('SHARED OBJECTS NOT SUPPORTED YET')
os.exit(1)
end
if test_file then
compile({test_file, 'lib/'..ciabatta_lib}, 'a', '-pie')
end

223
build.py Executable file
View File

@ -0,0 +1,223 @@
#!/usr/bin/env python3
import argparse # Parsing command-line args
import platform # Checking current OS
import shutil
import os
import sys
import pyjson5
dependencies = [
'nasm',
'llvm-ar'
]
# Parse command line arguments
arg_parser = argparse.ArgumentParser('build.py')
arg_parser.add_argument('--clean', action='store_true', help='Remove all object files and binaries')
arg_parser.add_argument('--test', help='Compile ciabatta executable with given file')
arg_parser.add_argument('--mode', '-m', choices=['debug', 'release'], default='debug', help='Select build configuration')
arg_parser.add_argument('--target', '-t', help='Select target OS (default=host)')
arg_parser.add_argument('--compiler', '-c', choices=['clang', 'cuik'], default='clang', help='Select compiler')
arg_parser.add_argument('--cflags', nargs='*', default=[], help='Pass additional compiler flags')
args = arg_parser.parse_args()
compiler = args.compiler
print('==> Performing basic checks')
# Perform cleaning if required
if args.clean:
shutil.rmtree('bin')
shutil.rmtree('lib')
os.remove(os.path.join('src', 'ciabatta.c'))
os.remove('a')
sys.exit(0)
# Check host OS
target = args.target
if target is None:
host_os = platform.system().lower()
print(f" -> Compiling for host OS: '{host_os}'")
if not os.path.exists(os.path.join('src', host_os)):
print(f" -> [ERROR] OS '{host_os}' isn't implemented.")
sys.exit(1)
target = host_os
# Add compiler to dependencies
dependencies.append(args.compiler)
# Check dependencies
print('==> Checking dependencies')
for dependency in dependencies:
if shutil.which(dependency) is None:
print(f" -> [ERROR] Missing dependency: '{dependency}'")
sys.exit(1)
print(' -> Everything OK')
# Figure out the flags
includes = ['include']
cc = ''
cc_defines = []
cc_flags = ['-nostdlib']
crt_file = 'crt.lib'
lib_file = 'cia.lib'
cc = args.compiler
if args.mode == 'release':
cc_flags.append('-O2')
cc_defines.append('NDEBUG')
else: # 'debug'
cc_flags.append('-g')
cc_flags.append('-O0')
cc_defines.append('DEBUG')
# Generate TinyRT headers for the target platform
print(f"==> Generating TinyRT header for {target}")
tinyrt_config_path = os.path.join('src', target, 'tinyrt.json')
tinyrt_apis = []
try:
print(f" -> Reading file '{tinyrt_config_path}'")
with open(tinyrt_config_path, 'r') as tinyrt_config_file:
tinyrt_config = pyjson5.load(tinyrt_config_file)
except Exception as error:
print(f" -> [ERROR] reading file '{tinyrt_config_path}'")
print(f" * {error}")
sys.exit(1)
tinyrt_header_path = os.path.join('src', target, 'tinyrt-iface.h')
try:
print(f" -> Writing to file '{tinyrt_header_path}'")
with open(tinyrt_header_path, 'w') as tinyrt_header_file:
tinyrt_header_file.write('\n')
tinyrt_header_file.write(f'// This file is AUTO-GENERATED from {tinyrt_config_path}\n')
tinyrt_header_file.write('\n')
for tinyrt_api in tinyrt_config:
api_name = tinyrt_api
is_defined = tinyrt_config[tinyrt_api]
if is_defined:
tinyrt_apis.append(api_name)
is_defined_int = 1 if is_defined else 0
tinyrt_header_file.write(f'#define {api_name.upper()} {is_defined_int}\n')
except Exception as error:
print(f" -> [ERROR] writing to file '{tinyrt_header_path}'")
print(f" * {error}")
sys.exit(1)
print(' -> TinyRT header generated')
# Generate ciabatta header for the target platform and configuration
print(f"==> Generating ciabatta.c")
library_config_path = os.path.join('src', 'library.json')
try:
print(f" -> Reading file '{library_config_path}'")
with open(library_config_path, 'r') as library_config_file:
library_config = pyjson5.load(library_config_file)
except Exception as error:
print(f" -> [ERROR] reading file '{library_config_path}'")
print(f" * {error}")
sys.exit(1)
ciabatta_header_path = os.path.join('src', 'ciabatta.c')
try:
print(f" -> Writing to file '{ciabatta_header_path}'")
with open(ciabatta_header_path, 'w') as ciabatta_header:
# Write heading
ciabatta_header.write('\n')
ciabatta_header.write('// This file is AUTO-GENERATED by library.json\n')
ciabatta_header.write('\n')
# Write includes
for include in library_config['includes']:
ciabatta_header.write(f'#include <{include}>\n')
ciabatta_header.write('\n')
# Write platform includes
platform_config = None
for platform in library_config['platforms']:
if platform['name'] == target:
platform_config = platform
if platform_config is None:
print(f" -> [ERROR] library config doesn't contain configuration for platform {target}")
for include in platform_config['includes']:
include_path = os.path.join(platform_config['path'], include)
ciabatta_header.write(f'#include "{include_path}"\n')
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
ciabatta_header.write(f'#include "tinyrt.h"\n')
for tinyrt_source in platform_config['tinyrt']:
ciabatta_header.write(f'#include "{target}/{tinyrt_source}"\n')
# Write API includes
ciabatta_header.write('\n')
for api in library_config['apis']:
api_name = api['name']
api_path = api['path']
tinyrt_satisfied = True
for req in api['reqs']:
if not (req in tinyrt_apis):
tinyrt_satisfied = False
break
if not tinyrt_satisfied:
print(f" -> Not exporting API '{api_name}'")
else:
print(f" * Exporting API '{api_name}'")
ciabatta_header.write(f'// Module {api_name}\n')
for include in api['includes']:
ciabatta_header.write(f'#include "{api_path}/{include}"\n')
except Exception as error:
print(f" -> [ERROR] writing file '{ciabatta_header_path}'")
print(f" * {error}")
sys.exit(1)
def quote(s):
return '"' + s + '"'
def prefix(prefix):
return (lambda s: prefix + s)
def prefix_quote(prefix):
return (lambda s: prefix + '"' + s + '"')
cc_flags_str = ' '.join(
cc_flags +
list(map(prefix('-D '), cc_defines)) +
list(map(prefix_quote('-I '), includes)))
print(f"==> Compiling {lib_file}")
print(' * Compiler flags:', cc_flags_str)
def assemble(src, out):
format = 'elf64'
if target == 'windows':
format = 'win64'
cmdline = f'nasm -f "{format}" "{src}" -o "{out}"'
print(' >', cmdline)
code = os.system(cmdline)
if code != 0:
sys.exit(code)
def compile(srcs, out, extra_flags = ''):
flags = cc_flags_str + ' ' + extra_flags + ' '.join(args.cflags)
inputs = ' '.join(map(quote, srcs))
cmdline = f'{compiler} {flags} {inputs} -o {quote(out)}'
print(' >', cmdline)
code = os.system(cmdline)
if code != 0:
sys.exit(code)
def archive(srcs, out):
inputs = ' '.join(map(quote, srcs))
cmdline = f'llvm-ar -rcs {quote(out)} {inputs}'
print(' >', cmdline)
code = os.system(cmdline)
if code != 0:
sys.exit(code)
# Ciabatta build spec
if not os.path.exists('lib'):
os.mkdir('lib')
if not os.path.exists('bin'):
os.mkdir('bin')
p = os.path.join
assemble(p('src', 'linux', 'crt-entry.asm'), p('bin', 'crt-entry.o'))
compile([p('src', 'linux', 'crt-ctors.c')], p('bin', 'crt-ctors.o'), '-fpic -c')
compile([p('src', 'ciabatta.c')], p('bin', 'ciabatta.o'), '-fpic -c')
archive([p('bin', 'ciabatta.o'), p('bin', 'crt-ctors.o'), p('bin', 'crt-entry.o')], p('lib', lib_file))
if args.test:
compile([args.test, p('lib', lib_file)], 'a', '-pie')

View File

@ -44,13 +44,10 @@ Before proceeding please note that ciabatta can only be compiled and used
with `clang`. It may be able to work with `gcc` with some minor adjustments with `clang`. It may be able to work with `gcc` with some minor adjustments
but I didn't test. but I didn't test.
For executing the script you will need lua and some lua dependencies that For executing the script you will need at least python 3.3 and the pyjson5 package
you can install with luarocks:
``` ```
$ luarocks install luafilesystem $ pip install pyjson5
$ luarocks install lua-path
$ luarocks install argparse
``` ```
### Building ### Building
@ -59,17 +56,17 @@ On linux you can simply run `./build.lua` script. On windows you have to run
it like `lua build.lua`. Reference for command-line options: it like `lua build.lua`. Reference for command-line options:
``` ```
Usage: build.lua [-h] [-c] [-o] [-r] [-p <platform>] [-l <library>] Usage: build.py [-h] [--clean] [--test TEST]
[-t <test>] [--options <options>] [--mode {debug,release}] [--target TARGET]
[--compiler {clang,cuik}] [--cflags [CFLAGS ...]]
Options: Options:
-h, --help Show this help message and exit. -h, --help show this help message and exit
-c, --clean Remove all the binaries before recompiling --clean Remove all object files and binaries
-o, --only Do not compile ciabatta --test TEST Compile ciabatta executable with given file
-r, --release Compile the release version (without it will compile everything in debug mode) --mode, -m {debug,release} Select build configuration
-p --platform <platform> OS to compile for (linux, windows) --target, -t TARGET Select target OS (default=host)
-l --library <library> Type of library to compile (static, shared) --compiler, -c {clang,cuik} Select compiler
-t --test <test> Compile a C file and link the library against it --cflags [CFLAGS ...] Pass additional compiler flags
--options <options> Additional options to provide to the executable
``` ```
## Usage ## Usage

View File

@ -1,265 +0,0 @@
#!/usr/bin/env lua
local path = require 'path'
levels = {}
parser_obj = {}
parser_cur_ind = 0
parser_ind_lv = 0
-- Tokens
Token = {}
function Token.new(kind, value)
return {kind = kind, value = value}
end
function Token.keyword(kw) return Token.new('keyword', kw) end
function Token.string(str) return Token.new('string', str) end
function Token.lparen() return Token.new('(', nil) end
function Token.rparen() return Token.new(')', nil) end
function Token.lbrace() return Token.new('{', nil) end
function Token.rbrace() return Token.new('}', nil) end
function Token.colon() return Token.new(':', nil) end
function Token.comma() return Token.new(',', nil) end
function Token.eof() return Token.new('eof', nil) end
Parser = {
file = nil,
filename = nil,
row = 0,
col = 0,
ind_spaces = 0,
ind_levels = {0},
c = nil, -- Last Read Character
t = nil, -- Last Read Token
}
-- Character functions
function Parser.char_next(parser, c)
char = parser.file:read(1)
parser.col = parser.col + 1
if char == '\n' then
parser.row = parser.row + 1
parser.col = 0
end
parser.c = char
end
function Parser.char(parser)
return parser.c
end
function Parser.char_is(parser, pattern)
match = parser:char():match(pattern)
if match then
return true
else
return false
end
end
function Parser.char_match(parser, pattern)
if parser:char_is(pattern) then
parser:char_next()
return true
end
return false
end
-- Token functions
function Parser.token(parser)
return parser.t
end
function Parser.token_next(parser)
-- Skip over the whitespace
while true do
if parser.c == nil then
parser.t = Token.eof()
return
elseif parser:char_match('#') then
while not parser:char_match('\n') do
parser:char_next()
end
elseif parser:char_is('%s') then
parser:char_next()
else
break
end
end
-- print(1+parser.row, 1+parser.col, parser:char())
-- Keyword/identifier
if parser:char_is('[%a-_]') then
ident = ''
while parser:char_is('[%a%d-_]') do
ident = ident .. parser:char()
parser:char_next()
end
parser.t = Token.keyword(ident)
return
-- String
elseif parser:char_match('"') then
string = ''
while not parser:char_match('"') do
string = string .. parser:char()
parser:char_next()
end
parser.t = Token.string(string)
return
-- Single-char tokens
elseif parser:char_match('%(') then
parser.t = Token.lparen()
elseif parser:char_match('%)') then
parser.t = Token.rparen()
elseif parser:char_match('{') then
parser.t = Token.lbrace()
elseif parser:char_match('}') then
parser.t = Token.rbrace()
elseif parser:char_match(':') then
parser.t = Token.colon()
elseif parser:char_match(',') then
parser.t = Token.comma()
end
end
function Parser.token_is(parser, kind)
return parser:token().kind == kind
end
function Parser.token_kw_is(parser, name)
return parser:token().kind == 'keyword' and parser:token().value == name
end
function Parser.token_match(parser, kind)
if parser:token().kind == kind then
parser:token_next()
return true
end
return false
end
function Parser.token_kw_match(parser, name)
if parser:token().kind == 'keyword' and parser:token().value == name then
parser:token_next()
return true
end
return false
end
function Parser.new(filename)
file = io.open(filename, 'rb')
parser = Parser
parser.file = file
parser.filename = filename
parser:char_next()
parser:token_next()
return parser;
end
function parse_mf(mf_path)
parser = Parser.new(mf_path)
includes = {}
platforms = {}
apis = {}
while parser:token().kind ~= 'eof' do
if parser:token().kind ~= 'keyword' then
print(('%s(%d, %d): Expected keyword'):format(parser.filename, 1+parser.row, 1+parser.col))
end
-- TODO: add error handling
if parser:token_kw_match('include') then
parser:token_match('{')
while not parser:token_match('}') do
inc = parser:token().value
table.insert(includes, inc)
parser:token_next()
parser:token_match(',')
end
elseif parser:token_kw_match 'platform' then
platform_name = parser:token().value
parser:token_next()
parser:token_match('(')
platform_path = parser:token().value
if platform_path:sub(1,1) == '/' then
platform_path = platform_path:sub(2, -1)
end
parser:token_next()
parser:token_match(')')
parser:token_match('{')
platform_includes = {}
while not parser:token_match('}') do
if parser:token_kw_match('tinyrt') then
table.insert(platform_includes, path.join(platform_path, 'tinyrt.iface.h'))
table.insert(platform_includes, 'tinyrt.h')
parser:token_match('{')
while not parser:token_match('}') do
inc = parser:token().value
table.insert(platform_includes, path.join(platform_path, inc))
parser:token_next()
end
else
inc = parser:token().value
table.insert(platform_includes, path.join(platform_path, inc))
parser:token_next()
end
parser:token_match(',')
end
table.insert(platforms, {
name = platform_name,
includes = platform_includes
})
elseif parser:token_kw_match 'api' then
api_name = parser:token().value
parser:token_next()
parser:token_match('(')
api_path = parser:token().value
if api_path:sub(1,1) == '/' then
api_path = api_path:sub(2, -1)
end
parser:token_next()
parser:token_match(')')
parser:token_match('{')
api_includes = {}
rt_deps = {}
while not parser:token_match('}') do
if parser:token_kw_match('tinyrt') then
parser:token_match('{')
while not parser:token_match('}') do
dep = parser:token().value
table.insert(rt_deps, dep)
parser:token_next()
end
else
inc = parser:token().value
table.insert(api_includes, path.join(api_path, inc))
parser:token_next()
end
parser:token_match(',')
end
table.insert(apis, {
name = api_name,
deps = rt_deps,
includes = api_includes
})
else
print(('%s(%d, %d): Unknown directive: %s'):format(parser.filename, 1+parser.row, 1+parser.col, parser:token().value))
end
end
io.close(parser.file)
return {
includes = includes,
platforms = platforms,
apis = apis,
}
end
function print_r(arr, indentLevel)
local str = ""
local indentStr = ""
if(indentLevel == nil) then
print(print_r(arr, 0))
return
end
for i = 0, indentLevel do
indentStr = indentStr.." "
end
for index,value in pairs(arr) do
if type(value) == "table" then
str = str..indentStr..index..": \n"..print_r(value, (indentLevel + 1))
else
str = str..indentStr..index..": "..value.."\n"
end
end
return str
end
-- mf = parse_mf('src/library.mf')
-- print(print_r(mf, 0))

66
src/library.json Normal file
View File

@ -0,0 +1,66 @@
{
// Manifest file for the ciabatta build.
// Platform sections describe available platforms and
// which files they need to include to function
// API sections describe API subsets and their TinyRT
// dependencies. If an API requires TinyRT module that
// isn't implemented by the platform that API won't be included
// in the final build
// This file is used to auto-generate ciabatta.c
// `include` section specifies the header files that ciabatta
// implements
// `platform` sections describe platforms, the directories
// where the source code for these platforms resides and the
// files that should be included in the build for that platform
// (relative to "src" dir) as well as the location of TinyRT
// implementation.
// `api` sections describe modules, where the implementation resides,
// the source files and the TinyRT modules, on which this module
// depends. If the platform doesn't implement one of the dependencies
// this module will not be included in the final build
includes: [
"cia-def.h",
"stdlib.h"
],
platforms: [
{
name: "linux",
path: "linux",
includes: [
"syscall.c",
"errno.c",
"entry.c"
],
tinyrt: [
"tinyrt.c"
]
},
{
name: "windows",
path: "windows",
includes: [],
tinyrt: [],
},
],
apis: [
{
name: "stdlib_program",
path: "impl/stdlib-program",
includes: [
"program.c",
],
reqs: [
"rt_api_program",
]
},
]
// END
}

View File

@ -1,48 +0,0 @@
# Manifest file for the ciabatta build.
# Platform sections describe available platforms and
# which files they need to include to function
# API sections describe API subsets and their TinyRT
# dependencies. If an API requires TinyRT module that
# isn't implemented by the platform that API won't be included
# in the final build
# This file is used to auto-generate ciabatta.c
# `include` section specifies the header files that ciabatta
# implements
# `platform` sections describe platforms, the directories
# where the source code for these platforms resides and the
# files that should be included in the build for that platform
# (relative to "src" dir) as well as the location of TinyRT
# implementation.
# `api` sections describe modules, where the implementation resides,
# the source files and the TinyRT modules, on which this module
# depends. If the platform doesn't implement one of the dependencies
# this module will not be included in the final build
include {
"cia-def.h",
"stdlib.h"
}
platform linux("/linux") {
"syscall.c",
"errno.c",
"entry.c",
tinyrt {
"tinyrt.c"
}
}
platform windows("/windows") {
tinyrt {},
}
api stdlib_program("/impl/stdlib-program") {
"program.c",
tinyrt {
rt_api_program,
}
}

12
src/linux/tinyrt.json Normal file
View File

@ -0,0 +1,12 @@
{
// This file contains TinyRT API subsets that are exported
// for this operating system, one name per line. This file
// is used in a build script to generate tinyrt_macro file
// and to resolve higher-level API dependencies
rt_api_file: true,
rt_api_program: true,
rt_api_shell: false,
}

View File

@ -1,15 +0,0 @@
# This file contains TinyRT API subsets that are exported
# for this operating system, one name per line. This file
# is used in a build script to generate tinyrt_macro file
# and to resolve higher-level API dependencies
# For example file = 1 means that the file API is
# implemented on this operating system and during building
# a header file will be generated containing definition of
# the form
# #define RT_API_FILE
rt_api_file = 1
rt_api_program = 1
rt_api_shell = 0

View File

@ -1,5 +1,5 @@
#include <cia_definitions.h> #include <cia-def.h>
#define STDOUT_FILENO 1 #define STDOUT_FILENO 1
#define SYS_write 1 #define SYS_write 1