authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-16 21:10:03-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-16 21:10:03-05:00
loga26800c0992b123b1ef16712ec1e56fb62b0caf9
tree5e5e1ed32b65f332dca05e8300d820ab5e3a44ed
parent5c54d7bee7ca4d7d7948e2549fd67b61e2dcaf17
signaturelock-open Commit is signed but in an unrecognized format.

stage1: don't copy unchanged output files

when both `--cache on` and `--output-dir` parameters are provided. This prevents re-linking `zig` with every `make` even when `libzigstage2.a` was unchanged.

4 files changed, 147 insertions(+), 48 deletions(-)

CMakeLists.txt+12-11
......@@ -565,12 +565,12 @@ set_target_properties(opt_c_util PROPERTIES
565565 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
566566)
567567
568add_library(compiler STATIC ${ZIG_SOURCES})
569set_target_properties(compiler PROPERTIES
568add_library(zigcompiler STATIC ${ZIG_SOURCES})
569set_target_properties(zigcompiler PROPERTIES
570570 COMPILE_FLAGS ${EXE_CFLAGS}
571571 LINK_FLAGS ${EXE_LDFLAGS}
572572)
573target_link_libraries(compiler LINK_PUBLIC
573target_link_libraries(zigcompiler LINK_PUBLIC
574574 zig_cpp
575575 opt_c_util
576576 ${SOFTFLOAT_LIBRARIES}
......@@ -580,15 +580,15 @@ target_link_libraries(compiler LINK_PUBLIC
580580 ${CMAKE_THREAD_LIBS_INIT}
581581)
582582if(NOT MSVC)
583 target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
583 target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
584584endif()
585585
586586if(ZIG_DIA_GUIDS_LIB)
587 target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
587 target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
588588endif()
589589
590590if(MSVC OR MINGW)
591 target_link_libraries(compiler LINK_PUBLIC version)
591 target_link_libraries(zigcompiler LINK_PUBLIC version)
592592endif()
593593
594594add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
......@@ -596,12 +596,12 @@ set_target_properties(zig0 PROPERTIES
596596 COMPILE_FLAGS ${EXE_CFLAGS}
597597 LINK_FLAGS ${EXE_LDFLAGS}
598598)
599target_link_libraries(zig0 compiler)
599target_link_libraries(zig0 zigcompiler)
600600
601601if(MSVC)
602 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/stage2.lib")
602 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib")
603603else()
604 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libstage2.a")
604 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a")
605605endif()
606606if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
607607 set(LIBSTAGE2_RELEASE_ARG "")
......@@ -615,11 +615,12 @@ else()
615615endif()
616616
617617set(BUILD_LIBSTAGE2_ARGS "build-lib"
618 "src-self-hosted/stage2.zig"
619 --name zigstage2
618620 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
619621 --cache on
620622 --output-dir "${CMAKE_BINARY_DIR}"
621623 ${LIBSTAGE2_RELEASE_ARG}
622 "src-self-hosted/stage2.zig"
623624 --disable-gen-h
624625 --bundle-compiler-rt
625626 -fPIC
......@@ -639,7 +640,7 @@ set_target_properties(zig PROPERTIES
639640 COMPILE_FLAGS ${EXE_CFLAGS}
640641 LINK_FLAGS ${EXE_LDFLAGS}
641642)
642target_link_libraries(zig compiler "${LIBSTAGE2}")
643target_link_libraries(zig zigcompiler "${LIBSTAGE2}")
643644if(MSVC)
644645 target_link_libraries(zig ntdll.lib)
645646elseif(MINGW)
src/main.cpp+1-1
......@@ -1309,7 +1309,7 @@ static int main0(int argc, char **argv) {
13091309 Buf *dest_path = buf_alloc();
13101310 os_path_join(final_output_dir_step, dest_basename, dest_path);
13111311
1312 if ((err = os_copy_file(&g->output_file_path, dest_path))) {
1312 if ((err = os_update_file(&g->output_file_path, dest_path))) {
13131313 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path),
13141314 buf_ptr(dest_path), err_str(err));
13151315 return main_exit(root_progress_node, EXIT_FAILURE);
src/os.cpp+129-34
......@@ -1029,6 +1029,110 @@ Error os_write_file(Buf *full_path, Buf *contents) {
10291029 return ErrorNone;
10301030}
10311031
1032static Error copy_open_files(FILE *src_f, FILE *dest_f) {
1033 static const size_t buf_size = 2048;
1034 char buf[buf_size];
1035 for (;;) {
1036 size_t amt_read = fread(buf, 1, buf_size, src_f);
1037 if (amt_read != buf_size) {
1038 if (ferror(src_f)) {
1039 return ErrorFileSystem;
1040 }
1041 }
1042 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1043 if (amt_written != amt_read) {
1044 return ErrorFileSystem;
1045 }
1046 if (feof(src_f)) {
1047 return ErrorNone;
1048 }
1049 }
1050}
1051
1052#if defined(ZIG_OS_WINDOWS)
1053static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1054 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1055 mtime->nsec = 0;
1056}
1057static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
1058 FILETIME result;
1059 result.dwHighDateTime = mtime.sec >> 32;
1060 result.dwLowDateTime = mtime.sec;
1061 return result;
1062}
1063#endif
1064
1065static Error set_file_times(OsFile file, OsTimeStamp ts) {
1066#if defined(ZIG_OS_WINDOWS)
1067 const atime_ft = windows.nanoSecondsToFileTime(atime);
1068 const mtime_ft = windows.nanoSecondsToFileTime(mtime);
1069 return SetFileTime(file, null, &atime_ft, &mtime_ft);
1070#else
1071 struct timespec times[2] = {
1072 { ts.sec, ts.nsec },
1073 { ts.sec, ts.nsec },
1074 };
1075 if (futimens(file, times) == -1) {
1076 switch (errno) {
1077 case EBADF:
1078 zig_panic("futimens EBADF");
1079 default:
1080 return ErrorUnexpected;
1081 }
1082 }
1083 return ErrorNone;
1084#endif
1085}
1086
1087Error os_update_file(Buf *src_path, Buf *dst_path) {
1088 Error err;
1089
1090 OsFile src_file;
1091 OsFileAttr src_attr;
1092 if ((err = os_file_open_r(src_path, &src_file, &src_attr))) {
1093 return err;
1094 }
1095
1096 OsFile dst_file;
1097 OsFileAttr dst_attr;
1098 if ((err = os_file_open_w(dst_path, &dst_file, &dst_attr, src_attr.mode))) {
1099 os_file_close(&src_file);
1100 return err;
1101 }
1102
1103 if (src_attr.mtime.sec == dst_attr.mtime.sec &&
1104 src_attr.mtime.nsec == dst_attr.mtime.nsec &&
1105 src_attr.mode == dst_attr.mode)
1106 {
1107 os_file_close(&src_file);
1108 os_file_close(&dst_file);
1109 return ErrorNone;
1110 }
1111
1112 FILE *src_libc_file = fdopen(src_file, "rb");
1113 FILE *dst_libc_file = fdopen(dst_file, "wb");
1114 assert(src_libc_file);
1115 assert(dst_libc_file);
1116 if (ftruncate(dst_file, 0) == -1) {
1117 return ErrorUnexpected;
1118 }
1119 if ((err = copy_open_files(src_libc_file, dst_libc_file))) {
1120 fclose(src_libc_file);
1121 fclose(dst_libc_file);
1122 return err;
1123 }
1124 if (fflush(src_libc_file) == -1) {
1125 return ErrorUnexpected;
1126 }
1127 if (fflush(dst_libc_file) == -1) {
1128 return ErrorUnexpected;
1129 }
1130 err = set_file_times(dst_file, src_attr.mtime);
1131 fclose(src_libc_file);
1132 fclose(dst_libc_file);
1133 return err;
1134}
1135
10321136Error os_copy_file(Buf *src_path, Buf *dest_path) {
10331137 FILE *src_f = fopen(buf_ptr(src_path), "rb");
10341138 if (!src_f) {
......@@ -1055,30 +1159,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
10551159 return ErrorFileSystem;
10561160 }
10571161 }
1058
1059 static const size_t buf_size = 2048;
1060 char buf[buf_size];
1061 for (;;) {
1062 size_t amt_read = fread(buf, 1, buf_size, src_f);
1063 if (amt_read != buf_size) {
1064 if (ferror(src_f)) {
1065 fclose(src_f);
1066 fclose(dest_f);
1067 return ErrorFileSystem;
1068 }
1069 }
1070 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1071 if (amt_written != amt_read) {
1072 fclose(src_f);
1073 fclose(dest_f);
1074 return ErrorFileSystem;
1075 }
1076 if (feof(src_f)) {
1077 fclose(src_f);
1078 fclose(dest_f);
1079 return ErrorNone;
1080 }
1081 }
1162 Error err = copy_open_files(src_f, dest_f);
1163 fclose(src_f);
1164 fclose(dest_f);
1165 return err;
10821166}
10831167
10841168Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
......@@ -1218,13 +1302,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {
12181302 return ErrorNone;
12191303}
12201304
1221#if defined(ZIG_OS_WINDOWS)
1222static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1223 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1224 mtime->nsec = 0;
1225}
1226#endif
1227
12281305OsTimeStamp os_timestamp_calendar(void) {
12291306 OsTimeStamp result;
12301307#if defined(ZIG_OS_WINDOWS)
......@@ -1733,10 +1810,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
17331810#endif
17341811}
17351812
1736Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1813Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) {
17371814#if defined(ZIG_OS_WINDOWS)
17381815 // TODO use CreateFileW
1739 HANDLE result = CreateFileA(buf_ptr(full_path), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
1816 HANDLE result = CreateFileA(buf_ptr(full_path),
1817 need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
1818 need_write ? 0 : FILE_SHARE_READ,
1819 nullptr,
1820 need_write ? OPEN_ALWAYS : OPEN_EXISTING,
1821 FILE_ATTRIBUTE_NORMAL, nullptr);
17401822
17411823 if (result == INVALID_HANDLE_VALUE) {
17421824 DWORD err = GetLastError();
......@@ -1769,12 +1851,14 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
17691851 }
17701852 windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);
17711853 attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
1854 attr->mode = 0;
17721855 }
17731856
17741857 return ErrorNone;
17751858#else
17761859 for (;;) {
1777 int fd = open(buf_ptr(full_path), O_RDONLY|O_CLOEXEC);
1860 int fd = open(buf_ptr(full_path),
1861 need_write ? (O_RDWR|O_CLOEXEC|O_CREAT) : (O_RDONLY|O_CLOEXEC), mode);
17781862 if (fd == -1) {
17791863 switch (errno) {
17801864 case EINTR:
......@@ -1784,6 +1868,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
17841868 case EFAULT:
17851869 zig_unreachable();
17861870 case EACCES:
1871 case EPERM:
17871872 return ErrorAccess;
17881873 case EISDIR:
17891874 return ErrorIsDir;
......@@ -1813,12 +1898,21 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
18131898 attr->mtime.sec = statbuf.st_mtim.tv_sec;
18141899 attr->mtime.nsec = statbuf.st_mtim.tv_nsec;
18151900#endif
1901 attr->mode = statbuf.st_mode;
18161902 }
18171903 return ErrorNone;
18181904 }
18191905#endif
18201906}
18211907
1908Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1909 return os_file_open_rw(full_path, out_file, attr, false, 0);
1910}
1911
1912Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode) {
1913 return os_file_open_rw(full_path, out_file, attr, true, mode);
1914}
1915
18221916Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
18231917#if defined(ZIG_OS_WINDOWS)
18241918 for (;;) {
......@@ -1864,6 +1958,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
18641958 case EFAULT:
18651959 zig_unreachable();
18661960 case EACCES:
1961 case EPERM:
18671962 return ErrorAccess;
18681963 case EISDIR:
18691964 return ErrorIsDir;
src/os.hpp+5-2
......@@ -93,13 +93,14 @@ struct Termination {
9393#endif
9494
9595struct OsTimeStamp {
96 uint64_t sec;
97 uint64_t nsec;
96 int64_t sec;
97 int64_t nsec;
9898};
9999
100100struct OsFileAttr {
101101 OsTimeStamp mtime;
102102 uint64_t inode;
103 uint32_t mode;
103104};
104105
105106int os_init(void);
......@@ -121,6 +122,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
121122Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
122123
123124Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);
125Error ATTRIBUTE_MUST_USE os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode);
124126Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
125127Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
126128Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
......@@ -129,6 +131,7 @@ void os_file_close(OsFile *file);
129131
130132Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
131133Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
134Error ATTRIBUTE_MUST_USE os_update_file(Buf *src_path, Buf *dest_path);
132135
133136Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
134137Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);