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
parent
5c54d7bee7
commit
a26800c099
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
163
src/os.cpp
163
src/os.cpp
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue