Merge pull request #12 from ThakeeNathees/minimal-build-file

build script refactored to single file
This commit is contained in:
Thakee Nathees 2021-05-09 12:09:30 +05:30 committed by GitHub
commit 226b4844fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 261 additions and 267 deletions

View File

@ -1,44 +0,0 @@
Import('env')
import os
env.PROJECT_NAME = "pocketlang"
env.RUN_TARGET = os.path.join(env['variant_dir'], 'bin/pocket')
## TODO: automate types file generation.
## PocketLang source files
SOURCES = [
Glob('src/*.c'),
Glob('src/types/gen/*.c'),
]
if env['lib_shared']:
## Compile pocketlang dynamic lib.
dll = env.SharedLibrary(
target = 'bin/pocket' + env['bin_suffix'],
source = SOURCES,
CPPPATH = ['include/'],
CPPDEFINES = [env['CPPDEFINES'], 'MS_DLL', 'MS_COMPILE'],
)
else:
## Compile pocketlang static lib.
lib = env.Library(
target = 'bin/pocket' + env['bin_suffix'],
source = SOURCES,
CPPPATH = ['include/'],
)
## Test executable
test = env.Program(
target = 'bin/pocket' + env['bin_suffix'],
source = ['src/main/main.c'],
CPPPATH = ['include/'],
LIBPATH = 'bin',
LIBS = 'pocket' + env['bin_suffix'],
)
env.Append(CPPPATH=['include/'])
Requires(test, lib)

View File

@ -1,6 +1,54 @@
#!python
import os, subprocess, sys
def CONFIGURE_ENV(env):
root_dir = env['variant_dir']
assert(root_dir.endswith('/'))
env.PROJECT_NAME = "pocketlang"
env.RUN_TARGET = root_dir + 'bin/pocket'
## PocketLang source files
SOURCES = [
Glob(root_dir + '*.c'),
Glob(root_dir + 'buffers/*.c'),
]
target_dir = root_dir + '../bin/'
if env['lib_shared']:
## Compile pocketlang dynamic lib.
dll = env.SharedLibrary(
target = target_dir + 'pocket' + env['bin_suffix'],
source = SOURCES,
CPPPATH = [root_dir + 'include/'],
CPPDEFINES = [env['CPPDEFINES'], 'MS_DLL', 'MS_COMPILE'],
)
else:
## Compile pocketlang static lib.
lib = env.Library(
target = target_dir + 'pocket' + env['bin_suffix'],
source = SOURCES,
CPPPATH = [root_dir + 'include/'],
)
## Test executable
test = env.Program(
target = target_dir + 'pocket' + env['bin_suffix'],
source = [root_dir + 'main/main.c'],
CPPPATH = [root_dir + 'include/'],
LIBPATH = target_dir,
LIBS = 'pocket' + env['bin_suffix'],
)
Requires(test, lib)
env.Append(CPPPATH=['src/include/'])
## -----------------------------------------------------------------------------
## END OF CONFIGURATION
## -----------------------------------------------------------------------------
opts = Variables([], ARGUMENTS)
## Define our options
opts.Add(EnumVariable('platform', "Compilation platform", '', ['', 'windows', 'x11', 'linux', 'osx']))
@ -14,6 +62,12 @@ opts.Add(BoolVariable('verbose', "use verbose build command", True))
opts.Add(BoolVariable('lib_shared', "Compile as a shared library (only).", False))
## VariantDir
_build_target = ARGUMENTS.get('target', 'debug')
if _build_target in ('debug', 'release'): ## Otherwise error below.
_build_target = 'build/' + _build_target + '/src/'
VariantDir(_build_target, 'src', duplicate=0)
## Setup the Environment
DefaultEnvironment(tools=[]) ## not using any tools
env = Environment()
@ -101,29 +155,21 @@ def no_verbose(sys, env):
colors["end"] = "\033[0m" if sys.stdout.isatty() else ""
compile_source_message = "{}Compiling {}==> {}$SOURCE{}".format(
colors["blue"], colors["purple"], colors["yellow"], colors["end"]
)
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
java_compile_source_message = "{}Compiling {}==> {}$SOURCE{}".format(
colors["blue"], colors["purple"], colors["yellow"], colors["end"]
)
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
compile_shared_source_message = "{}Compiling shared {}==> {}$SOURCE{}".format(
colors["blue"], colors["purple"], colors["yellow"], colors["end"]
)
colors["blue"], colors["purple"], colors["yellow"], colors["end"])
link_program_message = "{}Linking Program {}==> {}$TARGET{}".format(
colors["red"], colors["purple"], colors["yellow"], colors["end"]
)
colors["red"], colors["purple"], colors["yellow"], colors["end"])
link_library_message = "{}Linking Static Library {}==> {}$TARGET{}".format(
colors["red"], colors["purple"], colors["yellow"], colors["end"]
)
colors["red"], colors["purple"], colors["yellow"], colors["end"])
ranlib_library_message = "{}Ranlib Library {}==> {}$TARGET{}".format(
colors["red"], colors["purple"], colors["yellow"], colors["end"]
)
colors["red"], colors["purple"], colors["yellow"], colors["end"])
link_shared_library_message = "{}Linking Shared Library {}==> {}$TARGET{}".format(
colors["red"], colors["purple"], colors["yellow"], colors["end"]
)
colors["red"], colors["purple"], colors["yellow"], colors["end"])
java_library_message = "{}Creating Java Archive {}==> {}$TARGET{}".format(
colors["red"], colors["purple"], colors["yellow"], colors["end"]
)
colors["red"], colors["purple"], colors["yellow"], colors["end"])
env.Append(CXXCOMSTR=[compile_source_message])
env.Append(CCCOMSTR=[compile_source_message])
env.Append(SHCCCOMSTR=[compile_shared_source_message])
@ -139,9 +185,9 @@ if not env['verbose']:
no_verbose(sys, env)
Export('env')
env['variant_dir'] = 'build/' + env['target'] + '/'
env['variant_dir'] = _build_target
env['bin_suffix'] = '' ## TODO: Maybe '.%s.%s' % (env['platform'], env['bits'])
SConscript('SConscript', variant_dir=env['variant_dir'], duplicate=0)
CONFIGURE_ENV(env)
## --------------------------------------------------------------------------------

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
/** A template header to emulate C++ template and every occurence of
* M__NAME will be replaced by the name of the buffer and M__TYPE will be
* replaced by the element type of the buffer (by a pre compile script) */
void M_CONC(M__NAME_L,BufferInit)(M_CONC(M__NAME,Buffer)* self) {
self->data = NULL;
self->count = 0;
self->capacity = 0;
}
void M_CONC(M__NAME_L,BufferClear)(M_CONC(M__NAME,Buffer)* self, MSVM* vm) {
vmRealloc(vm, self->data, self->capacity * sizeof(M__TYPE), 0);
self->data = NULL;
self->count = 0;
self->capacity = 0;
}
void M_CONC(M__NAME_L,BufferFill)(M_CONC(M__NAME,Buffer)* self, MSVM* vm, M__TYPE data, int count) {
if (self->capacity < self->count + count) {
int capacity = utilPowerOf2Ceil((int)self->count + count);
if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY;
self->data = (M__TYPE*)vmRealloc(vm, self->data,
self->capacity * sizeof(M__TYPE), capacity * sizeof(M__TYPE));
self->capacity = capacity;
}
for (int i = 0; i < count; i++) {
self->data[self->count++] = data;
}
}
void M_CONC(M__NAME_L,BufferWrite)(M_CONC(M__NAME,Buffer)* self, MSVM* vm, M__TYPE data) {
M_CONC(M__NAME_L,BufferFill)(self, vm, data, 1);
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
/** A template header to emulate C++ template and every occurence of
* M__NAME will be replaced by the name of the buffer and M__TYPE will be
* replaced by the element type of the buffer (by a pre compile script) */
typedef struct {
M__TYPE* data;
uint32_t count;
uint32_t capacity;
} M_CONC(M__NAME, Buffer);
// Initialize a new buffer int instance.
void M_CONC(M__NAME_L,BufferInit)(M_CONC(M__NAME, Buffer)* self);
// Clears the allocated elementes from the VM's realloc function.
void M_CONC(M__NAME_L,BufferClear)(M_CONC(M__NAME, Buffer)* self, MSVM* vm);
// Fill the buffer at the end of it with provided data if the capacity isn't
// enough using VM's realloc function.
void M_CONC(M__NAME_L,BufferFill)(M_CONC(M__NAME, Buffer)* self, MSVM* vm, M__TYPE data, int count);
// Write to the buffer with provided data at the end of the buffer.
void M_CONC(M__NAME_L,BufferWrite)(M_CONC(M__NAME, Buffer)* self, MSVM* vm, M__TYPE data);

59
src/buffers/buffers.c Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
#include "buffers.h"
#include "../utils.h"
#include "../vm.h"
#define M__HEADER "gen/uint_buffer.h"
#define M__NAME Uint
#define M__NAME_L uint
#define M__TYPE uint32_t
#include "buffer.c.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__HEADER "gen/byte_buffer.h"
#define M__NAME Byte
#define M__NAME_L byte
#define M__TYPE uint8_t
#include "buffer.c.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__HEADER "gen/var_buffer.h"
#define M__NAME Var
#define M__NAME_L var
#define M__TYPE Var
#include "buffer.c.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__HEADER "gen/string_buffer.h"
#define M__NAME String
#define M__NAME_L string
#define M__TYPE String*
#include "buffer.c.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__HEADER "gen/function_buffer.h"
#define M__NAME Function
#define M__NAME_L function
#define M__TYPE Function*
#include "buffer.c.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE

57
src/buffers/buffers.h Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
#ifndef BUFFERS_TEMPLATE_H
#define BUFFERS_TEMPLATE_H
#include "../common.h"
#include "miniscript.h"
#define M__NAME Uint
#define M__NAME_L uint
#define M__TYPE uint32_t
#include "buffer.h.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__NAME Byte
#define M__NAME_L byte
#define M__TYPE uint8_t
#include "buffer.h.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__NAME Var
#define M__NAME_L var
#define M__TYPE Var
#include "buffer.h.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__NAME String
#define M__NAME_L string
#define M__TYPE String*
#include "buffer.h.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#define M__NAME Function
#define M__NAME_L function
#define M__TYPE Function*
#include "buffer.h.template"
#undef M__HEADER
#undef M__NAME
#undef M__NAME_L
#undef M__TYPE
#endif // BUFFERS_TEMPLATE_H

View File

@ -70,6 +70,8 @@
#define STRINGIFY(x) TOSTRING(x)
#define TOSTRING(x) #x
#define M_CONC(a, b) M_CONC_(a, b)
#define M_CONC_(a, b) a##b
// The factor by which a buffer will grow when it's capacity reached.
#define GROW_FACTOR 2

View File

@ -9,7 +9,7 @@
#include <string.h>
#include "core.h"
#include "types/gen/byte_buffer.h"
#include "buffers/buffers.h"
#include "utils.h"
#include "vm.h"

View File

@ -1,4 +0,0 @@
## Ignore the generated sources.
## TODO: use template and macros instead of generating the source.
gen/

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
/** A template header to emulate C++ template and every occurence of
* $name$ will be replaced by the name of the buffer and $type$ will be
* replaced by the element type of the buffer (by a pre compile script) */
// Replace the following line with "$name$_buffer.h"
#include "buffer.template.h"
#include "../utils.h"
#include "../vm.h"
void $name_l$BufferInit($name$Buffer* self) {
self->data = NULL;
self->count = 0;
self->capacity = 0;
}
void $name_l$BufferClear($name$Buffer* self, MSVM* vm) {
vmRealloc(vm, self->data, self->capacity * sizeof($type$), 0);
self->data = NULL;
self->count = 0;
self->capacity = 0;
}
void $name_l$BufferFill($name$Buffer* self, MSVM* vm, $type$ data, int count) {
if (self->capacity < self->count + count) {
int capacity = utilPowerOf2Ceil((int)self->count + count);
if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY;
self->data = ($type$*)vmRealloc(vm, self->data,
self->capacity * sizeof($type$), capacity * sizeof($type$));
self->capacity = capacity;
}
for (int i = 0; i < count; i++) {
self->data[self->count++] = data;
}
}
void $name_l$BufferWrite($name$Buffer* self, MSVM* vm, $type$ data) {
$name_l$BufferFill(self, vm, data, 1);
}

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2021 Thakee Nathees
* Licensed under: MIT License
*/
/** A template header to emulate C++ template and every occurence of
* $name$ will be replaced by the name of the buffer and $type$ will be
* replaced by the element type of the buffer (by a pre compile script) */
#ifndef $name_u$_BUFFER_H
#define $name_u$_BUFFER_H
#include "../common.h"
#include "miniscript.h"
// A place holder typedef to prevent IDE syntax errors. Remove this line
// when generating the source.
typedef uint8_t $type$;
typedef struct {
$type$* data;
uint32_t count;
uint32_t capacity;
} $name$Buffer;
// Initialize a new buffer int instance.
void $name_l$BufferInit($name$Buffer* self);
// Clears the allocated elementes from the VM's realloc function.
void $name_l$BufferClear($name$Buffer* self, MSVM* vm);
// Fill the buffer at the end of it with provided data if the capacity isn't
// enough using VM's realloc function.
void $name_l$BufferFill($name$Buffer* self, MSVM* vm, $type$ data, int count);
// Write to the buffer with provided data at the end of the buffer.
void $name_l$BufferWrite($name$Buffer* self, MSVM* vm, $type$ data);
#endif // $name_u$_BUFFER_H

View File

@ -1,101 +0,0 @@
from pathlib import Path ## python 3.4
import shutil
import os, sys
## usage buffergen.py [--clean]
SCRIPT_PATH = Path(os.path.realpath(__file__))
ROOT = str(SCRIPT_PATH.parent)
GEN_LIST = [
## name type
('Uint', 'uint32_t'),
('Byte', 'uint8_t'),
('Var', 'Var'),
('String', 'String*'),
('Function', 'Function*'),
]
def log(msg):
print('[buffergen.py]', msg)
def gen():
cwd = os.getcwd()
os.chdir(ROOT)
_gen()
os.chdir(cwd)
return 0
def clean():
cwd = os.getcwd()
os.chdir(ROOT)
_clean()
os.chdir(cwd)
return 0
def _replace(text, _data):
text = text.replace('$name$', _data[0])
text = text.replace('$name_l$', _data[0].lower())
text = text.replace('$name_u$', _data[0].upper())
text = text.replace('$type$', _data[1])
## Fix relative imports.
text = text.replace('../vm.h', '../../vm.h')
text = text.replace('../utils.h', '../../utils.h')
text = text.replace('../common.h', '../../common.h')
return text
def _gen():
header = ''
source = ''
with open('buffer.c.template', 'r') as f:
header = f.read()
with open('buffer.h.template', 'r') as f:
source = f.read()
for _data in GEN_LIST:
_header = header.replace('''\
// A place holder typedef to prevent IDE syntax errors. Remove this line
// when generating the source.
typedef uint8_t $type$;
''', '')
_header = _replace(_header, _data)
_source = source.replace('''\
// Replace the following line with "$name$_buffer.h"
#include "buffer.template.h"''', '#include "%s_buffer.h"' % _data[0].lower())
_source = _replace(_source, _data)
if not os.path.exists('gen/'):
os.mkdir('gen/')
with open('gen/' + _data[0].lower() + '_buffer.h', 'w') as f:
f.write(_header)
log(_data[0].lower() + '_buffer.h' + ' generated' )
with open('gen/' + _data[0].lower() + '_buffer.c', 'w') as f:
f.write(_source)
log(_data[0].lower() + '_buffer.c' + ' generated' )
def _clean():
shutil.rmtree('gen/')
log("Buffer source files removed")
def error_exit(msg):
print("Error: %s\n\tusage buffergen.py [--clean]" % msg)
exit(1)
if __name__ == '__main__':
if len(sys.argv) > 2:
error_exit("invalid arg count")
if len(sys.argv) == 2:
if sys.argv[1] == '--clean':
_clean()
else:
error_exit("unknown argument")
else:
_gen()
exit(0)

View File

@ -31,11 +31,7 @@
#include <string.h>
#include "common.h"
#include "types/gen/byte_buffer.h"
#include "types/gen/function_buffer.h"
#include "types/gen/uint_buffer.h"
#include "types/gen/var_buffer.h"
#include "types/gen/string_buffer.h"
#include "buffers/buffers.h"
// To use dynamic variably-sized struct with a tail array add an array at the
// end of the struct with size \ref DYNAMIC_TAIL_ARRAY. This method was a

View File

@ -94,9 +94,9 @@ goto :END
:START
if not exist "bin" md "./bin"
if not exist "..\build\" md "..\build\"
set ADDNL_INCLUDE=/I..\include
set ADDNL_INCLUDE=/I..\src\include
set ADDNL_CPPFLAGS=/EHsc /MDd
if "%BUILD_DLL%" neq "true" goto :COMPILE
@ -110,31 +110,31 @@ set object_files=
:: Recursively loop all files in '.' matching *.c and compile.
for /r "..\src" %%f in (*.c) do (
for %%i in ("%%f") do (
call set "object_files=%%object_files%% bin\%%~ni.obj"
cl /nologo /c %ADDNL_INCLUDE% %ADDNL_DEFINES% %ADDNL_CPPFLAGS% "%%f" /Fobin\%%~ni.obj
call set "object_files=%%object_files%% ..\build\%%~ni.obj"
cl /nologo /c %ADDNL_INCLUDE% %ADDNL_DEFINES% %ADDNL_CPPFLAGS% "%%f" /Fo..\build\%%~ni.obj
if errorlevel 1 goto :FAIL
)
)
if "%BUILD_DLL%"=="true" goto :LINK_DLL
call :ColorText 0a "pocket.lib"
call :ColorText 0d "..\build\pocket.lib"
echo.
lib /nologo /OUT:bin\pocket.lib %object_files%
lib /nologo /OUT:..\build\pocket.lib %object_files%
if errorlevel 1 goto :FAIL
call :ColorText 0a "pocket.exe"
call :ColorText 0d "..\build\pocket.exe"
echo.
cl /nologo %ADDNL_CPPFLAGS% %ADDNL_INCLUDE% %object_files% /Febin\pocket.exe
cl /nologo %ADDNL_CPPFLAGS% %ADDNL_INCLUDE% %object_files% /Fe..\build\pocket.exe
if errorlevel 1 goto :FAIL
goto :CLEAN
:LINK_DLL
call :ColorText 0a "pocket.dll"
call :ColorText 0d "pocket.dll"
echo.
link /nologo /dll /out:bin\pocket.dll /implib:bin\pocket.lib %object_files%
link /nologo /dll /out:..\build\pocket.dll /implib:..\build\pocket.lib %object_files%
:CLEAN