all repos — circe-vpn @ e6e976ca669f07931e13bef5453e9b4969a76d83

Circe VPN

Started work on libcirce-core
Juniper Beatitudes [email protected]
Tue, 14 Jul 2026 19:11:08 -0500
commit

e6e976ca669f07931e13bef5453e9b4969a76d83

parent

839d2ba0b6f11d354c15606af67cabcf5610cefc

A common/cbor.c

@@ -0,0 +1,448 @@

+#include "cbor.h" +#include <stdint.h> +#include <stdbool.h> + +#define CIRCE_CBOR_ASSERT(x) \ + do \ + { \ + if (!(x)) \ + { \ + return false; \ + } \ + } \ + while (false) + +/* DECODING FUNCTIONS */ + +bool +circe_cbor_get_argument (struct circe_cbor_decoder *dc, uint64_t *out, bool *is_definite) +{ + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 1 <= dc->buf_len); + *out = *(dc->cursor) & 0b11111; + ++dc->cursor; + switch (*out) + { + case 24: + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 1 <= dc->buf_len); + *out = *dc->cursor; + ++dc->cursor; + break; + case 25: + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 2 <= dc->buf_len); + *out = 0; + for (unsigned int i = 0; i < 2; ++i) + { + *out <<= 8; + *out |= dc->cursor[i]; + } + dc->cursor += 2; + break; + case 26: + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 4 <= dc->buf_len); + *out = 0; + for (unsigned int i = 0; i < 4; ++i) + { + *out <<= 8; + *out |= dc->cursor[i]; + } + dc->cursor += 4; + break; + case 27: + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 8 <= dc->buf_len); + *out = 0; + for (unsigned int i = 0; i < 8; ++i) + { + *out <<= 8; + *out |= dc->cursor[i]; + } + dc->cursor += 8; + break; + case 28: + case 29: + case 30: + CIRCE_CBOR_ASSERT (false); + } + *is_definite = !(*out == 31); + return true; +} + +bool +circe_cbor_get_major_type (struct circe_cbor_decoder *dc, enum circe_cbor_major_type *out) +{ + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start < dc->buf_len); + *out = (enum circe_cbor_major_type) (*dc->cursor >> 5); + return true; +} + +bool +circe_cbor_get_simple_type (struct circe_cbor_decoder *dc, enum circe_cbor_simple_type *out) +{ + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start < dc->buf_len); + CIRCE_CBOR_ASSERT ((*dc->cursor & 0b11111) != 24); + *out = (enum circe_cbor_simple_type) (*dc->cursor & 0b11111); + return true; +} + +bool +circe_cbor_extract_length (struct circe_cbor_decoder *dc, uint64_t *out, bool *is_definite) +{ + CIRCE_CBOR_ASSERT (circe_cbor_get_argument (dc, out, is_definite)); + return true; +} + +bool +circe_cbor_skip (struct circe_cbor_decoder *dc, uint64_t max_depth) +{ + if (max_depth == 0) + { + return false; + } + enum circe_cbor_major_type type; + CIRCE_CBOR_ASSERT (circe_cbor_get_major_type (dc, &type)); + uint64_t num_throwaway; + struct circe_cbor_buffer buf_throwaway; + uint64_t len; + bool is_definite; + enum circe_cbor_simple_type st; + switch (type) + { + case CIRCE_CBOR_MAJOR_UNSIGNED: + CIRCE_CBOR_ASSERT (circe_cbor_extract_unsigned (dc, &num_throwaway)); + break; + case CIRCE_CBOR_MAJOR_NEGATIVE: + CIRCE_CBOR_ASSERT (circe_cbor_extract_negative (dc, &num_throwaway)); + break; + case CIRCE_CBOR_MAJOR_BYTESTR: + CIRCE_CBOR_ASSERT (circe_cbor_extract_bytestr (dc, &buf_throwaway)); + break; + case CIRCE_CBOR_MAJOR_TEXTSTR: + CIRCE_CBOR_ASSERT (circe_cbor_extract_bytestr (dc, &buf_throwaway)); + break; + case CIRCE_CBOR_MAJOR_ARRAY: + CIRCE_CBOR_ASSERT (circe_cbor_extract_length (dc, &len, &is_definite)); + if (!is_definite) + { + while (true) + { + CIRCE_CBOR_ASSERT (circe_cbor_get_major_type (dc, &type)); + if (type == CIRCE_CBOR_MAJOR_SIMPLE) + { + enum circe_cbor_simple_type st; + CIRCE_CBOR_ASSERT (circe_cbor_get_simple_type (dc, &st)); + if (st == CIRCE_CBOR_SIMPLE_BREAK) + { + break; + } + } + circe_cbor_skip (dc, max_depth - 1); + } + } + else + { + for (uint64_t i = 0; i < len; ++i) + { + circe_cbor_skip (dc, max_depth - 1); + } + } + break; + case CIRCE_CBOR_MAJOR_MAPPING: + CIRCE_CBOR_ASSERT (circe_cbor_extract_length (dc, &len, &is_definite)); + if (!is_definite) + { + while (true) + { + CIRCE_CBOR_ASSERT (circe_cbor_get_major_type (dc, &type)); + if (type == CIRCE_CBOR_MAJOR_SIMPLE) + { + CIRCE_CBOR_ASSERT (circe_cbor_get_simple_type (dc, &st)); + if (st == CIRCE_CBOR_SIMPLE_BREAK) + { + break; + } + } + circe_cbor_skip (dc, max_depth - 1); + circe_cbor_skip (dc, max_depth - 1); + } + } + else + { + for (uint64_t i = 0; i < len; ++i) + { + circe_cbor_skip (dc, max_depth - 1); + circe_cbor_skip (dc, max_depth - 1); + } + } + break; + case CIRCE_CBOR_MAJOR_TAG: + CIRCE_CBOR_ASSERT (circe_cbor_extract_tag (dc, &num_throwaway)); + circe_cbor_skip (dc, max_depth - 1); + break; + case CIRCE_CBOR_MAJOR_SIMPLE: + CIRCE_CBOR_ASSERT (circe_cbor_get_simple_type (dc, &st)); + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 1 <= dc->buf_len); + ++dc->cursor; + if (st == CIRCE_CBOR_SIMPLE_SINGLE) + { + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 4 <= dc->buf_len); + dc->cursor += 4; + } + else if (st == CIRCE_CBOR_SIMPLE_DOUBLE) + { + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 8 <= dc->buf_len); + dc->cursor += 8; + } + } + return true; +} + +bool +circe_cbor_extract_unsigned (struct circe_cbor_decoder *dc, uint64_t *out) +{ + bool _; + CIRCE_CBOR_ASSERT (circe_cbor_get_argument (dc, out, &_)); + return true; +} + +bool +circe_cbor_extract_negative (struct circe_cbor_decoder *dc, uint64_t *magnitude_out) +{ + bool _; + CIRCE_CBOR_ASSERT (circe_cbor_get_argument (dc, magnitude_out, &_)); + return true; +} + +bool +circe_cbor_extract_bytestr (struct circe_cbor_decoder *dc, struct circe_cbor_buffer *out) +{ + bool is_definite; + uint64_t len; + CIRCE_CBOR_ASSERT (circe_cbor_get_argument (dc, &len, &is_definite)); + if (is_definite) + { + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + len <= dc->buf_len); + *out = (struct circe_cbor_buffer){ + .buf_start = dc->cursor, + .buf_len = len, + }; + dc->cursor += len; + } + else + { + uint8_t *start = dc->cursor; + while (dc->cursor - dc->buf_start < dc->buf_len && *dc->cursor != 0xFF) + { + ++dc->cursor; + } + CIRCE_CBOR_ASSERT (*dc->cursor == 0xFF); + ++dc->cursor; + *out = (struct circe_cbor_buffer){ + .buf_start = start, + .buf_len = dc->cursor - start, + }; + } + return true; +} + +bool +circe_cbor_extract_textstr (struct circe_cbor_decoder *dc, struct circe_cbor_buffer *out) +{ + return circe_cbor_extract_bytestr (dc, out); +} + +bool +circe_cbor_extract_float (struct circe_cbor_decoder *dc, float *out) +{ + uint32_t raw = 0; + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 4 <= dc->buf_len); + for (unsigned int i = 4; i > 0; --i) + { + // TODO: adapt for non-little-endian + raw <<= 8; + raw |= *(dc->cursor + i - 1); + } + *out = *((float *)&raw); + return true; +} + +bool +circe_cbor_extract_double (struct circe_cbor_decoder *dc, double *out) +{ + uint64_t raw = 0; + CIRCE_CBOR_ASSERT (dc->cursor - dc->buf_start + 4 <= dc->buf_len); + for (unsigned int i = 8; i > 0; --i) + { + // TODO: adapt for non-little-endian + raw <<= 8; + raw |= *(dc->cursor + i - 1); + } + *out = *((double *)&raw); + return true; +} + +bool +circe_cbor_extract_tag (struct circe_cbor_decoder *dc, uint64_t *out) +{ + bool _; + CIRCE_CBOR_ASSERT (circe_cbor_get_argument (dc, out, &_)); + return true; +} + +/* ENCODING FUNCTIONS */ + +bool +circe_cbor_emit_with_arg (struct circe_cbor_encoder *ec, enum circe_cbor_major_type t, uint64_t arg) +{ + unsigned int needed = 1; + if (arg >= 24) + { + ++needed; + } + if (arg >= UINT8_MAX) + { + ++needed; + } + if (arg >= UINT16_MAX) + { + needed += 2; + } + if (arg >= UINT32_MAX) + { + needed += 4; + } + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + needed <= ec->buf_len); + *ec->cursor = (uint8_t)t << 5; + switch (needed) + { + case 1: + *ec->cursor |= (uint8_t)arg; + break; + case 2: + *ec->cursor |= 24; + *(ec->cursor + 1) = (uint8_t)arg; + break; + case 3: + *ec->cursor |= 25; + for (unsigned int i = 0; i < 2; ++i) + { + *(ec->cursor + 1 + i) = (uint8_t)(arg & 0xff); + arg >>= 8; + } + break; + case 5: + *ec->cursor |= 26; + for (unsigned int i = 0; i < 4; ++i) + { + *(ec->cursor + 1 + i) = (uint8_t)(arg & 0xff); + arg >>= 8; + } + break; + case 9: + *ec->cursor |= 27; + for (unsigned int i = 0; i < 8; ++i) + { + *(ec->cursor + 1 + i) = (uint8_t)(arg & 0xff); + arg >>= 8; + } + break; + } + ec->cursor += needed; + return true; +} + +bool +circe_cbor_emit_unsigned (struct circe_cbor_encoder *ec, uint64_t n) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_UNSIGNED, n)); + return true; +} + +bool +circe_cbor_emit_negative (struct circe_cbor_encoder *ec, uint64_t magnitude) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_NEGATIVE, magnitude)); + return true; +} + +bool +circe_cbor_emit_bytestr (struct circe_cbor_encoder *ec, struct circe_cbor_buffer contents) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_BYTESTR, contents.buf_len)); + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + contents.buf_len <= ec->buf_len); + for (uint64_t i = 0; i < contents.buf_len; ++i) + { + ec->cursor[i] = contents.buf_start[i]; + } + ec->cursor += contents.buf_len; + return true; +} + +bool +circe_cbor_emit_textstr (struct circe_cbor_encoder *ec, struct circe_cbor_buffer contents) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_TEXTSTR, contents.buf_len)); + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + contents.buf_len <= ec->buf_len); + for (uint64_t i = 0; i < contents.buf_len; ++i) + { + ec->cursor[i] = contents.buf_start[i]; + } + ec->cursor += contents.buf_len; + return true; +} + +bool +circe_cbor_emit_simple (struct circe_cbor_encoder *ec, enum circe_cbor_simple_type t) +{ + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + 1 <= ec->buf_len); + *ec->cursor = ((uint8_t)CIRCE_CBOR_MAJOR_SIMPLE << 5) | (uint8_t)t; + ++ec->cursor; + return true; +} + +bool +circe_cbor_emit_float (struct circe_cbor_encoder *ec, float x) +{ + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + 4 <= ec->buf_len); + uint32_t raw = *((uint32_t *)&x); + for (unsigned int i = 0; i < 4; ++i) + { + ec->cursor[i] = (uint8_t)(raw & 0xff); + raw >>= 8; + } + ec->cursor += 4; + return true; +} + +bool +circe_cbor_emit_double (struct circe_cbor_encoder *ec, double x) +{ + CIRCE_CBOR_ASSERT (ec->cursor - ec->buf_start + 4 <= ec->buf_len); + uint64_t raw = *((uint64_t *)&x); + for (unsigned int i = 0; i < 8; ++i) + { + ec->cursor[i] = (uint8_t)(raw & 0xff); + raw >>= 8; + } + ec->cursor += 4; + return true; +} + +bool +circe_cbor_emit_tag (struct circe_cbor_encoder *ec, uint64_t tagnum) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_TAG, tagnum)); + return true; +} + +bool +circe_cbor_emit_mapping_header (struct circe_cbor_encoder *ec, uint64_t len) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_MAPPING, len)); + return true; +} + +bool +circe_cbor_emit_array_header (struct circe_cbor_encoder *ec, uint64_t len) +{ + CIRCE_CBOR_ASSERT (circe_cbor_emit_with_arg (ec, CIRCE_CBOR_MAJOR_ARRAY, len)); + return true; +}
A common/cbor.h

@@ -0,0 +1,98 @@

+#ifndef CIRCE_CBOR_H +#define CIRCE_CBOR_H + +#include <stdbool.h> +#include <stdint.h> + +/// Represents all major types in the standard +enum circe_cbor_major_type +{ + CIRCE_CBOR_MAJOR_UNSIGNED = 0, + CIRCE_CBOR_MAJOR_NEGATIVE, + CIRCE_CBOR_MAJOR_BYTESTR, + CIRCE_CBOR_MAJOR_TEXTSTR, + CIRCE_CBOR_MAJOR_ARRAY, + CIRCE_CBOR_MAJOR_MAPPING, + CIRCE_CBOR_MAJOR_TAG, + /// Also includes floating-point numbers + CIRCE_CBOR_MAJOR_SIMPLE, +}; + +/// Represents most simple value types, missing IEEE 754 half-precision floats +/// because those are not standard in C without stdlib access +enum circe_cbor_simple_type +{ + CIRCE_CBOR_SIMPLE_FALSE = 20, + CIRCE_CBOR_SIMPLE_TRUE = 21, + CIRCE_CBOR_SIMPLE_NULL = 22, + CIRCE_CBOR_SIMPLE_UNDEFINED = 23, + CIRCE_CBOR_SIMPLE_SINGLE = 26, + CIRCE_CBOR_SIMPLE_DOUBLE = 27, + CIRCE_CBOR_SIMPLE_BREAK = 31, +}; + +/// Decoder context object +struct circe_cbor_decoder +{ + const uint8_t *buf_start; + const uint64_t buf_len; + const uint8_t *cursor; +}; + +/// Used to tie together buffer attributes in a single struct +struct circe_cbor_buffer +{ + uint8_t *buf_start; + uint64_t buf_len; +}; + +bool circe_cbor_get_major_type (struct circe_cbor_decoder *dc, enum circe_cbor_major_type *out); + +bool circe_cbor_get_simple_type (struct circe_cbor_decoder *dc, enum circe_cbor_simple_type *out); + +bool circe_cbor_extract_length (struct circe_cbor_decoder *dc, uint64_t *out, bool *is_definite); + +bool circe_cbor_skip (struct circe_cbor_decoder *dc, uint64_t max_depth); + +bool circe_cbor_extract_unsigned (struct circe_cbor_decoder *dc, uint64_t *out); + +bool circe_cbor_extract_negative (struct circe_cbor_decoder *dc, uint64_t *magnitude_out); + +bool circe_cbor_extract_bytestr (struct circe_cbor_decoder *dc, struct circe_cbor_buffer *out); + +bool circe_cbor_extract_textstr (struct circe_cbor_decoder *dc, struct circe_cbor_buffer *out); + +bool circe_cbor_extract_float (struct circe_cbor_decoder *dc, float *out); + +bool circe_cbor_extract_double (struct circe_cbor_decoder *dc, double *out); + +bool circe_cbor_extract_tag (struct circe_cbor_decoder *dc, uint64_t *out); + +struct circe_cbor_encoder +{ + uint8_t *buf_start; + const uint64_t buf_len; + uint8_t *cursor; +}; + +bool circe_cbor_emit_unsigned (struct circe_cbor_encoder *ec, uint64_t n); + +bool circe_cbor_emit_negative (struct circe_cbor_encoder *ec, uint64_t magnitude); + +bool circe_cbor_emit_bytestr (struct circe_cbor_encoder *ec, struct circe_cbor_buffer contents); + +bool circe_cbor_emit_textstr (struct circe_cbor_encoder *ec, struct circe_cbor_buffer contents); + +bool circe_cbor_emit_simple (struct circe_cbor_encoder *ec, enum circe_cbor_simple_type t); + +bool circe_cbor_emit_float (struct circe_cbor_encoder *ec, float x); + +bool circe_cbor_emit_double (struct circe_cbor_encoder *ec, double x); + +bool circe_cbor_emit_tag (struct circe_cbor_encoder *ec, uint64_t tagnum); + +bool circe_cbor_emit_mapping_header (struct circe_cbor_encoder *ec, uint64_t len); + +bool circe_cbor_emit_array_header (struct circe_cbor_encoder *ec, uint64_t len); + +#endif
A core/core.c

@@ -0,0 +1,45 @@

+#include "core.h" +#include "cbor.h" +#include "packet.h" +#include <stdbool.h> + +#define CIRCE_CORE_ASSERT(x, err) \ + do \ + { \ + if (!(x)) \ + { \ + return err; \ + } \ + } \ + while (false) + +enum circe_result +circe_handle_packet (struct circe_ctx *ctx, const uint8_t *in, uint32_t len, + uint64_t now_ms, uint8_t *out, uint32_t *out_len, + struct circe_event *events, uint32_t *n_events) +{ + struct circe_cbor_decoder cd = { + .buf_start = in, + .buf_len = len, + .cursor = in, + }; + enum circe_cbor_major_type major_type; + CIRCE_CORE_ASSERT (circe_cbor_get_major_type (&cd, &major_type), + CIRCE_RESULT_INVALID_PACKET); + CIRCE_CORE_ASSERT (major_type == CIRCE_CBOR_MAJOR_MAPPING, + CIRCE_RESULT_INVALID_PACKET); + uint64_t num_fields; + CIRCE_CORE_ASSERT (circe_cbor_extract_unsigned (&cd, &num_fields), + CIRCE_RESULT_INVALID_PACKET); + CIRCE_CORE_ASSERT (num_fields > 0, CIRCE_RESULT_INVALID_PACKET); + CIRCE_CORE_ASSERT (circe_cbor_get_major_type (&cd, &major_type), + CIRCE_RESULT_INVALID_PACKET); + CIRCE_CORE_ASSERT (major_type == CIRCE_CBOR_MAJOR_UNSIGNED, + CIRCE_RESULT_INVALID_PACKET); + uint64_t field; + CIRCE_CORE_ASSERT (circe_cbor_extract_unsigned (&cd, &field), + CIRCE_RESULT_INVALID_PACKET); + CIRCE_CORE_ASSERT (field < CIRCE_PACKET_FIELD_OVERMAX, + CIRCE_RESULT_INVALID_PACKET); + return CIRCE_RESULT_SUCCESS; +}
A core/core.h

@@ -0,0 +1,36 @@

+#ifndef CIRCE_CORE_H +#define CIRCE_CORE_H + +#include <stdint.h> + +enum circe_result +{ + CIRCE_RESULT_SUCCESS = 0, + CIRCE_RESULT_INSUFFICIENT_MEM, + CIRCE_RESULT_INVALID_PACKET, +}; + +struct circe_ctx +{ +}; + +struct circe_event +{ +}; + +/// Process a new raw Circe packet. +enum circe_result +circe_handle_packet (struct circe_ctx *ctx, const uint8_t *in, uint32_t len, + uint64_t now_ms, uint8_t *out, uint32_t *out_len, + struct circe_event *events, uint32_t *n_events); + +/// Get millisecond timestamp for next timer deadline (at which point +/// `circe_tick` should be called). +uint64_t circe_next_deadline (const struct circe_ctx *ctx); + +/// Iterate the Circe core logic. Assumes `now_ms` increases monotonically with +/// time. +enum circe_result circe_tick (struct circe_ctx *ctx, uint64_t now_ms, + uint8_t *out, uint32_t *out_len); + +#endif
A core/packet.h

@@ -0,0 +1,24 @@

+#ifndef CIRCE_CORE_PACKET_H +#define CIRCE_CORE_PACKET_H + +enum circe_packet_type +{ + CIRCE_PACKET_OPENTUNNEL = 0x0, + CIRCE_PACKET_ACKOPEN = 0x1, + CIRCE_PACKET_IDENTIFY = 0x2, + CIRCE_PACKET_DATA = 0x3, + CIRCE_PACKET_COMMAND = 0x4, +}; + +enum circe_packet_field +{ + CIRCE_PACKET_FIELD_TYPE = 0x0, + CIRCE_PACKET_FIELD_ECDH_FRAGMENT, + CIRCE_PACKET_FIELD_MLKEM_PUBKEY, + CIRCE_PACKET_FIELD_MLKEM_ENCAPSULATED, + CIRCE_PACKET_FIELD_IDENTITY, + CIRCE_PACKET_FIELD_PAYLOAD, + CIRCE_PACKET_FIELD_OVERMAX, +}; + +#endif
A core/peer_table.h

@@ -0,0 +1,6 @@

+#ifndef CIRCE_CORE_PEER_TABLE_H +#define CIRCE_CORE_PEER_TABLE_H + + + +#endif
M docs/PROTOCOL.mddocs/PROTOCOL.md

@@ -41,6 +41,12 @@ Polites->>Eurylochus: DATA, seqn1, k_d_p2e.encrypt(nonce=seqn1, packet length | packet contents), random padding bytes

Eurylochus->>Polites: COMMAND, seqn2, k_d_e2p.encrypt(nonce=seqn2, CLOSE_TUNNEL | sig_e), random padding bytes ``` +## State Machine + +## Wire Format + + + ## References - [Curve25519](http://cr.yp.to/ecdh/curve25519-20051115.pdf)
M meson.buildmeson.build

@@ -1,26 +1,59 @@

project('Circe', 'c', version: '0.1.0') -build_args = [ +## EXTERNAL DEPENDENCIES + +tct_subproj = subproject('TinyCrypT') +tct_dependency = tct_subproj.get_variable('TinyCrypT_dep') + +## LIBCIRCE-COMMON + +common_build_args = [ '-O3', '-ffreestanding', + '-nostdlib', + '-lgcc', ] -# if target_machine.cpu_family() == 'x86_64' -# build_args += '-march=native' -# endif +common_sources = [ + 'common/cbor.c', +] + +common_incdir = include_directories('common/') + +common_target = static_library( + 'circe-common', + common_sources, + c_args: common_build_args, + include_directories: common_incdir, +) + +common_dep = declare_dependency(include_directories: common_incdir, link_with: common_target) +set_variable(meson.project_name() + '_common_dep', common_dep) ## LIBCIRCE-CORE -core_sources = [] +core_build_args = [ + '-O3', + '-ffreestanding', + '-nostdlib', + '-lgcc', +] -core_incdir = include_directories('core/') +core_sources = [ + 'core/core.c', +] -core_target = static_library('circe-core', core_sources, c_args: build_args, include_directories: core_incdir) +core_incdir = include_directories('core/') -core_dep = declare_dependency( - include_directories: core_incdir, - link_with : core_target +core_target = static_library( + 'circe-core', + core_sources, + c_args: core_build_args, + include_directories: core_incdir, + dependencies: [common_dep, tct_dependency], ) + +core_dep = declare_dependency(include_directories: core_incdir, link_with: core_target) set_variable(meson.project_name() + '_core_dep', core_dep) if not meson.is_subproject() and not meson.is_cross_build()