mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
restore shared library functionality
This commit is contained in:
parent
320e26590a
commit
f18e34c2c6
@ -1,6 +1,3 @@
|
||||
#version("2.0.0")
|
||||
export library "mathtest";
|
||||
|
||||
export fn add(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
@ -1288,7 +1288,8 @@ struct CodeGen {
|
||||
LLVMValueRef cur_ret_ptr;
|
||||
ZigList<LLVMBasicBlockRef> break_block_stack;
|
||||
ZigList<LLVMBasicBlockRef> continue_block_stack;
|
||||
bool c_stdint_used;
|
||||
bool c_want_stdint;
|
||||
bool c_want_stdbool;
|
||||
AstNode *root_export_decl;
|
||||
int version_major;
|
||||
int version_minor;
|
||||
|
142
src/codegen.cpp
142
src/codegen.cpp
@ -4992,31 +4992,121 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
|
||||
do_code_gen(g);
|
||||
}
|
||||
|
||||
static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) {
|
||||
zig_panic("TODO this function needs some love");
|
||||
TypeTableEntry *type_entry = get_resolved_expr(type_node)->type_entry;
|
||||
static const char *c_int_type_names[] = {
|
||||
[CIntTypeShort] = "short",
|
||||
[CIntTypeUShort] = "unsigned short",
|
||||
[CIntTypeInt] = "int",
|
||||
[CIntTypeUInt] = "unsigned int",
|
||||
[CIntTypeLong] = "long",
|
||||
[CIntTypeULong] = "unsigned long",
|
||||
[CIntTypeLongLong] = "long long",
|
||||
[CIntTypeULongLong] = "unsigned long long",
|
||||
};
|
||||
|
||||
static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
|
||||
assert(type_entry);
|
||||
|
||||
if (type_entry == g->builtin_types.entry_u8) {
|
||||
g->c_stdint_used = true;
|
||||
buf_init_from_str(out_buf, "uint8_t");
|
||||
} else if (type_entry == g->builtin_types.entry_i32) {
|
||||
g->c_stdint_used = true;
|
||||
buf_init_from_str(out_buf, "int32_t");
|
||||
} else if (type_entry == g->builtin_types.entry_isize) {
|
||||
g->c_stdint_used = true;
|
||||
buf_init_from_str(out_buf, "intptr_t");
|
||||
} else if (type_entry == g->builtin_types.entry_f32) {
|
||||
buf_init_from_str(out_buf, "float");
|
||||
} else if (type_entry == g->builtin_types.entry_unreachable) {
|
||||
buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void");
|
||||
} else if (type_entry == g->builtin_types.entry_bool) {
|
||||
buf_init_from_str(out_buf, "unsigned char");
|
||||
} else if (type_entry == g->builtin_types.entry_void) {
|
||||
buf_init_from_str(out_buf, "void");
|
||||
} else {
|
||||
zig_panic("TODO to_c_type");
|
||||
for (int i = 0; i < array_length(c_int_type_names); i += 1) {
|
||||
if (type_entry == g->builtin_types.entry_c_int[i]) {
|
||||
buf_init_from_str(out_buf, c_int_type_names[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (type_entry == g->builtin_types.entry_c_long_double) {
|
||||
buf_init_from_str(out_buf, "long double");
|
||||
return;
|
||||
}
|
||||
if (type_entry == g->builtin_types.entry_c_void) {
|
||||
buf_init_from_str(out_buf, "void");
|
||||
return;
|
||||
}
|
||||
if (type_entry == g->builtin_types.entry_isize) {
|
||||
g->c_want_stdint = true;
|
||||
buf_init_from_str(out_buf, "intptr_t");
|
||||
return;
|
||||
}
|
||||
if (type_entry == g->builtin_types.entry_usize) {
|
||||
g->c_want_stdint = true;
|
||||
buf_init_from_str(out_buf, "uintptr_t");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type_entry->id) {
|
||||
case TypeTableEntryIdVoid:
|
||||
buf_init_from_str(out_buf, "void");
|
||||
break;
|
||||
case TypeTableEntryIdBool:
|
||||
buf_init_from_str(out_buf, "bool");
|
||||
g->c_want_stdbool = true;
|
||||
break;
|
||||
case TypeTableEntryIdUnreachable:
|
||||
buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void");
|
||||
break;
|
||||
case TypeTableEntryIdFloat:
|
||||
switch (type_entry->data.floating.bit_count) {
|
||||
case 32:
|
||||
buf_init_from_str(out_buf, "float");
|
||||
break;
|
||||
case 64:
|
||||
buf_init_from_str(out_buf, "double");
|
||||
break;
|
||||
default:
|
||||
zig_unreachable();
|
||||
}
|
||||
break;
|
||||
case TypeTableEntryIdInt:
|
||||
g->c_want_stdint = true;
|
||||
buf_resize(out_buf, 0);
|
||||
buf_appendf(out_buf, "%sint%d_t",
|
||||
type_entry->data.integral.is_signed ? "" : "u",
|
||||
type_entry->data.integral.bit_count);
|
||||
break;
|
||||
case TypeTableEntryIdPointer:
|
||||
{
|
||||
Buf child_buf = BUF_INIT;
|
||||
TypeTableEntry *child_type = type_entry->data.pointer.child_type;
|
||||
get_c_type(g, child_type, &child_buf);
|
||||
|
||||
const char *const_str = type_entry->data.pointer.is_const ? "const " : "";
|
||||
buf_resize(out_buf, 0);
|
||||
buf_appendf(out_buf, "%s*%s", const_str, buf_ptr(&child_buf));
|
||||
break;
|
||||
}
|
||||
case TypeTableEntryIdArray:
|
||||
case TypeTableEntryIdStruct:
|
||||
case TypeTableEntryIdMaybe:
|
||||
case TypeTableEntryIdErrorUnion:
|
||||
case TypeTableEntryIdPureError:
|
||||
case TypeTableEntryIdEnum:
|
||||
case TypeTableEntryIdUnion:
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdInvalid:
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdNumLitFloat:
|
||||
case TypeTableEntryIdNumLitInt:
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
zig_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
static void get_c_type_node(CodeGen *g, AstNode *type_node, Buf *out_buf) {
|
||||
assert(type_node->type != NodeTypeSymbol || !type_node->data.symbol_expr.override_type_entry);
|
||||
|
||||
Expr *expr = get_resolved_expr(type_node);
|
||||
assert(expr->type_entry);
|
||||
assert(expr->type_entry->id == TypeTableEntryIdMetaType);
|
||||
|
||||
ConstExprValue *const_val = &expr->const_val;
|
||||
assert(const_val->ok);
|
||||
|
||||
TypeTableEntry *type_entry = const_val->data.x_type;
|
||||
|
||||
return get_c_type(g, type_entry, out_buf);
|
||||
}
|
||||
|
||||
void codegen_generate_h_file(CodeGen *g) {
|
||||
@ -5045,7 +5135,7 @@ void codegen_generate_h_file(CodeGen *g) {
|
||||
continue;
|
||||
|
||||
Buf return_type_c = BUF_INIT;
|
||||
to_c_type(g, fn_proto->return_type, &return_type_c);
|
||||
get_c_type_node(g, fn_proto->return_type, &return_type_c);
|
||||
|
||||
buf_appendf(&h_buf, "%s %s %s(",
|
||||
buf_ptr(export_macro),
|
||||
@ -5057,7 +5147,7 @@ void codegen_generate_h_file(CodeGen *g) {
|
||||
for (int param_i = 0; param_i < fn_proto->params.length; param_i += 1) {
|
||||
AstNode *param_decl_node = fn_proto->params.at(param_i);
|
||||
AstNode *param_type = param_decl_node->data.param_decl.type;
|
||||
to_c_type(g, param_type, ¶m_type_c);
|
||||
get_c_type_node(g, param_type, ¶m_type_c);
|
||||
buf_appendf(&h_buf, "%s %s",
|
||||
buf_ptr(¶m_type_c),
|
||||
buf_ptr(param_decl_node->data.param_decl.name));
|
||||
@ -5080,7 +5170,9 @@ void codegen_generate_h_file(CodeGen *g) {
|
||||
fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name));
|
||||
fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name));
|
||||
|
||||
if (g->c_stdint_used)
|
||||
if (g->c_want_stdbool)
|
||||
fprintf(out_h, "#include <stdbool.h>\n");
|
||||
if (g->c_want_stdint)
|
||||
fprintf(out_h, "#include <stdint.h>\n");
|
||||
|
||||
fprintf(out_h, "\n");
|
||||
|
16
src/link.cpp
16
src/link.cpp
@ -159,6 +159,7 @@ static void construct_linker_job_linux(LinkJob *lj) {
|
||||
|
||||
bool is_lib = g->out_type == OutTypeLib;
|
||||
bool shared = !g->is_static && is_lib;
|
||||
Buf *soname = nullptr;
|
||||
if (g->is_static) {
|
||||
if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb ||
|
||||
g->zig_target.arch.arch == ZigLLVM_thumb || g->zig_target.arch.arch == ZigLLVM_thumbeb)
|
||||
@ -169,6 +170,11 @@ static void construct_linker_job_linux(LinkJob *lj) {
|
||||
}
|
||||
} else if (shared) {
|
||||
lj->args.append("-shared");
|
||||
|
||||
buf_resize(&lj->out_file, 0);
|
||||
buf_appendf(&lj->out_file, "lib%s.so.%d.%d.%d",
|
||||
buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
|
||||
soname = buf_sprintf("lib%s.so.%d", buf_ptr(g->root_out_name), g->version_major);
|
||||
}
|
||||
|
||||
lj->args.append("-o");
|
||||
@ -211,11 +217,7 @@ static void construct_linker_job_linux(LinkJob *lj) {
|
||||
lj->args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeLib) {
|
||||
buf_resize(&lj->out_file, 0);
|
||||
buf_appendf(&lj->out_file, "lib%s.so.%d.%d.%d",
|
||||
buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
|
||||
Buf *soname = buf_sprintf("lib%s.so.%d", buf_ptr(g->root_out_name), g->version_major);
|
||||
if (shared) {
|
||||
lj->args.append("-soname");
|
||||
lj->args.append(buf_ptr(soname));
|
||||
}
|
||||
@ -849,7 +851,9 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
||||
fprintf(stderr, "%s\n", buf_ptr(&ld_stderr));
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeLib) {
|
||||
if (g->out_type == OutTypeLib ||
|
||||
g->out_type == OutTypeObj)
|
||||
{
|
||||
codegen_generate_h_file(g);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user