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.
master
Andrew Kelley 2020-02-16 21:10:03 -05:00
parent 5c54d7bee7
commit a26800c099
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
4 changed files with 147 additions and 48 deletions

View File

@ -565,12 +565,12 @@ set_target_properties(opt_c_util PROPERTIES
COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
)
add_library(compiler STATIC ${ZIG_SOURCES})
set_target_properties(compiler PROPERTIES
add_library(zigcompiler STATIC ${ZIG_SOURCES})
set_target_properties(zigcompiler PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
target_link_libraries(compiler LINK_PUBLIC
target_link_libraries(zigcompiler LINK_PUBLIC
zig_cpp
opt_c_util
${SOFTFLOAT_LIBRARIES}
@ -580,15 +580,15 @@ target_link_libraries(compiler LINK_PUBLIC
${CMAKE_THREAD_LIBS_INIT}
)
if(NOT MSVC)
target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
endif()
if(ZIG_DIA_GUIDS_LIB)
target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
endif()
if(MSVC OR MINGW)
target_link_libraries(compiler LINK_PUBLIC version)
target_link_libraries(zigcompiler LINK_PUBLIC version)
endif()
add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
@ -596,12 +596,12 @@ set_target_properties(zig0 PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
target_link_libraries(zig0 compiler)
target_link_libraries(zig0 zigcompiler)
if(MSVC)
set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/stage2.lib")
set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib")
else()
set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libstage2.a")
set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a")
endif()
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
set(LIBSTAGE2_RELEASE_ARG "")
@ -615,11 +615,12 @@ else()
endif()
set(BUILD_LIBSTAGE2_ARGS "build-lib"
"src-self-hosted/stage2.zig"
--name zigstage2
--override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
--cache on
--output-dir "${CMAKE_BINARY_DIR}"
${LIBSTAGE2_RELEASE_ARG}
"src-self-hosted/stage2.zig"
--disable-gen-h
--bundle-compiler-rt
-fPIC
@ -639,7 +640,7 @@ set_target_properties(zig PROPERTIES
COMPILE_FLAGS ${EXE_CFLAGS}
LINK_FLAGS ${EXE_LDFLAGS}
)
target_link_libraries(zig compiler "${LIBSTAGE2}")
target_link_libraries(zig zigcompiler "${LIBSTAGE2}")
if(MSVC)
target_link_libraries(zig ntdll.lib)
elseif(MINGW)

View File

@ -1309,7 +1309,7 @@ static int main0(int argc, char **argv) {
Buf *dest_path = buf_alloc();
os_path_join(final_output_dir_step, dest_basename, dest_path);
if ((err = os_copy_file(&g->output_file_path, dest_path))) {
if ((err = os_update_file(&g->output_file_path, dest_path))) {
fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path),
buf_ptr(dest_path), err_str(err));
return main_exit(root_progress_node, EXIT_FAILURE);

View File

@ -1029,6 +1029,110 @@ Error os_write_file(Buf *full_path, Buf *contents) {
return ErrorNone;
}
static Error copy_open_files(FILE *src_f, FILE *dest_f) {
static const size_t buf_size = 2048;
char buf[buf_size];
for (;;) {
size_t amt_read = fread(buf, 1, buf_size, src_f);
if (amt_read != buf_size) {
if (ferror(src_f)) {
return ErrorFileSystem;
}
}
size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
if (amt_written != amt_read) {
return ErrorFileSystem;
}
if (feof(src_f)) {
return ErrorNone;
}
}
}
#if defined(ZIG_OS_WINDOWS)
static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
mtime->nsec = 0;
}
static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
FILETIME result;
result.dwHighDateTime = mtime.sec >> 32;
result.dwLowDateTime = mtime.sec;
return result;
}
#endif
static Error set_file_times(OsFile file, OsTimeStamp ts) {
#if defined(ZIG_OS_WINDOWS)
const atime_ft = windows.nanoSecondsToFileTime(atime);
const mtime_ft = windows.nanoSecondsToFileTime(mtime);
return SetFileTime(file, null, &atime_ft, &mtime_ft);
#else
struct timespec times[2] = {
{ ts.sec, ts.nsec },
{ ts.sec, ts.nsec },
};
if (futimens(file, times) == -1) {
switch (errno) {
case EBADF:
zig_panic("futimens EBADF");
default:
return ErrorUnexpected;
}
}
return ErrorNone;
#endif
}
Error os_update_file(Buf *src_path, Buf *dst_path) {
Error err;
OsFile src_file;
OsFileAttr src_attr;
if ((err = os_file_open_r(src_path, &src_file, &src_attr))) {
return err;
}
OsFile dst_file;
OsFileAttr dst_attr;
if ((err = os_file_open_w(dst_path, &dst_file, &dst_attr, src_attr.mode))) {
os_file_close(&src_file);
return err;
}
if (src_attr.mtime.sec == dst_attr.mtime.sec &&
src_attr.mtime.nsec == dst_attr.mtime.nsec &&
src_attr.mode == dst_attr.mode)
{
os_file_close(&src_file);
os_file_close(&dst_file);
return ErrorNone;
}
FILE *src_libc_file = fdopen(src_file, "rb");
FILE *dst_libc_file = fdopen(dst_file, "wb");
assert(src_libc_file);
assert(dst_libc_file);
if (ftruncate(dst_file, 0) == -1) {
return ErrorUnexpected;
}
if ((err = copy_open_files(src_libc_file, dst_libc_file))) {
fclose(src_libc_file);
fclose(dst_libc_file);
return err;
}
if (fflush(src_libc_file) == -1) {
return ErrorUnexpected;
}
if (fflush(dst_libc_file) == -1) {
return ErrorUnexpected;
}
err = set_file_times(dst_file, src_attr.mtime);
fclose(src_libc_file);
fclose(dst_libc_file);
return err;
}
Error os_copy_file(Buf *src_path, Buf *dest_path) {
FILE *src_f = fopen(buf_ptr(src_path), "rb");
if (!src_f) {
@ -1055,30 +1159,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
return ErrorFileSystem;
}
}
static const size_t buf_size = 2048;
char buf[buf_size];
for (;;) {
size_t amt_read = fread(buf, 1, buf_size, src_f);
if (amt_read != buf_size) {
if (ferror(src_f)) {
fclose(src_f);
fclose(dest_f);
return ErrorFileSystem;
}
}
size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
if (amt_written != amt_read) {
fclose(src_f);
fclose(dest_f);
return ErrorFileSystem;
}
if (feof(src_f)) {
fclose(src_f);
fclose(dest_f);
return ErrorNone;
}
}
Error err = copy_open_files(src_f, dest_f);
fclose(src_f);
fclose(dest_f);
return err;
}
Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
@ -1218,13 +1302,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {
return ErrorNone;
}
#if defined(ZIG_OS_WINDOWS)
static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
mtime->nsec = 0;
}
#endif
OsTimeStamp os_timestamp_calendar(void) {
OsTimeStamp result;
#if defined(ZIG_OS_WINDOWS)
@ -1733,10 +1810,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
#endif
}
Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) {
#if defined(ZIG_OS_WINDOWS)
// TODO use CreateFileW
HANDLE result = CreateFileA(buf_ptr(full_path), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
HANDLE result = CreateFileA(buf_ptr(full_path),
need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
need_write ? 0 : FILE_SHARE_READ,
nullptr,
need_write ? OPEN_ALWAYS : OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, nullptr);
if (result == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
@ -1769,12 +1851,14 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
}
windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);
attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
attr->mode = 0;
}
return ErrorNone;
#else
for (;;) {
int fd = open(buf_ptr(full_path), O_RDONLY|O_CLOEXEC);
int fd = open(buf_ptr(full_path),
need_write ? (O_RDWR|O_CLOEXEC|O_CREAT) : (O_RDONLY|O_CLOEXEC), mode);
if (fd == -1) {
switch (errno) {
case EINTR:
@ -1784,6 +1868,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
case EFAULT:
zig_unreachable();
case EACCES:
case EPERM:
return ErrorAccess;
case EISDIR:
return ErrorIsDir;
@ -1813,12 +1898,21 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
attr->mtime.sec = statbuf.st_mtim.tv_sec;
attr->mtime.nsec = statbuf.st_mtim.tv_nsec;
#endif
attr->mode = statbuf.st_mode;
}
return ErrorNone;
}
#endif
}
Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
return os_file_open_rw(full_path, out_file, attr, false, 0);
}
Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode) {
return os_file_open_rw(full_path, out_file, attr, true, mode);
}
Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
#if defined(ZIG_OS_WINDOWS)
for (;;) {
@ -1864,6 +1958,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
case EFAULT:
zig_unreachable();
case EACCES:
case EPERM:
return ErrorAccess;
case EISDIR:
return ErrorIsDir;

View File

@ -93,13 +93,14 @@ struct Termination {
#endif
struct OsTimeStamp {
uint64_t sec;
uint64_t nsec;
int64_t sec;
int64_t nsec;
};
struct OsFileAttr {
OsTimeStamp mtime;
uint64_t inode;
uint32_t mode;
};
int os_init(void);
@ -121,6 +122,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);
Error ATTRIBUTE_MUST_USE os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode);
Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
@ -129,6 +131,7 @@ void os_file_close(OsFile *file);
Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
Error ATTRIBUTE_MUST_USE os_update_file(Buf *src_path, Buf *dest_path);
Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);