windows building support

This commit is contained in:
2026-07-06 14:17:22 +10:00
parent 820fd618a3
commit 3a1cefffd7
6 changed files with 178 additions and 4 deletions

View File

@@ -13,6 +13,33 @@ Install with:
meson install -C builddir meson install -C builddir
``` ```
# Cross Compiling for Windows
We all hate Windows, right? As much as we hate it, people still use it, so it's nice to be able to run our good software on their crappy platform.
You'll need the cross compiler (install command is for Arch and derivatives):
```sh
sudo pacman -S mingw-w64-gcc
```
First, cross compile libffi for Windows (look up a guide) and install it to `/usr/x86_64-w64-mingw32/`.
Cross compile for Windows with the following commands:
```sh
meson setup --cross-file x86_64-w64-mingw32.txt -Ddefault_library=static --prefix=/usr/x86_64-w64-mingw32/ windows-builddir
meson compile -C windows-builddir
```
If you'd like it to be installed as a library to link with (for example with Solstice), run
```sh
meson install -C windows-builddir
```
This will install it to `/usr/x86_64-w64-mingw32/`, for convenient usage with other Windows cross compilation projects.
You may need to run `ldconfig` or reboot to update your ld cache. You may need to run `ldconfig` or reboot to update your ld cache.
## Bytecode Format ## Bytecode Format

View File

@@ -10,7 +10,6 @@
#ifdef _WIN32 #ifdef _WIN32
// TODO: check if this works // TODO: check if this works
#include <minwindef.h> #include <minwindef.h>
#define PATH_MAX MAX_PATH
#else #else
#include <limits.h> #include <limits.h>
#endif #endif

View File

@@ -119,9 +119,14 @@ sources = files(
'src/Struct/addField.c', 'src/Struct/addField.c',
'src/linenoise/linenoise.c' #'src/linenoise/linenoise.c'
) )
if host_machine.system() != 'windows'
sources += ['src/linenoise/linenoise.c']
endif
cli_sources = files( cli_sources = files(
'src/cli/main.c' 'src/cli/main.c'
) )
@@ -132,6 +137,7 @@ libffi = dependency('libffi', version : '>=3.0.0')
install_headers('include/ground.h') install_headers('include/ground.h')
lib = library('ground', sources, include_directories : incdir, dependencies : libffi, install : true)
lib = shared_library('ground', sources, include_directories : incdir, dependencies : libffi, install : true) lib = shared_library('ground', sources, include_directories : incdir, dependencies : libffi, install : true)
pkg.generate(lib, pkg.generate(lib,

View File

@@ -1,5 +1,7 @@
#include "../../../include/ground.h" #include "../../../include/ground.h"
#ifndef _WIN32
#include "../../linenoise/linenoise.h" #include "../../linenoise/linenoise.h"
#endif
#include <stdint.h> #include <stdint.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
@@ -86,10 +88,16 @@ struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeIns
return END( HEAP_GET(heap, instruction->args.at[0])->as.Int ); return END( HEAP_GET(heap, instruction->args.at[0])->as.Int );
} }
INPUT: { INPUT: {
#ifdef _WIN32
// TODO implement line input on Windows
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(""))));
return CONTINUE;
#else
char* input = linenoise(""); char* input = linenoise("");
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input)))); HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(input))));
free(input); free(input);
return CONTINUE; return CONTINUE;
#endif
} }
PRINT: { PRINT: {
for (GroundSize i = 0; i < instruction->args.len; i++) { for (GroundSize i = 0; i < instruction->args.len; i++) {
@@ -914,7 +922,98 @@ struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeIns
return CONTINUE; return CONTINUE;
} }
STRUCT: { STRUCT: {
// no-op GroundBytecodeStruct* gbs = &HEAP_GET(heap, instruction->args.at[0])->as.Struct;
// struct &structName &field OP $value &field OP $value &field OP $value...
// where:
// &field is the field to initialise
// OP is a numeric identifier:
// 0 -> none
// 1 -> init
// 2 -> set
// 3 -> attach closure to function
// $value is either a type reference (OP=0), a value reference (OP=1), or none (OP=2)
for (GroundSize i = 1; i < instruction->args.len; i++) {
GroundSize offset = instruction->args.at[i];
i++;
switch (i) {
case 0: break;
case 1: {
i++;
GroundBytecodeValue* type = HEAP_GET(heap, instruction->args.at[i]);
switch (type->type.type) {
case GroundType_Struct: {
// TODO nested structs
break;
}
case GroundType_CoreType: {
switch (type->as.CoreType) {
case GroundType_Int: {
gbs->values[offset] = Ground.New.BytecodeValue(Ground.New.Value.Int(0));
break;
}
case GroundType_Double: {
gbs->values[offset] = Ground.New.BytecodeValue(Ground.New.Value.Double(0.0));
break;
}
case GroundType_String: {
gbs->values[offset] = Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String("")));
break;
}
case GroundType_Char: {
gbs->values[offset] = Ground.New.BytecodeValue(Ground.New.Value.Char(0));
break;
}
case GroundType_Bool: {
gbs->values[offset] = Ground.New.BytecodeValue(Ground.New.Value.Bool(false));
break;
}
default: break; // TODO implement all the other stuff
}
}
}
break;
}
case 2: {
i++;
gbs->values[offset] = Ground.Copy.BytecodeValue(HEAP_GET(heap, instruction->args.at[i]));
break;
}
case 3: {
GroundBytecodeFunction* function = &gbs->values[offset].as.Function;
if (function->closure == NULL) {
function->closure = malloc(sizeof(GroundBytecodeHeap));
if (function->closure == NULL) {
Ground.Log.Error("malloc failed in Ground.Bytecode.Instruction.execute");
Ground.Flags.error = true;
return CONTINUE;
}
} else {
free(function->closure->heap);
}
function->closure->capacity = heap->capacity;
function->closure->len = heap->len;
function->closure->heap = malloc(sizeof(GroundBytecodeValue) * heap->capacity);
if (function->closure->heap == NULL) {
Ground.Log.Error("malloc failed in Ground.Bytecode.Instruction.execute");
Ground.Flags.error = true;
return CONTINUE;
} else {
// forget all values in previous closure
for (GroundSize i = 0; i < function->closure->len; i++) {
Ground.Free.BytecodeValue(&function->closure->heap[i]);
}
}
for (GroundSize i = 0; i < heap->len; i++) {
function->closure->heap[i] = Ground.Copy.BytecodeValue(&heap->heap[i]);
}
break;
}
}
}
return CONTINUE; return CONTINUE;
} }
ENDSTRUCT: { ENDSTRUCT: {
@@ -922,6 +1021,38 @@ struct GroundExecutionResult _GroundBytecodeInstructionExecute(GroundBytecodeIns
return CONTINUE; return CONTINUE;
} }
INIT: { INIT: {
GroundBytecodeValue* type = HEAP_GET(heap, instruction->args.at[1]);
switch (type->type.type) {
case GroundType_Struct: {
// TODO nested structs
break;
}
case GroundType_CoreType: {
switch (type->as.CoreType) {
case GroundType_Int: {
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.Int(0)));
break;
}
case GroundType_Double: {
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.Double(0.0)));
break;
}
case GroundType_String: {
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.String(Ground.New.String(""))));
break;
}
case GroundType_Char: {
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.Char(0)));
break;
}
case GroundType_Bool: {
HEAP_SET(heap, instruction->args.at[0], Ground.New.BytecodeValue(Ground.New.Value.Bool(false)));
break;
}
default: break; // TODO implement all the other stuff
}
}
}
return CONTINUE; return CONTINUE;
} }
GETFIELD: { GETFIELD: {

View File

@@ -112,7 +112,7 @@ static void doStruct(GroundProgram* program, GroundProgram* newProgram, GroundSt
GroundStruct gs = Ground.New.Struct(); GroundStruct gs = Ground.New.Struct();
// The aim is to compile an instruction which looks like this: // The aim is to compile an instruction which looks like this:
// struct &field OP $value &field OP $value &field OP $value... // struct &structName &field OP $value &field OP $value &field OP $value...
// where: // where:
// &field is the field to initialise // &field is the field to initialise
// OP is a numeric identifier: // OP is a numeric identifier:

11
x86_64-w64-mingw32.txt Normal file
View File

@@ -0,0 +1,11 @@
[binaries]
c = 'x86_64-w64-mingw32-gcc'
ar = 'x86_64-w64-mingw32-ar'
exe_wrapper = 'wine'
pkg-config = 'pkg-config'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'