| author | |
| committer | |
| log | 32be6e9b2a9e6de501aadbe271c554a4682a10f8 |
| tree | ee37daa15c6e8c2d3a3a9dafc30c060eb52ca10c |
| parent | fbe5737c84c783cd31e6e2d595fc47eb782c5e3c |
| signature |
* add almost all the input parameter state to the hash
- missing items are the detected MSVC installation on Windows
and detected libc installation on POSIX
- also missing are C files and .h files that libclang finds
* artifacts are created in global cache directory instead of
zig-cache.
- exception: builtin.zig is still in zig-cache
* zig run uses the new cache correctly
* zig run uses execv on posix systems13 files changed, 418 insertions(+), 370 deletions(-)
src/all_types.hpp+128-137| ... | ... | @@ -1554,6 +1554,40 @@ struct CodeGen { |
| 1554 | 1554 | ZigLLVMDICompileUnit *compile_unit; |
| 1555 | 1555 | ZigLLVMDIFile *compile_unit_file; |
| 1556 | 1556 | LinkLib *libc_link_lib; |
| 1557 | LLVMTargetDataRef target_data_ref; | |
| 1558 | LLVMTargetMachineRef target_machine; | |
| 1559 | ZigLLVMDIFile *dummy_di_file; | |
| 1560 | LLVMValueRef cur_ret_ptr; | |
| 1561 | LLVMValueRef cur_fn_val; | |
| 1562 | LLVMValueRef cur_err_ret_trace_val_arg; | |
| 1563 | LLVMValueRef cur_err_ret_trace_val_stack; | |
| 1564 | LLVMValueRef memcpy_fn_val; | |
| 1565 | LLVMValueRef memset_fn_val; | |
| 1566 | LLVMValueRef trap_fn_val; | |
| 1567 | LLVMValueRef return_address_fn_val; | |
| 1568 | LLVMValueRef frame_address_fn_val; | |
| 1569 | LLVMValueRef coro_destroy_fn_val; | |
| 1570 | LLVMValueRef coro_id_fn_val; | |
| 1571 | LLVMValueRef coro_alloc_fn_val; | |
| 1572 | LLVMValueRef coro_size_fn_val; | |
| 1573 | LLVMValueRef coro_begin_fn_val; | |
| 1574 | LLVMValueRef coro_suspend_fn_val; | |
| 1575 | LLVMValueRef coro_end_fn_val; | |
| 1576 | LLVMValueRef coro_free_fn_val; | |
| 1577 | LLVMValueRef coro_resume_fn_val; | |
| 1578 | LLVMValueRef coro_save_fn_val; | |
| 1579 | LLVMValueRef coro_promise_fn_val; | |
| 1580 | LLVMValueRef coro_alloc_helper_fn_val; | |
| 1581 | LLVMValueRef coro_frame_fn_val; | |
| 1582 | LLVMValueRef merge_err_ret_traces_fn_val; | |
| 1583 | LLVMValueRef add_error_return_trace_addr_fn_val; | |
| 1584 | LLVMValueRef stacksave_fn_val; | |
| 1585 | LLVMValueRef stackrestore_fn_val; | |
| 1586 | LLVMValueRef write_register_fn_val; | |
| 1587 | LLVMValueRef sp_md_node; | |
| 1588 | LLVMValueRef err_name_table; | |
| 1589 | LLVMValueRef safety_crash_err_fn; | |
| 1590 | LLVMValueRef return_err_fn; | |
| 1557 | 1591 | |
| 1558 | 1592 | // reminder: hash tables must be initialized before use |
| 1559 | 1593 | HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table; |
| ... | ... | @@ -1576,8 +1610,23 @@ struct CodeGen { |
| 1576 | 1610 | size_t resolve_queue_index; |
| 1577 | 1611 | ZigList<AstNode *> use_queue; |
| 1578 | 1612 | size_t use_queue_index; |
| 1613 | ZigList<TimeEvent> timing_events; | |
| 1614 | ZigList<ZigLLVMDIType **> error_di_types; | |
| 1615 | ZigList<AstNode *> tld_ref_source_node_stack; | |
| 1616 | ZigList<ZigFn *> inline_fns; | |
| 1617 | ZigList<ZigFn *> test_fns; | |
| 1618 | ZigList<ZigLLVMDIEnumerator *> err_enumerators; | |
| 1619 | ZigList<ErrorTableEntry *> errors_by_index; | |
| 1620 | size_t largest_err_name_len; | |
| 1579 | 1621 | |
| 1580 | uint32_t next_unresolved_index; | |
| 1622 | PackageTableEntry *std_package; | |
| 1623 | PackageTableEntry *panic_package; | |
| 1624 | PackageTableEntry *test_runner_package; | |
| 1625 | PackageTableEntry *compile_var_package; | |
| 1626 | ImportTableEntry *compile_var_import; | |
| 1627 | ImportTableEntry *root_import; | |
| 1628 | ImportTableEntry *bootstrap_import; | |
| 1629 | ImportTableEntry *test_runner_import; | |
| 1581 | 1630 | |
| 1582 | 1631 | struct { |
| 1583 | 1632 | ZigType *entry_bool; |
| ... | ... | @@ -1613,30 +1662,45 @@ struct CodeGen { |
| 1613 | 1662 | ZigType *entry_arg_tuple; |
| 1614 | 1663 | ZigType *entry_promise; |
| 1615 | 1664 | } builtin_types; |
| 1665 | ZigType *align_amt_type; | |
| 1666 | ZigType *stack_trace_type; | |
| 1667 | ZigType *ptr_to_stack_trace_type; | |
| 1668 | ZigType *err_tag_type; | |
| 1669 | ZigType *test_fn_type; | |
| 1616 | 1670 | |
| 1617 | CacheHash cache_hash; | |
| 1671 | Buf triple_str; | |
| 1672 | Buf global_asm; | |
| 1673 | Buf *out_h_path; | |
| 1674 | Buf cache_dir; | |
| 1675 | Buf artifact_dir; | |
| 1676 | Buf output_file_path; | |
| 1677 | Buf o_file_output_path; | |
| 1678 | Buf *wanted_output_file_path; | |
| 1618 | 1679 | |
| 1619 | //////////////////////////// Participates in Input Parameter Cache Hash | |
| 1620 | Buf *compiler_id; | |
| 1621 | ZigList<LinkLib *> link_libs_list; | |
| 1622 | // add -framework [name] args to linker | |
| 1623 | ZigList<Buf *> darwin_frameworks; | |
| 1624 | // add -rpath [name] args to linker | |
| 1625 | ZigList<Buf *> rpath_list; | |
| 1680 | IrInstruction *invalid_instruction; | |
| 1626 | 1681 | |
| 1627 | EmitFileType emit_file_type; | |
| 1628 | BuildMode build_mode; | |
| 1629 | OutType out_type; | |
| 1682 | ConstExprValue const_void_val; | |
| 1683 | ConstExprValue panic_msg_vals[PanicMsgIdCount]; | |
| 1630 | 1684 | |
| 1685 | // The function definitions this module includes. | |
| 1686 | ZigList<ZigFn *> fn_defs; | |
| 1687 | size_t fn_defs_index; | |
| 1688 | ZigList<TldVar *> global_vars; | |
| 1631 | 1689 | |
| 1632 | //////////////////////////// Unsorted | |
| 1690 | ZigFn *cur_fn; | |
| 1691 | ZigFn *main_fn; | |
| 1692 | ZigFn *panic_fn; | |
| 1693 | AstNode *root_export_decl; | |
| 1633 | 1694 | |
| 1634 | ZigTarget zig_target; | |
| 1635 | LLVMTargetDataRef target_data_ref; | |
| 1695 | CacheHash cache_hash; | |
| 1696 | ErrColor err_color; | |
| 1697 | uint32_t next_unresolved_index; | |
| 1636 | 1698 | unsigned pointer_size_bytes; |
| 1699 | uint32_t target_os_index; | |
| 1700 | uint32_t target_arch_index; | |
| 1701 | uint32_t target_environ_index; | |
| 1702 | uint32_t target_oformat_index; | |
| 1637 | 1703 | bool is_big_endian; |
| 1638 | bool is_static; | |
| 1639 | bool strip_debug_symbols; | |
| 1640 | 1704 | bool want_h_file; |
| 1641 | 1705 | bool have_pub_main; |
| 1642 | 1706 | bool have_c_main; |
| ... | ... | @@ -1644,148 +1708,75 @@ struct CodeGen { |
| 1644 | 1708 | bool have_winmain_crt_startup; |
| 1645 | 1709 | bool have_dllmain_crt_startup; |
| 1646 | 1710 | bool have_pub_panic; |
| 1647 | Buf *libc_lib_dir; | |
| 1648 | Buf *libc_static_lib_dir; | |
| 1649 | Buf *libc_include_dir; | |
| 1650 | Buf *msvc_lib_dir; | |
| 1651 | Buf *kernel32_lib_dir; | |
| 1652 | Buf *zig_lib_dir; | |
| 1653 | Buf *zig_std_dir; | |
| 1654 | Buf *zig_c_headers_dir; | |
| 1655 | Buf *zig_std_special_dir; | |
| 1656 | Buf *dynamic_linker; | |
| 1657 | Buf *ar_path; | |
| 1658 | ZigWindowsSDK *win_sdk; | |
| 1659 | Buf triple_str; | |
| 1660 | bool is_test_build; | |
| 1661 | 1711 | bool have_err_ret_tracing; |
| 1662 | uint32_t target_os_index; | |
| 1663 | uint32_t target_arch_index; | |
| 1664 | uint32_t target_environ_index; | |
| 1665 | uint32_t target_oformat_index; | |
| 1666 | LLVMTargetMachineRef target_machine; | |
| 1667 | ZigLLVMDIFile *dummy_di_file; | |
| 1668 | bool is_native_target; | |
| 1669 | PackageTableEntry *root_package; // participates in cache hash | |
| 1670 | PackageTableEntry *std_package; | |
| 1671 | PackageTableEntry *panic_package; | |
| 1672 | PackageTableEntry *test_runner_package; | |
| 1673 | PackageTableEntry *compile_var_package; | |
| 1674 | ImportTableEntry *compile_var_import; | |
| 1675 | Buf *root_out_name; // participates in cache hash | |
| 1676 | bool windows_subsystem_windows; | |
| 1677 | bool windows_subsystem_console; | |
| 1678 | Buf *mmacosx_version_min; | |
| 1679 | Buf *mios_version_min; | |
| 1680 | bool linker_rdynamic; | |
| 1681 | const char *linker_script; | |
| 1682 | ||
| 1683 | // The function definitions this module includes. | |
| 1684 | ZigList<ZigFn *> fn_defs; | |
| 1685 | size_t fn_defs_index; | |
| 1686 | ZigList<TldVar *> global_vars; | |
| 1687 | ||
| 1688 | ZigFn *cur_fn; | |
| 1689 | ZigFn *main_fn; | |
| 1690 | ZigFn *panic_fn; | |
| 1691 | LLVMValueRef cur_ret_ptr; | |
| 1692 | LLVMValueRef cur_fn_val; | |
| 1693 | LLVMValueRef cur_err_ret_trace_val_arg; | |
| 1694 | LLVMValueRef cur_err_ret_trace_val_stack; | |
| 1695 | 1712 | bool c_want_stdint; |
| 1696 | 1713 | bool c_want_stdbool; |
| 1697 | AstNode *root_export_decl; | |
| 1698 | size_t version_major; | |
| 1699 | size_t version_minor; | |
| 1700 | size_t version_patch; | |
| 1701 | 1714 | bool verbose_tokenize; |
| 1702 | 1715 | bool verbose_ast; |
| 1703 | 1716 | bool verbose_link; |
| 1704 | 1717 | bool verbose_ir; |
| 1705 | 1718 | bool verbose_llvm_ir; |
| 1706 | 1719 | bool verbose_cimport; |
| 1707 | ErrColor err_color; | |
| 1708 | ImportTableEntry *root_import; | |
| 1709 | ImportTableEntry *bootstrap_import; | |
| 1710 | ImportTableEntry *test_runner_import; | |
| 1711 | LLVMValueRef memcpy_fn_val; | |
| 1712 | LLVMValueRef memset_fn_val; | |
| 1713 | LLVMValueRef trap_fn_val; | |
| 1714 | LLVMValueRef return_address_fn_val; | |
| 1715 | LLVMValueRef frame_address_fn_val; | |
| 1716 | LLVMValueRef coro_destroy_fn_val; | |
| 1717 | LLVMValueRef coro_id_fn_val; | |
| 1718 | LLVMValueRef coro_alloc_fn_val; | |
| 1719 | LLVMValueRef coro_size_fn_val; | |
| 1720 | LLVMValueRef coro_begin_fn_val; | |
| 1721 | LLVMValueRef coro_suspend_fn_val; | |
| 1722 | LLVMValueRef coro_end_fn_val; | |
| 1723 | LLVMValueRef coro_free_fn_val; | |
| 1724 | LLVMValueRef coro_resume_fn_val; | |
| 1725 | LLVMValueRef coro_save_fn_val; | |
| 1726 | LLVMValueRef coro_promise_fn_val; | |
| 1727 | LLVMValueRef coro_alloc_helper_fn_val; | |
| 1728 | LLVMValueRef coro_frame_fn_val; | |
| 1729 | LLVMValueRef merge_err_ret_traces_fn_val; | |
| 1730 | LLVMValueRef add_error_return_trace_addr_fn_val; | |
| 1731 | LLVMValueRef stacksave_fn_val; | |
| 1732 | LLVMValueRef stackrestore_fn_val; | |
| 1733 | LLVMValueRef write_register_fn_val; | |
| 1734 | 1720 | bool error_during_imports; |
| 1721 | bool generate_error_name_table; | |
| 1735 | 1722 | |
| 1736 | LLVMValueRef sp_md_node; | |
| 1737 | ||
| 1738 | const char **clang_argv; | |
| 1739 | size_t clang_argv_len; | |
| 1723 | //////////////////////////// Participates in Input Parameter Cache Hash | |
| 1724 | ZigList<LinkLib *> link_libs_list; | |
| 1725 | // add -framework [name] args to linker | |
| 1726 | ZigList<Buf *> darwin_frameworks; | |
| 1727 | // add -rpath [name] args to linker | |
| 1728 | ZigList<Buf *> rpath_list; | |
| 1729 | ZigList<Buf *> forbidden_libs; | |
| 1730 | ZigList<Buf *> link_objects; | |
| 1731 | ZigList<Buf *> assembly_files; | |
| 1740 | 1732 | ZigList<const char *> lib_dirs; |
| 1741 | 1733 | |
| 1742 | const char **llvm_argv; | |
| 1743 | size_t llvm_argv_len; | |
| 1744 | ||
| 1745 | ZigList<ZigFn *> test_fns; | |
| 1746 | ZigType *test_fn_type; | |
| 1734 | Buf *compiler_id; | |
| 1735 | size_t version_major; | |
| 1736 | size_t version_minor; | |
| 1737 | size_t version_patch; | |
| 1738 | const char *linker_script; | |
| 1747 | 1739 | |
| 1740 | EmitFileType emit_file_type; | |
| 1741 | BuildMode build_mode; | |
| 1742 | OutType out_type; | |
| 1743 | ZigTarget zig_target; | |
| 1744 | bool is_static; | |
| 1745 | bool strip_debug_symbols; | |
| 1746 | bool is_test_build; | |
| 1747 | bool is_native_target; | |
| 1748 | bool windows_subsystem_windows; | |
| 1749 | bool windows_subsystem_console; | |
| 1750 | bool linker_rdynamic; | |
| 1751 | bool no_rosegment_workaround; | |
| 1748 | 1752 | bool each_lib_rpath; |
| 1749 | 1753 | |
| 1750 | ZigType *err_tag_type; | |
| 1751 | ZigList<ZigLLVMDIEnumerator *> err_enumerators; | |
| 1752 | ZigList<ErrorTableEntry *> errors_by_index; | |
| 1753 | bool generate_error_name_table; | |
| 1754 | LLVMValueRef err_name_table; | |
| 1755 | size_t largest_err_name_len; | |
| 1756 | LLVMValueRef safety_crash_err_fn; | |
| 1757 | ||
| 1758 | LLVMValueRef return_err_fn; | |
| 1759 | ||
| 1760 | IrInstruction *invalid_instruction; | |
| 1761 | ConstExprValue const_void_val; | |
| 1762 | ||
| 1763 | ConstExprValue panic_msg_vals[PanicMsgIdCount]; | |
| 1764 | ||
| 1765 | Buf global_asm; | |
| 1766 | ZigList<Buf *> link_objects; | |
| 1767 | ZigList<Buf *> assembly_files; | |
| 1768 | ||
| 1754 | Buf *mmacosx_version_min; | |
| 1755 | Buf *mios_version_min; | |
| 1756 | Buf *root_out_name; | |
| 1769 | 1757 | Buf *test_filter; |
| 1770 | 1758 | Buf *test_name_prefix; |
| 1759 | PackageTableEntry *root_package; | |
| 1771 | 1760 | |
| 1772 | ZigList<TimeEvent> timing_events; | |
| 1773 | ||
| 1774 | Buf cache_dir; | |
| 1775 | Buf *out_h_path; | |
| 1776 | ||
| 1777 | ZigList<ZigFn *> inline_fns; | |
| 1778 | ZigList<AstNode *> tld_ref_source_node_stack; | |
| 1779 | ||
| 1780 | ZigType *align_amt_type; | |
| 1781 | ZigType *stack_trace_type; | |
| 1782 | ZigType *ptr_to_stack_trace_type; | |
| 1761 | const char **llvm_argv; | |
| 1762 | size_t llvm_argv_len; | |
| 1783 | 1763 | |
| 1784 | ZigList<ZigLLVMDIType **> error_di_types; | |
| 1764 | const char **clang_argv; | |
| 1765 | size_t clang_argv_len; | |
| 1785 | 1766 | |
| 1786 | ZigList<Buf *> forbidden_libs; | |
| 1767 | //////////////////////////// Unsorted | |
| 1787 | 1768 | |
| 1788 | bool no_rosegment_workaround; | |
| 1769 | Buf *libc_lib_dir; | |
| 1770 | Buf *libc_static_lib_dir; | |
| 1771 | Buf *libc_include_dir; | |
| 1772 | Buf *msvc_lib_dir; | |
| 1773 | Buf *kernel32_lib_dir; | |
| 1774 | Buf *zig_lib_dir; | |
| 1775 | Buf *zig_std_dir; | |
| 1776 | Buf *zig_c_headers_dir; | |
| 1777 | Buf *zig_std_special_dir; | |
| 1778 | Buf *dynamic_linker; | |
| 1779 | ZigWindowsSDK *win_sdk; | |
| 1789 | 1780 | }; |
| 1790 | 1781 | |
| 1791 | 1782 | enum VarLinkage { |
src/cache_hash.cpp+61-9| ... | ... | @@ -37,6 +37,20 @@ void cache_int(CacheHash *ch, int x) { |
| 37 | 37 | blake2b_update(&ch->blake, buf, sizeof(int) + 1); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | void cache_usize(CacheHash *ch, size_t x) { | |
| 41 | assert(ch->manifest_file_path == nullptr); | |
| 42 | // + 1 to include the null byte | |
| 43 | uint8_t buf[sizeof(size_t) + 1]; | |
| 44 | memcpy(buf, &x, sizeof(size_t)); | |
| 45 | buf[sizeof(size_t)] = 0; | |
| 46 | blake2b_update(&ch->blake, buf, sizeof(size_t) + 1); | |
| 47 | } | |
| 48 | ||
| 49 | void cache_bool(CacheHash *ch, bool x) { | |
| 50 | assert(ch->manifest_file_path == nullptr); | |
| 51 | blake2b_update(&ch->blake, &x, 1); | |
| 52 | } | |
| 53 | ||
| 40 | 54 | void cache_buf(CacheHash *ch, Buf *buf) { |
| 41 | 55 | assert(ch->manifest_file_path == nullptr); |
| 42 | 56 | assert(buf != nullptr); |
| ... | ... | @@ -74,6 +88,26 @@ void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len) { |
| 74 | 88 | cache_str(ch, ""); |
| 75 | 89 | } |
| 76 | 90 | |
| 91 | void cache_list_of_file(CacheHash *ch, Buf **ptr, size_t len) { | |
| 92 | assert(ch->manifest_file_path == nullptr); | |
| 93 | ||
| 94 | for (size_t i = 0; i < len; i += 1) { | |
| 95 | Buf *buf = ptr[i]; | |
| 96 | cache_file(ch, buf); | |
| 97 | } | |
| 98 | cache_str(ch, ""); | |
| 99 | } | |
| 100 | ||
| 101 | void cache_list_of_str(CacheHash *ch, const char **ptr, size_t len) { | |
| 102 | assert(ch->manifest_file_path == nullptr); | |
| 103 | ||
| 104 | for (size_t i = 0; i < len; i += 1) { | |
| 105 | const char *s = ptr[i]; | |
| 106 | cache_str(ch, s); | |
| 107 | } | |
| 108 | cache_str(ch, ""); | |
| 109 | } | |
| 110 | ||
| 77 | 111 | void cache_file(CacheHash *ch, Buf *file_path) { |
| 78 | 112 | assert(ch->manifest_file_path == nullptr); |
| 79 | 113 | assert(file_path != nullptr); |
| ... | ... | @@ -154,9 +188,13 @@ static Error base64_decode(Slice<uint8_t> dest, Slice<uint8_t> source) { |
| 154 | 188 | return ErrorNone; |
| 155 | 189 | } |
| 156 | 190 | |
| 157 | static Error hash_file(uint8_t *digest, OsFile handle) { | |
| 191 | static Error hash_file(uint8_t *digest, OsFile handle, Buf *contents) { | |
| 158 | 192 | Error err; |
| 159 | 193 | |
| 194 | if (contents) { | |
| 195 | buf_resize(contents, 0); | |
| 196 | } | |
| 197 | ||
| 160 | 198 | blake2b_state blake; |
| 161 | 199 | int rc = blake2b_init(&blake, 48); |
| 162 | 200 | assert(rc == 0); |
| ... | ... | @@ -172,10 +210,13 @@ static Error hash_file(uint8_t *digest, OsFile handle) { |
| 172 | 210 | return ErrorNone; |
| 173 | 211 | } |
| 174 | 212 | blake2b_update(&blake, buf, amt); |
| 213 | if (contents) { | |
| 214 | buf_append_mem(contents, (char*)buf, amt); | |
| 215 | } | |
| 175 | 216 | } |
| 176 | 217 | } |
| 177 | 218 | |
| 178 | static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf) { | |
| 219 | static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf, Buf *contents) { | |
| 179 | 220 | Error err; |
| 180 | 221 | |
| 181 | 222 | assert(chf->path != nullptr); |
| ... | ... | @@ -189,7 +230,7 @@ static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf) { |
| 189 | 230 | return err; |
| 190 | 231 | } |
| 191 | 232 | |
| 192 | if ((err = hash_file(chf->bin_digest, this_file))) { | |
| 233 | if ((err = hash_file(chf->bin_digest, this_file, contents))) { | |
| 193 | 234 | os_file_close(this_file); |
| 194 | 235 | return err; |
| 195 | 236 | } |
| ... | ... | @@ -323,7 +364,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { |
| 323 | 364 | chf->mtime = actual_mtime; |
| 324 | 365 | |
| 325 | 366 | uint8_t actual_digest[48]; |
| 326 | if ((err = hash_file(actual_digest, this_file))) { | |
| 367 | if ((err = hash_file(actual_digest, this_file, nullptr))) { | |
| 327 | 368 | os_file_close(this_file); |
| 328 | 369 | os_file_close(ch->manifest_file); |
| 329 | 370 | return err; |
| ... | ... | @@ -344,7 +385,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { |
| 344 | 385 | ch->manifest_dirty = true; |
| 345 | 386 | for (; file_i < input_file_count; file_i += 1) { |
| 346 | 387 | CacheHashFile *chf = &ch->files.at(file_i); |
| 347 | if ((err = populate_file_hash(ch, chf))) { | |
| 388 | if ((err = populate_file_hash(ch, chf, nullptr))) { | |
| 348 | 389 | os_file_close(ch->manifest_file); |
| 349 | 390 | return err; |
| 350 | 391 | } |
| ... | ... | @@ -355,13 +396,13 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) { |
| 355 | 396 | return cache_final(ch, out_digest); |
| 356 | 397 | } |
| 357 | 398 | |
| 358 | Error cache_add_file(CacheHash *ch, Buf *path) { | |
| 399 | Error cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents) { | |
| 359 | 400 | Error err; |
| 360 | 401 | |
| 361 | 402 | assert(ch->manifest_file_path != nullptr); |
| 362 | 403 | CacheHashFile *chf = ch->files.add_one(); |
| 363 | chf->path = path; | |
| 364 | if ((err = populate_file_hash(ch, chf))) { | |
| 404 | chf->path = resolved_path; | |
| 405 | if ((err = populate_file_hash(ch, chf, contents))) { | |
| 365 | 406 | os_file_close(ch->manifest_file); |
| 366 | 407 | return err; |
| 367 | 408 | } |
| ... | ... | @@ -369,6 +410,12 @@ Error cache_add_file(CacheHash *ch, Buf *path) { |
| 369 | 410 | return ErrorNone; |
| 370 | 411 | } |
| 371 | 412 | |
| 413 | Error cache_add_file(CacheHash *ch, Buf *path) { | |
| 414 | Buf *resolved_path = buf_alloc(); | |
| 415 | *resolved_path = os_path_resolve(&path, 1); | |
| 416 | return cache_add_file_fetch(ch, resolved_path, nullptr); | |
| 417 | } | |
| 418 | ||
| 372 | 419 | static Error write_manifest_file(CacheHash *ch) { |
| 373 | 420 | Error err; |
| 374 | 421 | Buf contents = BUF_INIT; |
| ... | ... | @@ -398,7 +445,8 @@ Error cache_final(CacheHash *ch, Buf *out_digest) { |
| 398 | 445 | buf_ptr(ch->manifest_file_path), err_str(err)); |
| 399 | 446 | } |
| 400 | 447 | } |
| 401 | os_file_close(ch->manifest_file); | |
| 448 | // We don't close the manifest file yet, because we want to | |
| 449 | // keep it locked until the API user is done using it. | |
| 402 | 450 | |
| 403 | 451 | uint8_t bin_digest[48]; |
| 404 | 452 | int rc = blake2b_final(&ch->blake, bin_digest, 48); |
| ... | ... | @@ -408,3 +456,7 @@ Error cache_final(CacheHash *ch, Buf *out_digest) { |
| 408 | 456 | |
| 409 | 457 | return ErrorNone; |
| 410 | 458 | } |
| 459 | ||
| 460 | void cache_release(CacheHash *ch) { | |
| 461 | os_file_close(ch->manifest_file); | |
| 462 | } |
src/cache_hash.hpp+20-7| ... | ... | @@ -17,6 +17,7 @@ struct CacheHashFile { |
| 17 | 17 | Buf *path; |
| 18 | 18 | OsTimeStamp mtime; |
| 19 | 19 | uint8_t bin_digest[48]; |
| 20 | Buf *contents; | |
| 20 | 21 | }; |
| 21 | 22 | |
| 22 | 23 | struct CacheHash { |
| ... | ... | @@ -34,24 +35,36 @@ void cache_init(CacheHash *ch, Buf *manifest_dir); |
| 34 | 35 | // Next, use the hash population functions to add the initial parameters. |
| 35 | 36 | void cache_str(CacheHash *ch, const char *ptr); |
| 36 | 37 | void cache_int(CacheHash *ch, int x); |
| 38 | void cache_bool(CacheHash *ch, bool x); | |
| 39 | void cache_usize(CacheHash *ch, size_t x); | |
| 37 | 40 | void cache_buf(CacheHash *ch, Buf *buf); |
| 38 | 41 | void cache_buf_opt(CacheHash *ch, Buf *buf); |
| 39 | 42 | void cache_list_of_link_lib(CacheHash *ch, LinkLib **ptr, size_t len); |
| 40 | 43 | void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len); |
| 44 | void cache_list_of_file(CacheHash *ch, Buf **ptr, size_t len); | |
| 45 | void cache_list_of_str(CacheHash *ch, const char **ptr, size_t len); | |
| 41 | 46 | void cache_file(CacheHash *ch, Buf *path); |
| 42 | 47 | void cache_file_opt(CacheHash *ch, Buf *path); |
| 43 | 48 | |
| 44 | 49 | // Then call cache_hit when you're ready to see if you can skip the next step. |
| 45 | // out_b64_digest will be left unchanged if it was a cache miss | |
| 50 | // out_b64_digest will be left unchanged if it was a cache miss. | |
| 51 | // If you got a cache hit, the next step is cache_release. | |
| 52 | // From this point on, there is a lock on the input params. Release | |
| 53 | // the lock with cache_release. | |
| 46 | 54 | Error ATTRIBUTE_MUST_USE cache_hit(CacheHash *ch, Buf *out_b64_digest); |
| 47 | 55 | |
| 48 | // If you got a cache hit, the flow is done. No more functions to call. | |
| 49 | // Next call this function for every file that is depended on. | |
| 56 | // If you did not get a cache hit, call this function for every file | |
| 57 | // that is depended on, and then finish with cache_final. | |
| 50 | 58 | Error ATTRIBUTE_MUST_USE cache_add_file(CacheHash *ch, Buf *path); |
| 51 | 59 | |
| 52 | // If you did not get a cache hit, use the hash population functions again | |
| 53 | // and do all the actual work. When done use cache_final to save the cache | |
| 54 | // for next time. | |
| 55 | Error ATTRIBUTE_MUST_USE cache_final(CacheHash *ch, Buf *out_digest); | |
| 60 | // This variant of cache_add_file returns the file contents. | |
| 61 | // Also the file path argument must be already resolved. | |
| 62 | Error ATTRIBUTE_MUST_USE cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents); | |
| 63 | ||
| 64 | // out_b64_digest will be the same thing that cache_hit returns if you got a cache hit | |
| 65 | Error ATTRIBUTE_MUST_USE cache_final(CacheHash *ch, Buf *out_b64_digest); | |
| 66 | ||
| 67 | // Until this function is called, no one will be able to get a lock on your input params. | |
| 68 | void cache_release(CacheHash *ch); | |
| 56 | 69 | |
| 57 | 70 | #endif |
src/codegen.cpp+139-58| ... | ... | @@ -13,7 +13,6 @@ |
| 13 | 13 | #include "error.hpp" |
| 14 | 14 | #include "hash_map.hpp" |
| 15 | 15 | #include "ir.hpp" |
| 16 | #include "link.hpp" | |
| 17 | 16 | #include "os.hpp" |
| 18 | 17 | #include "translate_c.hpp" |
| 19 | 18 | #include "target.hpp" |
| ... | ... | @@ -188,6 +187,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) { |
| 188 | 187 | g->out_h_path = h_path; |
| 189 | 188 | } |
| 190 | 189 | |
| 190 | void codegen_set_output_path(CodeGen *g, Buf *path) { | |
| 191 | g->wanted_output_file_path = path; | |
| 192 | } | |
| 193 | ||
| 191 | 194 | void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { |
| 192 | 195 | g->clang_argv = args; |
| 193 | 196 | g->clang_argv_len = len; |
| ... | ... | @@ -5756,8 +5759,6 @@ static void validate_inline_fns(CodeGen *g) { |
| 5756 | 5759 | static void do_code_gen(CodeGen *g) { |
| 5757 | 5760 | assert(!g->errors.length); |
| 5758 | 5761 | |
| 5759 | codegen_add_time_event(g, "Code Generation"); | |
| 5760 | ||
| 5761 | 5762 | { |
| 5762 | 5763 | // create debug type for error sets |
| 5763 | 5764 | assert(g->err_enumerators.length == g->errors_by_index.length); |
| ... | ... | @@ -6068,38 +6069,10 @@ static void do_code_gen(CodeGen *g) { |
| 6068 | 6069 | |
| 6069 | 6070 | codegen_add_time_event(g, "LLVM Emit Output"); |
| 6070 | 6071 | |
| 6071 | char *err_msg = nullptr; | |
| 6072 | Buf *o_basename = buf_create_from_buf(g->root_out_name); | |
| 6073 | ||
| 6074 | switch (g->emit_file_type) { | |
| 6075 | case EmitFileTypeBinary: | |
| 6076 | { | |
| 6077 | const char *o_ext = target_o_file_ext(&g->zig_target); | |
| 6078 | buf_append_str(o_basename, o_ext); | |
| 6079 | break; | |
| 6080 | } | |
| 6081 | case EmitFileTypeAssembly: | |
| 6082 | { | |
| 6083 | const char *asm_ext = target_asm_file_ext(&g->zig_target); | |
| 6084 | buf_append_str(o_basename, asm_ext); | |
| 6085 | break; | |
| 6086 | } | |
| 6087 | case EmitFileTypeLLVMIr: | |
| 6088 | { | |
| 6089 | const char *llvm_ir_ext = target_llvm_ir_file_ext(&g->zig_target); | |
| 6090 | buf_append_str(o_basename, llvm_ir_ext); | |
| 6091 | break; | |
| 6092 | } | |
| 6093 | default: | |
| 6094 | zig_unreachable(); | |
| 6095 | } | |
| 6096 | ||
| 6097 | Buf *output_path = buf_alloc(); | |
| 6098 | os_path_join(&g->cache_dir, o_basename, output_path); | |
| 6099 | ensure_cache_dir(g); | |
| 6100 | ||
| 6101 | 6072 | bool is_small = g->build_mode == BuildModeSmallRelease; |
| 6102 | 6073 | |
| 6074 | Buf *output_path = &g->o_file_output_path; | |
| 6075 | char *err_msg = nullptr; | |
| 6103 | 6076 | switch (g->emit_file_type) { |
| 6104 | 6077 | case EmitFileTypeBinary: |
| 6105 | 6078 | if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), |
| ... | ... | @@ -6118,7 +6091,6 @@ static void do_code_gen(CodeGen *g) { |
| 6118 | 6091 | zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); |
| 6119 | 6092 | } |
| 6120 | 6093 | validate_inline_fns(g); |
| 6121 | g->link_objects.append(output_path); | |
| 6122 | 6094 | break; |
| 6123 | 6095 | |
| 6124 | 6096 | case EmitFileTypeLLVMIr: |
| ... | ... | @@ -6128,7 +6100,6 @@ static void do_code_gen(CodeGen *g) { |
| 6128 | 6100 | zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); |
| 6129 | 6101 | } |
| 6130 | 6102 | validate_inline_fns(g); |
| 6131 | g->link_objects.append(output_path); | |
| 6132 | 6103 | break; |
| 6133 | 6104 | |
| 6134 | 6105 | default: |
| ... | ... | @@ -7035,8 +7006,8 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package |
| 7035 | 7006 | Buf *resolved_path = buf_alloc(); |
| 7036 | 7007 | *resolved_path = os_path_resolve(resolve_paths, 1); |
| 7037 | 7008 | Buf *import_code = buf_alloc(); |
| 7038 | int err; | |
| 7039 | if ((err = os_fetch_file_path(resolved_path, import_code, false))) { | |
| 7009 | Error err; | |
| 7010 | if ((err = cache_add_file_fetch(&g->cache_hash, resolved_path, import_code))) { | |
| 7040 | 7011 | zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err)); |
| 7041 | 7012 | } |
| 7042 | 7013 | |
| ... | ... | @@ -7131,6 +7102,8 @@ static void gen_root_source(CodeGen *g) { |
| 7131 | 7102 | |
| 7132 | 7103 | Buf *source_code = buf_alloc(); |
| 7133 | 7104 | int err; |
| 7105 | // No need for using the caching system for this file fetch because it is handled | |
| 7106 | // separately. | |
| 7134 | 7107 | if ((err = os_fetch_file_path(resolved_path, source_code, true))) { |
| 7135 | 7108 | fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); |
| 7136 | 7109 | exit(1); |
| ... | ... | @@ -7197,6 +7170,8 @@ static void gen_global_asm(CodeGen *g) { |
| 7197 | 7170 | int err; |
| 7198 | 7171 | for (size_t i = 0; i < g->assembly_files.length; i += 1) { |
| 7199 | 7172 | Buf *asm_file = g->assembly_files.at(i); |
| 7173 | // No need to use the caching system for these fetches because they | |
| 7174 | // are handled separately. | |
| 7200 | 7175 | if ((err = os_fetch_file_path(asm_file, &contents, false))) { |
| 7201 | 7176 | zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err)); |
| 7202 | 7177 | } |
| ... | ... | @@ -7460,14 +7435,9 @@ static Buf *preprocessor_mangle(Buf *src) { |
| 7460 | 7435 | } |
| 7461 | 7436 | |
| 7462 | 7437 | static void gen_h_file(CodeGen *g) { |
| 7463 | if (!g->want_h_file) | |
| 7464 | return; | |
| 7465 | ||
| 7466 | 7438 | GenH gen_h_data = {0}; |
| 7467 | 7439 | GenH *gen_h = &gen_h_data; |
| 7468 | 7440 | |
| 7469 | codegen_add_time_event(g, "Generate .h"); | |
| 7470 | ||
| 7471 | 7441 | assert(!g->is_test_build); |
| 7472 | 7442 | |
| 7473 | 7443 | if (!g->out_h_path) { |
| ... | ... | @@ -7675,6 +7645,24 @@ void codegen_add_time_event(CodeGen *g, const char *name) { |
| 7675 | 7645 | g->timing_events.append({os_get_time(), name}); |
| 7676 | 7646 | } |
| 7677 | 7647 | |
| 7648 | static void add_cache_pkg(CodeGen *g, CacheHash *ch, PackageTableEntry *pkg) { | |
| 7649 | if (buf_len(&pkg->root_src_path) == 0) | |
| 7650 | return; | |
| 7651 | ||
| 7652 | Buf *rel_full_path = buf_alloc(); | |
| 7653 | os_path_join(&pkg->root_src_dir, &pkg->root_src_path, rel_full_path); | |
| 7654 | cache_file(ch, rel_full_path); | |
| 7655 | ||
| 7656 | auto it = pkg->package_table.entry_iterator(); | |
| 7657 | for (;;) { | |
| 7658 | auto *entry = it.next(); | |
| 7659 | if (!entry) | |
| 7660 | break; | |
| 7661 | ||
| 7662 | cache_buf(ch, entry->key); | |
| 7663 | add_cache_pkg(g, ch, entry->value); | |
| 7664 | } | |
| 7665 | } | |
| 7678 | 7666 | |
| 7679 | 7667 | // Called before init() |
| 7680 | 7668 | static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| ... | ... | @@ -7683,16 +7671,46 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 7683 | 7671 | CacheHash *ch = &g->cache_hash; |
| 7684 | 7672 | cache_init(ch, manifest_dir); |
| 7685 | 7673 | |
| 7674 | add_cache_pkg(g, ch, g->root_package); | |
| 7675 | if (g->linker_script != nullptr) { | |
| 7676 | cache_file(ch, buf_create_from_str(g->linker_script)); | |
| 7677 | } | |
| 7686 | 7678 | cache_buf(ch, g->compiler_id); |
| 7687 | 7679 | cache_buf(ch, g->root_out_name); |
| 7688 | cache_file(ch, get_resolved_root_src_path(g)); // Root source file | |
| 7689 | 7680 | cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length); |
| 7690 | 7681 | cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length); |
| 7691 | 7682 | cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length); |
| 7683 | cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length); | |
| 7684 | cache_list_of_file(ch, g->link_objects.items, g->link_objects.length); | |
| 7685 | cache_list_of_file(ch, g->assembly_files.items, g->assembly_files.length); | |
| 7692 | 7686 | cache_int(ch, g->emit_file_type); |
| 7693 | 7687 | cache_int(ch, g->build_mode); |
| 7694 | 7688 | cache_int(ch, g->out_type); |
| 7695 | // TODO the rest of the struct CodeGen fields | |
| 7689 | cache_int(ch, g->zig_target.arch.arch); | |
| 7690 | cache_int(ch, g->zig_target.arch.sub_arch); | |
| 7691 | cache_int(ch, g->zig_target.vendor); | |
| 7692 | cache_int(ch, g->zig_target.os); | |
| 7693 | cache_int(ch, g->zig_target.env_type); | |
| 7694 | cache_int(ch, g->zig_target.oformat); | |
| 7695 | cache_bool(ch, g->is_static); | |
| 7696 | cache_bool(ch, g->strip_debug_symbols); | |
| 7697 | cache_bool(ch, g->is_test_build); | |
| 7698 | cache_bool(ch, g->is_native_target); | |
| 7699 | cache_bool(ch, g->windows_subsystem_windows); | |
| 7700 | cache_bool(ch, g->windows_subsystem_console); | |
| 7701 | cache_bool(ch, g->linker_rdynamic); | |
| 7702 | cache_bool(ch, g->no_rosegment_workaround); | |
| 7703 | cache_bool(ch, g->each_lib_rpath); | |
| 7704 | cache_buf_opt(ch, g->mmacosx_version_min); | |
| 7705 | cache_buf_opt(ch, g->mios_version_min); | |
| 7706 | cache_usize(ch, g->version_major); | |
| 7707 | cache_usize(ch, g->version_minor); | |
| 7708 | cache_usize(ch, g->version_patch); | |
| 7709 | cache_buf_opt(ch, g->test_filter); | |
| 7710 | cache_buf_opt(ch, g->test_name_prefix); | |
| 7711 | cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len); | |
| 7712 | cache_list_of_str(ch, g->clang_argv, g->clang_argv_len); | |
| 7713 | cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length); | |
| 7696 | 7714 | |
| 7697 | 7715 | buf_resize(digest, 0); |
| 7698 | 7716 | if ((err = cache_hit(ch, digest))) |
| ... | ... | @@ -7701,10 +7719,53 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { |
| 7701 | 7719 | return ErrorNone; |
| 7702 | 7720 | } |
| 7703 | 7721 | |
| 7704 | void codegen_build(CodeGen *g) { | |
| 7722 | static void resolve_out_paths(CodeGen *g) { | |
| 7723 | Buf *o_basename = buf_create_from_buf(g->root_out_name); | |
| 7724 | ||
| 7725 | switch (g->emit_file_type) { | |
| 7726 | case EmitFileTypeBinary: | |
| 7727 | { | |
| 7728 | const char *o_ext = target_o_file_ext(&g->zig_target); | |
| 7729 | buf_append_str(o_basename, o_ext); | |
| 7730 | break; | |
| 7731 | } | |
| 7732 | case EmitFileTypeAssembly: | |
| 7733 | { | |
| 7734 | const char *asm_ext = target_asm_file_ext(&g->zig_target); | |
| 7735 | buf_append_str(o_basename, asm_ext); | |
| 7736 | break; | |
| 7737 | } | |
| 7738 | case EmitFileTypeLLVMIr: | |
| 7739 | { | |
| 7740 | const char *llvm_ir_ext = target_llvm_ir_file_ext(&g->zig_target); | |
| 7741 | buf_append_str(o_basename, llvm_ir_ext); | |
| 7742 | break; | |
| 7743 | } | |
| 7744 | default: | |
| 7745 | zig_unreachable(); | |
| 7746 | } | |
| 7747 | ||
| 7748 | os_path_join(&g->artifact_dir, o_basename, &g->o_file_output_path); | |
| 7749 | ||
| 7750 | if (g->out_type == OutTypeObj) { | |
| 7751 | buf_init_from_buf(&g->output_file_path, &g->o_file_output_path); | |
| 7752 | } else if (g->out_type == OutTypeExe) { | |
| 7753 | assert(g->root_out_name); | |
| 7754 | ||
| 7755 | Buf basename = BUF_INIT; | |
| 7756 | buf_init_from_buf(&basename, g->root_out_name); | |
| 7757 | buf_append_str(&basename, target_exe_file_ext(&g->zig_target)); | |
| 7758 | os_path_join(&g->artifact_dir, &basename, &g->output_file_path); | |
| 7759 | } | |
| 7760 | } | |
| 7761 | ||
| 7762 | ||
| 7763 | void codegen_build_and_link(CodeGen *g) { | |
| 7705 | 7764 | Error err; |
| 7706 | 7765 | assert(g->out_type != OutTypeUnknown); |
| 7707 | 7766 | |
| 7767 | codegen_add_time_event(g, "Check Cache"); | |
| 7768 | ||
| 7708 | 7769 | Buf app_data_dir = BUF_INIT; |
| 7709 | 7770 | if ((err = os_get_app_data_dir(&app_data_dir, "zig"))) { |
| 7710 | 7771 | fprintf(stderr, "Unable to get app data dir: %s\n", err_str(err)); |
| ... | ... | @@ -7721,25 +7782,45 @@ void codegen_build(CodeGen *g) { |
| 7721 | 7782 | fprintf(stderr, "Unable to check cache: %s\n", err_str(err)); |
| 7722 | 7783 | exit(1); |
| 7723 | 7784 | } |
| 7785 | ||
| 7786 | Buf *artifact_dir = buf_alloc(); | |
| 7787 | os_path_join(stage1_dir, buf_create_from_str("artifact"), artifact_dir); | |
| 7788 | ||
| 7724 | 7789 | if (buf_len(&digest) != 0) { |
| 7725 | Buf *artifact_dir = buf_alloc(); | |
| 7726 | os_path_join(stage1_dir, buf_create_from_str("artifact"), artifact_dir); | |
| 7790 | os_path_join(artifact_dir, &digest, &g->artifact_dir); | |
| 7791 | resolve_out_paths(g); | |
| 7792 | } else { | |
| 7793 | init(g); | |
| 7727 | 7794 | |
| 7728 | Buf *this_artifact_dir = buf_alloc(); | |
| 7729 | os_path_join(artifact_dir, &digest, this_artifact_dir); | |
| 7795 | codegen_add_time_event(g, "Semantic Analysis"); | |
| 7730 | 7796 | |
| 7731 | fprintf(stderr, "copy artifacts from %s\n", buf_ptr(this_artifact_dir)); | |
| 7732 | return; | |
| 7733 | } | |
| 7797 | gen_global_asm(g); | |
| 7798 | gen_root_source(g); | |
| 7734 | 7799 | |
| 7735 | init(g); | |
| 7800 | if ((err = cache_final(&g->cache_hash, &digest))) { | |
| 7801 | fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); | |
| 7802 | exit(1); | |
| 7803 | } | |
| 7804 | os_path_join(artifact_dir, &digest, &g->artifact_dir); | |
| 7805 | if ((err = os_make_path(&g->artifact_dir))) { | |
| 7806 | fprintf(stderr, "Unable to create artifact directory: %s\n", err_str(err)); | |
| 7807 | exit(1); | |
| 7808 | } | |
| 7809 | resolve_out_paths(g); | |
| 7736 | 7810 | |
| 7737 | codegen_add_time_event(g, "Semantic Analysis"); | |
| 7811 | codegen_add_time_event(g, "Code Generation"); | |
| 7812 | do_code_gen(g); | |
| 7813 | if (g->want_h_file) { | |
| 7814 | codegen_add_time_event(g, "Generate .h"); | |
| 7815 | gen_h_file(g); | |
| 7816 | } | |
| 7817 | if (g->out_type != OutTypeObj) { | |
| 7818 | codegen_link(g); | |
| 7819 | } | |
| 7820 | } | |
| 7821 | // TODO hard link output_file_path to wanted_output_file_path | |
| 7738 | 7822 | |
| 7739 | gen_global_asm(g); | |
| 7740 | gen_root_source(g); | |
| 7741 | do_code_gen(g); | |
| 7742 | gen_h_file(g); | |
| 7823 | codegen_add_time_event(g, "Done"); | |
| 7743 | 7824 | } |
| 7744 | 7825 | |
| 7745 | 7826 | PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path) { |
src/codegen.hpp+3-1| ... | ... | @@ -48,9 +48,11 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 48 | 48 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); |
| 49 | 49 | void codegen_set_cache_dir(CodeGen *g, Buf cache_dir); |
| 50 | 50 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path); |
| 51 | void codegen_set_output_path(CodeGen *g, Buf *path); | |
| 51 | 52 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 52 | 53 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
| 53 | void codegen_build(CodeGen *g); | |
| 54 | void codegen_link(CodeGen *g); | |
| 55 | void codegen_build_and_link(CodeGen *g); | |
| 54 | 56 | |
| 55 | 57 | PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path); |
| 56 | 58 | void codegen_add_assembly(CodeGen *g, Buf *path); |
src/error.cpp+1| ... | ... | @@ -29,6 +29,7 @@ const char *err_str(int err) { |
| 29 | 29 | case ErrorCCompileErrors: return "C compile errors"; |
| 30 | 30 | case ErrorEndOfFile: return "end of file"; |
| 31 | 31 | case ErrorIsDir: return "is directory"; |
| 32 | case ErrorUnsupportedOperatingSystem: return "unsupported operating system"; | |
| 32 | 33 | } |
| 33 | 34 | return "(invalid error)"; |
| 34 | 35 | } |
src/error.hpp+1| ... | ... | @@ -29,6 +29,7 @@ enum Error { |
| 29 | 29 | ErrorCCompileErrors, |
| 30 | 30 | ErrorEndOfFile, |
| 31 | 31 | ErrorIsDir, |
| 32 | ErrorUnsupportedOperatingSystem, | |
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | const char *err_str(int err); |
src/ir.cpp+5-6| ... | ... | @@ -16232,6 +16232,8 @@ static ZigType *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUn |
| 16232 | 16232 | } |
| 16233 | 16233 | |
| 16234 | 16234 | static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { |
| 16235 | Error err; | |
| 16236 | ||
| 16235 | 16237 | IrInstruction *name_value = import_instruction->name->other; |
| 16236 | 16238 | Buf *import_target_str = ir_resolve_str(ira, name_value); |
| 16237 | 16239 | if (!import_target_str) |
| ... | ... | @@ -16275,8 +16277,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor |
| 16275 | 16277 | return ira->codegen->builtin_types.entry_namespace; |
| 16276 | 16278 | } |
| 16277 | 16279 | |
| 16278 | int err; | |
| 16279 | if ((err = os_fetch_file_path(resolved_path, import_code, true))) { | |
| 16280 | if ((err = cache_add_file_fetch(&ira->codegen->cache_hash, resolved_path, import_code))) { | |
| 16280 | 16281 | if (err == ErrorFileNotFound) { |
| 16281 | 16282 | ir_add_error_node(ira, source_node, |
| 16282 | 16283 | buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); |
| ... | ... | @@ -16287,6 +16288,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor |
| 16287 | 16288 | return ira->codegen->builtin_types.entry_invalid; |
| 16288 | 16289 | } |
| 16289 | 16290 | } |
| 16291 | ||
| 16290 | 16292 | ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code); |
| 16291 | 16293 | |
| 16292 | 16294 | scan_import(ira->codegen, target_import); |
| ... | ... | @@ -18106,7 +18108,7 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE |
| 18106 | 18108 | // load from file system into const expr |
| 18107 | 18109 | Buf *file_contents = buf_alloc(); |
| 18108 | 18110 | int err; |
| 18109 | if ((err = os_fetch_file_path(&file_path, file_contents, false))) { | |
| 18111 | if ((err = cache_add_file_fetch(&ira->codegen->cache_hash, &file_path, file_contents))) { | |
| 18110 | 18112 | if (err == ErrorFileNotFound) { |
| 18111 | 18113 | ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path))); |
| 18112 | 18114 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -18116,9 +18118,6 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE |
| 18116 | 18118 | } |
| 18117 | 18119 | } |
| 18118 | 18120 | |
| 18119 | // TODO add dependency on the file we embedded so that we know if it changes | |
| 18120 | // we'll have to invalidate the cache | |
| 18121 | ||
| 18122 | 18121 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 18123 | 18122 | init_const_str_lit(ira->codegen, out_val, file_contents); |
| 18124 | 18123 |
src/link.cpp+17-57| ... | ... | @@ -5,7 +5,6 @@ |
| 5 | 5 | * See http://opensource.org/licenses/MIT |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | #include "link.hpp" | |
| 9 | 8 | #include "os.hpp" |
| 10 | 9 | #include "config.h" |
| 11 | 10 | #include "codegen.hpp" |
| ... | ... | @@ -13,7 +12,6 @@ |
| 13 | 12 | |
| 14 | 13 | struct LinkJob { |
| 15 | 14 | CodeGen *codegen; |
| 16 | Buf out_file; | |
| 17 | 15 | ZigList<const char *> args; |
| 18 | 16 | bool link_in_crt; |
| 19 | 17 | HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table; |
| ... | ... | @@ -62,14 +60,8 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path) |
| 62 | 60 | new_link_lib->provided_explicitly = link_lib->provided_explicitly; |
| 63 | 61 | } |
| 64 | 62 | |
| 65 | codegen_build(child_gen); | |
| 66 | const char *o_ext = target_o_file_ext(&child_gen->zig_target); | |
| 67 | Buf *o_out_name = buf_sprintf("%s%s", oname, o_ext); | |
| 68 | Buf *output_path = buf_alloc(); | |
| 69 | os_path_join(&parent_gen->cache_dir, o_out_name, output_path); | |
| 70 | codegen_link(child_gen, buf_ptr(output_path)); | |
| 71 | ||
| 72 | return output_path; | |
| 63 | codegen_build_and_link(child_gen); | |
| 64 | return &child_gen->output_file_path; | |
| 73 | 65 | } |
| 74 | 66 | |
| 75 | 67 | static Buf *build_o(CodeGen *parent_gen, const char *oname) { |
| ... | ... | @@ -237,15 +229,15 @@ static void construct_linker_job_elf(LinkJob *lj) { |
| 237 | 229 | } else if (shared) { |
| 238 | 230 | lj->args.append("-shared"); |
| 239 | 231 | |
| 240 | if (buf_len(&lj->out_file) == 0) { | |
| 241 | buf_appendf(&lj->out_file, "lib%s.so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize "", | |
| 232 | if (buf_len(&g->output_file_path) == 0) { | |
| 233 | buf_appendf(&g->output_file_path, "lib%s.so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize "", | |
| 242 | 234 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); |
| 243 | 235 | } |
| 244 | 236 | soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major); |
| 245 | 237 | } |
| 246 | 238 | |
| 247 | 239 | lj->args.append("-o"); |
| 248 | lj->args.append(buf_ptr(&lj->out_file)); | |
| 240 | lj->args.append(buf_ptr(&g->output_file_path)); | |
| 249 | 241 | |
| 250 | 242 | if (lj->link_in_crt) { |
| 251 | 243 | const char *crt1o; |
| ... | ... | @@ -397,7 +389,7 @@ static void construct_linker_job_wasm(LinkJob *lj) { |
| 397 | 389 | |
| 398 | 390 | lj->args.append("--relocatable"); // So lld doesn't look for _start. |
| 399 | 391 | lj->args.append("-o"); |
| 400 | lj->args.append(buf_ptr(&lj->out_file)); | |
| 392 | lj->args.append(buf_ptr(&g->output_file_path)); | |
| 401 | 393 | |
| 402 | 394 | // .o files |
| 403 | 395 | for (size_t i = 0; i < g->link_objects.length; i += 1) { |
| ... | ... | @@ -478,7 +470,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 478 | 470 | // } |
| 479 | 471 | //} |
| 480 | 472 | |
| 481 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&lj->out_file)))); | |
| 473 | lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path)))); | |
| 482 | 474 | |
| 483 | 475 | if (g->libc_link_lib != nullptr) { |
| 484 | 476 | lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir)))); |
| ... | ... | @@ -585,11 +577,11 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 585 | 577 | buf_appendf(def_contents, "\n"); |
| 586 | 578 | |
| 587 | 579 | Buf *def_path = buf_alloc(); |
| 588 | os_path_join(&g->cache_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path); | |
| 580 | os_path_join(&g->artifact_dir, buf_sprintf("%s.def", buf_ptr(link_lib->name)), def_path); | |
| 589 | 581 | os_write_file(def_path, def_contents); |
| 590 | 582 | |
| 591 | 583 | Buf *generated_lib_path = buf_alloc(); |
| 592 | os_path_join(&g->cache_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path); | |
| 584 | os_path_join(&g->artifact_dir, buf_sprintf("%s.lib", buf_ptr(link_lib->name)), generated_lib_path); | |
| 593 | 585 | |
| 594 | 586 | gen_lib_args.resize(0); |
| 595 | 587 | gen_lib_args.append("link"); |
| ... | ... | @@ -797,8 +789,8 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 797 | 789 | //lj->args.append("-install_name"); |
| 798 | 790 | //lj->args.append(buf_ptr(dylib_install_name)); |
| 799 | 791 | |
| 800 | if (buf_len(&lj->out_file) == 0) { | |
| 801 | buf_appendf(&lj->out_file, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib", | |
| 792 | if (buf_len(&g->output_file_path) == 0) { | |
| 793 | buf_appendf(&g->output_file_path, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib", | |
| 802 | 794 | buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch); |
| 803 | 795 | } |
| 804 | 796 | } |
| ... | ... | @@ -832,13 +824,13 @@ static void construct_linker_job_macho(LinkJob *lj) { |
| 832 | 824 | } |
| 833 | 825 | |
| 834 | 826 | lj->args.append("-o"); |
| 835 | lj->args.append(buf_ptr(&lj->out_file)); | |
| 827 | lj->args.append(buf_ptr(&g->output_file_path)); | |
| 836 | 828 | |
| 837 | 829 | for (size_t i = 0; i < g->rpath_list.length; i += 1) { |
| 838 | 830 | Buf *rpath = g->rpath_list.at(i); |
| 839 | 831 | add_rpath(lj, rpath); |
| 840 | 832 | } |
| 841 | add_rpath(lj, &lj->out_file); | |
| 833 | add_rpath(lj, &g->output_file_path); | |
| 842 | 834 | |
| 843 | 835 | if (shared) { |
| 844 | 836 | lj->args.append("-headerpad_max_install_names"); |
| ... | ... | @@ -942,7 +934,8 @@ static void construct_linker_job(LinkJob *lj) { |
| 942 | 934 | } |
| 943 | 935 | } |
| 944 | 936 | |
| 945 | void codegen_link(CodeGen *g, const char *out_file) { | |
| 937 | void codegen_link(CodeGen *g) { | |
| 938 | assert(g->out_type != OutTypeObj); | |
| 946 | 939 | codegen_add_time_event(g, "Build Dependencies"); |
| 947 | 940 | |
| 948 | 941 | LinkJob lj = {0}; |
| ... | ... | @@ -953,11 +946,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 953 | 946 | |
| 954 | 947 | lj.rpath_table.init(4); |
| 955 | 948 | lj.codegen = g; |
| 956 | if (out_file) { | |
| 957 | buf_init_from_str(&lj.out_file, out_file); | |
| 958 | } else { | |
| 959 | buf_resize(&lj.out_file, 0); | |
| 960 | } | |
| 961 | 949 | |
| 962 | 950 | if (g->verbose_llvm_ir) { |
| 963 | 951 | fprintf(stderr, "\nOptimization:\n"); |
| ... | ... | @@ -966,35 +954,9 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 966 | 954 | LLVMDumpModule(g->module); |
| 967 | 955 | } |
| 968 | 956 | |
| 969 | bool override_out_file = (buf_len(&lj.out_file) != 0); | |
| 970 | if (!override_out_file) { | |
| 971 | assert(g->root_out_name); | |
| 972 | ||
| 973 | buf_init_from_buf(&lj.out_file, g->root_out_name); | |
| 974 | if (g->out_type == OutTypeExe) { | |
| 975 | buf_append_str(&lj.out_file, target_exe_file_ext(&g->zig_target)); | |
| 976 | } | |
| 977 | } | |
| 978 | ||
| 979 | if (g->out_type == OutTypeObj) { | |
| 980 | if (override_out_file) { | |
| 981 | assert(g->link_objects.length == 1); | |
| 982 | Buf *o_file_path = g->link_objects.at(0); | |
| 983 | int err; | |
| 984 | if ((err = os_rename(o_file_path, &lj.out_file))) { | |
| 985 | zig_panic("unable to rename object file %s into final output %s: %s", buf_ptr(o_file_path), buf_ptr(&lj.out_file), err_str(err)); | |
| 986 | } | |
| 987 | } | |
| 988 | return; | |
| 989 | } | |
| 990 | ||
| 991 | 957 | if (g->out_type == OutTypeLib && g->is_static) { |
| 992 | // invoke `ar` | |
| 993 | // example: | |
| 994 | // # static link into libfoo.a | |
| 995 | // ar rcs libfoo.a foo1.o foo2.o | |
| 996 | zig_panic("TODO invoke ar"); | |
| 997 | return; | |
| 958 | fprintf(stderr, "Zig does not yet support creating static libraries\nSee https://github.com/ziglang/zig/issues/1493\n"); | |
| 959 | exit(1); | |
| 998 | 960 | } |
| 999 | 961 | |
| 1000 | 962 | lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe); |
| ... | ... | @@ -1017,6 +979,4 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 1017 | 979 | fprintf(stderr, "%s\n", buf_ptr(&diag)); |
| 1018 | 980 | exit(1); |
| 1019 | 981 | } |
| 1020 | ||
| 1021 | codegen_add_time_event(g, "Done"); | |
| 1022 | 982 | } |
src/link.hpp deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | /* | |
| 2 | * Copyright (c) 2015 Andrew Kelley | |
| 3 | * | |
| 4 | * This file is part of zig, which is MIT licensed. | |
| 5 | * See http://opensource.org/licenses/MIT | |
| 6 | */ | |
| 7 | ||
| 8 | #ifndef ZIG_LINK_HPP | |
| 9 | #define ZIG_LINK_HPP | |
| 10 | ||
| 11 | #include "all_types.hpp" | |
| 12 | ||
| 13 | void codegen_link(CodeGen *g, const char *out_file); | |
| 14 | ||
| 15 | ||
| 16 | #endif | |
| 17 |
src/main.cpp+26-38| ... | ... | @@ -10,7 +10,6 @@ |
| 10 | 10 | #include "codegen.hpp" |
| 11 | 11 | #include "config.h" |
| 12 | 12 | #include "error.hpp" |
| 13 | #include "link.hpp" | |
| 14 | 13 | #include "os.hpp" |
| 15 | 14 | #include "target.hpp" |
| 16 | 15 | #include "cache_hash.hpp" |
| ... | ... | @@ -385,8 +384,7 @@ int main(int argc, char **argv) { |
| 385 | 384 | CliPkg *cur_pkg = allocate<CliPkg>(1); |
| 386 | 385 | BuildMode build_mode = BuildModeDebug; |
| 387 | 386 | ZigList<const char *> test_exec_args = {0}; |
| 388 | int comptime_args_end = 0; | |
| 389 | int runtime_args_start = argc; | |
| 387 | int runtime_args_start = -1; | |
| 390 | 388 | bool no_rosegment_workaround = false; |
| 391 | 389 | |
| 392 | 390 | if (argc >= 2 && strcmp(argv[1], "build") == 0) { |
| ... | ... | @@ -454,8 +452,6 @@ int main(int argc, char **argv) { |
| 454 | 452 | full_cache_dir = os_path_resolve(&cache_dir_buf, 1); |
| 455 | 453 | } |
| 456 | 454 | |
| 457 | Buf *path_to_build_exe = buf_alloc(); | |
| 458 | os_path_join(&full_cache_dir, buf_create_from_str("build"), path_to_build_exe); | |
| 459 | 455 | codegen_set_cache_dir(g, full_cache_dir); |
| 460 | 456 | |
| 461 | 457 | args.items[1] = buf_ptr(&build_file_dirname); |
| ... | ... | @@ -525,14 +521,13 @@ int main(int argc, char **argv) { |
| 525 | 521 | PackageTableEntry *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname), |
| 526 | 522 | buf_ptr(&build_file_basename)); |
| 527 | 523 | g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg); |
| 528 | codegen_build(g); | |
| 529 | codegen_link(g, buf_ptr(path_to_build_exe)); | |
| 524 | codegen_build_and_link(g); | |
| 530 | 525 | |
| 531 | 526 | Termination term; |
| 532 | os_spawn_process(buf_ptr(path_to_build_exe), args, &term); | |
| 527 | os_spawn_process(buf_ptr(&g->output_file_path), args, &term); | |
| 533 | 528 | if (term.how != TerminationIdClean || term.code != 0) { |
| 534 | 529 | fprintf(stderr, "\nBuild failed. The following command failed:\n"); |
| 535 | fprintf(stderr, "%s", buf_ptr(path_to_build_exe)); | |
| 530 | fprintf(stderr, "%s", buf_ptr(&g->output_file_path)); | |
| 536 | 531 | for (size_t i = 0; i < args.length; i += 1) { |
| 537 | 532 | fprintf(stderr, " %s", args.at(i)); |
| 538 | 533 | } |
| ... | ... | @@ -541,15 +536,11 @@ int main(int argc, char **argv) { |
| 541 | 536 | return (term.how == TerminationIdClean) ? term.code : -1; |
| 542 | 537 | } |
| 543 | 538 | |
| 544 | for (int i = 1; i < argc; i += 1, comptime_args_end += 1) { | |
| 539 | for (int i = 1; i < argc; i += 1) { | |
| 545 | 540 | char *arg = argv[i]; |
| 546 | 541 | |
| 547 | 542 | if (arg[0] == '-') { |
| 548 | if (strcmp(arg, "--") == 0) { | |
| 549 | // ignore -- from both compile and runtime arg sets | |
| 550 | runtime_args_start = i + 1; | |
| 551 | break; | |
| 552 | } else if (strcmp(arg, "--release-fast") == 0) { | |
| 543 | if (strcmp(arg, "--release-fast") == 0) { | |
| 553 | 544 | build_mode = BuildModeFastRelease; |
| 554 | 545 | } else if (strcmp(arg, "--release-safe") == 0) { |
| 555 | 546 | build_mode = BuildModeSafeRelease; |
| ... | ... | @@ -746,6 +737,10 @@ int main(int argc, char **argv) { |
| 746 | 737 | case CmdTest: |
| 747 | 738 | if (!in_file) { |
| 748 | 739 | in_file = arg; |
| 740 | if (cmd == CmdRun) { | |
| 741 | runtime_args_start = i + 1; | |
| 742 | break; // rest of the args are for the program | |
| 743 | } | |
| 749 | 744 | } else { |
| 750 | 745 | fprintf(stderr, "Unexpected extra parameter: %s\n", arg); |
| 751 | 746 | return usage(arg0); |
| ... | ... | @@ -856,19 +851,10 @@ int main(int argc, char **argv) { |
| 856 | 851 | Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf; |
| 857 | 852 | |
| 858 | 853 | Buf full_cache_dir = BUF_INIT; |
| 859 | Buf *run_exec_path = buf_alloc(); | |
| 860 | if (cmd == CmdRun) { | |
| 861 | if (buf_out_name == nullptr) { | |
| 862 | buf_out_name = buf_create_from_str("run"); | |
| 863 | } | |
| 864 | ||
| 865 | Buf *global_cache_dir = buf_alloc(); | |
| 866 | os_get_global_cache_directory(global_cache_dir); | |
| 867 | os_path_join(global_cache_dir, buf_out_name, run_exec_path); | |
| 868 | full_cache_dir = os_path_resolve(&global_cache_dir, 1); | |
| 869 | ||
| 870 | out_file = buf_ptr(run_exec_path); | |
| 871 | } else { | |
| 854 | if (cmd == CmdRun && buf_out_name == nullptr) { | |
| 855 | buf_out_name = buf_create_from_str("run"); | |
| 856 | } | |
| 857 | { | |
| 872 | 858 | Buf *resolve_paths = buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir); |
| 873 | 859 | full_cache_dir = os_path_resolve(&resolve_paths, 1); |
| 874 | 860 | } |
| ... | ... | @@ -957,6 +943,8 @@ int main(int argc, char **argv) { |
| 957 | 943 | codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix)); |
| 958 | 944 | } |
| 959 | 945 | |
| 946 | if (out_file) | |
| 947 | codegen_set_output_path(g, buf_create_from_str(out_file)); | |
| 960 | 948 | if (out_file_h) |
| 961 | 949 | codegen_set_output_h_path(g, buf_create_from_str(out_file_h)); |
| 962 | 950 | |
| ... | ... | @@ -976,8 +964,7 @@ int main(int argc, char **argv) { |
| 976 | 964 | if (cmd == CmdBuild || cmd == CmdRun) { |
| 977 | 965 | codegen_set_emit_file_type(g, emit_file_type); |
| 978 | 966 | |
| 979 | codegen_build(g); | |
| 980 | codegen_link(g, out_file); | |
| 967 | codegen_build_and_link(g); | |
| 981 | 968 | if (timing_info) |
| 982 | 969 | codegen_print_timing_report(g, stdout); |
| 983 | 970 | |
| ... | ... | @@ -987,8 +974,14 @@ int main(int argc, char **argv) { |
| 987 | 974 | args.append(argv[i]); |
| 988 | 975 | } |
| 989 | 976 | |
| 977 | const char *exec_path = buf_ptr(&g->output_file_path); | |
| 978 | args.append(nullptr); | |
| 979 | ||
| 980 | os_execv(exec_path, args.items); | |
| 981 | ||
| 982 | args.pop(); | |
| 990 | 983 | Termination term; |
| 991 | os_spawn_process(buf_ptr(run_exec_path), args, &term); | |
| 984 | os_spawn_process(exec_path, args, &term); | |
| 992 | 985 | return term.code; |
| 993 | 986 | } |
| 994 | 987 | |
| ... | ... | @@ -1005,11 +998,8 @@ int main(int argc, char **argv) { |
| 1005 | 998 | ZigTarget native; |
| 1006 | 999 | get_native_target(&native); |
| 1007 | 1000 | |
| 1008 | ZigTarget *non_null_target = target ? target : &native; | |
| 1009 | ||
| 1010 | Buf *test_exe_name = buf_sprintf("test%s", target_exe_file_ext(non_null_target)); | |
| 1011 | Buf *test_exe_path = buf_alloc(); | |
| 1012 | os_path_join(&full_cache_dir, test_exe_name, test_exe_path); | |
| 1001 | codegen_build_and_link(g); | |
| 1002 | Buf *test_exe_path = &g->output_file_path; | |
| 1013 | 1003 | |
| 1014 | 1004 | for (size_t i = 0; i < test_exec_args.length; i += 1) { |
| 1015 | 1005 | if (test_exec_args.items[i] == nullptr) { |
| ... | ... | @@ -1017,8 +1007,6 @@ int main(int argc, char **argv) { |
| 1017 | 1007 | } |
| 1018 | 1008 | } |
| 1019 | 1009 | |
| 1020 | codegen_build(g); | |
| 1021 | codegen_link(g, buf_ptr(test_exe_path)); | |
| 1022 | 1010 | |
| 1023 | 1011 | if (!target_can_exec(&native, target)) { |
| 1024 | 1012 | fprintf(stderr, "Created %s but skipping execution because it is non-native.\n", |
src/os.cpp+16-38| ... | ... | @@ -972,6 +972,22 @@ static int os_exec_process_windows(const char *exe, ZigList<const char *> &args, |
| 972 | 972 | } |
| 973 | 973 | #endif |
| 974 | 974 | |
| 975 | Error os_execv(const char *exe, const char **argv) { | |
| 976 | #if defined(ZIG_OS_WINDOWS) | |
| 977 | return ErrorUnsupportedOperatingSystem; | |
| 978 | #else | |
| 979 | execv(exe, (char *const *)argv); | |
| 980 | switch (errno) { | |
| 981 | case ENOMEM: | |
| 982 | return ErrorSystemResources; | |
| 983 | case EIO: | |
| 984 | return ErrorFileSystem; | |
| 985 | default: | |
| 986 | return ErrorUnexpected; | |
| 987 | } | |
| 988 | #endif | |
| 989 | } | |
| 990 | ||
| 975 | 991 | int os_exec_process(const char *exe, ZigList<const char *> &args, |
| 976 | 992 | Termination *term, Buf *out_stderr, Buf *out_stdout) |
| 977 | 993 | { |
| ... | ... | @@ -1238,44 +1254,6 @@ int os_buf_to_tmp_file(Buf *contents, Buf *suffix, Buf *out_tmp_path) { |
| 1238 | 1254 | #endif |
| 1239 | 1255 | } |
| 1240 | 1256 | |
| 1241 | #if defined(ZIG_OS_POSIX) | |
| 1242 | int os_get_global_cache_directory(Buf *out_tmp_path) { | |
| 1243 | const char *tmp_dir = getenv("TMPDIR"); | |
| 1244 | if (!tmp_dir) { | |
| 1245 | tmp_dir = P_tmpdir; | |
| 1246 | } | |
| 1247 | ||
| 1248 | Buf *tmp_dir_buf = buf_create_from_str(tmp_dir); | |
| 1249 | Buf *cache_dirname_buf = buf_create_from_str("zig-cache"); | |
| 1250 | ||
| 1251 | buf_resize(out_tmp_path, 0); | |
| 1252 | os_path_join(tmp_dir_buf, cache_dirname_buf, out_tmp_path); | |
| 1253 | ||
| 1254 | buf_deinit(tmp_dir_buf); | |
| 1255 | buf_deinit(cache_dirname_buf); | |
| 1256 | return 0; | |
| 1257 | } | |
| 1258 | #endif | |
| 1259 | ||
| 1260 | #if defined(ZIG_OS_WINDOWS) | |
| 1261 | int os_get_global_cache_directory(Buf *out_tmp_path) { | |
| 1262 | char tmp_dir[MAX_PATH + 1]; | |
| 1263 | if (GetTempPath(MAX_PATH, tmp_dir) == 0) { | |
| 1264 | zig_panic("GetTempPath failed"); | |
| 1265 | } | |
| 1266 | ||
| 1267 | Buf *tmp_dir_buf = buf_create_from_str(tmp_dir); | |
| 1268 | Buf *cache_dirname_buf = buf_create_from_str("zig-cache"); | |
| 1269 | ||
| 1270 | buf_resize(out_tmp_path, 0); | |
| 1271 | os_path_join(tmp_dir_buf, cache_dirname_buf, out_tmp_path); | |
| 1272 | ||
| 1273 | buf_deinit(tmp_dir_buf); | |
| 1274 | buf_deinit(cache_dirname_buf); | |
| 1275 | return 0; | |
| 1276 | } | |
| 1277 | #endif | |
| 1278 | ||
| 1279 | 1257 | int os_delete_file(Buf *path) { |
| 1280 | 1258 | if (remove(buf_ptr(path))) { |
| 1281 | 1259 | return ErrorFileSystem; |
src/os.hpp+1-2| ... | ... | @@ -87,6 +87,7 @@ int os_init(void); |
| 87 | 87 | void os_spawn_process(const char *exe, ZigList<const char *> &args, Termination *term); |
| 88 | 88 | int os_exec_process(const char *exe, ZigList<const char *> &args, |
| 89 | 89 | Termination *term, Buf *out_stderr, Buf *out_stdout); |
| 90 | Error os_execv(const char *exe, const char **argv); | |
| 90 | 91 | |
| 91 | 92 | void os_path_dirname(Buf *full_path, Buf *out_dirname); |
| 92 | 93 | void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename); |
| ... | ... | @@ -96,8 +97,6 @@ int os_path_real(Buf *rel_path, Buf *out_abs_path); |
| 96 | 97 | Buf os_path_resolve(Buf **paths_ptr, size_t paths_len); |
| 97 | 98 | bool os_path_is_absolute(Buf *path); |
| 98 | 99 | |
| 99 | int os_get_global_cache_directory(Buf *out_tmp_path); | |
| 100 | ||
| 101 | 100 | Error ATTRIBUTE_MUST_USE os_make_path(Buf *path); |
| 102 | 101 | Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path); |
| 103 | 102 |