commit 9d435bb0ab6d807c382d87031faef722fdbba8a6
parent c9156e6d621e9cd054a69a81f36cfa93015afd81
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 20 May 2026 05:30:37 -0700
Split target and hosted predefined macros
Diffstat:
10 files changed, 124 insertions(+), 5 deletions(-)
diff --git a/driver/cc.c b/driver/cc.c
@@ -247,7 +247,9 @@ static int cc_alloc_arrays(CcOptions* o, int argc) {
}
o->new_dtags = 1;
o->cur_link_mode = CFREE_LM_DEFAULT;
- if (driver_cflags_init(&o->cf, o->env, (int)bound) != 0) {
+ if (driver_cflags_init(&o->cf, o->env,
+ (int)(bound + DRIVER_HOSTED_MAX_DEFINES +
+ DRIVER_HOSTED_MAX_INCLUDES)) != 0) {
driver_errf(CC_TOOL, "out of memory");
return 1;
}
@@ -759,6 +761,9 @@ static int cc_apply_hosted_profile(CcOptions* o) {
o->cf.system_include_dirs[o->cf.nsystem_include_dirs++] =
o->hosted.system_includes[i];
}
+ for (i = 0; i < o->hosted.ndefines; ++i) {
+ o->cf.defines[o->cf.ndefines++] = o->hosted.defines[i];
+ }
for (i = 0; i < o->hosted.nbefore; ++i) {
if (o->no_startfiles) break;
if (cc_append_hosted_input(o, &o->hosted.before[i], insert_pos, 1) != 0)
diff --git a/driver/hosted.c b/driver/hosted.c
@@ -173,6 +173,53 @@ static int hosted_add_existing_include(DriverHostedPlan* plan, DriverEnv* env,
return 0;
}
+static int hosted_add_define(DriverHostedPlan* plan, const char* name,
+ const char* body) {
+ if (plan->ndefines >= DRIVER_HOSTED_MAX_DEFINES) return 1;
+ plan->defines[plan->ndefines].name = name;
+ plan->defines[plan->ndefines].body = body;
+ plan->ndefines++;
+ return 0;
+}
+
+static int hosted_add_clang_compat_defines(DriverHostedPlan* plan) {
+ if (hosted_add_define(plan, "__clang__", "1") != 0 ||
+ hosted_add_define(plan, "__clang_major__", "17") != 0 ||
+ hosted_add_define(plan, "__clang_minor__", "0") != 0 ||
+ hosted_add_define(plan, "__clang_patchlevel__", "0") != 0 ||
+ hosted_add_define(plan, "__GNUC__", "4") != 0 ||
+ hosted_add_define(plan, "__GNUC_MINOR__", "2") != 0 ||
+ hosted_add_define(plan, "__GNUC_PATCHLEVEL__", "1") != 0 ||
+ hosted_add_define(plan, "__has_builtin(x)", "0") != 0 ||
+ hosted_add_define(plan, "__has_include(x)", "0") != 0 ||
+ hosted_add_define(plan, "__has_include_next(x)", "0") != 0 ||
+ hosted_add_define(plan, "__has_feature(x)", "0") != 0 ||
+ hosted_add_define(plan, "__has_extension(x)", "0") != 0 ||
+ hosted_add_define(plan, "__has_attribute(x)", "0") != 0)
+ return 1;
+ return 0;
+}
+
+static int hosted_add_darwin_defines(DriverHostedPlan* plan) {
+ if (hosted_add_clang_compat_defines(plan) != 0 ||
+ hosted_add_define(plan, "__APPLE__", "1") != 0 ||
+ hosted_add_define(plan, "__MACH__", "1") != 0 ||
+ hosted_add_define(plan, "__DYNAMIC__", "1") != 0)
+ return 1;
+ return 0;
+}
+
+static int hosted_add_linux_defines(DriverHostedPlan* plan, int gnu) {
+ if (hosted_add_clang_compat_defines(plan) != 0 ||
+ hosted_add_define(plan, "__linux__", "1") != 0 ||
+ hosted_add_define(plan, "__linux", "1") != 0 ||
+ hosted_add_define(plan, "linux", "1") != 0 ||
+ hosted_add_define(plan, "__ELF__", "1") != 0)
+ return 1;
+ if (gnu && hosted_add_define(plan, "__gnu_linux__", "1") != 0) return 1;
+ return 0;
+}
+
static const char* hosted_linux_arch_suffix(CfreeArchKind arch) {
switch (arch) {
case CFREE_ARCH_ARM_64:
@@ -352,7 +399,8 @@ static int hosted_resolve_darwin(const DriverHostedRequest* req,
return 1;
}
plan->profile_name = "macos-libSystem";
- if (hosted_add_existing_include(plan, req->env, support_root,
+ if (hosted_add_darwin_defines(plan) != 0 ||
+ hosted_add_existing_include(plan, req->env, support_root,
"rt/include/libc") != 0 ||
hosted_add_existing_include(plan, req->env, req->sysroot,
"usr/include") != 0) {
@@ -396,7 +444,8 @@ static int hosted_resolve_linux_musl_static(const DriverHostedRequest* req,
DriverHostedPlan* plan,
const char* support_root) {
plan->profile_name = "linux-musl-static";
- if (hosted_add_existing_include(plan, req->env, support_root,
+ if (hosted_add_linux_defines(plan, 0) != 0 ||
+ hosted_add_existing_include(plan, req->env, support_root,
"rt/include/libc") != 0 ||
hosted_add_existing_include(plan, req->env, req->sysroot, "include") !=
0) {
@@ -432,7 +481,8 @@ static int hosted_resolve_linux_musl_dynamic(const DriverHostedRequest* req,
}
plan->profile_name = "linux-musl-dynamic";
plan->interp_path = interp;
- if (hosted_add_existing_include(plan, req->env, support_root,
+ if (hosted_add_linux_defines(plan, 0) != 0 ||
+ hosted_add_existing_include(plan, req->env, support_root,
"rt/include/libc") != 0 ||
hosted_add_existing_include(plan, req->env, req->sysroot, "include") !=
0) {
@@ -468,7 +518,8 @@ static int hosted_resolve_linux_glibc_dynamic(const DriverHostedRequest* req,
}
plan->profile_name = "linux-glibc-dynamic";
plan->interp_path = interp;
- if (hosted_add_existing_include(plan, req->env, support_root,
+ if (hosted_add_linux_defines(plan, 1) != 0 ||
+ hosted_add_existing_include(plan, req->env, support_root,
"rt/include/libc") != 0 ||
hosted_add_existing_include(plan, req->env, req->sysroot, "include") !=
0) {
diff --git a/driver/hosted.h b/driver/hosted.h
@@ -3,6 +3,8 @@
#include <stdint.h>
+#include <cfree/compile.h>
+
#include "driver.h"
typedef enum DriverHostedInputKind {
@@ -23,6 +25,7 @@ typedef struct DriverHostedInput {
#define DRIVER_HOSTED_MAX_AFTER 6
#define DRIVER_HOSTED_MAX_FINAL 2
#define DRIVER_HOSTED_MAX_INCLUDES 4
+#define DRIVER_HOSTED_MAX_DEFINES 20
typedef struct DriverHostedPlan {
const char* profile_name;
@@ -37,6 +40,8 @@ typedef struct DriverHostedPlan {
char* owned_system_includes[DRIVER_HOSTED_MAX_INCLUDES];
size_t owned_system_include_sizes[DRIVER_HOSTED_MAX_INCLUDES];
uint32_t nsystem_includes;
+ CfreeDefine defines[DRIVER_HOSTED_MAX_DEFINES];
+ uint32_t ndefines;
} DriverHostedPlan;
typedef struct DriverHostedRequest {
diff --git a/include/cfree/compile.h b/include/cfree/compile.h
@@ -31,6 +31,8 @@ typedef struct CfreeDefine {
const char *body; /* NULL means "1" */
} CfreeDefine;
+typedef CfreeDefine CfreePredefinedMacro;
+
typedef struct CfreePreprocessOptions {
const char *const *include_dirs;
uint32_t ninclude_dirs;
@@ -73,6 +75,9 @@ CfreeLanguage cfree_language_for_path(const char *path);
CfreeStatus cfree_register_frontend(CfreeCompiler *, CfreeLanguage,
CfreeCompileFn);
+uint32_t cfree_compiler_arch_predefines(CfreeCompiler *,
+ const CfreePredefinedMacro **out);
+
CfreeStatus cfree_compile_c_obj(CfreeCompiler *, const CfreeCCompileOptions *,
const CfreeBytes *, CfreeObjBuilder **out);
CfreeStatus cfree_compile_c_obj_emit(CfreeCompiler *,
diff --git a/lang/c/pp/pp.c b/lang/c/pp/pp.c
@@ -14,6 +14,8 @@
#include "pp/pp_priv.h"
+#include <cfree/compile.h>
+
/* ============================================================
* Source stack
* ============================================================ */
@@ -335,8 +337,15 @@ static void pp_register_static_predefined(Pp* pp) {
* not yet a supported target, so `long` always tracks pointer width here. */
static void pp_register_target_predefined(Pp* pp) {
CfreeTarget target = cfree_compiler_target(pp->c);
+ const CfreePredefinedMacro* arch_defs = NULL;
+ uint32_t narch_defs = cfree_compiler_arch_predefines(pp->c, &arch_defs);
+ uint32_t i;
int lp64 = (target.ptr_size == 8);
+ for (i = 0; i < narch_defs; ++i) {
+ pp_define(pp, arch_defs[i].name, arch_defs[i].body);
+ }
+
pp_define(pp, "__USER_LABEL_PREFIX__",
target.obj == CFREE_OBJ_MACHO ? "_" : "");
diff --git a/src/api/compile.c b/src/api/compile.c
@@ -59,6 +59,18 @@ CfreeStatus cfree_register_frontend(CfreeCompiler* c, CfreeLanguage lang,
return CFREE_OK;
}
+uint32_t cfree_compiler_arch_predefines(CfreeCompiler* c,
+ const CfreePredefinedMacro** out) {
+ const ArchImpl* arch;
+ if (out) *out = NULL;
+ if (!c) return 0;
+ arch = arch_for_compiler((Compiler*)c);
+ if (!arch || !arch->predefined_macros || arch->npredefined_macros == 0)
+ return 0;
+ if (out) *out = arch->predefined_macros;
+ return arch->npredefined_macros;
+}
+
static void validate_bytes(Compiler* c, const CfreeBytes* in) {
if (!in->name) panic_bad_options(c, "input name is NULL");
if (!in->data && in->len != 0) {
diff --git a/src/arch/aa64/arch.c b/src/arch/aa64/arch.c
@@ -79,6 +79,12 @@ static int aa64_apply_label_fixup(Compiler* c, const ArchLabelFixup* fx) {
return 0;
}
+static const CfreePredefinedMacro aa64_predefined_macros[] = {
+ {"__aarch64__", "1"},
+ {"__arm64__", "1"},
+ {"__LP64__", "1"},
+};
+
const ArchImpl arch_impl_aa64 = {
.kind = CFREE_ARCH_ARM_64,
.name = "aa64",
@@ -90,6 +96,9 @@ const ArchImpl arch_impl_aa64 = {
.link = &link_arch_aa64,
.elf = &aa64_elf_ops,
.macho = &aa64_macho_ops,
+ .predefined_macros = aa64_predefined_macros,
+ .npredefined_macros =
+ (u32)(sizeof aa64_predefined_macros / sizeof aa64_predefined_macros[0]),
.register_name = aa64_register_name,
.register_index = aa64_register_index,
.register_count = aa64_register_iter_size,
diff --git a/src/arch/arch.h b/src/arch/arch.h
@@ -2,6 +2,7 @@
#define CFREE_INTERNAL_ARCH_H
#include <cfree/arch.h>
+#include <cfree/compile.h>
#include <cfree/disasm.h>
#include "abi/abi.h"
@@ -907,6 +908,9 @@ typedef struct ArchImpl {
const ArchElfOps* elf;
const ArchMachoOps* macho;
+ const CfreePredefinedMacro* predefined_macros;
+ u32 npredefined_macros;
+
const char* (*register_name)(uint32_t dwarf_idx);
int (*register_index)(const char* name, uint32_t* idx_out);
uint32_t (*register_count)(void);
diff --git a/src/arch/rv64/arch.c b/src/arch/rv64/arch.c
@@ -61,6 +61,13 @@ static int rv64_apply_label_fixup(Compiler* c, const ArchLabelFixup* fx) {
return 0;
}
+static const CfreePredefinedMacro rv64_predefined_macros[] = {
+ {"__riscv", "1"},
+ {"__riscv_xlen", "64"},
+ {"__riscv_float_abi_double", "1"},
+ {"__LP64__", "1"},
+};
+
const ArchImpl arch_impl_rv64 = {
.kind = CFREE_ARCH_RV64,
.name = "rv64",
@@ -72,6 +79,9 @@ const ArchImpl arch_impl_rv64 = {
.link = &link_arch_rv64,
.elf = &rv64_elf_ops,
.macho = NULL,
+ .predefined_macros = rv64_predefined_macros,
+ .npredefined_macros =
+ (u32)(sizeof rv64_predefined_macros / sizeof rv64_predefined_macros[0]),
.register_name = NULL,
.register_index = NULL,
.register_count = NULL,
diff --git a/src/arch/x64/arch.c b/src/arch/x64/arch.c
@@ -44,6 +44,12 @@ static int x64_apply_label_fixup(Compiler* c, const ArchLabelFixup* fx) {
return 0;
}
+static const CfreePredefinedMacro x64_predefined_macros[] = {
+ {"__x86_64__", "1"},
+ {"__amd64__", "1"},
+ {"__LP64__", "1"},
+};
+
const ArchImpl arch_impl_x64 = {
.kind = CFREE_ARCH_X86_64,
.name = "x64",
@@ -55,6 +61,9 @@ const ArchImpl arch_impl_x64 = {
.link = &link_arch_x64,
.elf = &x64_elf_ops,
.macho = &x64_macho_ops,
+ .predefined_macros = x64_predefined_macros,
+ .npredefined_macros =
+ (u32)(sizeof x64_predefined_macros / sizeof x64_predefined_macros[0]),
.register_name = NULL,
.register_index = NULL,
.register_count = NULL,