authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-10 13:46:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-10 13:46:23-04:00
log32be6e9b2a9e6de501aadbe271c554a4682a10f8
treeee37daa15c6e8c2d3a3a9dafc30c060eb52ca10c
parentfbe5737c84c783cd31e6e2d595fc47eb782c5e3c
signaturelock-open Commit is signed but in an unrecognized format.

caching is working

* 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 systems

13 files changed, 418 insertions(+), 370 deletions(-)

src/all_types.hpp+128-137
...@@ -1554,6 +1554,40 @@ struct CodeGen {...@@ -1554,6 +1554,40 @@ struct CodeGen {
1554 ZigLLVMDICompileUnit *compile_unit;1554 ZigLLVMDICompileUnit *compile_unit;
1555 ZigLLVMDIFile *compile_unit_file;1555 ZigLLVMDIFile *compile_unit_file;
1556 LinkLib *libc_link_lib;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;
15571591
1558 // reminder: hash tables must be initialized before use1592 // reminder: hash tables must be initialized before use
1559 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;1593 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
...@@ -1576,8 +1610,23 @@ struct CodeGen {...@@ -1576,8 +1610,23 @@ struct CodeGen {
1576 size_t resolve_queue_index;1610 size_t resolve_queue_index;
1577 ZigList<AstNode *> use_queue;1611 ZigList<AstNode *> use_queue;
1578 size_t use_queue_index;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;
15791621
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;
15811630
1582 struct {1631 struct {
1583 ZigType *entry_bool;1632 ZigType *entry_bool;
...@@ -1613,30 +1662,45 @@ struct CodeGen {...@@ -1613,30 +1662,45 @@ struct CodeGen {
1613 ZigType *entry_arg_tuple;1662 ZigType *entry_arg_tuple;
1614 ZigType *entry_promise;1663 ZigType *entry_promise;
1615 } builtin_types;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;
16161670
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;
16181679
1619 //////////////////////////// Participates in Input Parameter Cache Hash1680 IrInstruction *invalid_instruction;
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;
16261681
1627 EmitFileType emit_file_type;1682 ConstExprValue const_void_val;
1628 BuildMode build_mode;1683 ConstExprValue panic_msg_vals[PanicMsgIdCount];
1629 OutType out_type;
16301684
1685 // The function definitions this module includes.
1686 ZigList<ZigFn *> fn_defs;
1687 size_t fn_defs_index;
1688 ZigList<TldVar *> global_vars;
16311689
1632 //////////////////////////// Unsorted1690 ZigFn *cur_fn;
1691 ZigFn *main_fn;
1692 ZigFn *panic_fn;
1693 AstNode *root_export_decl;
16331694
1634 ZigTarget zig_target;1695 CacheHash cache_hash;
1635 LLVMTargetDataRef target_data_ref;1696 ErrColor err_color;
1697 uint32_t next_unresolved_index;
1636 unsigned pointer_size_bytes;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 bool is_big_endian;1703 bool is_big_endian;
1638 bool is_static;
1639 bool strip_debug_symbols;
1640 bool want_h_file;1704 bool want_h_file;
1641 bool have_pub_main;1705 bool have_pub_main;
1642 bool have_c_main;1706 bool have_c_main;
...@@ -1644,148 +1708,75 @@ struct CodeGen {...@@ -1644,148 +1708,75 @@ struct CodeGen {
1644 bool have_winmain_crt_startup;1708 bool have_winmain_crt_startup;
1645 bool have_dllmain_crt_startup;1709 bool have_dllmain_crt_startup;
1646 bool have_pub_panic;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 bool have_err_ret_tracing;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 bool c_want_stdint;1712 bool c_want_stdint;
1696 bool c_want_stdbool;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 bool verbose_tokenize;1714 bool verbose_tokenize;
1702 bool verbose_ast;1715 bool verbose_ast;
1703 bool verbose_link;1716 bool verbose_link;
1704 bool verbose_ir;1717 bool verbose_ir;
1705 bool verbose_llvm_ir;1718 bool verbose_llvm_ir;
1706 bool verbose_cimport;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 bool error_during_imports;1720 bool error_during_imports;
1721 bool generate_error_name_table;
17351722
1736 LLVMValueRef sp_md_node;1723 //////////////////////////// Participates in Input Parameter Cache Hash
17371724 ZigList<LinkLib *> link_libs_list;
1738 const char **clang_argv;1725 // add -framework [name] args to linker
1739 size_t clang_argv_len;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 ZigList<const char *> lib_dirs;1732 ZigList<const char *> lib_dirs;
17411733
1742 const char **llvm_argv;1734 Buf *compiler_id;
1743 size_t llvm_argv_len;1735 size_t version_major;
17441736 size_t version_minor;
1745 ZigList<ZigFn *> test_fns;1737 size_t version_patch;
1746 ZigType *test_fn_type;1738 const char *linker_script;
17471739
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 bool each_lib_rpath;1752 bool each_lib_rpath;
17491753
1750 ZigType *err_tag_type;1754 Buf *mmacosx_version_min;
1751 ZigList<ZigLLVMDIEnumerator *> err_enumerators;1755 Buf *mios_version_min;
1752 ZigList<ErrorTableEntry *> errors_by_index;1756 Buf *root_out_name;
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
1769 Buf *test_filter;1757 Buf *test_filter;
1770 Buf *test_name_prefix;1758 Buf *test_name_prefix;
1759 PackageTableEntry *root_package;
17711760
1772 ZigList<TimeEvent> timing_events;1761 const char **llvm_argv;
17731762 size_t llvm_argv_len;
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;
17831763
1784 ZigList<ZigLLVMDIType **> error_di_types;1764 const char **clang_argv;
1765 size_t clang_argv_len;
17851766
1786 ZigList<Buf *> forbidden_libs;1767 //////////////////////////// Unsorted
17871768
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};
17901781
1791enum VarLinkage {1782enum VarLinkage {
src/cache_hash.cpp+61-9
...@@ -37,6 +37,20 @@ void cache_int(CacheHash *ch, int x) {...@@ -37,6 +37,20 @@ void cache_int(CacheHash *ch, int x) {
37 blake2b_update(&ch->blake, buf, sizeof(int) + 1);37 blake2b_update(&ch->blake, buf, sizeof(int) + 1);
38}38}
3939
40void 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
49void cache_bool(CacheHash *ch, bool x) {
50 assert(ch->manifest_file_path == nullptr);
51 blake2b_update(&ch->blake, &x, 1);
52}
53
40void cache_buf(CacheHash *ch, Buf *buf) {54void cache_buf(CacheHash *ch, Buf *buf) {
41 assert(ch->manifest_file_path == nullptr);55 assert(ch->manifest_file_path == nullptr);
42 assert(buf != nullptr);56 assert(buf != nullptr);
...@@ -74,6 +88,26 @@ void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len) {...@@ -74,6 +88,26 @@ void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len) {
74 cache_str(ch, "");88 cache_str(ch, "");
75}89}
7690
91void 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
101void 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
77void cache_file(CacheHash *ch, Buf *file_path) {111void cache_file(CacheHash *ch, Buf *file_path) {
78 assert(ch->manifest_file_path == nullptr);112 assert(ch->manifest_file_path == nullptr);
79 assert(file_path != nullptr);113 assert(file_path != nullptr);
...@@ -154,9 +188,13 @@ static Error base64_decode(Slice<uint8_t> dest, Slice<uint8_t> source) {...@@ -154,9 +188,13 @@ static Error base64_decode(Slice<uint8_t> dest, Slice<uint8_t> source) {
154 return ErrorNone;188 return ErrorNone;
155}189}
156190
157static Error hash_file(uint8_t *digest, OsFile handle) {191static Error hash_file(uint8_t *digest, OsFile handle, Buf *contents) {
158 Error err;192 Error err;
159193
194 if (contents) {
195 buf_resize(contents, 0);
196 }
197
160 blake2b_state blake;198 blake2b_state blake;
161 int rc = blake2b_init(&blake, 48);199 int rc = blake2b_init(&blake, 48);
162 assert(rc == 0);200 assert(rc == 0);
...@@ -172,10 +210,13 @@ static Error hash_file(uint8_t *digest, OsFile handle) {...@@ -172,10 +210,13 @@ static Error hash_file(uint8_t *digest, OsFile handle) {
172 return ErrorNone;210 return ErrorNone;
173 }211 }
174 blake2b_update(&blake, buf, amt);212 blake2b_update(&blake, buf, amt);
213 if (contents) {
214 buf_append_mem(contents, (char*)buf, amt);
215 }
175 }216 }
176}217}
177218
178static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf) {219static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf, Buf *contents) {
179 Error err;220 Error err;
180221
181 assert(chf->path != nullptr);222 assert(chf->path != nullptr);
...@@ -189,7 +230,7 @@ static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf) {...@@ -189,7 +230,7 @@ static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf) {
189 return err;230 return err;
190 }231 }
191232
192 if ((err = hash_file(chf->bin_digest, this_file))) {233 if ((err = hash_file(chf->bin_digest, this_file, contents))) {
193 os_file_close(this_file);234 os_file_close(this_file);
194 return err;235 return err;
195 }236 }
...@@ -323,7 +364,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {...@@ -323,7 +364,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
323 chf->mtime = actual_mtime;364 chf->mtime = actual_mtime;
324365
325 uint8_t actual_digest[48];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 os_file_close(this_file);368 os_file_close(this_file);
328 os_file_close(ch->manifest_file);369 os_file_close(ch->manifest_file);
329 return err;370 return err;
...@@ -344,7 +385,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {...@@ -344,7 +385,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
344 ch->manifest_dirty = true;385 ch->manifest_dirty = true;
345 for (; file_i < input_file_count; file_i += 1) {386 for (; file_i < input_file_count; file_i += 1) {
346 CacheHashFile *chf = &ch->files.at(file_i);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 os_file_close(ch->manifest_file);389 os_file_close(ch->manifest_file);
349 return err;390 return err;
350 }391 }
...@@ -355,13 +396,13 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {...@@ -355,13 +396,13 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
355 return cache_final(ch, out_digest);396 return cache_final(ch, out_digest);
356}397}
357398
358Error cache_add_file(CacheHash *ch, Buf *path) {399Error cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents) {
359 Error err;400 Error err;
360401
361 assert(ch->manifest_file_path != nullptr);402 assert(ch->manifest_file_path != nullptr);
362 CacheHashFile *chf = ch->files.add_one();403 CacheHashFile *chf = ch->files.add_one();
363 chf->path = path;404 chf->path = resolved_path;
364 if ((err = populate_file_hash(ch, chf))) {405 if ((err = populate_file_hash(ch, chf, contents))) {
365 os_file_close(ch->manifest_file);406 os_file_close(ch->manifest_file);
366 return err;407 return err;
367 }408 }
...@@ -369,6 +410,12 @@ Error cache_add_file(CacheHash *ch, Buf *path) {...@@ -369,6 +410,12 @@ Error cache_add_file(CacheHash *ch, Buf *path) {
369 return ErrorNone;410 return ErrorNone;
370}411}
371412
413Error 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
372static Error write_manifest_file(CacheHash *ch) {419static Error write_manifest_file(CacheHash *ch) {
373 Error err;420 Error err;
374 Buf contents = BUF_INIT;421 Buf contents = BUF_INIT;
...@@ -398,7 +445,8 @@ Error cache_final(CacheHash *ch, Buf *out_digest) {...@@ -398,7 +445,8 @@ Error cache_final(CacheHash *ch, Buf *out_digest) {
398 buf_ptr(ch->manifest_file_path), err_str(err));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.
402450
403 uint8_t bin_digest[48];451 uint8_t bin_digest[48];
404 int rc = blake2b_final(&ch->blake, bin_digest, 48);452 int rc = blake2b_final(&ch->blake, bin_digest, 48);
...@@ -408,3 +456,7 @@ Error cache_final(CacheHash *ch, Buf *out_digest) {...@@ -408,3 +456,7 @@ Error cache_final(CacheHash *ch, Buf *out_digest) {
408456
409 return ErrorNone;457 return ErrorNone;
410}458}
459
460void 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,6 +17,7 @@ struct CacheHashFile {
17 Buf *path;17 Buf *path;
18 OsTimeStamp mtime;18 OsTimeStamp mtime;
19 uint8_t bin_digest[48];19 uint8_t bin_digest[48];
20 Buf *contents;
20};21};
2122
22struct CacheHash {23struct CacheHash {
...@@ -34,24 +35,36 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);...@@ -34,24 +35,36 @@ void cache_init(CacheHash *ch, Buf *manifest_dir);
34// Next, use the hash population functions to add the initial parameters.35// Next, use the hash population functions to add the initial parameters.
35void cache_str(CacheHash *ch, const char *ptr);36void cache_str(CacheHash *ch, const char *ptr);
36void cache_int(CacheHash *ch, int x);37void cache_int(CacheHash *ch, int x);
38void cache_bool(CacheHash *ch, bool x);
39void cache_usize(CacheHash *ch, size_t x);
37void cache_buf(CacheHash *ch, Buf *buf);40void cache_buf(CacheHash *ch, Buf *buf);
38void cache_buf_opt(CacheHash *ch, Buf *buf);41void cache_buf_opt(CacheHash *ch, Buf *buf);
39void cache_list_of_link_lib(CacheHash *ch, LinkLib **ptr, size_t len);42void cache_list_of_link_lib(CacheHash *ch, LinkLib **ptr, size_t len);
40void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len);43void cache_list_of_buf(CacheHash *ch, Buf **ptr, size_t len);
44void cache_list_of_file(CacheHash *ch, Buf **ptr, size_t len);
45void cache_list_of_str(CacheHash *ch, const char **ptr, size_t len);
41void cache_file(CacheHash *ch, Buf *path);46void cache_file(CacheHash *ch, Buf *path);
42void cache_file_opt(CacheHash *ch, Buf *path);47void cache_file_opt(CacheHash *ch, Buf *path);
4348
44// Then call cache_hit when you're ready to see if you can skip the next step.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 miss50// 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.
46Error ATTRIBUTE_MUST_USE cache_hit(CacheHash *ch, Buf *out_b64_digest);54Error ATTRIBUTE_MUST_USE cache_hit(CacheHash *ch, Buf *out_b64_digest);
4755
48// If you got a cache hit, the flow is done. No more functions to call.56// If you did not get a cache hit, call this function for every file
49// Next call this function for every file that is depended on.57// that is depended on, and then finish with cache_final.
50Error ATTRIBUTE_MUST_USE cache_add_file(CacheHash *ch, Buf *path);58Error ATTRIBUTE_MUST_USE cache_add_file(CacheHash *ch, Buf *path);
5159
52// If you did not get a cache hit, use the hash population functions again60// This variant of cache_add_file returns the file contents.
53// and do all the actual work. When done use cache_final to save the cache61// Also the file path argument must be already resolved.
54// for next time.62Error ATTRIBUTE_MUST_USE cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents);
55Error ATTRIBUTE_MUST_USE cache_final(CacheHash *ch, Buf *out_digest);63
64// out_b64_digest will be the same thing that cache_hit returns if you got a cache hit
65Error 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.
68void cache_release(CacheHash *ch);
5669
57#endif70#endif
src/codegen.cpp+139-58
...@@ -13,7 +13,6 @@...@@ -13,7 +13,6 @@
13#include "error.hpp"13#include "error.hpp"
14#include "hash_map.hpp"14#include "hash_map.hpp"
15#include "ir.hpp"15#include "ir.hpp"
16#include "link.hpp"
17#include "os.hpp"16#include "os.hpp"
18#include "translate_c.hpp"17#include "translate_c.hpp"
19#include "target.hpp"18#include "target.hpp"
...@@ -188,6 +187,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {...@@ -188,6 +187,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) {
188 g->out_h_path = h_path;187 g->out_h_path = h_path;
189}188}
190189
190void codegen_set_output_path(CodeGen *g, Buf *path) {
191 g->wanted_output_file_path = path;
192}
193
191void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {194void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) {
192 g->clang_argv = args;195 g->clang_argv = args;
193 g->clang_argv_len = len;196 g->clang_argv_len = len;
...@@ -5756,8 +5759,6 @@ static void validate_inline_fns(CodeGen *g) {...@@ -5756,8 +5759,6 @@ static void validate_inline_fns(CodeGen *g) {
5756static void do_code_gen(CodeGen *g) {5759static void do_code_gen(CodeGen *g) {
5757 assert(!g->errors.length);5760 assert(!g->errors.length);
57585761
5759 codegen_add_time_event(g, "Code Generation");
5760
5761 {5762 {
5762 // create debug type for error sets5763 // create debug type for error sets
5763 assert(g->err_enumerators.length == g->errors_by_index.length);5764 assert(g->err_enumerators.length == g->errors_by_index.length);
...@@ -6068,38 +6069,10 @@ static void do_code_gen(CodeGen *g) {...@@ -6068,38 +6069,10 @@ static void do_code_gen(CodeGen *g) {
60686069
6069 codegen_add_time_event(g, "LLVM Emit Output");6070 codegen_add_time_event(g, "LLVM Emit Output");
60706071
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 bool is_small = g->build_mode == BuildModeSmallRelease;6072 bool is_small = g->build_mode == BuildModeSmallRelease;
61026073
6074 Buf *output_path = &g->o_file_output_path;
6075 char *err_msg = nullptr;
6103 switch (g->emit_file_type) {6076 switch (g->emit_file_type) {
6104 case EmitFileTypeBinary:6077 case EmitFileTypeBinary:
6105 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),6078 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
...@@ -6118,7 +6091,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6118,7 +6091,6 @@ static void do_code_gen(CodeGen *g) {
6118 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);6091 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);
6119 }6092 }
6120 validate_inline_fns(g);6093 validate_inline_fns(g);
6121 g->link_objects.append(output_path);
6122 break;6094 break;
61236095
6124 case EmitFileTypeLLVMIr:6096 case EmitFileTypeLLVMIr:
...@@ -6128,7 +6100,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6128,7 +6100,6 @@ static void do_code_gen(CodeGen *g) {
6128 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);6100 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);
6129 }6101 }
6130 validate_inline_fns(g);6102 validate_inline_fns(g);
6131 g->link_objects.append(output_path);
6132 break;6103 break;
61336104
6134 default:6105 default:
...@@ -7035,8 +7006,8 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package...@@ -7035,8 +7006,8 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package
7035 Buf *resolved_path = buf_alloc();7006 Buf *resolved_path = buf_alloc();
7036 *resolved_path = os_path_resolve(resolve_paths, 1);7007 *resolved_path = os_path_resolve(resolve_paths, 1);
7037 Buf *import_code = buf_alloc();7008 Buf *import_code = buf_alloc();
7038 int err;7009 Error err;
7039 if ((err = os_fetch_file_path(resolved_path, import_code, false))) {7010 if ((err = cache_add_file_fetch(&g->cache_hash, resolved_path, import_code))) {
7040 zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));7011 zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
7041 }7012 }
70427013
...@@ -7131,6 +7102,8 @@ static void gen_root_source(CodeGen *g) {...@@ -7131,6 +7102,8 @@ static void gen_root_source(CodeGen *g) {
71317102
7132 Buf *source_code = buf_alloc();7103 Buf *source_code = buf_alloc();
7133 int err;7104 int err;
7105 // No need for using the caching system for this file fetch because it is handled
7106 // separately.
7134 if ((err = os_fetch_file_path(resolved_path, source_code, true))) {7107 if ((err = os_fetch_file_path(resolved_path, source_code, true))) {
7135 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err));7108 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err));
7136 exit(1);7109 exit(1);
...@@ -7197,6 +7170,8 @@ static void gen_global_asm(CodeGen *g) {...@@ -7197,6 +7170,8 @@ static void gen_global_asm(CodeGen *g) {
7197 int err;7170 int err;
7198 for (size_t i = 0; i < g->assembly_files.length; i += 1) {7171 for (size_t i = 0; i < g->assembly_files.length; i += 1) {
7199 Buf *asm_file = g->assembly_files.at(i);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 if ((err = os_fetch_file_path(asm_file, &contents, false))) {7175 if ((err = os_fetch_file_path(asm_file, &contents, false))) {
7201 zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err));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,14 +7435,9 @@ static Buf *preprocessor_mangle(Buf *src) {
7460}7435}
74617436
7462static void gen_h_file(CodeGen *g) {7437static void gen_h_file(CodeGen *g) {
7463 if (!g->want_h_file)
7464 return;
7465
7466 GenH gen_h_data = {0};7438 GenH gen_h_data = {0};
7467 GenH *gen_h = &gen_h_data;7439 GenH *gen_h = &gen_h_data;
74687440
7469 codegen_add_time_event(g, "Generate .h");
7470
7471 assert(!g->is_test_build);7441 assert(!g->is_test_build);
74727442
7473 if (!g->out_h_path) {7443 if (!g->out_h_path) {
...@@ -7675,6 +7645,24 @@ void codegen_add_time_event(CodeGen *g, const char *name) {...@@ -7675,6 +7645,24 @@ void codegen_add_time_event(CodeGen *g, const char *name) {
7675 g->timing_events.append({os_get_time(), name});7645 g->timing_events.append({os_get_time(), name});
7676}7646}
76777647
7648static 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}
76787666
7679// Called before init()7667// Called before init()
7680static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {7668static 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,16 +7671,46 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
7683 CacheHash *ch = &g->cache_hash;7671 CacheHash *ch = &g->cache_hash;
7684 cache_init(ch, manifest_dir);7672 cache_init(ch, manifest_dir);
76857673
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 cache_buf(ch, g->compiler_id);7678 cache_buf(ch, g->compiler_id);
7687 cache_buf(ch, g->root_out_name);7679 cache_buf(ch, g->root_out_name);
7688 cache_file(ch, get_resolved_root_src_path(g)); // Root source file
7689 cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);7680 cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length);
7690 cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);7681 cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length);
7691 cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length);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 cache_int(ch, g->emit_file_type);7686 cache_int(ch, g->emit_file_type);
7693 cache_int(ch, g->build_mode);7687 cache_int(ch, g->build_mode);
7694 cache_int(ch, g->out_type);7688 cache_int(ch, g->out_type);
7695 // TODO the rest of the struct CodeGen fields7689 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);
76967714
7697 buf_resize(digest, 0);7715 buf_resize(digest, 0);
7698 if ((err = cache_hit(ch, digest)))7716 if ((err = cache_hit(ch, digest)))
...@@ -7701,10 +7719,53 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -7701,10 +7719,53 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
7701 return ErrorNone;7719 return ErrorNone;
7702}7720}
77037721
7704void codegen_build(CodeGen *g) {7722static 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
7763void codegen_build_and_link(CodeGen *g) {
7705 Error err;7764 Error err;
7706 assert(g->out_type != OutTypeUnknown);7765 assert(g->out_type != OutTypeUnknown);
77077766
7767 codegen_add_time_event(g, "Check Cache");
7768
7708 Buf app_data_dir = BUF_INIT;7769 Buf app_data_dir = BUF_INIT;
7709 if ((err = os_get_app_data_dir(&app_data_dir, "zig"))) {7770 if ((err = os_get_app_data_dir(&app_data_dir, "zig"))) {
7710 fprintf(stderr, "Unable to get app data dir: %s\n", err_str(err));7771 fprintf(stderr, "Unable to get app data dir: %s\n", err_str(err));
...@@ -7721,25 +7782,45 @@ void codegen_build(CodeGen *g) {...@@ -7721,25 +7782,45 @@ void codegen_build(CodeGen *g) {
7721 fprintf(stderr, "Unable to check cache: %s\n", err_str(err));7782 fprintf(stderr, "Unable to check cache: %s\n", err_str(err));
7722 exit(1);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 if (buf_len(&digest) != 0) {7789 if (buf_len(&digest) != 0) {
7725 Buf *artifact_dir = buf_alloc();7790 os_path_join(artifact_dir, &digest, &g->artifact_dir);
7726 os_path_join(stage1_dir, buf_create_from_str("artifact"), artifact_dir);7791 resolve_out_paths(g);
7792 } else {
7793 init(g);
77277794
7728 Buf *this_artifact_dir = buf_alloc();7795 codegen_add_time_event(g, "Semantic Analysis");
7729 os_path_join(artifact_dir, &digest, this_artifact_dir);
77307796
7731 fprintf(stderr, "copy artifacts from %s\n", buf_ptr(this_artifact_dir));7797 gen_global_asm(g);
7732 return;7798 gen_root_source(g);
7733 }
77347799
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);
77367810
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
77387822
7739 gen_global_asm(g);7823 codegen_add_time_event(g, "Done");
7740 gen_root_source(g);
7741 do_code_gen(g);
7742 gen_h_file(g);
7743}7824}
77447825
7745PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path) {7826PackageTableEntry *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,9 +48,11 @@ void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix);
48void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);48void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch);
49void codegen_set_cache_dir(CodeGen *g, Buf cache_dir);49void codegen_set_cache_dir(CodeGen *g, Buf cache_dir);
50void codegen_set_output_h_path(CodeGen *g, Buf *h_path);50void codegen_set_output_h_path(CodeGen *g, Buf *h_path);
51void codegen_set_output_path(CodeGen *g, Buf *path);
51void codegen_add_time_event(CodeGen *g, const char *name);52void codegen_add_time_event(CodeGen *g, const char *name);
52void codegen_print_timing_report(CodeGen *g, FILE *f);53void codegen_print_timing_report(CodeGen *g, FILE *f);
53void codegen_build(CodeGen *g);54void codegen_link(CodeGen *g);
55void codegen_build_and_link(CodeGen *g);
5456
55PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path);57PackageTableEntry *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path);
56void codegen_add_assembly(CodeGen *g, Buf *path);58void codegen_add_assembly(CodeGen *g, Buf *path);
src/error.cpp+1
...@@ -29,6 +29,7 @@ const char *err_str(int err) {...@@ -29,6 +29,7 @@ const char *err_str(int err) {
29 case ErrorCCompileErrors: return "C compile errors";29 case ErrorCCompileErrors: return "C compile errors";
30 case ErrorEndOfFile: return "end of file";30 case ErrorEndOfFile: return "end of file";
31 case ErrorIsDir: return "is directory";31 case ErrorIsDir: return "is directory";
32 case ErrorUnsupportedOperatingSystem: return "unsupported operating system";
32 }33 }
33 return "(invalid error)";34 return "(invalid error)";
34}35}
src/error.hpp+1
...@@ -29,6 +29,7 @@ enum Error {...@@ -29,6 +29,7 @@ enum Error {
29 ErrorCCompileErrors,29 ErrorCCompileErrors,
30 ErrorEndOfFile,30 ErrorEndOfFile,
31 ErrorIsDir,31 ErrorIsDir,
32 ErrorUnsupportedOperatingSystem,
32};33};
3334
34const char *err_str(int err);35const 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,6 +16232,8 @@ static ZigType *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUn
16232}16232}
1623316233
16234static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {16234static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {
16235 Error err;
16236
16235 IrInstruction *name_value = import_instruction->name->other;16237 IrInstruction *name_value = import_instruction->name->other;
16236 Buf *import_target_str = ir_resolve_str(ira, name_value);16238 Buf *import_target_str = ir_resolve_str(ira, name_value);
16237 if (!import_target_str)16239 if (!import_target_str)
...@@ -16275,8 +16277,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor...@@ -16275,8 +16277,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor
16275 return ira->codegen->builtin_types.entry_namespace;16277 return ira->codegen->builtin_types.entry_namespace;
16276 }16278 }
1627716279
16278 int err;16280 if ((err = cache_add_file_fetch(&ira->codegen->cache_hash, resolved_path, import_code))) {
16279 if ((err = os_fetch_file_path(resolved_path, import_code, true))) {
16280 if (err == ErrorFileNotFound) {16281 if (err == ErrorFileNotFound) {
16281 ir_add_error_node(ira, source_node,16282 ir_add_error_node(ira, source_node,
16282 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));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,6 +16288,7 @@ static ZigType *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImpor
16287 return ira->codegen->builtin_types.entry_invalid;16288 return ira->codegen->builtin_types.entry_invalid;
16288 }16289 }
16289 }16290 }
16291
16290 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code);16292 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code);
1629116293
16292 scan_import(ira->codegen, target_import);16294 scan_import(ira->codegen, target_import);
...@@ -18106,7 +18108,7 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE...@@ -18106,7 +18108,7 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE
18106 // load from file system into const expr18108 // load from file system into const expr
18107 Buf *file_contents = buf_alloc();18109 Buf *file_contents = buf_alloc();
18108 int err;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 if (err == ErrorFileNotFound) {18112 if (err == ErrorFileNotFound) {
18111 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));18113 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));
18112 return ira->codegen->builtin_types.entry_invalid;18114 return ira->codegen->builtin_types.entry_invalid;
...@@ -18116,9 +18118,6 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE...@@ -18116,9 +18118,6 @@ static ZigType *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionE
18116 }18118 }
18117 }18119 }
1811818120
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 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);18121 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
18123 init_const_str_lit(ira->codegen, out_val, file_contents);18122 init_const_str_lit(ira->codegen, out_val, file_contents);
1812418123
src/link.cpp+17-57
...@@ -5,7 +5,6 @@...@@ -5,7 +5,6 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8#include "link.hpp"
9#include "os.hpp"8#include "os.hpp"
10#include "config.h"9#include "config.h"
11#include "codegen.hpp"10#include "codegen.hpp"
...@@ -13,7 +12,6 @@...@@ -13,7 +12,6 @@
1312
14struct LinkJob {13struct LinkJob {
15 CodeGen *codegen;14 CodeGen *codegen;
16 Buf out_file;
17 ZigList<const char *> args;15 ZigList<const char *> args;
18 bool link_in_crt;16 bool link_in_crt;
19 HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;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,14 +60,8 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
62 new_link_lib->provided_explicitly = link_lib->provided_explicitly;60 new_link_lib->provided_explicitly = link_lib->provided_explicitly;
63 }61 }
6462
65 codegen_build(child_gen);63 codegen_build_and_link(child_gen);
66 const char *o_ext = target_o_file_ext(&child_gen->zig_target);64 return &child_gen->output_file_path;
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;
73}65}
7466
75static Buf *build_o(CodeGen *parent_gen, const char *oname) {67static Buf *build_o(CodeGen *parent_gen, const char *oname) {
...@@ -237,15 +229,15 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -237,15 +229,15 @@ static void construct_linker_job_elf(LinkJob *lj) {
237 } else if (shared) {229 } else if (shared) {
238 lj->args.append("-shared");230 lj->args.append("-shared");
239231
240 if (buf_len(&lj->out_file) == 0) {232 if (buf_len(&g->output_file_path) == 0) {
241 buf_appendf(&lj->out_file, "lib%s.so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize "",233 buf_appendf(&g->output_file_path, "lib%s.so.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize "",
242 buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);234 buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
243 }235 }
244 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major);236 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize "", buf_ptr(g->root_out_name), g->version_major);
245 }237 }
246238
247 lj->args.append("-o");239 lj->args.append("-o");
248 lj->args.append(buf_ptr(&lj->out_file));240 lj->args.append(buf_ptr(&g->output_file_path));
249241
250 if (lj->link_in_crt) {242 if (lj->link_in_crt) {
251 const char *crt1o;243 const char *crt1o;
...@@ -397,7 +389,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -397,7 +389,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
397389
398 lj->args.append("--relocatable"); // So lld doesn't look for _start.390 lj->args.append("--relocatable"); // So lld doesn't look for _start.
399 lj->args.append("-o");391 lj->args.append("-o");
400 lj->args.append(buf_ptr(&lj->out_file));392 lj->args.append(buf_ptr(&g->output_file_path));
401393
402 // .o files394 // .o files
403 for (size_t i = 0; i < g->link_objects.length; i += 1) {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,7 +470,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
478 // }470 // }
479 //}471 //}
480472
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))));
482474
483 if (g->libc_link_lib != nullptr) {475 if (g->libc_link_lib != nullptr) {
484 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(g->msvc_lib_dir))));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,11 +577,11 @@ static void construct_linker_job_coff(LinkJob *lj) {
585 buf_appendf(def_contents, "\n");577 buf_appendf(def_contents, "\n");
586578
587 Buf *def_path = buf_alloc();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 os_write_file(def_path, def_contents);581 os_write_file(def_path, def_contents);
590582
591 Buf *generated_lib_path = buf_alloc();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);
593585
594 gen_lib_args.resize(0);586 gen_lib_args.resize(0);
595 gen_lib_args.append("link");587 gen_lib_args.append("link");
...@@ -797,8 +789,8 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -797,8 +789,8 @@ static void construct_linker_job_macho(LinkJob *lj) {
797 //lj->args.append("-install_name");789 //lj->args.append("-install_name");
798 //lj->args.append(buf_ptr(dylib_install_name));790 //lj->args.append(buf_ptr(dylib_install_name));
799791
800 if (buf_len(&lj->out_file) == 0) {792 if (buf_len(&g->output_file_path) == 0) {
801 buf_appendf(&lj->out_file, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",793 buf_appendf(&g->output_file_path, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
802 buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);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,13 +824,13 @@ static void construct_linker_job_macho(LinkJob *lj) {
832 }824 }
833825
834 lj->args.append("-o");826 lj->args.append("-o");
835 lj->args.append(buf_ptr(&lj->out_file));827 lj->args.append(buf_ptr(&g->output_file_path));
836828
837 for (size_t i = 0; i < g->rpath_list.length; i += 1) {829 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
838 Buf *rpath = g->rpath_list.at(i);830 Buf *rpath = g->rpath_list.at(i);
839 add_rpath(lj, rpath);831 add_rpath(lj, rpath);
840 }832 }
841 add_rpath(lj, &lj->out_file);833 add_rpath(lj, &g->output_file_path);
842834
843 if (shared) {835 if (shared) {
844 lj->args.append("-headerpad_max_install_names");836 lj->args.append("-headerpad_max_install_names");
...@@ -942,7 +934,8 @@ static void construct_linker_job(LinkJob *lj) {...@@ -942,7 +934,8 @@ static void construct_linker_job(LinkJob *lj) {
942 }934 }
943}935}
944936
945void codegen_link(CodeGen *g, const char *out_file) {937void codegen_link(CodeGen *g) {
938 assert(g->out_type != OutTypeObj);
946 codegen_add_time_event(g, "Build Dependencies");939 codegen_add_time_event(g, "Build Dependencies");
947940
948 LinkJob lj = {0};941 LinkJob lj = {0};
...@@ -953,11 +946,6 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -953,11 +946,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
953946
954 lj.rpath_table.init(4);947 lj.rpath_table.init(4);
955 lj.codegen = g;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 }
961949
962 if (g->verbose_llvm_ir) {950 if (g->verbose_llvm_ir) {
963 fprintf(stderr, "\nOptimization:\n");951 fprintf(stderr, "\nOptimization:\n");
...@@ -966,35 +954,9 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -966,35 +954,9 @@ void codegen_link(CodeGen *g, const char *out_file) {
966 LLVMDumpModule(g->module);954 LLVMDumpModule(g->module);
967 }955 }
968956
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 if (g->out_type == OutTypeLib && g->is_static) {957 if (g->out_type == OutTypeLib && g->is_static) {
992 // invoke `ar`958 fprintf(stderr, "Zig does not yet support creating static libraries\nSee https://github.com/ziglang/zig/issues/1493\n");
993 // example:959 exit(1);
994 // # static link into libfoo.a
995 // ar rcs libfoo.a foo1.o foo2.o
996 zig_panic("TODO invoke ar");
997 return;
998 }960 }
999961
1000 lj.link_in_crt = (g->libc_link_lib != nullptr && g->out_type == OutTypeExe);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,6 +979,4 @@ void codegen_link(CodeGen *g, const char *out_file) {
1017 fprintf(stderr, "%s\n", buf_ptr(&diag));979 fprintf(stderr, "%s\n", buf_ptr(&diag));
1018 exit(1);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
13void codegen_link(CodeGen *g, const char *out_file);
14
15
16#endif
17
src/main.cpp+26-38
...@@ -10,7 +10,6 @@...@@ -10,7 +10,6 @@
10#include "codegen.hpp"10#include "codegen.hpp"
11#include "config.h"11#include "config.h"
12#include "error.hpp"12#include "error.hpp"
13#include "link.hpp"
14#include "os.hpp"13#include "os.hpp"
15#include "target.hpp"14#include "target.hpp"
16#include "cache_hash.hpp"15#include "cache_hash.hpp"
...@@ -385,8 +384,7 @@ int main(int argc, char **argv) {...@@ -385,8 +384,7 @@ int main(int argc, char **argv) {
385 CliPkg *cur_pkg = allocate<CliPkg>(1);384 CliPkg *cur_pkg = allocate<CliPkg>(1);
386 BuildMode build_mode = BuildModeDebug;385 BuildMode build_mode = BuildModeDebug;
387 ZigList<const char *> test_exec_args = {0};386 ZigList<const char *> test_exec_args = {0};
388 int comptime_args_end = 0;387 int runtime_args_start = -1;
389 int runtime_args_start = argc;
390 bool no_rosegment_workaround = false;388 bool no_rosegment_workaround = false;
391389
392 if (argc >= 2 && strcmp(argv[1], "build") == 0) {390 if (argc >= 2 && strcmp(argv[1], "build") == 0) {
...@@ -454,8 +452,6 @@ int main(int argc, char **argv) {...@@ -454,8 +452,6 @@ int main(int argc, char **argv) {
454 full_cache_dir = os_path_resolve(&cache_dir_buf, 1);452 full_cache_dir = os_path_resolve(&cache_dir_buf, 1);
455 }453 }
456454
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 codegen_set_cache_dir(g, full_cache_dir);455 codegen_set_cache_dir(g, full_cache_dir);
460456
461 args.items[1] = buf_ptr(&build_file_dirname);457 args.items[1] = buf_ptr(&build_file_dirname);
...@@ -525,14 +521,13 @@ int main(int argc, char **argv) {...@@ -525,14 +521,13 @@ int main(int argc, char **argv) {
525 PackageTableEntry *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname),521 PackageTableEntry *build_pkg = codegen_create_package(g, buf_ptr(&build_file_dirname),
526 buf_ptr(&build_file_basename));522 buf_ptr(&build_file_basename));
527 g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);523 g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
528 codegen_build(g);524 codegen_build_and_link(g);
529 codegen_link(g, buf_ptr(path_to_build_exe));
530525
531 Termination term;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 if (term.how != TerminationIdClean || term.code != 0) {528 if (term.how != TerminationIdClean || term.code != 0) {
534 fprintf(stderr, "\nBuild failed. The following command failed:\n");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 for (size_t i = 0; i < args.length; i += 1) {531 for (size_t i = 0; i < args.length; i += 1) {
537 fprintf(stderr, " %s", args.at(i));532 fprintf(stderr, " %s", args.at(i));
538 }533 }
...@@ -541,15 +536,11 @@ int main(int argc, char **argv) {...@@ -541,15 +536,11 @@ int main(int argc, char **argv) {
541 return (term.how == TerminationIdClean) ? term.code : -1;536 return (term.how == TerminationIdClean) ? term.code : -1;
542 }537 }
543538
544 for (int i = 1; i < argc; i += 1, comptime_args_end += 1) {539 for (int i = 1; i < argc; i += 1) {
545 char *arg = argv[i];540 char *arg = argv[i];
546541
547 if (arg[0] == '-') {542 if (arg[0] == '-') {
548 if (strcmp(arg, "--") == 0) {543 if (strcmp(arg, "--release-fast") == 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) {
553 build_mode = BuildModeFastRelease;544 build_mode = BuildModeFastRelease;
554 } else if (strcmp(arg, "--release-safe") == 0) {545 } else if (strcmp(arg, "--release-safe") == 0) {
555 build_mode = BuildModeSafeRelease;546 build_mode = BuildModeSafeRelease;
...@@ -746,6 +737,10 @@ int main(int argc, char **argv) {...@@ -746,6 +737,10 @@ int main(int argc, char **argv) {
746 case CmdTest:737 case CmdTest:
747 if (!in_file) {738 if (!in_file) {
748 in_file = arg;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 } else {744 } else {
750 fprintf(stderr, "Unexpected extra parameter: %s\n", arg);745 fprintf(stderr, "Unexpected extra parameter: %s\n", arg);
751 return usage(arg0);746 return usage(arg0);
...@@ -856,19 +851,10 @@ int main(int argc, char **argv) {...@@ -856,19 +851,10 @@ int main(int argc, char **argv) {
856 Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;851 Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;
857852
858 Buf full_cache_dir = BUF_INIT;853 Buf full_cache_dir = BUF_INIT;
859 Buf *run_exec_path = buf_alloc();854 if (cmd == CmdRun && buf_out_name == nullptr) {
860 if (cmd == CmdRun) {855 buf_out_name = buf_create_from_str("run");
861 if (buf_out_name == nullptr) {856 }
862 buf_out_name = buf_create_from_str("run");857 {
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 {
872 Buf *resolve_paths = buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir);858 Buf *resolve_paths = buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir);
873 full_cache_dir = os_path_resolve(&resolve_paths, 1);859 full_cache_dir = os_path_resolve(&resolve_paths, 1);
874 }860 }
...@@ -957,6 +943,8 @@ int main(int argc, char **argv) {...@@ -957,6 +943,8 @@ int main(int argc, char **argv) {
957 codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));943 codegen_set_test_name_prefix(g, buf_create_from_str(test_name_prefix));
958 }944 }
959945
946 if (out_file)
947 codegen_set_output_path(g, buf_create_from_str(out_file));
960 if (out_file_h)948 if (out_file_h)
961 codegen_set_output_h_path(g, buf_create_from_str(out_file_h));949 codegen_set_output_h_path(g, buf_create_from_str(out_file_h));
962950
...@@ -976,8 +964,7 @@ int main(int argc, char **argv) {...@@ -976,8 +964,7 @@ int main(int argc, char **argv) {
976 if (cmd == CmdBuild || cmd == CmdRun) {964 if (cmd == CmdBuild || cmd == CmdRun) {
977 codegen_set_emit_file_type(g, emit_file_type);965 codegen_set_emit_file_type(g, emit_file_type);
978966
979 codegen_build(g);967 codegen_build_and_link(g);
980 codegen_link(g, out_file);
981 if (timing_info)968 if (timing_info)
982 codegen_print_timing_report(g, stdout);969 codegen_print_timing_report(g, stdout);
983970
...@@ -987,8 +974,14 @@ int main(int argc, char **argv) {...@@ -987,8 +974,14 @@ int main(int argc, char **argv) {
987 args.append(argv[i]);974 args.append(argv[i]);
988 }975 }
989976
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 Termination term;983 Termination term;
991 os_spawn_process(buf_ptr(run_exec_path), args, &term);984 os_spawn_process(exec_path, args, &term);
992 return term.code;985 return term.code;
993 }986 }
994987
...@@ -1005,11 +998,8 @@ int main(int argc, char **argv) {...@@ -1005,11 +998,8 @@ int main(int argc, char **argv) {
1005 ZigTarget native;998 ZigTarget native;
1006 get_native_target(&native);999 get_native_target(&native);
10071000
1008 ZigTarget *non_null_target = target ? target : &native;1001 codegen_build_and_link(g);
10091002 Buf *test_exe_path = &g->output_file_path;
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);
10131003
1014 for (size_t i = 0; i < test_exec_args.length; i += 1) {1004 for (size_t i = 0; i < test_exec_args.length; i += 1) {
1015 if (test_exec_args.items[i] == nullptr) {1005 if (test_exec_args.items[i] == nullptr) {
...@@ -1017,8 +1007,6 @@ int main(int argc, char **argv) {...@@ -1017,8 +1007,6 @@ int main(int argc, char **argv) {
1017 }1007 }
1018 }1008 }
10191009
1020 codegen_build(g);
1021 codegen_link(g, buf_ptr(test_exe_path));
10221010
1023 if (!target_can_exec(&native, target)) {1011 if (!target_can_exec(&native, target)) {
1024 fprintf(stderr, "Created %s but skipping execution because it is non-native.\n",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,6 +972,22 @@ static int os_exec_process_windows(const char *exe, ZigList<const char *> &args,
972}972}
973#endif973#endif
974974
975Error 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
975int os_exec_process(const char *exe, ZigList<const char *> &args,991int os_exec_process(const char *exe, ZigList<const char *> &args,
976 Termination *term, Buf *out_stderr, Buf *out_stdout)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,44 +1254,6 @@ int os_buf_to_tmp_file(Buf *contents, Buf *suffix, Buf *out_tmp_path) {
1238#endif1254#endif
1239}1255}
12401256
1241#if defined(ZIG_OS_POSIX)
1242int 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)
1261int 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
1279int os_delete_file(Buf *path) {1257int os_delete_file(Buf *path) {
1280 if (remove(buf_ptr(path))) {1258 if (remove(buf_ptr(path))) {
1281 return ErrorFileSystem;1259 return ErrorFileSystem;
src/os.hpp+1-2
...@@ -87,6 +87,7 @@ int os_init(void);...@@ -87,6 +87,7 @@ int os_init(void);
87void os_spawn_process(const char *exe, ZigList<const char *> &args, Termination *term);87void os_spawn_process(const char *exe, ZigList<const char *> &args, Termination *term);
88int os_exec_process(const char *exe, ZigList<const char *> &args,88int os_exec_process(const char *exe, ZigList<const char *> &args,
89 Termination *term, Buf *out_stderr, Buf *out_stdout);89 Termination *term, Buf *out_stderr, Buf *out_stdout);
90Error os_execv(const char *exe, const char **argv);
9091
91void os_path_dirname(Buf *full_path, Buf *out_dirname);92void os_path_dirname(Buf *full_path, Buf *out_dirname);
92void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename);93void 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,8 +97,6 @@ int os_path_real(Buf *rel_path, Buf *out_abs_path);
96Buf os_path_resolve(Buf **paths_ptr, size_t paths_len);97Buf os_path_resolve(Buf **paths_ptr, size_t paths_len);
97bool os_path_is_absolute(Buf *path);98bool os_path_is_absolute(Buf *path);
9899
99int os_get_global_cache_directory(Buf *out_tmp_path);
100
101Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);100Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
102Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);101Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
103102