| author | |
| committer | |
| log | 984e7d6cc79df0a1dec4cc9ae37e899376a5f641 |
| tree | 47dd9effd4306cc8f9dad277e08fe00267ac506a |
| parent | f580c7fa4330a0c181226060d2e778285fa38dc0 |
7 files changed, 357 insertions(+), 31 deletions(-)
CMakeLists.txt+21| ... | @@ -144,6 +144,27 @@ set(ZIG_STD_SRC | ... | @@ -144,6 +144,27 @@ set(ZIG_STD_SRC |
| 144 | "${CMAKE_SOURCE_DIR}/std/math.zig" | 144 | "${CMAKE_SOURCE_DIR}/std/math.zig" |
| 145 | ) | 145 | ) |
| 146 | 146 | ||
| 147 | |||
| 148 | set(ZIG_HOST_LINK_VERSION) | ||
| 149 | if (APPLE) | ||
| 150 | set(LD_V_OUTPUT) | ||
| 151 | execute_process( | ||
| 152 | COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1" | ||
| 153 | RESULT_VARIABLE HAD_ERROR | ||
| 154 | OUTPUT_VARIABLE LD_V_OUTPUT | ||
| 155 | ) | ||
| 156 | if (NOT HAD_ERROR) | ||
| 157 | if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*") | ||
| 158 | string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" ZIG_HOST_LINK_VERSION ${LD_V_OUTPUT}) | ||
| 159 | elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*") | ||
| 160 | string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" ZIG_HOST_LINK_VERSION ${LD_V_OUTPUT}) | ||
| 161 | endif() | ||
| 162 | else() | ||
| 163 | message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}") | ||
| 164 | endif() | ||
| 165 | endif() | ||
| 166 | |||
| 167 | |||
| 147 | set(C_HEADERS_DEST "lib/zig/include") | 168 | set(C_HEADERS_DEST "lib/zig/include") |
| 148 | set(ZIG_STD_DEST "lib/zig/std") | 169 | set(ZIG_STD_DEST "lib/zig/std") |
| 149 | set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h") | 170 | set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h") |
src/all_types.hpp+4| ... | @@ -1130,6 +1130,10 @@ struct CodeGen { | ... | @@ -1130,6 +1130,10 @@ struct CodeGen { |
| 1130 | bool windows_subsystem_windows; | 1130 | bool windows_subsystem_windows; |
| 1131 | bool windows_subsystem_console; | 1131 | bool windows_subsystem_console; |
| 1132 | bool windows_linker_unicode; | 1132 | bool windows_linker_unicode; |
| 1133 | Buf *darwin_linker_version; | ||
| 1134 | Buf *mmacosx_version_min; | ||
| 1135 | Buf *mios_version_min; | ||
| 1136 | bool linker_rdynamic; | ||
| 1133 | 1137 | ||
| 1134 | // The function definitions this module includes. There must be a corresponding | 1138 | // The function definitions this module includes. There must be a corresponding |
| 1135 | // fn_protos entry. | 1139 | // fn_protos entry. |
src/codegen.cpp+51| ... | @@ -22,6 +22,31 @@ | ... | @@ -22,6 +22,31 @@ |
| 22 | #include <errno.h> | 22 | #include <errno.h> |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | static void init_darwin_native(CodeGen *g) { | ||
| 26 | char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); | ||
| 27 | char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); | ||
| 28 | |||
| 29 | // Allow conflicts among OSX and iOS, but choose the default platform. | ||
| 30 | if (osx_target && ios_target) { | ||
| 31 | if (g->zig_target.arch.arch == ZigLLVM_arm || | ||
| 32 | g->zig_target.arch.arch == ZigLLVM_aarch64 || | ||
| 33 | g->zig_target.arch.arch == ZigLLVM_thumb) | ||
| 34 | { | ||
| 35 | osx_target = nullptr; | ||
| 36 | } else { | ||
| 37 | ios_target = nullptr; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | if (osx_target) { | ||
| 42 | g->mmacosx_version_min = buf_create_from_str(osx_target); | ||
| 43 | } else if (ios_target) { | ||
| 44 | g->mios_version_min = buf_create_from_str(ios_target); | ||
| 45 | } else { | ||
| 46 | zig_panic("unable to determine -mmacosx-version-min or -mios-version-min"); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 25 | CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | 50 | CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { |
| 26 | CodeGen *g = allocate<CodeGen>(1); | 51 | CodeGen *g = allocate<CodeGen>(1); |
| 27 | g->import_table.init(32); | 52 | g->import_table.init(32); |
| ... | @@ -46,6 +71,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | ... | @@ -46,6 +71,7 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { |
| 46 | g->libc_static_lib_dir = buf_create_from_str(""); | 71 | g->libc_static_lib_dir = buf_create_from_str(""); |
| 47 | g->libc_include_dir = buf_create_from_str(""); | 72 | g->libc_include_dir = buf_create_from_str(""); |
| 48 | g->linker_path = buf_create_from_str(""); | 73 | g->linker_path = buf_create_from_str(""); |
| 74 | g->darwin_linker_version = buf_create_from_str(""); | ||
| 49 | } else { | 75 | } else { |
| 50 | // native compilation, we can rely on the configuration stuff | 76 | // native compilation, we can rely on the configuration stuff |
| 51 | g->is_native_target = true; | 77 | g->is_native_target = true; |
| ... | @@ -56,6 +82,15 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { | ... | @@ -56,6 +82,15 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) { |
| 56 | g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR); | 82 | g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR); |
| 57 | g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR); | 83 | g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR); |
| 58 | g->linker_path = buf_create_from_str(ZIG_LD_PATH); | 84 | g->linker_path = buf_create_from_str(ZIG_LD_PATH); |
| 85 | g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION); | ||
| 86 | |||
| 87 | if (g->zig_target.os == ZigLLVM_Darwin || | ||
| 88 | g->zig_target.os == ZigLLVM_MacOSX || | ||
| 89 | g->zig_target.os == ZigLLVM_IOS) | ||
| 90 | { | ||
| 91 | init_darwin_native(g); | ||
| 92 | } | ||
| 93 | |||
| 59 | } | 94 | } |
| 60 | 95 | ||
| 61 | return g; | 96 | return g; |
| ... | @@ -131,6 +166,22 @@ void codegen_set_windows_unicode(CodeGen *g, bool municode) { | ... | @@ -131,6 +166,22 @@ void codegen_set_windows_unicode(CodeGen *g, bool municode) { |
| 131 | g->windows_linker_unicode = municode; | 166 | g->windows_linker_unicode = municode; |
| 132 | } | 167 | } |
| 133 | 168 | ||
| 169 | void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version) { | ||
| 170 | g->darwin_linker_version = darwin_linker_version; | ||
| 171 | } | ||
| 172 | |||
| 173 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { | ||
| 174 | g->mmacosx_version_min = mmacosx_version_min; | ||
| 175 | } | ||
| 176 | |||
| 177 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min) { | ||
| 178 | g->mios_version_min = mios_version_min; | ||
| 179 | } | ||
| 180 | |||
| 181 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { | ||
| 182 | g->linker_rdynamic = rdynamic; | ||
| 183 | } | ||
| 184 | |||
| 134 | static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node); | 185 | static LLVMValueRef gen_expr(CodeGen *g, AstNode *expr_node); |
| 135 | static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, TypeTableEntry **out_type_entry); | 186 | static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node, TypeTableEntry **out_type_entry); |
| 136 | static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue); | 187 | static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue); |
src/codegen.hpp+4| ... | @@ -34,6 +34,10 @@ void codegen_set_linker_path(CodeGen *g, Buf *linker_path); | ... | @@ -34,6 +34,10 @@ void codegen_set_linker_path(CodeGen *g, Buf *linker_path); |
| 34 | void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); | 34 | void codegen_set_windows_subsystem(CodeGen *g, bool mwindows, bool mconsole); |
| 35 | void codegen_set_windows_unicode(CodeGen *g, bool municode); | 35 | void codegen_set_windows_unicode(CodeGen *g, bool municode); |
| 36 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); | 36 | void codegen_add_lib_dir(CodeGen *codegen, const char *dir); |
| 37 | void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version); | ||
| 38 | void codegen_set_rdynamic(CodeGen *g, bool rdynamic); | ||
| 39 | void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min); | ||
| 40 | void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min); | ||
| 37 | 41 | ||
| 38 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); | 42 | void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code); |
| 39 | 43 |
src/config.h.in+1| ... | @@ -13,6 +13,7 @@ | ... | @@ -13,6 +13,7 @@ |
| 13 | #define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@" | 13 | #define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@" |
| 14 | #define ZIG_LD_PATH "@ZIG_LD_PATH@" | 14 | #define ZIG_LD_PATH "@ZIG_LD_PATH@" |
| 15 | #define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@" | 15 | #define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@" |
| 16 | #define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@" | ||
| 16 | 17 | ||
| 17 | #cmakedefine ZIG_LLVM_OLD_CXX_ABI | 18 | #cmakedefine ZIG_LLVM_OLD_CXX_ABI |
| 18 | 19 |
src/link.cpp+242-27| ... | @@ -50,6 +50,9 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { | ... | @@ -50,6 +50,9 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| 50 | codegen_set_verbose(child_gen, parent_gen->verbose); | 50 | codegen_set_verbose(child_gen, parent_gen->verbose); |
| 51 | codegen_set_errmsg_color(child_gen, parent_gen->err_color); | 51 | codegen_set_errmsg_color(child_gen, parent_gen->err_color); |
| 52 | 52 | ||
| 53 | codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); | ||
| 54 | codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); | ||
| 55 | |||
| 53 | Buf *full_path = buf_alloc(); | 56 | Buf *full_path = buf_alloc(); |
| 54 | os_path_join(std_dir_path, source_basename, full_path); | 57 | os_path_join(std_dir_path, source_basename, full_path); |
| 55 | Buf source_code = BUF_INIT; | 58 | Buf source_code = BUF_INIT; |
| ... | @@ -391,38 +394,251 @@ static void construct_linker_job_mingw(LinkJob *lj) { | ... | @@ -391,38 +394,251 @@ static void construct_linker_job_mingw(LinkJob *lj) { |
| 391 | } | 394 | } |
| 392 | } | 395 | } |
| 393 | 396 | ||
| 397 | |||
| 398 | // Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and return the | ||
| 399 | // grouped values as integers. Numbers which are not provided are set to 0. | ||
| 400 | // return true if the entire string was parsed (9.2), or all groups were | ||
| 401 | // parsed (10.3.5extrastuff). | ||
| 402 | static bool darwin_get_release_version(const char *str, int *major, int *minor, int *micro, bool *had_extra) { | ||
| 403 | *had_extra = false; | ||
| 404 | |||
| 405 | *major = 0; | ||
| 406 | *minor = 0; | ||
| 407 | *micro = 0; | ||
| 408 | |||
| 409 | if (*str == '\0') | ||
| 410 | return false; | ||
| 411 | |||
| 412 | char *end; | ||
| 413 | *major = strtol(str, &end, 10); | ||
| 414 | if (*str != '\0' && *end == '\0') | ||
| 415 | return true; | ||
| 416 | if (*end != '.') | ||
| 417 | return false; | ||
| 418 | |||
| 419 | str = end + 1; | ||
| 420 | *minor = strtol(str, &end, 10); | ||
| 421 | if (*str != '\0' && *end == '\0') | ||
| 422 | return true; | ||
| 423 | if (*end != '.') | ||
| 424 | return false; | ||
| 425 | |||
| 426 | str = end + 1; | ||
| 427 | *micro = strtol(str, &end, 10); | ||
| 428 | if (*str != '\0' && *end == '\0') | ||
| 429 | return true; | ||
| 430 | if (str == end) | ||
| 431 | return false; | ||
| 432 | *had_extra = true; | ||
| 433 | return true; | ||
| 434 | } | ||
| 435 | |||
| 436 | enum DarwinPlatformKind { | ||
| 437 | MacOS, | ||
| 438 | IPhoneOS, | ||
| 439 | IPhoneOSSimulator, | ||
| 440 | }; | ||
| 441 | |||
| 442 | struct DarwinPlatform { | ||
| 443 | DarwinPlatformKind kind; | ||
| 444 | int major; | ||
| 445 | int minor; | ||
| 446 | int micro; | ||
| 447 | }; | ||
| 448 | |||
| 449 | static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { | ||
| 450 | CodeGen *g = lj->codegen; | ||
| 451 | |||
| 452 | if (g->mmacosx_version_min) { | ||
| 453 | platform->kind = MacOS; | ||
| 454 | } else if (g->mios_version_min) { | ||
| 455 | platform->kind = IPhoneOS; | ||
| 456 | } else { | ||
| 457 | zig_panic("unable to infer -macosx-version-min or -mios-version-min"); | ||
| 458 | } | ||
| 459 | |||
| 460 | bool had_extra; | ||
| 461 | if (platform->kind == MacOS) { | ||
| 462 | if (!darwin_get_release_version(buf_ptr(g->mmacosx_version_min), | ||
| 463 | &platform->major, &platform->minor, &platform->micro, &had_extra) || | ||
| 464 | had_extra || platform->major != 10 || platform->minor >= 100 || platform->micro >= 100) | ||
| 465 | { | ||
| 466 | zig_panic("invalid -mmacosx-version-min"); | ||
| 467 | } | ||
| 468 | } else if (platform->kind == IPhoneOS) { | ||
| 469 | if (!darwin_get_release_version(buf_ptr(g->mios_version_min), | ||
| 470 | &platform->major, &platform->minor, &platform->micro, &had_extra) || | ||
| 471 | had_extra || platform->major >= 10 || platform->minor >= 100 || platform->micro >= 100) | ||
| 472 | { | ||
| 473 | zig_panic("invalid -mios-version-min"); | ||
| 474 | } | ||
| 475 | } else { | ||
| 476 | zig_unreachable(); | ||
| 477 | } | ||
| 478 | |||
| 479 | if (platform->kind == IPhoneOS && | ||
| 480 | (g->zig_target.arch.arch == ZigLLVM_x86 || | ||
| 481 | g->zig_target.arch.arch == ZigLLVM_x86_64)) | ||
| 482 | { | ||
| 483 | platform->kind = IPhoneOSSimulator; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) { | ||
| 488 | if (platform->major < major) { | ||
| 489 | return true; | ||
| 490 | } else if (platform->major > major) { | ||
| 491 | return false; | ||
| 492 | } | ||
| 493 | if (platform->minor < minor) { | ||
| 494 | return true; | ||
| 495 | } | ||
| 496 | return false; | ||
| 497 | } | ||
| 498 | |||
| 499 | static void construct_linker_job_darwin(LinkJob *lj) { | ||
| 500 | CodeGen *g = lj->codegen; | ||
| 501 | |||
| 502 | int ver_major; | ||
| 503 | int ver_minor; | ||
| 504 | int ver_micro; | ||
| 505 | bool had_extra; | ||
| 506 | |||
| 507 | if (!darwin_get_release_version(buf_ptr(g->darwin_linker_version), &ver_major, &ver_minor, &ver_micro, | ||
| 508 | &had_extra) || had_extra) | ||
| 509 | { | ||
| 510 | zig_panic("invalid linker version number"); | ||
| 511 | } | ||
| 512 | |||
| 513 | // Newer linkers support -demangle. Pass it if supported and not disabled by | ||
| 514 | // the user. | ||
| 515 | if (ver_major >= 100) { | ||
| 516 | lj->args.append("-demangle"); | ||
| 517 | } | ||
| 518 | |||
| 519 | if (g->linker_rdynamic && ver_major >= 137) { | ||
| 520 | lj->args.append("-export_dynamic"); | ||
| 521 | } | ||
| 522 | |||
| 523 | bool is_lib = g->out_type == OutTypeLib; | ||
| 524 | bool shared = !g->is_static && is_lib; | ||
| 525 | if (g->is_static) { | ||
| 526 | lj->args.append("-static"); | ||
| 527 | } else { | ||
| 528 | lj->args.append("-dynamic"); | ||
| 529 | } | ||
| 530 | |||
| 531 | if (is_lib) { | ||
| 532 | zig_panic("TODO linker args on darwin for making a library"); | ||
| 533 | } | ||
| 534 | |||
| 535 | DarwinPlatform platform; | ||
| 536 | get_darwin_platform(lj, &platform); | ||
| 537 | switch (platform.kind) { | ||
| 538 | case MacOS: | ||
| 539 | lj->args.append("-macosx_version_min"); | ||
| 540 | break; | ||
| 541 | case IPhoneOS: | ||
| 542 | lj->args.append("-iphoneos_version_min"); | ||
| 543 | break; | ||
| 544 | case IPhoneOSSimulator: | ||
| 545 | lj->args.append("-ios_simulator_version_min"); | ||
| 546 | break; | ||
| 547 | } | ||
| 548 | lj->args.append(buf_ptr(buf_sprintf("%d.%d.%d", platform.major, platform.minor, platform.micro))); | ||
| 549 | |||
| 550 | |||
| 551 | if (g->out_type == OutTypeExe) { | ||
| 552 | if (g->is_static) { | ||
| 553 | lj->args.append("-no_pie"); | ||
| 554 | } else { | ||
| 555 | lj->args.append("-pie"); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | |||
| 559 | lj->args.append("-o"); | ||
| 560 | lj->args.append(buf_ptr(&lj->out_file)); | ||
| 561 | |||
| 562 | if (lj->link_in_crt) { | ||
| 563 | if (shared) { | ||
| 564 | zig_panic("TODO"); | ||
| 565 | } else if (g->is_static) { | ||
| 566 | lj->args.append("-lcrt0.o"); | ||
| 567 | } else { | ||
| 568 | switch (platform.kind) { | ||
| 569 | case MacOS: | ||
| 570 | if (darwin_version_lt(&platform, 10, 5)) { | ||
| 571 | lj->args.append("-lcrt1.o"); | ||
| 572 | } else if (darwin_version_lt(&platform, 10, 6)) { | ||
| 573 | lj->args.append("-lcrt1.10.5.o"); | ||
| 574 | } else if (darwin_version_lt(&platform, 10, 8)) { | ||
| 575 | lj->args.append("-lcrt1.10.6.o"); | ||
| 576 | } | ||
| 577 | break; | ||
| 578 | case IPhoneOS: | ||
| 579 | if (g->zig_target.arch.arch == ZigLLVM_aarch64) { | ||
| 580 | // iOS does not need any crt1 files for arm64 | ||
| 581 | } else if (darwin_version_lt(&platform, 3, 1)) { | ||
| 582 | lj->args.append("-lcrt1.o"); | ||
| 583 | } else if (darwin_version_lt(&platform, 6, 0)) { | ||
| 584 | lj->args.append("-lcrt1.3.1.o"); | ||
| 585 | } | ||
| 586 | break; | ||
| 587 | case IPhoneOSSimulator: | ||
| 588 | // no crt1.o needed | ||
| 589 | break; | ||
| 590 | } | ||
| 591 | } | ||
| 592 | } | ||
| 593 | |||
| 594 | for (int i = 0; i < g->lib_dirs.length; i += 1) { | ||
| 595 | const char *lib_dir = g->lib_dirs.at(i); | ||
| 596 | lj->args.append("-L"); | ||
| 597 | lj->args.append(lib_dir); | ||
| 598 | } | ||
| 599 | |||
| 600 | lj->args.append((const char *)buf_ptr(&lj->out_file_o)); | ||
| 601 | |||
| 602 | for (int i = 0; i < g->link_libs.length; i += 1) { | ||
| 603 | Buf *link_lib = g->link_libs.at(i); | ||
| 604 | Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib)); | ||
| 605 | lj->args.append(buf_ptr(arg)); | ||
| 606 | } | ||
| 607 | |||
| 608 | } | ||
| 609 | |||
| 394 | static void construct_linker_job(LinkJob *lj) { | 610 | static void construct_linker_job(LinkJob *lj) { |
| 395 | switch (lj->codegen->zig_target.os) { | 611 | switch (lj->codegen->zig_target.os) { |
| 396 | case ZigLLVM_UnknownOS: | 612 | case ZigLLVM_UnknownOS: |
| 397 | zig_unreachable(); | 613 | zig_unreachable(); |
| 398 | case ZigLLVM_Linux: | 614 | case ZigLLVM_Linux: |
| 399 | if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) { | 615 | if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) { |
| 400 | zig_panic("TODO construct hexagon_TC linker job"); | 616 | zig_panic("TODO construct hexagon_TC linker job"); |
| 401 | } else { | 617 | } else { |
| 402 | return construct_linker_job_linux(lj); | 618 | return construct_linker_job_linux(lj); |
| 403 | } | 619 | } |
| 404 | case ZigLLVM_CloudABI: | 620 | case ZigLLVM_CloudABI: |
| 405 | zig_panic("TODO construct CloudABI linker job"); | 621 | zig_panic("TODO construct CloudABI linker job"); |
| 406 | case ZigLLVM_Darwin: | 622 | case ZigLLVM_Darwin: |
| 407 | case ZigLLVM_MacOSX: | 623 | case ZigLLVM_MacOSX: |
| 408 | case ZigLLVM_IOS: | 624 | case ZigLLVM_IOS: |
| 409 | zig_panic("TODO construct DarwinClang linker job"); | 625 | return construct_linker_job_darwin(lj); |
| 410 | case ZigLLVM_DragonFly: | 626 | case ZigLLVM_DragonFly: |
| 411 | zig_panic("TODO construct DragonFly linker job"); | 627 | zig_panic("TODO construct DragonFly linker job"); |
| 412 | case ZigLLVM_OpenBSD: | 628 | case ZigLLVM_OpenBSD: |
| 413 | zig_panic("TODO construct OpenBSD linker job"); | 629 | zig_panic("TODO construct OpenBSD linker job"); |
| 414 | case ZigLLVM_Bitrig: | 630 | case ZigLLVM_Bitrig: |
| 415 | zig_panic("TODO construct Bitrig linker job"); | 631 | zig_panic("TODO construct Bitrig linker job"); |
| 416 | case ZigLLVM_NetBSD: | 632 | case ZigLLVM_NetBSD: |
| 417 | zig_panic("TODO construct NetBSD linker job"); | 633 | zig_panic("TODO construct NetBSD linker job"); |
| 418 | case ZigLLVM_FreeBSD: | 634 | case ZigLLVM_FreeBSD: |
| 419 | zig_panic("TODO construct FreeBSD linker job"); | 635 | zig_panic("TODO construct FreeBSD linker job"); |
| 420 | case ZigLLVM_Minix: | 636 | case ZigLLVM_Minix: |
| 421 | zig_panic("TODO construct Minix linker job"); | 637 | zig_panic("TODO construct Minix linker job"); |
| 422 | case ZigLLVM_NaCl: | 638 | case ZigLLVM_NaCl: |
| 423 | zig_panic("TODO construct NaCl_TC linker job"); | 639 | zig_panic("TODO construct NaCl_TC linker job"); |
| 424 | case ZigLLVM_Solaris: | 640 | case ZigLLVM_Solaris: |
| 425 | zig_panic("TODO construct Solaris linker job"); | 641 | zig_panic("TODO construct Solaris linker job"); |
| 426 | case ZigLLVM_Win32: | 642 | case ZigLLVM_Win32: |
| 427 | switch (lj->codegen->zig_target.environ) { | 643 | switch (lj->codegen->zig_target.environ) { |
| 428 | default: | 644 | default: |
| ... | @@ -440,27 +656,27 @@ static void construct_linker_job(LinkJob *lj) { | ... | @@ -440,27 +656,27 @@ static void construct_linker_job(LinkJob *lj) { |
| 440 | case ZigLLVM_MSVC: | 656 | case ZigLLVM_MSVC: |
| 441 | case ZigLLVM_UnknownEnvironment: | 657 | case ZigLLVM_UnknownEnvironment: |
| 442 | zig_panic("TODO construct MSVC linker job"); | 658 | zig_panic("TODO construct MSVC linker job"); |
| 443 | } | 659 | } |
| 444 | case ZigLLVM_CUDA: | 660 | case ZigLLVM_CUDA: |
| 445 | zig_panic("TODO construct Cuda linker job"); | 661 | zig_panic("TODO construct Cuda linker job"); |
| 446 | default: | 662 | default: |
| 447 | // Of these targets, Hexagon is the only one that might have | 663 | // Of these targets, Hexagon is the only one that might have |
| 448 | // an OS of Linux, in which case it got handled above already. | 664 | // an OS of Linux, in which case it got handled above already. |
| 449 | if (lj->codegen->zig_target.arch.arch == ZigLLVM_tce) { | 665 | if (lj->codegen->zig_target.arch.arch == ZigLLVM_tce) { |
| 450 | zig_panic("TODO construct TCE linker job"); | 666 | zig_panic("TODO construct TCE linker job"); |
| 451 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) { | 667 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_hexagon) { |
| 452 | zig_panic("TODO construct Hexagon_TC linker job"); | 668 | zig_panic("TODO construct Hexagon_TC linker job"); |
| 453 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_xcore) { | 669 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_xcore) { |
| 454 | zig_panic("TODO construct XCore linker job"); | 670 | zig_panic("TODO construct XCore linker job"); |
| 455 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_shave) { | 671 | } else if (lj->codegen->zig_target.arch.arch == ZigLLVM_shave) { |
| 456 | zig_panic("TODO construct SHAVE linker job"); | 672 | zig_panic("TODO construct SHAVE linker job"); |
| 457 | } else if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) { | 673 | } else if (lj->codegen->zig_target.oformat == ZigLLVM_ELF) { |
| 458 | zig_panic("TODO construct Generic_ELF linker job"); | 674 | zig_panic("TODO construct Generic_ELF linker job"); |
| 459 | } else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) { | 675 | } else if (lj->codegen->zig_target.oformat == ZigLLVM_MachO) { |
| 460 | zig_panic("TODO construct MachO linker job"); | 676 | zig_panic("TODO construct MachO linker job"); |
| 461 | } else { | 677 | } else { |
| 462 | zig_panic("TODO construct Generic_GCC linker job"); | 678 | zig_panic("TODO construct Generic_GCC linker job"); |
| 463 | } | 679 | } |
| 464 | 680 | ||
| 465 | } | 681 | } |
| 466 | } | 682 | } |
| ... | @@ -535,7 +751,6 @@ void codegen_link(CodeGen *g, const char *out_file) { | ... | @@ -535,7 +751,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 535 | } | 751 | } |
| 536 | 752 | ||
| 537 | lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe); | 753 | lj.link_in_crt = (g->link_libc && g->out_type == OutTypeExe); |
| 538 | // invoke `ld` | ||
| 539 | ensure_we_have_linker_path(g); | 754 | ensure_we_have_linker_path(g); |
| 540 | 755 | ||
| 541 | construct_linker_job(&lj); | 756 | construct_linker_job(&lj); |
src/main.cpp+34-4| ... | @@ -18,10 +18,10 @@ | ... | @@ -18,10 +18,10 @@ |
| 18 | static int usage(const char *arg0) { | 18 | static int usage(const char *arg0) { |
| 19 | fprintf(stderr, "Usage: %s [command] [options]\n" | 19 | fprintf(stderr, "Usage: %s [command] [options]\n" |
| 20 | "Commands:\n" | 20 | "Commands:\n" |
| 21 | " build create executable, object, or library from target\n" | 21 | " build [source] create executable, object, or library from source\n" |
| 22 | " test create and run a test build\n" | 22 | " test [source] create and run a test build\n" |
| 23 | " parseh [source] convert a c header file to zig extern declarations\n" | ||
| 23 | " version print version number and exit\n" | 24 | " version print version number and exit\n" |
| 24 | " parseh convert a c header file to zig extern declarations\n" | ||
| 25 | " targets list available compilation targets\n" | 25 | " targets list available compilation targets\n" |
| 26 | "Options:\n" | 26 | "Options:\n" |
| 27 | " --release build with optimizations on and debug protection off\n" | 27 | " --release build with optimizations on and debug protection off\n" |
| ... | @@ -33,7 +33,7 @@ static int usage(const char *arg0) { | ... | @@ -33,7 +33,7 @@ static int usage(const char *arg0) { |
| 33 | " --verbose turn on compiler debug output\n" | 33 | " --verbose turn on compiler debug output\n" |
| 34 | " --color [auto|off|on] enable or disable colored error messages\n" | 34 | " --color [auto|off|on] enable or disable colored error messages\n" |
| 35 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" | 35 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" |
| 36 | " --libc-static-lib-dir [path] directory where libc crtbeginT.o resides\n" | 36 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" |
| 37 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | 37 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" |
| 38 | " --dynamic-linker [path] set the path to ld.so\n" | 38 | " --dynamic-linker [path] set the path to ld.so\n" |
| 39 | " --ld-path [path] set the path to the linker\n" | 39 | " --ld-path [path] set the path to the linker\n" |
| ... | @@ -46,6 +46,10 @@ static int usage(const char *arg0) { | ... | @@ -46,6 +46,10 @@ static int usage(const char *arg0) { |
| 46 | " -mwindows (windows only) --subsystem windows to the linker\n" | 46 | " -mwindows (windows only) --subsystem windows to the linker\n" |
| 47 | " -mconsole (windows only) --subsystem console to the linker\n" | 47 | " -mconsole (windows only) --subsystem console to the linker\n" |
| 48 | " -municode (windows only) link with unicode\n" | 48 | " -municode (windows only) link with unicode\n" |
| 49 | " -mlinker-version [ver] (darwin only) override linker version\n" | ||
| 50 | " -rdynamic add all symbols to the dynamic symbol table\n" | ||
| 51 | " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n" | ||
| 52 | " -mios-version-min [ver] (darwin only) set iOS deployment target\n" | ||
| 49 | , arg0); | 53 | , arg0); |
| 50 | return EXIT_FAILURE; | 54 | return EXIT_FAILURE; |
| 51 | } | 55 | } |
| ... | @@ -119,6 +123,10 @@ int main(int argc, char **argv) { | ... | @@ -119,6 +123,10 @@ int main(int argc, char **argv) { |
| 119 | bool mwindows = false; | 123 | bool mwindows = false; |
| 120 | bool mconsole = false; | 124 | bool mconsole = false; |
| 121 | bool municode = false; | 125 | bool municode = false; |
| 126 | const char *mlinker_version = nullptr; | ||
| 127 | bool rdynamic = false; | ||
| 128 | const char *mmacosx_version_min = nullptr; | ||
| 129 | const char *mios_version_min = nullptr; | ||
| 122 | 130 | ||
| 123 | for (int i = 1; i < argc; i += 1) { | 131 | for (int i = 1; i < argc; i += 1) { |
| 124 | char *arg = argv[i]; | 132 | char *arg = argv[i]; |
| ... | @@ -138,6 +146,8 @@ int main(int argc, char **argv) { | ... | @@ -138,6 +146,8 @@ int main(int argc, char **argv) { |
| 138 | mconsole = true; | 146 | mconsole = true; |
| 139 | } else if (strcmp(arg, "-municode") == 0) { | 147 | } else if (strcmp(arg, "-municode") == 0) { |
| 140 | municode = true; | 148 | municode = true; |
| 149 | } else if (strcmp(arg, "-rdynamic") == 0) { | ||
| 150 | rdynamic = true; | ||
| 141 | } else if (i + 1 >= argc) { | 151 | } else if (i + 1 >= argc) { |
| 142 | return usage(arg0); | 152 | return usage(arg0); |
| 143 | } else { | 153 | } else { |
| ... | @@ -192,6 +202,12 @@ int main(int argc, char **argv) { | ... | @@ -192,6 +202,12 @@ int main(int argc, char **argv) { |
| 192 | target_os = argv[i]; | 202 | target_os = argv[i]; |
| 193 | } else if (strcmp(arg, "--target-environ") == 0) { | 203 | } else if (strcmp(arg, "--target-environ") == 0) { |
| 194 | target_environ = argv[i]; | 204 | target_environ = argv[i]; |
| 205 | } else if (strcmp(arg, "-mlinker-version") == 0) { | ||
| 206 | mlinker_version = argv[i]; | ||
| 207 | } else if (strcmp(arg, "-mmacosx-version-min") == 0) { | ||
| 208 | mmacosx_version_min = argv[i]; | ||
| 209 | } else if (strcmp(arg, "-mios-version-min") == 0) { | ||
| 210 | mios_version_min = argv[i]; | ||
| 195 | } else { | 211 | } else { |
| 196 | fprintf(stderr, "Invalid argument: %s\n", arg); | 212 | fprintf(stderr, "Invalid argument: %s\n", arg); |
| 197 | return usage(arg0); | 213 | return usage(arg0); |
| ... | @@ -327,6 +343,20 @@ int main(int argc, char **argv) { | ... | @@ -327,6 +343,20 @@ int main(int argc, char **argv) { |
| 327 | 343 | ||
| 328 | codegen_set_windows_subsystem(g, mwindows, mconsole); | 344 | codegen_set_windows_subsystem(g, mwindows, mconsole); |
| 329 | codegen_set_windows_unicode(g, municode); | 345 | codegen_set_windows_unicode(g, municode); |
| 346 | codegen_set_rdynamic(g, rdynamic); | ||
| 347 | if (mlinker_version) { | ||
| 348 | codegen_set_mlinker_version(g, buf_create_from_str(mlinker_version)); | ||
| 349 | } | ||
| 350 | if (mmacosx_version_min && mios_version_min) { | ||
| 351 | fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n"); | ||
| 352 | return EXIT_FAILURE; | ||
| 353 | } | ||
| 354 | if (mmacosx_version_min) { | ||
| 355 | codegen_set_mmacosx_version_min(g, buf_create_from_str(mmacosx_version_min)); | ||
| 356 | } | ||
| 357 | if (mios_version_min) { | ||
| 358 | codegen_set_mios_version_min(g, buf_create_from_str(mios_version_min)); | ||
| 359 | } | ||
| 330 | 360 | ||
| 331 | if (cmd == CmdBuild) { | 361 | if (cmd == CmdBuild) { |
| 332 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); | 362 | codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code); |