refactor: LLVM目标初始化解耦 — 抽取 target.h/c

- 新增 src/codegen/target.h/c: target_init/get_default_triple/create_machine/emit_obj
- main.c 移除 inline LLVM Target API 调用,改调 target_* 接口
- codegen.c 专注 AST→IR,不再混入目标平台初始化

基于 Codex 分析报告 4.1 节架构改进建议。
This commit is contained in:
2026-06-05 00:49:08 +08:00
parent 9a53d97274
commit 9ff2990724
3 changed files with 63 additions and 25 deletions
+35
View File
@@ -0,0 +1,35 @@
#include "target.h"
#include <llvm-c/Target.h>
#include <stdio.h>
void target_init(void) {
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter();
LLVMInitializeX86AsmParser();
}
char* target_get_default_triple(void) {
return LLVMGetDefaultTargetTriple();
}
LLVMTargetMachineRef target_create_machine(const char* triple) {
LLVMTargetRef target;
char* error = NULL;
if (LLVMGetTargetFromTriple(triple, &target, &error)) {
fprintf(stderr, "目标平台错误: %s\n", error);
LLVMDisposeMessage(error);
return NULL;
}
return LLVMCreateTargetMachine(
target, triple, "generic", "",
LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
}
int target_emit_obj(LLVMTargetMachineRef tm, LLVMModuleRef module,
const char* filename, char** error_msg) {
return LLVMTargetMachineEmitToFile(tm, module, (char*)filename,
LLVMObjectFile, error_msg);
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef TARGET_H
#define TARGET_H
#include <llvm-c/Core.h>
#include <llvm-c/TargetMachine.h>
// 初始化 X86 目标平台(LLVMInitializeAllTarget* 的替代,LLVM-C.lib 不导出 All 系列)
void target_init(void);
// 获取默认目标三元组
char* target_get_default_triple(void);
// 从三元组获取目标机
LLVMTargetMachineRef target_create_machine(const char* triple);
// 将模块写入目标文件
// 返回 0 成功,非 0 失败(*error_msg 包含错误信息)
int target_emit_obj(LLVMTargetMachineRef tm, LLVMModuleRef module,
const char* filename, char** error_msg);
#endif
+7 -25
View File
@@ -3,12 +3,11 @@
#include "parser.h"
#include "sema.h"
#include "codegen.h"
#include "target.h"
#include "error.h"
#include "arena.h"
#include <llvm-c/Core.h>
#include <llvm-c/TargetMachine.h>
#include <llvm-c/Target.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -111,35 +110,18 @@ int main(int argc, char** argv) {
printf("IR 已输出到: %s\n", ir_path);
LLVMDisposeMessage(ir);
} else {
// 初始化 X86 目标(LLVM-C.lib 中没有 InitializeAll 系列符号)
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter();
LLVMInitializeX86AsmParser();
// LLVM 目标平台初始化和目标代码生成
target_init();
char* triple = LLVMGetDefaultTargetTriple();
LLVMTargetRef target;
char* target_error = NULL;
if (LLVMGetTargetFromTriple(triple, &target, &target_error)) {
fprintf(stderr, "目标平台错误: %s\n", target_error);
LLVMDisposeMessage(target_error); LLVMDisposeMessage(triple);
free(source); arena_destroy(&arena); LLVMDisposeModule(module);
return 1;
}
LLVMTargetMachineRef tm = LLVMCreateTargetMachine(
target, triple, "generic", "",
LLVMCodeGenLevelDefault, LLVMRelocDefault,
LLVMCodeModelDefault);
char* triple = target_get_default_triple();
LLVMTargetMachineRef tm = target_create_machine(triple);
LLVMDisposeMessage(triple);
if (!tm) { free(source); arena_destroy(&arena); LLVMDisposeModule(module); return 1; }
// 输出目标文件
char obj_path[512];
snprintf(obj_path, sizeof(obj_path), "%s.o", input);
char* obj_error = NULL;
if (LLVMTargetMachineEmitToFile(tm, module, obj_path,
LLVMObjectFile, &obj_error)) {
if (target_emit_obj(tm, module, obj_path, &obj_error)) {
fprintf(stderr, "目标代码生成错误: %s\n", obj_error);
LLVMDisposeMessage(obj_error);
free(source); arena_destroy(&arena);