mirror of https://github.com/flysand7/ciabatta.git
Make it compile on windows
This commit is contained in:
parent
5e177fae50
commit
1f811d7646
95
build.py
95
build.py
|
@ -7,10 +7,6 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import pyjson5
|
import pyjson5
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
'nasm',
|
|
||||||
'llvm-ar'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
arg_parser = argparse.ArgumentParser('build.py')
|
arg_parser = argparse.ArgumentParser('build.py')
|
||||||
|
@ -23,17 +19,25 @@ arg_parser.add_argument('--cflags', nargs='*', default=[], help='Pass additional
|
||||||
args = arg_parser.parse_args()
|
args = arg_parser.parse_args()
|
||||||
compiler = args.compiler
|
compiler = args.compiler
|
||||||
|
|
||||||
print('==> Performing basic checks')
|
|
||||||
|
|
||||||
# Perform cleaning if required
|
# Perform cleaning if required
|
||||||
|
def rm(path):
|
||||||
|
if os.path.exists(path):
|
||||||
|
os.remove(path)
|
||||||
if args.clean:
|
if args.clean:
|
||||||
|
if os.path.exists('bin'):
|
||||||
shutil.rmtree('bin')
|
shutil.rmtree('bin')
|
||||||
|
if os.path.exists('lib'):
|
||||||
shutil.rmtree('lib')
|
shutil.rmtree('lib')
|
||||||
os.remove(os.path.join('src', 'ciabatta.c'))
|
rm(os.path.join('src', 'ciabatta.c'))
|
||||||
os.remove('a')
|
rm('a')
|
||||||
|
rm('a.exe')
|
||||||
|
rm('a.ilk')
|
||||||
|
rm('a.pdb')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# Check host OS
|
# Check host OS
|
||||||
|
print('==> Performing basic checks')
|
||||||
target = args.target
|
target = args.target
|
||||||
if target is None:
|
if target is None:
|
||||||
host_os = platform.system().lower()
|
host_os = platform.system().lower()
|
||||||
|
@ -44,8 +48,31 @@ if target is None:
|
||||||
target = host_os
|
target = host_os
|
||||||
|
|
||||||
# Add compiler to dependencies
|
# Add compiler to dependencies
|
||||||
|
dependencies = [
|
||||||
|
'nasm',
|
||||||
|
'llvm-ar'
|
||||||
|
]
|
||||||
dependencies.append(args.compiler)
|
dependencies.append(args.compiler)
|
||||||
|
|
||||||
|
|
||||||
|
# Figure out the flags
|
||||||
|
includes = ['include']
|
||||||
|
cc = args.compiler
|
||||||
|
cc_defines = []
|
||||||
|
cc_flags = ['-nostdlib']
|
||||||
|
crt_file = 'crt.lib'
|
||||||
|
lib_file = 'cia.lib'
|
||||||
|
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')
|
||||||
|
if target != 'windows':
|
||||||
|
cc_flags.append('-fpic')
|
||||||
|
cc_defines.append(f'_CIA_OS_{target.upper()}')
|
||||||
|
|
||||||
# Check dependencies
|
# Check dependencies
|
||||||
print('==> Checking dependencies')
|
print('==> Checking dependencies')
|
||||||
for dependency in dependencies:
|
for dependency in dependencies:
|
||||||
|
@ -54,24 +81,6 @@ for dependency in dependencies:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
print(' -> Everything OK')
|
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')
|
|
||||||
cc_defines.append(f'_CIA_OS_{target.upper()}')
|
|
||||||
|
|
||||||
# Generate TinyRT headers for the target platform
|
# Generate TinyRT headers for the target platform
|
||||||
print(f"==> Generating TinyRT header for {target}")
|
print(f"==> Generating TinyRT header for {target}")
|
||||||
tinyrt_config_path = os.path.join('src', target, 'tinyrt.json')
|
tinyrt_config_path = os.path.join('src', target, 'tinyrt.json')
|
||||||
|
@ -133,8 +142,8 @@ try:
|
||||||
if platform_config is None:
|
if platform_config is None:
|
||||||
print(f" -> [ERROR] library config doesn't contain configuration for platform {target}")
|
print(f" -> [ERROR] library config doesn't contain configuration for platform {target}")
|
||||||
for include in platform_config['includes']:
|
for include in platform_config['includes']:
|
||||||
include_path = os.path.join(platform_config['path'], include)
|
include_path = platform_config['path']
|
||||||
ciabatta_header.write(f'#include "{include_path}"\n')
|
ciabatta_header.write(f'#include "{include_path}/{include}"\n')
|
||||||
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
|
ciabatta_header.write(f'#include "{target}/tinyrt-iface.h"\n')
|
||||||
ciabatta_header.write(f'#include <tinyrt.h>\n')
|
ciabatta_header.write(f'#include <tinyrt.h>\n')
|
||||||
for tinyrt_source in platform_config['tinyrt']:
|
for tinyrt_source in platform_config['tinyrt']:
|
||||||
|
@ -193,7 +202,7 @@ def assemble(src, out):
|
||||||
def compile(srcs, out, extra_flags = ''):
|
def compile(srcs, out, extra_flags = ''):
|
||||||
flags = cc_flags_str + ' ' + extra_flags + ' '.join(args.cflags)
|
flags = cc_flags_str + ' ' + extra_flags + ' '.join(args.cflags)
|
||||||
inputs = ' '.join(map(quote, srcs))
|
inputs = ' '.join(map(quote, srcs))
|
||||||
cmdline = f'{compiler} {flags} {inputs} -o {quote(out)}'
|
cmdline = f'{cc} {flags} {inputs} -o {quote(out)}'
|
||||||
print(' >', cmdline)
|
print(' >', cmdline)
|
||||||
code = os.system(cmdline)
|
code = os.system(cmdline)
|
||||||
if code != 0:
|
if code != 0:
|
||||||
|
@ -207,20 +216,34 @@ def archive(srcs, out):
|
||||||
if code != 0:
|
if code != 0:
|
||||||
sys.exit(code)
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
# Ciabatta build spec
|
# Ciabatta build spec
|
||||||
if not os.path.exists('lib'):
|
if not os.path.exists('lib'):
|
||||||
os.mkdir('lib')
|
os.mkdir('lib')
|
||||||
if not os.path.exists('bin'):
|
if not os.path.exists('bin'):
|
||||||
os.mkdir('bin')
|
os.mkdir('bin')
|
||||||
|
|
||||||
p = os.path.join
|
def p(path):
|
||||||
|
l = path.split('/')
|
||||||
|
return os.path.join(*l)
|
||||||
|
|
||||||
assemble(p('src', 'linux', 'crt-entry.asm'), p('bin', 'crt-entry.o'))
|
cia_lib = p(f'lib/{lib_file}')
|
||||||
compile([p('src', 'linux', 'crt-ctors.c')], p('bin', 'crt-ctors.o'), '-fpic -c')
|
crt_lib = p(f'lib/{crt_file}')
|
||||||
compile([p('src', 'ciabatta.c')], p('bin', 'ciabatta.o'), '-fpic -c')
|
ciabatta_c = p('src/ciabatta.c')
|
||||||
archive([p('bin', 'crt-ctors.o'), p('bin', 'crt-entry.o')], p('lib', crt_file))
|
ciabatta_o = p('bin/ciabatta.o')
|
||||||
archive([p('bin', 'ciabatta.o'), ], p('lib', lib_file))
|
|
||||||
|
if target == 'linux':
|
||||||
|
assemble(p('src/linux/crt-entry.asm'), p('bin/crt-entry.o'))
|
||||||
|
compile([p('src/linux/crt-ctors.c')], p('bin/crt-ctors.o'), '-c')
|
||||||
|
archive([p('bin/crt-ctors.o'), p('bin/crt-entry.o')], p('lib', crt_file))
|
||||||
|
elif target == 'windows':
|
||||||
|
assemble(p('src/windows/chkstk.asm'), p('bin/chkstk.o'))
|
||||||
|
compile([p('src/windows/crt-entry.c')], p('bin/crt-entry.o'), '-c')
|
||||||
|
archive([p('bin/crt-entry.o')], crt_lib)
|
||||||
|
compile([ciabatta_c], ciabatta_o, '-c')
|
||||||
|
archive([ciabatta_o], cia_lib)
|
||||||
|
|
||||||
if args.test:
|
if args.test:
|
||||||
compile([args.test, p('lib', lib_file), p('lib', crt_file)], 'a', '-pie')
|
if target == 'linux':
|
||||||
|
compile([args.test, cia_lib, crt_lib], 'a', '-pie')
|
||||||
|
elif target == 'windows':
|
||||||
|
compile([args.test, cia_lib, crt_lib], 'a.exe', '-lkernel32')
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// Since we're re-defining noreturn below, this would mess
|
||||||
|
// with __declspec(noreturn) in windows headers, which
|
||||||
|
// is hidden behind a define. Good thing, because now we
|
||||||
|
// can override that define over here.
|
||||||
|
#if defined(_CIA_OS_WINDOWS)
|
||||||
|
#define DECLSPEC_NORETURN __declspec("noreturn")
|
||||||
|
#endif
|
||||||
|
|
||||||
// Pre-C23 keyword macros and stddef
|
// Pre-C23 keyword macros and stddef
|
||||||
#define static_assert _Static_assert
|
#define static_assert _Static_assert
|
||||||
#define noreturn _Noreturn
|
|
||||||
#define NULL ((void *)0)
|
#define NULL ((void *)0)
|
||||||
|
|
||||||
// Assert commonly-accepted platform-invariant sizes
|
// Assert commonly-accepted platform-invariant sizes
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
int atexit(void (*func)(void));
|
int atexit(void (*func)(void));
|
||||||
int at_quick_exit(void (*func)(void));
|
int at_quick_exit(void (*func)(void));
|
||||||
noreturn void abort(void);
|
[[noreturn]] void abort(void);
|
||||||
noreturn void exit(int code);
|
[[noreturn]] void exit(int code);
|
||||||
noreturn void _Exit(int code);
|
[[noreturn]] void _Exit(int code);
|
||||||
noreturn void quick_exit(int code);
|
[[noreturn]] void quick_exit(int code);
|
|
@ -41,7 +41,7 @@ static _RT_Status _rt_deinit();
|
||||||
|
|
||||||
// Program API
|
// Program API
|
||||||
#if _RT_API_PROGRAM == 1
|
#if _RT_API_PROGRAM == 1
|
||||||
static noreturn void _rt_program_exit(int code);
|
[[noreturn]] static void _rt_program_exit(int code);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _RT_API_ENVIRONMENT == 1
|
#if _RT_API_ENVIRONMENT == 1
|
||||||
|
|
|
@ -25,12 +25,13 @@ int at_quick_exit(void (*func)(void)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void abort(void) {
|
[[noreturn]] void abort(void) {
|
||||||
// TODO: Ideally do a debug trap if the process is being debugged
|
// TODO: Ideally do a debug trap if the process is being debugged
|
||||||
_Exit(-1);
|
_rt_program_exit(1);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void exit(int code) {
|
[[noreturn]] void exit(int code) {
|
||||||
for(u64 i = n_atexit_handlers-1; i-- != 0; ) {
|
for(u64 i = n_atexit_handlers-1; i-- != 0; ) {
|
||||||
void (*handler)(void) = atexit_handlers[i];
|
void (*handler)(void) = atexit_handlers[i];
|
||||||
handler();
|
handler();
|
||||||
|
@ -38,17 +39,20 @@ noreturn void exit(int code) {
|
||||||
// TODO(bumbread): flush all the unflushed file streams
|
// TODO(bumbread): flush all the unflushed file streams
|
||||||
// TODO(bumbread): close all file streams and delete temporary files
|
// TODO(bumbread): close all file streams and delete temporary files
|
||||||
_rt_program_exit(code);
|
_rt_program_exit(code);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void _Exit(int code) {
|
[[noreturn]] void _Exit(int code) {
|
||||||
_rt_program_exit(code);
|
_rt_program_exit(code);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void quick_exit(int code) {
|
[[noreturn]] void quick_exit(int code) {
|
||||||
for(u64 i = n_at_quick_exit_handlers-1; i-- != 0; ) {
|
for(u64 i = n_at_quick_exit_handlers-1; i-- != 0; ) {
|
||||||
void (*handler)(void) = at_quick_exit_handlers[i];
|
void (*handler)(void) = at_quick_exit_handlers[i];
|
||||||
handler();
|
handler();
|
||||||
}
|
}
|
||||||
_rt_program_exit(code);
|
_rt_program_exit(code);
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,13 @@ platforms: [
|
||||||
{
|
{
|
||||||
name: "windows",
|
name: "windows",
|
||||||
path: "windows",
|
path: "windows",
|
||||||
includes: [],
|
includes: [
|
||||||
tinyrt: [],
|
"windows.c"
|
||||||
|
],
|
||||||
|
tinyrt: [
|
||||||
|
"tinyrt.c",
|
||||||
|
"cia-init.c"
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
|
|
||||||
// See src/tinyrt.h file for the interface this file implements
|
// See src/tinyrt.h file for the interface this file implements
|
||||||
|
|
||||||
static _RT_File _rt_file_stdin;
|
|
||||||
static _RT_File _rt_file_stderr;
|
|
||||||
|
|
||||||
static _RT_Status _rt_file_std_handles_init() {
|
static _RT_Status _rt_file_std_handles_init() {
|
||||||
_rt_file_stdin.fd = 0;
|
_rt_file_stdin.fd = 0;
|
||||||
_rt_file_stdin.flags = _RT_FILE_READ;
|
_rt_file_stdin.flags = _RT_FILE_READ;
|
||||||
|
@ -68,6 +65,6 @@ static _RT_Status _rt_file_close(_RT_File *file) {
|
||||||
return _RT_STATUS_OK;
|
return _RT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static noreturn void _rt_program_exit(int code) {
|
[[noreturn]] static void _rt_program_exit(int code) {
|
||||||
syscall_exit(code);
|
syscall_exit(code);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
bits 64
|
||||||
|
|
||||||
|
segment .text
|
||||||
|
global __chkstk
|
||||||
|
__chkstk:
|
||||||
|
sub rsp, 0x10
|
||||||
|
mov [rsp], r10
|
||||||
|
mov [rsp+0x8], r11
|
||||||
|
xor r11, r11
|
||||||
|
lea r10, [rsp+0x18]
|
||||||
|
sub r10, rax
|
||||||
|
cmovb r10, r11
|
||||||
|
mov r11, gs:[0x10]
|
||||||
|
cmp r10, r11
|
||||||
|
jnb .end
|
||||||
|
and r10w, 0xf000
|
||||||
|
.loop:
|
||||||
|
lea r11, [r11-0x1000]
|
||||||
|
mov byte [r11], 0x0
|
||||||
|
cmp r10, r11
|
||||||
|
jnz .loop
|
||||||
|
.end:
|
||||||
|
mov r10, [rsp]
|
||||||
|
mov r11, [rsp+0x8]
|
||||||
|
add rsp, 0x10
|
||||||
|
ret
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
static void _fileapi_init();
|
||||||
|
|
||||||
|
void _cia_init() {
|
||||||
|
_fileapi_init();
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
#include <cia-def.h>
|
||||||
|
#include "windows.c"
|
||||||
|
|
||||||
|
extern int main(int argc, char **argv, char **envp);
|
||||||
|
extern void _cia_init();
|
||||||
|
|
||||||
|
void mainCRTStartup() {
|
||||||
|
_cia_init();
|
||||||
|
__security_init_cookie();
|
||||||
|
main(0, NULL, NULL);
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wmainCRTStartup() {
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _WinMainCRTStartup() {
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wWinMainCRTStartup() {
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL _DllMainCRTStartup(HINSTANCE instance, DWORD reason, void *_reserved) {
|
||||||
|
switch(reason) {
|
||||||
|
case DLL_PROCESS_ATTACH: {
|
||||||
|
// Initialize once for each new process.
|
||||||
|
// Return FALSE to fail DLL load.
|
||||||
|
} break;
|
||||||
|
case DLL_THREAD_ATTACH: {
|
||||||
|
// Do thread-specific initialization.
|
||||||
|
} break;
|
||||||
|
case DLL_THREAD_DETACH: {
|
||||||
|
// Do thread-specific cleanup.
|
||||||
|
} break;
|
||||||
|
case DLL_PROCESS_DETACH: {
|
||||||
|
// Perform any necessary cleanup.
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 __security_cookie;
|
||||||
|
|
||||||
|
void __security_init_cookie() {
|
||||||
|
// They say it's a random number so I generated
|
||||||
|
// one using numbergenerator.org
|
||||||
|
__security_cookie = 0xb26e04cc62ba48aULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __security_check_cookie(u64 retrieved) {
|
||||||
|
if(__security_cookie != retrieved) {
|
||||||
|
char buf[] = "Buffer overrun detected!\n";
|
||||||
|
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
WriteFile(stdout, buf, sizeof buf, NULL, NULL);
|
||||||
|
// TODO: abort-like behaviour here
|
||||||
|
ExitProcess(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
// See src/tinyrt.h file for the interface this file implements
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_std_handles_init() {
|
||||||
|
_rt_file_stdin.handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
_rt_file_stdin.flags = _RT_FILE_READ;
|
||||||
|
_rt_file_stdout.handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
||||||
|
_rt_file_stderr.handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
_rt_file_stdout.flags = _RT_FILE_WRITE;
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_open(_RT_File *file, char const *name, int _rt_flags) {
|
||||||
|
u32 access = 0;
|
||||||
|
if(_rt_flags & _RT_FILE_READ) access |= GENERIC_READ;
|
||||||
|
if(_rt_flags & _RT_FILE_WRITE) access |= GENERIC_WRITE;
|
||||||
|
u32 share = 0;
|
||||||
|
if((_rt_flags & _RT_FILE_READ) == 0) share |= FILE_SHARE_READ;
|
||||||
|
u32 creation = 0;
|
||||||
|
if(_rt_flags & _RT_FILE_TRUNCATE) {
|
||||||
|
creation = TRUNCATE_EXISTING;
|
||||||
|
}
|
||||||
|
else if(_rt_flags & _RT_FILE_CREATE) {
|
||||||
|
if(_rt_flags & _RT_FILE_EXCLUSIVE) creation = CREATE_ALWAYS;
|
||||||
|
else creation = CREATE_NEW;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(_rt_flags & _RT_FILE_EXCLUSIVE) creation = OPEN_ALWAYS;
|
||||||
|
else creation = OPEN_EXISTING;
|
||||||
|
}
|
||||||
|
HANDLE handle = CreateFileA(name, access, share, NULL, creation, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if(file == INVALID_HANDLE_VALUE) {
|
||||||
|
// ERROR_FILE_NOT_FOUND
|
||||||
|
// ERROR_PATH_NOT_FOUND
|
||||||
|
// ERROR_ACCESS_DENIED
|
||||||
|
// ERROR_NOT_ENOUGH_MEMORY
|
||||||
|
return _RT_STATUS_FILE_IO_ERROR;
|
||||||
|
|
||||||
|
}
|
||||||
|
file->handle = handle;
|
||||||
|
file->flags = _rt_flags;
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_read(u64 size, void *buffer, _RT_File *from, u64 *out_bytes_read) {
|
||||||
|
*out_bytes_read = 0;
|
||||||
|
BOOL ok = ReadFile(from->handle, buffer, size, (unsigned long *)out_bytes_read, NULL);
|
||||||
|
if(!ok) {
|
||||||
|
return _RT_STATUS_FILE_IO_ERROR;
|
||||||
|
}
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_write(_RT_File *to, u64 size, void *buffer, u64 *out_bytes_written) {
|
||||||
|
*out_bytes_written = 0;
|
||||||
|
BOOL ok = WriteFile(to->handle, buffer, size, (unsigned long *)out_bytes_written, NULL);
|
||||||
|
if(!ok) {
|
||||||
|
return _RT_STATUS_FILE_IO_ERROR;
|
||||||
|
}
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _RT_Status _rt_file_close(_RT_File *file) {
|
||||||
|
BOOL ok = CloseHandle(file->handle);
|
||||||
|
if(!ok) {
|
||||||
|
return _RT_STATUS_FILE_BAD_FILE;
|
||||||
|
}
|
||||||
|
return _RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]] static void _rt_program_exit(int code) {
|
||||||
|
ExitProcess(code);
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
#define NOGDI
|
||||||
|
#define NOUSER
|
||||||
|
#define NOMINMAX
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
|
@ -1,9 +1,4 @@
|
||||||
|
|
||||||
#include <cia-def.h>
|
int main(int argc, char **argv) {
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main(int argc, char **argv, char **envp) {
|
|
||||||
char string[] = "Hello, world!\n";
|
|
||||||
fwrite(string, 1, sizeof string-1, stdout);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
#include <cia-def.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(int argc, char **argv, char **envp) {
|
||||||
|
char string[] = "Hello, world!\n";
|
||||||
|
fwrite(string, 1, sizeof string-1, stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue