diff --git a/05/musl-0.6.0/arch/x86_64/bits/alltypes.h b/05/musl-0.6.0/arch/x86_64/bits/alltypes.h deleted file mode 100644 index f07dc5c..0000000 --- a/05/musl-0.6.0/arch/x86_64/bits/alltypes.h +++ /dev/null @@ -1,468 +0,0 @@ - -#include - -#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) -typedef unsigned long size_t; -#define __DEFINED_size_t -#endif - -#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) -typedef long ssize_t; -#define __DEFINED_ssize_t -#endif - -#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) -typedef long ptrdiff_t; -#define __DEFINED_ptrdiff_t -#endif - -#if 0 -#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) -typedef __builtin_va_list va_list; -#define __DEFINED_va_list -#endif - -#endif - -#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) -typedef int wchar_t; -#define __DEFINED_wchar_t -#endif - -#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) -typedef int wint_t; -#define __DEFINED_wint_t -#endif - -#if defined(__NEED_wctrans_t) && !defined(__DEFINED_wctrans_t) -typedef int wctrans_t; -#define __DEFINED_wctrans_t -#endif - -#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) -typedef int wctype_t; -#define __DEFINED_wctype_t -#endif - - -#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) -typedef char int8_t; -#define __DEFINED_int8_t -#endif - -#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) -typedef short int16_t; -#define __DEFINED_int16_t -#endif - -#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) -typedef int int32_t; -#define __DEFINED_int32_t -#endif - -#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) -typedef long int64_t; -#define __DEFINED_int64_t -#endif - - -#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) -typedef unsigned char uint8_t; -#define __DEFINED_uint8_t -#endif - -#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) -typedef unsigned short uint16_t; -#define __DEFINED_uint16_t -#endif - -#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) -typedef unsigned int uint32_t; -#define __DEFINED_uint32_t -#endif - -#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) -typedef unsigned long uint64_t; -#define __DEFINED_uint64_t -#endif - - -#if defined(__NEED___uint8_t) && !defined(__DEFINED___uint8_t) -typedef unsigned char __uint8_t; -#define __DEFINED___uint8_t -#endif - -#if defined(__NEED___uint16_t) && !defined(__DEFINED___uint16_t) -typedef unsigned short __uint16_t; -#define __DEFINED___uint16_t -#endif - -#if defined(__NEED___uint32_t) && !defined(__DEFINED___uint32_t) -typedef unsigned int __uint32_t; -#define __DEFINED___uint32_t -#endif - -#if defined(__NEED___uint64_t) && !defined(__DEFINED___uint64_t) -typedef unsigned long __uint64_t; -#define __DEFINED___uint64_t -#endif - - -#if defined(__NEED_int_least8_t) && !defined(__DEFINED_int_least8_t) -typedef int8_t int_least8_t; -#define __DEFINED_int_least8_t -#endif - -#if defined(__NEED_int_least16_t) && !defined(__DEFINED_int_least16_t) -typedef int16_t int_least16_t; -#define __DEFINED_int_least16_t -#endif - -#if defined(__NEED_int_least32_t) && !defined(__DEFINED_int_least32_t) -typedef int32_t int_least32_t; -#define __DEFINED_int_least32_t -#endif - -#if defined(__NEED_int_least64_t) && !defined(__DEFINED_int_least64_t) -typedef int64_t int_least64_t; -#define __DEFINED_int_least64_t -#endif - - -#if defined(__NEED_uint_least8_t) && !defined(__DEFINED_uint_least8_t) -typedef uint8_t uint_least8_t; -#define __DEFINED_uint_least8_t -#endif - -#if defined(__NEED_uint_least16_t) && !defined(__DEFINED_uint_least16_t) -typedef uint16_t uint_least16_t; -#define __DEFINED_uint_least16_t -#endif - -#if defined(__NEED_uint_least32_t) && !defined(__DEFINED_uint_least32_t) -typedef uint32_t uint_least32_t; -#define __DEFINED_uint_least32_t -#endif - -#if defined(__NEED_uint_least64_t) && !defined(__DEFINED_uint_least64_t) -typedef uint64_t uint_least64_t; -#define __DEFINED_uint_least64_t -#endif - - -#if defined(__NEED_int_fast8_t) && !defined(__DEFINED_int_fast8_t) -typedef int8_t int_fast8_t; -#define __DEFINED_int_fast8_t -#endif - -#if defined(__NEED_int_fast16_t) && !defined(__DEFINED_int_fast16_t) -typedef int int_fast16_t; -#define __DEFINED_int_fast16_t -#endif - -#if defined(__NEED_int_fast32_t) && !defined(__DEFINED_int_fast32_t) -typedef int int_fast32_t; -#define __DEFINED_int_fast32_t -#endif - -#if defined(__NEED_int_fast64_t) && !defined(__DEFINED_int_fast64_t) -typedef int64_t int_fast64_t; -#define __DEFINED_int_fast64_t -#endif - - -#if defined(__NEED_uint_fast8_t) && !defined(__DEFINED_uint_fast8_t) -typedef unsigned char uint_fast8_t; -#define __DEFINED_uint_fast8_t -#endif - -#if defined(__NEED_uint_fast16_t) && !defined(__DEFINED_uint_fast16_t) -typedef unsigned int uint_fast16_t; -#define __DEFINED_uint_fast16_t -#endif - -#if defined(__NEED_uint_fast32_t) && !defined(__DEFINED_uint_fast32_t) -typedef unsigned int uint_fast32_t; -#define __DEFINED_uint_fast32_t -#endif - -#if defined(__NEED_uint_fast64_t) && !defined(__DEFINED_uint_fast64_t) -typedef uint64_t uint_fast64_t; -#define __DEFINED_uint_fast64_t -#endif - - -#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) -typedef long intptr_t; -#define __DEFINED_intptr_t -#endif - -#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) -typedef unsigned long uintptr_t; -#define __DEFINED_uintptr_t -#endif - - -#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) -typedef long long intmax_t; -#define __DEFINED_intmax_t -#endif - -#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) -typedef unsigned long long uintmax_t; -#define __DEFINED_uintmax_t -#endif - - -#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) -typedef long time_t; -#define __DEFINED_time_t -#endif - -#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) -typedef long useconds_t; -#define __DEFINED_useconds_t -#endif - -#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef long suseconds_t; -#define __DEFINED_suseconds_t -#endif - -#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) -struct timeval { time_t tv_sec; int tv_usec; }; -#define __DEFINED_struct_timeval -#endif - -#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) -struct timespec { time_t tv_sec; unsigned long tv_nsec; }; -#define __DEFINED_struct_timespec -#endif - - -#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) -typedef int pid_t; -#define __DEFINED_pid_t -#endif - -#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) -typedef int id_t; -#define __DEFINED_id_t -#endif - -#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) -typedef unsigned int uid_t; -#define __DEFINED_uid_t -#endif - -#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) -typedef unsigned int gid_t; -#define __DEFINED_gid_t -#endif - -#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) -typedef int key_t; -#define __DEFINED_key_t -#endif - - -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef struct __pthread * pthread_t; -#define __DEFINED_pthread_t -#endif - -#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) -typedef int pthread_once_t; -#define __DEFINED_pthread_once_t -#endif - -#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) -typedef int pthread_key_t; -#define __DEFINED_pthread_key_t -#endif - -#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) -typedef int pthread_spinlock_t; -#define __DEFINED_pthread_spinlock_t -#endif - - -#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[14]; size_t __s[2]; } __u; } pthread_attr_t; -#define __DEFINED_pthread_attr_t -#endif - -#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) -typedef unsigned pthread_mutexattr_t; -#define __DEFINED_pthread_mutexattr_t -#endif - -#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) -typedef unsigned pthread_condattr_t; -#define __DEFINED_pthread_condattr_t -#endif - -#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) -typedef unsigned pthread_barrierattr_t; -#define __DEFINED_pthread_barrierattr_t -#endif - -#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) -typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; -#define __DEFINED_pthread_rwlockattr_t -#endif - - -#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) -typedef struct { union { int __i[10]; void *__p[1]; } __u; } pthread_mutex_t; -#define __DEFINED_pthread_mutex_t -#endif - -#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) -typedef struct { union { int __i[12]; void *__p[1]; } __u; } pthread_cond_t; -#define __DEFINED_pthread_cond_t -#endif - -#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) -typedef struct { union { int __i[14]; void *__p[1]; } __u; } pthread_rwlock_t; -#define __DEFINED_pthread_rwlock_t -#endif - -#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) -typedef struct { union { int __i[8]; void *__p[1]; } __u; } pthread_barrier_t; -#define __DEFINED_pthread_barrier_t -#endif - - -#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) -typedef long off_t; -#define __DEFINED_off_t -#endif - - -#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) -typedef unsigned int mode_t; -#define __DEFINED_mode_t -#endif - - -#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) -typedef unsigned long nlink_t; -#define __DEFINED_nlink_t -#endif - -#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) -typedef unsigned long long ino_t; -#define __DEFINED_ino_t -#endif - -#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned long dev_t; -#define __DEFINED_dev_t -#endif - -#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef long blksize_t; -#define __DEFINED_blksize_t -#endif - -#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef long long blkcnt_t; -#define __DEFINED_blkcnt_t -#endif - -#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) -typedef unsigned long long fsblkcnt_t; -#define __DEFINED_fsblkcnt_t -#endif - -#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) -typedef unsigned long long fsfilcnt_t; -#define __DEFINED_fsfilcnt_t -#endif - - -#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) -typedef void * timer_t; -#define __DEFINED_timer_t -#endif - -#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) -typedef int clockid_t; -#define __DEFINED_clockid_t -#endif - -#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) -typedef long clock_t; -#define __DEFINED_clock_t -#endif - - -#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) -typedef struct { unsigned long __bits[128/sizeof(long)]; } sigset_t; -#define __DEFINED_sigset_t -#endif - -#if 1 -#if defined(__NEED_siginfo_t) && !defined(__DEFINED_siginfo_t) -typedef struct __siginfo siginfo_t; -#define __DEFINED_siginfo_t -#endif - -#else -#if defined(__NEED_siginfo_t) && !defined(__DEFINED_siginfo_t) -#define siginfo_t struct __siginfo -#define __DEFINED_siginfo_t -#endif -#endif - -#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) -typedef unsigned int socklen_t; -#define __DEFINED_socklen_t -#endif - -#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) -typedef unsigned short sa_family_t; -#define __DEFINED_sa_family_t -#endif - -#if defined(__NEED_in_port_t) && !defined(__DEFINED_in_port_t) -typedef unsigned short in_port_t; -#define __DEFINED_in_port_t -#endif - -#if defined(__NEED_in_addr_t) && !defined(__DEFINED_in_addr_t) -typedef unsigned int in_addr_t; -#define __DEFINED_in_addr_t -#endif - -#if defined(__NEED_struct_in_addr) && !defined(__DEFINED_struct_in_addr) -struct in_addr { in_addr_t s_addr; }; -#define __DEFINED_struct_in_addr -#endif - - -#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) -typedef struct __FILE_s FILE; -#define __DEFINED_FILE -#endif - - -#if defined(__NEED_nl_item) && !defined(__DEFINED_nl_item) -typedef int nl_item; -#define __DEFINED_nl_item -#endif - - -#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) -typedef struct __locale * locale_t; -#define __DEFINED_locale_t -#endif - - -#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) -struct iovec { void *iov_base; size_t iov_len; }; -#define __DEFINED_struct_iovec -#endif - - diff --git a/05/musl-0.6.0/include/bits b/05/musl-0.6.0/include/bits deleted file mode 120000 index ed2f0a7..0000000 --- a/05/musl-0.6.0/include/bits +++ /dev/null @@ -1 +0,0 @@ -../arch/x86_64/bits \ No newline at end of file diff --git a/05/musl-final/arch/x86_64/bits/alltypes.h b/05/musl-final/arch/x86_64/bits/alltypes.h deleted file mode 100644 index f07dc5c..0000000 --- a/05/musl-final/arch/x86_64/bits/alltypes.h +++ /dev/null @@ -1,468 +0,0 @@ - -#include - -#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) -typedef unsigned long size_t; -#define __DEFINED_size_t -#endif - -#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) -typedef long ssize_t; -#define __DEFINED_ssize_t -#endif - -#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) -typedef long ptrdiff_t; -#define __DEFINED_ptrdiff_t -#endif - -#if 0 -#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) -typedef __builtin_va_list va_list; -#define __DEFINED_va_list -#endif - -#endif - -#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) -typedef int wchar_t; -#define __DEFINED_wchar_t -#endif - -#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) -typedef int wint_t; -#define __DEFINED_wint_t -#endif - -#if defined(__NEED_wctrans_t) && !defined(__DEFINED_wctrans_t) -typedef int wctrans_t; -#define __DEFINED_wctrans_t -#endif - -#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) -typedef int wctype_t; -#define __DEFINED_wctype_t -#endif - - -#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) -typedef char int8_t; -#define __DEFINED_int8_t -#endif - -#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) -typedef short int16_t; -#define __DEFINED_int16_t -#endif - -#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) -typedef int int32_t; -#define __DEFINED_int32_t -#endif - -#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) -typedef long int64_t; -#define __DEFINED_int64_t -#endif - - -#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) -typedef unsigned char uint8_t; -#define __DEFINED_uint8_t -#endif - -#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) -typedef unsigned short uint16_t; -#define __DEFINED_uint16_t -#endif - -#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) -typedef unsigned int uint32_t; -#define __DEFINED_uint32_t -#endif - -#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) -typedef unsigned long uint64_t; -#define __DEFINED_uint64_t -#endif - - -#if defined(__NEED___uint8_t) && !defined(__DEFINED___uint8_t) -typedef unsigned char __uint8_t; -#define __DEFINED___uint8_t -#endif - -#if defined(__NEED___uint16_t) && !defined(__DEFINED___uint16_t) -typedef unsigned short __uint16_t; -#define __DEFINED___uint16_t -#endif - -#if defined(__NEED___uint32_t) && !defined(__DEFINED___uint32_t) -typedef unsigned int __uint32_t; -#define __DEFINED___uint32_t -#endif - -#if defined(__NEED___uint64_t) && !defined(__DEFINED___uint64_t) -typedef unsigned long __uint64_t; -#define __DEFINED___uint64_t -#endif - - -#if defined(__NEED_int_least8_t) && !defined(__DEFINED_int_least8_t) -typedef int8_t int_least8_t; -#define __DEFINED_int_least8_t -#endif - -#if defined(__NEED_int_least16_t) && !defined(__DEFINED_int_least16_t) -typedef int16_t int_least16_t; -#define __DEFINED_int_least16_t -#endif - -#if defined(__NEED_int_least32_t) && !defined(__DEFINED_int_least32_t) -typedef int32_t int_least32_t; -#define __DEFINED_int_least32_t -#endif - -#if defined(__NEED_int_least64_t) && !defined(__DEFINED_int_least64_t) -typedef int64_t int_least64_t; -#define __DEFINED_int_least64_t -#endif - - -#if defined(__NEED_uint_least8_t) && !defined(__DEFINED_uint_least8_t) -typedef uint8_t uint_least8_t; -#define __DEFINED_uint_least8_t -#endif - -#if defined(__NEED_uint_least16_t) && !defined(__DEFINED_uint_least16_t) -typedef uint16_t uint_least16_t; -#define __DEFINED_uint_least16_t -#endif - -#if defined(__NEED_uint_least32_t) && !defined(__DEFINED_uint_least32_t) -typedef uint32_t uint_least32_t; -#define __DEFINED_uint_least32_t -#endif - -#if defined(__NEED_uint_least64_t) && !defined(__DEFINED_uint_least64_t) -typedef uint64_t uint_least64_t; -#define __DEFINED_uint_least64_t -#endif - - -#if defined(__NEED_int_fast8_t) && !defined(__DEFINED_int_fast8_t) -typedef int8_t int_fast8_t; -#define __DEFINED_int_fast8_t -#endif - -#if defined(__NEED_int_fast16_t) && !defined(__DEFINED_int_fast16_t) -typedef int int_fast16_t; -#define __DEFINED_int_fast16_t -#endif - -#if defined(__NEED_int_fast32_t) && !defined(__DEFINED_int_fast32_t) -typedef int int_fast32_t; -#define __DEFINED_int_fast32_t -#endif - -#if defined(__NEED_int_fast64_t) && !defined(__DEFINED_int_fast64_t) -typedef int64_t int_fast64_t; -#define __DEFINED_int_fast64_t -#endif - - -#if defined(__NEED_uint_fast8_t) && !defined(__DEFINED_uint_fast8_t) -typedef unsigned char uint_fast8_t; -#define __DEFINED_uint_fast8_t -#endif - -#if defined(__NEED_uint_fast16_t) && !defined(__DEFINED_uint_fast16_t) -typedef unsigned int uint_fast16_t; -#define __DEFINED_uint_fast16_t -#endif - -#if defined(__NEED_uint_fast32_t) && !defined(__DEFINED_uint_fast32_t) -typedef unsigned int uint_fast32_t; -#define __DEFINED_uint_fast32_t -#endif - -#if defined(__NEED_uint_fast64_t) && !defined(__DEFINED_uint_fast64_t) -typedef uint64_t uint_fast64_t; -#define __DEFINED_uint_fast64_t -#endif - - -#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) -typedef long intptr_t; -#define __DEFINED_intptr_t -#endif - -#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) -typedef unsigned long uintptr_t; -#define __DEFINED_uintptr_t -#endif - - -#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) -typedef long long intmax_t; -#define __DEFINED_intmax_t -#endif - -#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) -typedef unsigned long long uintmax_t; -#define __DEFINED_uintmax_t -#endif - - -#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) -typedef long time_t; -#define __DEFINED_time_t -#endif - -#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) -typedef long useconds_t; -#define __DEFINED_useconds_t -#endif - -#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) -typedef long suseconds_t; -#define __DEFINED_suseconds_t -#endif - -#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) -struct timeval { time_t tv_sec; int tv_usec; }; -#define __DEFINED_struct_timeval -#endif - -#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) -struct timespec { time_t tv_sec; unsigned long tv_nsec; }; -#define __DEFINED_struct_timespec -#endif - - -#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) -typedef int pid_t; -#define __DEFINED_pid_t -#endif - -#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) -typedef int id_t; -#define __DEFINED_id_t -#endif - -#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) -typedef unsigned int uid_t; -#define __DEFINED_uid_t -#endif - -#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) -typedef unsigned int gid_t; -#define __DEFINED_gid_t -#endif - -#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) -typedef int key_t; -#define __DEFINED_key_t -#endif - - -#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) -typedef struct __pthread * pthread_t; -#define __DEFINED_pthread_t -#endif - -#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) -typedef int pthread_once_t; -#define __DEFINED_pthread_once_t -#endif - -#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) -typedef int pthread_key_t; -#define __DEFINED_pthread_key_t -#endif - -#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) -typedef int pthread_spinlock_t; -#define __DEFINED_pthread_spinlock_t -#endif - - -#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) -typedef struct { union { int __i[14]; size_t __s[2]; } __u; } pthread_attr_t; -#define __DEFINED_pthread_attr_t -#endif - -#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) -typedef unsigned pthread_mutexattr_t; -#define __DEFINED_pthread_mutexattr_t -#endif - -#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) -typedef unsigned pthread_condattr_t; -#define __DEFINED_pthread_condattr_t -#endif - -#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) -typedef unsigned pthread_barrierattr_t; -#define __DEFINED_pthread_barrierattr_t -#endif - -#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) -typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; -#define __DEFINED_pthread_rwlockattr_t -#endif - - -#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) -typedef struct { union { int __i[10]; void *__p[1]; } __u; } pthread_mutex_t; -#define __DEFINED_pthread_mutex_t -#endif - -#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) -typedef struct { union { int __i[12]; void *__p[1]; } __u; } pthread_cond_t; -#define __DEFINED_pthread_cond_t -#endif - -#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) -typedef struct { union { int __i[14]; void *__p[1]; } __u; } pthread_rwlock_t; -#define __DEFINED_pthread_rwlock_t -#endif - -#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) -typedef struct { union { int __i[8]; void *__p[1]; } __u; } pthread_barrier_t; -#define __DEFINED_pthread_barrier_t -#endif - - -#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) -typedef long off_t; -#define __DEFINED_off_t -#endif - - -#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) -typedef unsigned int mode_t; -#define __DEFINED_mode_t -#endif - - -#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) -typedef unsigned long nlink_t; -#define __DEFINED_nlink_t -#endif - -#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) -typedef unsigned long long ino_t; -#define __DEFINED_ino_t -#endif - -#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) -typedef unsigned long dev_t; -#define __DEFINED_dev_t -#endif - -#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) -typedef long blksize_t; -#define __DEFINED_blksize_t -#endif - -#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) -typedef long long blkcnt_t; -#define __DEFINED_blkcnt_t -#endif - -#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) -typedef unsigned long long fsblkcnt_t; -#define __DEFINED_fsblkcnt_t -#endif - -#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) -typedef unsigned long long fsfilcnt_t; -#define __DEFINED_fsfilcnt_t -#endif - - -#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) -typedef void * timer_t; -#define __DEFINED_timer_t -#endif - -#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) -typedef int clockid_t; -#define __DEFINED_clockid_t -#endif - -#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) -typedef long clock_t; -#define __DEFINED_clock_t -#endif - - -#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) -typedef struct { unsigned long __bits[128/sizeof(long)]; } sigset_t; -#define __DEFINED_sigset_t -#endif - -#if 1 -#if defined(__NEED_siginfo_t) && !defined(__DEFINED_siginfo_t) -typedef struct __siginfo siginfo_t; -#define __DEFINED_siginfo_t -#endif - -#else -#if defined(__NEED_siginfo_t) && !defined(__DEFINED_siginfo_t) -#define siginfo_t struct __siginfo -#define __DEFINED_siginfo_t -#endif -#endif - -#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) -typedef unsigned int socklen_t; -#define __DEFINED_socklen_t -#endif - -#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) -typedef unsigned short sa_family_t; -#define __DEFINED_sa_family_t -#endif - -#if defined(__NEED_in_port_t) && !defined(__DEFINED_in_port_t) -typedef unsigned short in_port_t; -#define __DEFINED_in_port_t -#endif - -#if defined(__NEED_in_addr_t) && !defined(__DEFINED_in_addr_t) -typedef unsigned int in_addr_t; -#define __DEFINED_in_addr_t -#endif - -#if defined(__NEED_struct_in_addr) && !defined(__DEFINED_struct_in_addr) -struct in_addr { in_addr_t s_addr; }; -#define __DEFINED_struct_in_addr -#endif - - -#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) -typedef struct __FILE_s FILE; -#define __DEFINED_FILE -#endif - - -#if defined(__NEED_nl_item) && !defined(__DEFINED_nl_item) -typedef int nl_item; -#define __DEFINED_nl_item -#endif - - -#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) -typedef struct __locale * locale_t; -#define __DEFINED_locale_t -#endif - - -#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) -struct iovec { void *iov_base; size_t iov_len; }; -#define __DEFINED_struct_iovec -#endif - - diff --git a/05/musl-final/include/bits b/05/musl-final/include/bits deleted file mode 120000 index ed2f0a7..0000000 --- a/05/musl-final/include/bits +++ /dev/null @@ -1 +0,0 @@ -../arch/x86_64/bits \ No newline at end of file diff --git a/06 b/06 deleted file mode 160000 index d2f9454..0000000 --- a/06 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d2f9454b34fef570cfb32cf5b17d85a90dba81bf diff --git a/06/.github/workflows/is-tested-enough.yml b/06/.github/workflows/is-tested-enough.yml new file mode 100644 index 0000000..6f53f32 --- /dev/null +++ b/06/.github/workflows/is-tested-enough.yml @@ -0,0 +1,16 @@ +name: "git notes Built-on: checks" +on: + push: + branches: + - main + - staging + pull_request: + branches: + - main + - staging +jobs: + is-tested-enough: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: helpers/maint/is-tested-enough diff --git a/06/.github/workflows/release-checks.yml b/06/.github/workflows/release-checks.yml new file mode 100644 index 0000000..7ad21b2 --- /dev/null +++ b/06/.github/workflows/release-checks.yml @@ -0,0 +1,19 @@ +name: "release checks" +on: + push: + branches: + - main + - staging + pull_request: + branches: + - main + - staging +jobs: + release-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v23 + with: + extra_nix_config: "experimental-features = flakes nix-command ca-derivations" + - run: helpers/maint/release # checks hashes in 0.nix + some more diff --git a/06/.github/workflows/stage1.yml b/06/.github/workflows/stage1.yml new file mode 100644 index 0000000..40146f2 --- /dev/null +++ b/06/.github/workflows/stage1.yml @@ -0,0 +1,77 @@ +name: "build stage1" +on: + push: + branches: + - main + - staging + pull_request: + branches: + - main + - staging +jobs: + stage1-nix-plain: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v23 + with: + extra_nix_config: "experimental-features = flakes nix-command ca-derivations" + - run: nix build -L '.#protosrc' + - run: nix build -L '.#tcc-seed' + - run: nix build -L '.#stage1^*' + - name: trim verification list + run: | + head -n3 verify.nix > verify.nix.tmp + mv verify.nix.tmp verify.nix + grep -F stage1^protomusl verify.nix + grep -F stage1^protobusybox verify.nix + grep -F stage1^tinycc verify.nix + - run: make verify-nix-plain-checksums + + stage1-make-ubuntu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v23 + with: + extra_nix_config: "experimental-features = flakes nix-command ca-derivations" + # run: sudo apt -y install make wget zstd # are installed by default + - run: make tcc-seed # using nix + - run: make pkgs/1-stage1.pkg TAR=$(nix build 'nixpkgs#gnutar' --no-link --print-out-paths)/bin/tar # tar <1.35 had different hashes + - name: trim verification list + run: | + head -n2 verify.pkgs.sha256 > verify.pkgs.sha256.tmp + mv verify.pkgs.sha256.tmp verify.pkgs.sha256 + grep 0-tcc-seed verify.pkgs.sha256 + grep 1-stage1 verify.pkgs.sha256 + - run: make verify-pkgs-checksums + + stage1-make-alpine: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: jirutka/setup-alpine@v1 + with: + branch: edge + packages: tar make wget zstd bash coreutils gcc build-base + - run: git clone https://repo.or.cz/tinycc.git tinycc + - run: cd tinycc && git checkout af1abf1f45d45b34f0b02437f559f4dfdba7d23c + - run: cd tinycc && ./configure --config-musl --enable-static --extra-ldflags=-static && make -j $(nproc) + shell: alpine.sh --root {0} + - run: cp tinycc/tcc tcc-seed + shell: alpine.sh --root {0} + - run: | + sed -i 's|unshare -nr||' Makefile + sed -i 's|unshare -nrm|unshare -rm|' helpers/chroot + shell: alpine.sh --root {0} + - run: make pkgs/1-stage1.pkg + shell: alpine.sh --root {0} + - name: trim verification list + run: | + head -n2 verify.pkgs.sha256 > verify.pkgs.sha256.tmp + mv verify.pkgs.sha256.tmp verify.pkgs.sha256 + grep 0-tcc-seed verify.pkgs.sha256 + grep 1-stage1 verify.pkgs.sha256 + shell: alpine.sh --root {0} + - run: make verify-pkgs-checksums # warning: CUSTOM tcc is expected + shell: alpine.sh --root {0} diff --git a/06/.gitignore b/06/.gitignore new file mode 100644 index 0000000..a7d9664 --- /dev/null +++ b/06/.gitignore @@ -0,0 +1,20 @@ +tcc-seed + +/stage +/tmp +/downloads + +/log +/log.tmp +/result* +/scratch +/pkgs +/trees +/nix-checksums-stage4 +/nix-checksums-stage5 +/nix-checksums-stage5-custom + +/ZilchOS-core.iso +/ZilchOS-core-raw.iso + +/TODO diff --git a/06/.oldgit/HEAD b/06/.oldgit/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/06/.oldgit/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/06/.oldgit/ORIG_HEAD b/06/.oldgit/ORIG_HEAD new file mode 100644 index 0000000..2f59c5e --- /dev/null +++ b/06/.oldgit/ORIG_HEAD @@ -0,0 +1 @@ +d2f9454b34fef570cfb32cf5b17d85a90dba81bf diff --git a/06/.oldgit/config b/06/.oldgit/config new file mode 100644 index 0000000..1bc5cd8 --- /dev/null +++ b/06/.oldgit/config @@ -0,0 +1,11 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = git@github.com:Dawid33/bootstrap-from-tcc.git + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "main"] + remote = origin + merge = refs/heads/main diff --git a/06/.oldgit/description b/06/.oldgit/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/06/.oldgit/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/06/.oldgit/hooks/applypatch-msg.sample b/06/.oldgit/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/06/.oldgit/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/06/.oldgit/hooks/commit-msg.sample b/06/.oldgit/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/06/.oldgit/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/06/.oldgit/hooks/fsmonitor-watchman.sample b/06/.oldgit/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..14ed0aa --- /dev/null +++ b/06/.oldgit/hooks/fsmonitor-watchman.sample @@ -0,0 +1,173 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + } + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $last_update_token, + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/06/.oldgit/hooks/post-update.sample b/06/.oldgit/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/06/.oldgit/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/06/.oldgit/hooks/pre-applypatch.sample b/06/.oldgit/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/06/.oldgit/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/06/.oldgit/hooks/pre-commit.sample b/06/.oldgit/hooks/pre-commit.sample new file mode 100755 index 0000000..e144712 --- /dev/null +++ b/06/.oldgit/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/06/.oldgit/hooks/pre-merge-commit.sample b/06/.oldgit/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/06/.oldgit/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/06/.oldgit/hooks/pre-push.sample b/06/.oldgit/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/06/.oldgit/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/06/.oldgit/hooks/pre-rebase.sample b/06/.oldgit/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/06/.oldgit/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/06/.oldgit/hooks/pre-receive.sample b/06/.oldgit/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/06/.oldgit/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/06/.oldgit/hooks/prepare-commit-msg.sample b/06/.oldgit/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/06/.oldgit/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/06/.oldgit/hooks/push-to-checkout.sample b/06/.oldgit/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/06/.oldgit/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/06/.oldgit/index b/06/.oldgit/index new file mode 100644 index 0000000..38e78b8 Binary files /dev/null and b/06/.oldgit/index differ diff --git a/06/.oldgit/info/exclude b/06/.oldgit/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/06/.oldgit/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/06/.oldgit/logs/HEAD b/06/.oldgit/logs/HEAD new file mode 100644 index 0000000..90b2104 --- /dev/null +++ b/06/.oldgit/logs/HEAD @@ -0,0 +1,4 @@ +0000000000000000000000000000000000000000 d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744959465 +0100 clone: from github.com:Dawid33/bootstrap-from-tcc.git +d2f9454b34fef570cfb32cf5b17d85a90dba81bf d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744962847 +0100 checkout: moving from main to main +d2f9454b34fef570cfb32cf5b17d85a90dba81bf d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744973869 +0100 reset: moving to HEAD +d2f9454b34fef570cfb32cf5b17d85a90dba81bf d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744973918 +0100 reset: moving to HEAD diff --git a/06/.oldgit/logs/refs/heads/main b/06/.oldgit/logs/refs/heads/main new file mode 100644 index 0000000..6e6a380 --- /dev/null +++ b/06/.oldgit/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744959465 +0100 clone: from github.com:Dawid33/bootstrap-from-tcc.git diff --git a/06/.oldgit/logs/refs/remotes/origin/HEAD b/06/.oldgit/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6e6a380 --- /dev/null +++ b/06/.oldgit/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 d2f9454b34fef570cfb32cf5b17d85a90dba81bf Dawid Sobczak 1744959465 +0100 clone: from github.com:Dawid33/bootstrap-from-tcc.git diff --git a/06/.oldgit/objects/38/0dd4861a9837e60a666c58e43a14ff12ea4603 b/06/.oldgit/objects/38/0dd4861a9837e60a666c58e43a14ff12ea4603 new file mode 100644 index 0000000..a20cddb Binary files /dev/null and b/06/.oldgit/objects/38/0dd4861a9837e60a666c58e43a14ff12ea4603 differ diff --git a/06/.oldgit/objects/44/b6c0c855a0b28ba2565a50f92aca8257bc5128 b/06/.oldgit/objects/44/b6c0c855a0b28ba2565a50f92aca8257bc5128 new file mode 100644 index 0000000..7653883 Binary files /dev/null and b/06/.oldgit/objects/44/b6c0c855a0b28ba2565a50f92aca8257bc5128 differ diff --git a/06/.oldgit/objects/49/27a2d50ee572da5f019e227e5df1afdc6c3963 b/06/.oldgit/objects/49/27a2d50ee572da5f019e227e5df1afdc6c3963 new file mode 100644 index 0000000..8b3e413 Binary files /dev/null and b/06/.oldgit/objects/49/27a2d50ee572da5f019e227e5df1afdc6c3963 differ diff --git a/06/.oldgit/objects/4b/5eb3f8368f574620aa1908fbac2a9b95600f4a b/06/.oldgit/objects/4b/5eb3f8368f574620aa1908fbac2a9b95600f4a new file mode 100644 index 0000000..f11c8aa Binary files /dev/null and b/06/.oldgit/objects/4b/5eb3f8368f574620aa1908fbac2a9b95600f4a differ diff --git a/06/.oldgit/objects/4c/4d8b09b35845aab8b1ca27ea99476a2614610d b/06/.oldgit/objects/4c/4d8b09b35845aab8b1ca27ea99476a2614610d new file mode 100644 index 0000000..7b659c2 --- /dev/null +++ b/06/.oldgit/objects/4c/4d8b09b35845aab8b1ca27ea99476a2614610d @@ -0,0 +1,2 @@ +x¥PÁJ1ô¼_ñîBI6ÉKRDÚƒAôàù%ï…»»e›"úõF¤_ Ìe†a†™¼LSm`¬¾i«˜ ˜m@M1/¨³ b i[Š…,*3œh•¹%Zg“±EŠó*—dÆ\\Òžƒ£¨8QЩ\ýäÇ"â;SAm<ÆhIaBŸ"‹18FèÒË +;ú¬ oKÊßôwüKÏì¡Ð¹MT›¼L÷ ½µÑ›€n•VjèjŸÖä_!ÃûÓ ,3ôžy{] ¯ûÇÝó~3ñ„û}gÉ­vWÇ*§uáK®©kûúÒülÅ \ No newline at end of file diff --git a/06/.oldgit/objects/4e/3f03ef0a8729af8451b24ef139f779d7721f20 b/06/.oldgit/objects/4e/3f03ef0a8729af8451b24ef139f779d7721f20 new file mode 100644 index 0000000..d970e42 Binary files /dev/null and b/06/.oldgit/objects/4e/3f03ef0a8729af8451b24ef139f779d7721f20 differ diff --git a/06/.oldgit/objects/63/45cc24f98d393f2da3f9e307f5a1402f95b015 b/06/.oldgit/objects/63/45cc24f98d393f2da3f9e307f5a1402f95b015 new file mode 100644 index 0000000..6f3a134 Binary files /dev/null and b/06/.oldgit/objects/63/45cc24f98d393f2da3f9e307f5a1402f95b015 differ diff --git a/06/.oldgit/objects/66/133e31e865aaadaca08072ddad7f987a0fd230 b/06/.oldgit/objects/66/133e31e865aaadaca08072ddad7f987a0fd230 new file mode 100644 index 0000000..d45c243 Binary files /dev/null and b/06/.oldgit/objects/66/133e31e865aaadaca08072ddad7f987a0fd230 differ diff --git a/06/.oldgit/objects/9f/a1dd951fc8994e7f4beba5b94b2503cac13b3d b/06/.oldgit/objects/9f/a1dd951fc8994e7f4beba5b94b2503cac13b3d new file mode 100644 index 0000000..603ce36 --- /dev/null +++ b/06/.oldgit/objects/9f/a1dd951fc8994e7f4beba5b94b2503cac13b3d @@ -0,0 +1 @@ +x¥PËJAô¼_Ñw!Ì«çD’ƒAôà¹çÑd0»6D¿ÞÉu©¢¨¢*µy®´‘7}-´9o%¯]±‚¬µ }1š¤a–ª±BO'ZËÒ!+MÔ† £‰£V‰1J—=R9’—‘¯þäÙ#ÆÀÑjQ¡GŽÂ¢S1'”J“ÉNt釶Ž>k†·Ó7}À]þ¥ç?öÀtî3Õã&µù¤3&8¤‡[!…˜†:¦õò¯éýéÚ£gÙ^×Âëþq÷¼ßÌy %ûÎ%õ:\k9­-_RõXû×Àl§ \ No newline at end of file diff --git a/06/.oldgit/objects/a4/39d0d9d17edd5cc0161e7a50b4e1b3188b3db5 b/06/.oldgit/objects/a4/39d0d9d17edd5cc0161e7a50b4e1b3188b3db5 new file mode 100644 index 0000000..ecde869 Binary files /dev/null and b/06/.oldgit/objects/a4/39d0d9d17edd5cc0161e7a50b4e1b3188b3db5 differ diff --git a/06/.oldgit/objects/a7/2fee58d519bf613769936da06b67b9de33629a b/06/.oldgit/objects/a7/2fee58d519bf613769936da06b67b9de33629a new file mode 100644 index 0000000..dec1c3c --- /dev/null +++ b/06/.oldgit/objects/a7/2fee58d519bf613769936da06b67b9de33629a @@ -0,0 +1,2 @@ +x¥PKj1ëÚ§xû@°gì±JI!YvÓžÀÏÏšÆãàqèçôu)=AA ! ÅZJî0ùå®·”@¯HEŒÔÄ‹'#±ce1ù™Ýä‘U×ÐÒÚ&öÚhœ5'6VFÆyŠlPYr&xIœBáÖ_kƒSxÏ/ãWxƒ{ú¡Û/;rØz ù²µ<€²Z{;»ÅÃN*)ÅPÇÔžþ"òJéê +£i=üí‡çóãéé¼/t€Dã-Åž‡k ¥k«t‹ó%÷Oñ ÈYa˜ \ No newline at end of file diff --git a/06/.oldgit/objects/c8/f855b9fb630e2a585fb06572bdc5123a0975a6 b/06/.oldgit/objects/c8/f855b9fb630e2a585fb06572bdc5123a0975a6 new file mode 100644 index 0000000..b40f4d9 Binary files /dev/null and b/06/.oldgit/objects/c8/f855b9fb630e2a585fb06572bdc5123a0975a6 differ diff --git a/06/.oldgit/objects/d6/d52e7f9449ce98317a97830dc726e211c4744d b/06/.oldgit/objects/d6/d52e7f9449ce98317a97830dc726e211c4744d new file mode 100644 index 0000000..f0bcbfa Binary files /dev/null and b/06/.oldgit/objects/d6/d52e7f9449ce98317a97830dc726e211c4744d differ diff --git a/06/.oldgit/objects/db/42ebd40db62eaa1e868c31d924d317dda4c4a5 b/06/.oldgit/objects/db/42ebd40db62eaa1e868c31d924d317dda4c4a5 new file mode 100644 index 0000000..07090dd Binary files /dev/null and b/06/.oldgit/objects/db/42ebd40db62eaa1e868c31d924d317dda4c4a5 differ diff --git a/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.idx b/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.idx new file mode 100644 index 0000000..315d910 Binary files /dev/null and b/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.idx differ diff --git a/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.pack b/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.pack new file mode 100644 index 0000000..c83c6f5 Binary files /dev/null and b/06/.oldgit/objects/pack/pack-5358506a18ff05f1c00c67a067ffdd111ddf7303.pack differ diff --git a/06/.oldgit/packed-refs b/06/.oldgit/packed-refs new file mode 100644 index 0000000..f078706 --- /dev/null +++ b/06/.oldgit/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +d2f9454b34fef570cfb32cf5b17d85a90dba81bf refs/remotes/origin/main diff --git a/06/.oldgit/refs/heads/main b/06/.oldgit/refs/heads/main new file mode 100644 index 0000000..2f59c5e --- /dev/null +++ b/06/.oldgit/refs/heads/main @@ -0,0 +1 @@ +d2f9454b34fef570cfb32cf5b17d85a90dba81bf diff --git a/06/.oldgit/refs/remotes/origin/HEAD b/06/.oldgit/refs/remotes/origin/HEAD new file mode 100644 index 0000000..4b0a875 --- /dev/null +++ b/06/.oldgit/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/06/LICENSE b/06/LICENSE new file mode 100644 index 0000000..fcefa33 --- /dev/null +++ b/06/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Alexander Sosedkin. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/06/Makefile b/06/Makefile new file mode 100644 index 0000000..258df60 --- /dev/null +++ b/06/Makefile @@ -0,0 +1,840 @@ +# First-time readers, refer to `build.sh` instead, it's more clear. +# +# This Makefile is optional and is all to aid debugging and add extra isolation. +# +# None of what's below in this Makefile is needed to build the project. + +all: + @echo 'This Makefile is for debugging purposes, use ./build.sh' + exit 1 + +ISO_CHECKSUM=22a6339a46c627bf761d5e90f936ac8dcf5717f8858975796959e47245a1320b + +# the no-dependencies way: full bootstrap with no make +all-raw: build.sh seed.sh download.sh recipes/*.sh recipes/*/* using-nix/* + ./build.sh + cp stage/store/5-go-beyond-using-nix/ZilchOS-core.iso \ + ZilchOS-core-raw.iso + sha256sum -c <<<"$(ISO_CHECKSUM) ZilchOS-core-raw.iso" + +# the make scaffolding way: full bootstrap with make +all-with-make: iso all-pkgs all-tests verify-all-pkgs-checksums \ + verify-all-nix-stage4-checksums verify-all-nix-stage5-checksums + +# the your-nix way: build just the using-nix/ part with your nix +all-with-nix: verify-all-nix-plain-checksums + +################################################################################ + +SHELL := bash +.SHELLFLAGS := -eu -o pipefail -c +.DELETE_ON_ERROR: # if only it also worked for dirs, see helpers/inject +CHROOT ?= $(shell command -v chroot 2>/dev/null || \ + PATH=/sbin:/usr/sbin/ command -v chroot 2>/dev/null || \ + echo chroot \ +) +MAKEFLAGS += --warn-undefined-variables +MAKEFLAGS += --no-builtin-rules +.PHONY: all all-at-once all-with-make clean-stage clean deepclean iso \ + verify-all-pkgs-checksums verify-pkgs-checksums update-pkgs-checksums \ + verify-all-nix-stage4-checksums verify-all-nix-stage5-checksums \ + verify-all-nix-plain-checksums verify-nix-plain-checksums \ + me-suffer +NPROC ?= 1 # for inner make invocations, one can pass -j# this way +USE_CCACHE ?= 0 # for faster iterative debugging only +USE_NIX_CACHE ?= 0 # for faster iterative debugging only +USE_DISORDERFS ?= 0 # for more thorough reproducibility testing +SAVE_MISMATCHING_BUILD_TREES ?= 0 # for more thorough reproducibility testing + +SOURCE_DATE_EPOCH ?= $(shell date '--date=01 Jan 1970 00:00:00 UTC' +%s) +TAR := tar +TAR_REPR = $(TAR) --sort=name '--mtime=@$(SOURCE_DATE_EPOCH)' \ + --owner=0 --group=0 --numeric-owner \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime + +downloads/%: + @echo "### Makefile: downloading required $*..." + ONLY="$*" ./download.sh + [[ -e downloads/$* ]] + +################################################################################ + +stage/protosrc: seed.sh +stage/protosrc: recipes/1-stage1/syscall.h +stage/protosrc: recipes/1-stage1/seed.host-executed.sh +stage/protosrc: downloads/musl-1.2.4.tar.gz +stage/protosrc: downloads/busybox-1.36.1.tar.bz2 +stage/protosrc: downloads/tinycc-mob-af1abf1.tar.gz + env DESTDIR=stage recipes/1-stage1/seed.host-executed.sh + +NIXPKGS_HASH=21f524672f25f8c3e7a0b5775e6505fee8fe43ce +TCC_CHECKSUM=05aad934985939e9997127e93d63d6a94c88739313c496f10a90176688cc9167 +tcc-seed: + @echo '### Makefile: you are supposed to supply a trusted tcc-seed' + @echo '### Makefile: since you have not, building one from nixpkgs...' + cat $$(nix build "nixpkgs/${NIXPKGS_HASH}#pkgsStatic.tinycc.out" \ + --no-link --print-out-paths)/bin/tcc > tcc-seed + chmod +x tcc-seed + sha256sum -c <<<"$(TCC_CHECKSUM) tcc-seed" + @echo '### Makefile: using tcc-seed built with nix' + +# Stage 0 is special in that there are no sources, we just pack up tcc-seed +pkgs/0-tcc-seed.pkg: tcc-seed + @echo '### Makefile: special stage 0: just packing up tcc-seed...' + mkdir -p tmp/build/0-tcc-seed/store pkgs + cp tcc-seed tmp/build/0-tcc-seed/store/0-tcc-seed + $(TAR_REPR) -Izstd -cf pkgs/0-tcc-seed.pkg -C tmp/build/0-tcc-seed \ + store/0-tcc-seed + rm -rf tmp/build/0-tcc-seed + @echo '### Makefile: successfully packed up pkgs/0-tcc-seed.pkg' + +# Stage 1 is special in that: +# * we patch up some sources on the host +# * we have no shell and execute 1-stage1.c with tcc-seed +pkgs/1-stage1.pkg: pkgs/0-tcc-seed.pkg +pkgs/1-stage1.pkg: recipes/1-stage1.c +pkgs/1-stage1.pkg: recipes/1-stage1/seed.host-executed.sh +pkgs/1-stage1.pkg: recipes/1-stage1/syscall.h +pkgs/1-stage1.pkg: recipes/1-stage1/protobusybox.c +pkgs/1-stage1.pkg: recipes/1-stage1/protobusybox.h +pkgs/1-stage1.pkg: recipes/1-stage1/hello.c +pkgs/1-stage1.pkg: downloads/musl-1.2.4.tar.gz +pkgs/1-stage1.pkg: downloads/tinycc-mob-af1abf1.tar.gz +pkgs/1-stage1.pkg: downloads/busybox-1.36.1.tar.bz2 +pkgs/1-stage1.pkg: + @echo "### Makefile: creating temporary builddir tmp/build/1-stage1..." + rm -rf tmp/build/1-stage1 + DISORDER=$(USE_DISORDERFS) helpers/builddir create tmp/build/1-stage1 + @echo "### Makefile: injecting dependencies..." + helpers/inject tmp/build/1-stage1 $^ + @echo "### Makefile: seeding special stage 1 (and patching sources)..." + DESTDIR=tmp/build/1-stage1 recipes/1-stage1/seed.host-executed.sh + @echo "### Makefile: special stage 1: executing stage1.c with tcc-seed" + DISORDER=$(USE_DISORDERFS) helpers/builddir pre-build tmp/build/1-stage1 + env -i unshare -nr $(CHROOT) ./tmp/build/1-stage1 \ + /store/0-tcc-seed -nostdinc -nostdlib -Werror \ + -run recipes/1-stage1.c + DISORDER=$(USE_DISORDERFS) \ + helpers/builddir post-build tmp/build/1-stage1 + $(TAR_REPR) -Izstd -cf pkgs/1-stage1.pkg -C tmp/build/1-stage1 \ + store/1-stage1 + DISORDER=$(USE_DISORDERFS) helpers/builddir remove tmp/build/1-stage1 + @echo "### Makefile: 1-stage1 has been built as pkgs/1-stage1.pkg" + +# Consequent stages split up into packages have it simpler: +pkgs/%.pkg: recipes/%.sh + @echo "### Makefile: creating a temporary build area tmp/build/$*..." + if ! rm -rf "tmp/build/$*" 2>/dev/null; then \ + chmod -R +w "tmp/build/$*"; \ + rm -rf "tmp/build/$*"; \ + fi + [ ! -e "tmp/build/$*" ] + DISORDER=$(USE_DISORDERFS) helpers/builddir create "tmp/build/$*" + helpers/inject "tmp/build/$*" $^ +ifeq ($(USE_CCACHE), 1) + @echo "### Makefile: unpacking ccache from previous builds $*..." + mkdir -p "tmp/build/$*/ccache" + [[ ! -e "tmp/ccache/$*.tar.zstd" ]] || \ + tar -Izstd -xf "tmp/ccache/$*.tar.zstd" -C "tmp/build/$*/ccache" + ln -sf /store/_2a0-ccache/wrap-available "tmp/build/$*/ccache/setup" + ln -sf /store/_2a0-ccache/bin "tmp/build/$*/ccache/bin" +endif +ifeq ($(USE_NIX_CACHE), 1) + @echo "### Makefile: unpacking nix store and db from previous build..." + if [[ $* =~ .*-using-nix ]] && [[ -e "pkgs/$*.pkg" ]]; then \ + mkdir "tmp/build/$*/prev/"; \ + tar --strip-components=2 \ + -xf "pkgs/$*.pkg" -C "tmp/build/$*/prev/"; \ + fi +endif + DISORDER=$(USE_DISORDERFS) helpers/builddir pre-build "tmp/build/$*" + @echo "### Makefile: building $* ..." + env \ + DESTDIR="./tmp/build/$*" \ + NPROC="$(NPROC)" \ + SOURCE_DATE_EPOCH="$(SOURCE_DATE_EPOCH)" \ + ./helpers/chroot "/recipes/$*.sh" + DISORDER=$(USE_DISORDERFS) helpers/builddir post-build "tmp/build/$*" + @echo "### Makefile: packing up $* ..." + $(TAR_REPR) -Izstd -cf "pkgs/$*.pkg" -C "tmp/build/$*" "store/$*" +ifeq ($(USE_CCACHE), 1) + @echo "### Makefile: packing up $* ccache cache..." + if [[ -e "tmp/build/$*/store/_2a0-ccache/bin/ccache" ]]; then \ + mkdir -p tmp/ccache; \ + unshare -nr $(CHROOT) "tmp/build/$*" \ + /store/_2a0-ccache/bin/ccache -sz; \ + $(TAR_REPR) -Izstd -cf "tmp/ccache/$*.tar.zstd" \ + -C "tmp/build/$*/ccache" .; \ + fi + rm -rf "tmp/build/$*/store/_2a0-ccache" + rm -rf "tmp/build/$*/ccache" +endif +ifeq ($(SAVE_MISMATCHING_BUILD_TREES), 1) + computed_csum=$$(zstd -qcd "pkgs/$*.pkg" | sha256sum); \ + computed_csum=$$(<<<$$computed_csum tr ' ' '\t' | cut -f1); \ + if ! grep -q "$$computed_csum pkgs/$*" verify.pkgs.sha256; then \ + short_csum=$$(<<<$$computed_csum head -c7); \ + echo "### Makefile: packing up $* buildtree"; \ + mkdir -p trees; \ + $(TAR_REPR) -Izstd -cf "trees/$*-$$short_csum.pkg" \ + -C "tmp/build/$*" .; \ + fi +endif + @echo "### Makefile: cleaning up after $*" + DISORDER=$(USE_DISORDERFS) helpers/builddir remove "tmp/build/$*" + @echo "### Makefile: $* has been built as pkgs/$*.pkg" + +# Dependency graph: + +pkgs/2a0-static-gnumake.pkg: pkgs/1-stage1.pkg +pkgs/2a0-static-gnumake.pkg: downloads/make-4.4.1.tar.gz + +ifeq ($(USE_CCACHE), 1) +pkgs/_2a0-ccache.pkg: pkgs/1-stage1.pkg +pkgs/_2a0-ccache.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2a0-ccache.pkg: downloads/ccache-3.7.12.tar.xz +endif + +pkgs/2/01-gnumake.pkg: pkgs/1-stage1.pkg +pkgs/2/01-gnumake.pkg: pkgs/2/00-intermediate-gnumake.pkg +pkgs/2/01-gnumake.pkg: downloads/make-4.4.1.tar.gz + +pkgs/2a1-static-binutils.pkg: pkgs/1-stage1.pkg +pkgs/2a1-static-binutils.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a1-static-binutils.pkg: downloads/binutils-2.39.tar.xz + +pkgs/2a2-static-gnugcc4-c.pkg: pkgs/1-stage1.pkg +pkgs/2a2-static-gnugcc4-c.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a2-static-gnugcc4-c.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a2-static-gnugcc4-c.pkg: downloads/gmp-4.3.2.tar.xz +pkgs/2a2-static-gnugcc4-c.pkg: downloads/mpfr-2.4.2.tar.xz +pkgs/2a2-static-gnugcc4-c.pkg: downloads/mpc-0.8.1.tar.gz +pkgs/2a2-static-gnugcc4-c.pkg: downloads/gcc-4.7.4.tar.bz2 + +pkgs/2a3-intermediate-musl.pkg: pkgs/1-stage1.pkg +pkgs/2a3-intermediate-musl.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a3-intermediate-musl.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a3-intermediate-musl.pkg: pkgs/2a2-static-gnugcc4-c.pkg +pkgs/2a3-intermediate-musl.pkg: downloads/musl-1.2.4.tar.gz + +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/1-stage1.pkg +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/2a2-static-gnugcc4-c.pkg +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a4-gnugcc4-cpp.pkg: downloads/gmp-4.3.2.tar.xz +pkgs/2a4-gnugcc4-cpp.pkg: downloads/mpfr-2.4.2.tar.xz +pkgs/2a4-gnugcc4-cpp.pkg: downloads/mpc-0.8.1.tar.gz +pkgs/2a4-gnugcc4-cpp.pkg: downloads/gcc-4.7.4.tar.bz2 + +pkgs/2a5-gnugcc10.pkg: pkgs/1-stage1.pkg +pkgs/2a5-gnugcc10.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a5-gnugcc10.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a5-gnugcc10.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a5-gnugcc10.pkg: pkgs/2a4-gnugcc4-cpp.pkg +pkgs/2a5-gnugcc10.pkg: downloads/gcc-10.5.0.tar.xz +pkgs/2a5-gnugcc10.pkg: downloads/gmp-6.1.0.tar.xz +pkgs/2a5-gnugcc10.pkg: downloads/mpc-1.0.3.tar.gz +pkgs/2a5-gnugcc10.pkg: downloads/mpfr-3.1.4.tar.xz +pkgs/2a5-gnugcc10.pkg: downloads/isl-0.18.tar.bz2 + +pkgs/2a6-linux-headers.pkg: pkgs/1-stage1.pkg +pkgs/2a6-linux-headers.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a6-linux-headers.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a6-linux-headers.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a6-linux-headers.pkg: pkgs/2a5-gnugcc10.pkg +pkgs/2a6-linux-headers.pkg: downloads/linux-6.4.12.tar.xz + +pkgs/2a7-cmake.pkg: pkgs/1-stage1.pkg +pkgs/2a7-cmake.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a7-cmake.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a7-cmake.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a7-cmake.pkg: pkgs/2a5-gnugcc10.pkg +pkgs/2a7-cmake.pkg: pkgs/2a6-linux-headers.pkg +pkgs/2a7-cmake.pkg: downloads/cmake-3.27.4.tar.gz + +pkgs/2a8-python.pkg: pkgs/1-stage1.pkg +pkgs/2a8-python.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a8-python.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a8-python.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a8-python.pkg: pkgs/2a5-gnugcc10.pkg +pkgs/2a8-python.pkg: downloads/Python-3.12.0.tar.xz + +pkgs/2a9-intermediate-clang.pkg: pkgs/1-stage1.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a5-gnugcc10.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a6-linux-headers.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a7-cmake.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/2a8-python.pkg +pkgs/2a9-intermediate-clang.pkg: downloads/llvm-project-17.0.1.src.tar.xz + +pkgs/2b0-musl.pkg: pkgs/1-stage1.pkg +pkgs/2b0-musl.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2b0-musl.pkg: pkgs/2a1-static-binutils.pkg +pkgs/2b0-musl.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2b0-musl.pkg: pkgs/2a9-intermediate-clang.pkg +pkgs/2b0-musl.pkg: downloads/musl-1.2.4.tar.gz + +pkgs/2b1-clang.pkg: pkgs/1-stage1.pkg +pkgs/2b1-clang.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2b1-clang.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/2b1-clang.pkg: pkgs/2a6-linux-headers.pkg +pkgs/2b1-clang.pkg: pkgs/2a7-cmake.pkg +pkgs/2b1-clang.pkg: pkgs/2a8-python.pkg +pkgs/2b1-clang.pkg: pkgs/2a9-intermediate-clang.pkg +pkgs/2b1-clang.pkg: pkgs/2b0-musl.pkg +pkgs/2b1-clang.pkg: downloads/llvm-project-17.0.1.src.tar.xz + +pkgs/2b2-busybox.pkg: pkgs/1-stage1.pkg +pkgs/2b2-busybox.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2b2-busybox.pkg: pkgs/2b0-musl.pkg +pkgs/2b2-busybox.pkg: pkgs/2b1-clang.pkg +pkgs/2b2-busybox.pkg: pkgs/2a6-linux-headers.pkg +pkgs/2b2-busybox.pkg: downloads/busybox-1.36.1.tar.bz2 + +pkgs/2b3-gnumake.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/2b3-gnumake.pkg: pkgs/2b0-musl.pkg +pkgs/2b3-gnumake.pkg: pkgs/2b1-clang.pkg +pkgs/2b3-gnumake.pkg: pkgs/2b2-busybox.pkg +pkgs/2b3-gnumake.pkg: downloads/make-4.4.1.tar.gz + +pkgs/3a-sqlite.pkg: pkgs/2b0-musl.pkg +pkgs/3a-sqlite.pkg: pkgs/2b1-clang.pkg +pkgs/3a-sqlite.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-sqlite.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-sqlite.pkg: downloads/sqlite-autoconf-3430000.tar.gz + +pkgs/3a-boost.pkg: pkgs/2b0-musl.pkg +pkgs/3a-boost.pkg: pkgs/2b1-clang.pkg +pkgs/3a-boost.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-boost.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-boost.pkg: pkgs/2a6-linux-headers.pkg +pkgs/3a-boost.pkg: downloads/boost_1_83_0.tar.bz2 + +pkgs/3a-mbedtls.pkg: pkgs/2b0-musl.pkg +pkgs/3a-mbedtls.pkg: pkgs/2b1-clang.pkg +pkgs/3a-mbedtls.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-mbedtls.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-mbedtls.pkg: downloads/mbedtls-3.4.1.tar.gz + +pkgs/3a-pkg-config.pkg: pkgs/2b0-musl.pkg +pkgs/3a-pkg-config.pkg: pkgs/2b1-clang.pkg +pkgs/3a-pkg-config.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-pkg-config.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-pkg-config.pkg: downloads/pkg-config-0.29.2.tar.gz + +pkgs/3a-curl.pkg: pkgs/2b0-musl.pkg +pkgs/3a-curl.pkg: pkgs/2b1-clang.pkg +pkgs/3a-curl.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-curl.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-curl.pkg: pkgs/3a-mbedtls.pkg +pkgs/3a-curl.pkg: pkgs/3a-pkg-config.pkg +pkgs/3a-curl.pkg: downloads/curl-8.2.1.tar.xz + +pkgs/3a-editline.pkg: pkgs/2b0-musl.pkg +pkgs/3a-editline.pkg: pkgs/2b1-clang.pkg +pkgs/3a-editline.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-editline.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-editline.pkg: downloads/editline-1.17.1.tar.xz + +pkgs/3a-brotli.pkg: pkgs/2b0-musl.pkg +pkgs/3a-brotli.pkg: pkgs/2b1-clang.pkg +pkgs/3a-brotli.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-brotli.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-brotli.pkg: downloads/brotli-1.0.9.tar.gz + +pkgs/3a-gnugperf.pkg: pkgs/2b0-musl.pkg +pkgs/3a-gnugperf.pkg: pkgs/2b1-clang.pkg +pkgs/3a-gnugperf.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-gnugperf.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-gnugperf.pkg: downloads/gperf-3.1.tar.gz + +pkgs/3a-seccomp.pkg: pkgs/2b0-musl.pkg +pkgs/3a-seccomp.pkg: pkgs/2b1-clang.pkg +pkgs/3a-seccomp.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-seccomp.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-seccomp.pkg: pkgs/3a-gnugperf.pkg +pkgs/3a-seccomp.pkg: pkgs/2a6-linux-headers.pkg +pkgs/3a-seccomp.pkg: downloads/libseccomp-2.5.4.tar.gz + +pkgs/3a-libarchive.pkg: pkgs/2b0-musl.pkg +pkgs/3a-libarchive.pkg: pkgs/2b1-clang.pkg +pkgs/3a-libarchive.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-libarchive.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-libarchive.pkg: pkgs/3a-pkg-config.pkg +pkgs/3a-libarchive.pkg: downloads/libarchive-3.7.1.tar.xz + +pkgs/3a-libsodium.pkg: pkgs/2b0-musl.pkg +pkgs/3a-libsodium.pkg: pkgs/2b1-clang.pkg +pkgs/3a-libsodium.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-libsodium.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-libsodium.pkg: pkgs/3a-pkg-config.pkg +pkgs/3a-libsodium.pkg: downloads/libsodium-1.0.18.tar.gz + +pkgs/3a-lowdown.pkg: pkgs/2b0-musl.pkg +pkgs/3a-lowdown.pkg: pkgs/2b1-clang.pkg +pkgs/3a-lowdown.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-lowdown.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-lowdown.pkg: downloads/lowdown-1.0.2.tar.gz + +pkgs/3a-nlohmann-json.pkg: pkgs/2b0-musl.pkg +pkgs/3a-nlohmann-json.pkg: pkgs/2b1-clang.pkg +pkgs/3a-nlohmann-json.pkg: pkgs/2b2-busybox.pkg +pkgs/3a-nlohmann-json.pkg: pkgs/2b3-gnumake.pkg +pkgs/3a-nlohmann-json.pkg: downloads/nlohmann-json-3.11.2.tar.xz + +pkgs/3b-busybox-static.pkg: pkgs/2b0-musl.pkg +pkgs/3b-busybox-static.pkg: pkgs/2b1-clang.pkg +pkgs/3b-busybox-static.pkg: pkgs/2b2-busybox.pkg +pkgs/3b-busybox-static.pkg: pkgs/2b3-gnumake.pkg +pkgs/3b-busybox-static.pkg: pkgs/2a6-linux-headers.pkg +pkgs/3b-busybox-static.pkg: downloads/busybox-1.36.1.tar.bz2 + +pkgs/3b-tinycc-static.pkg: pkgs/2b0-musl.pkg +pkgs/3b-tinycc-static.pkg: pkgs/2b1-clang.pkg +pkgs/3b-tinycc-static.pkg: pkgs/2b2-busybox.pkg +pkgs/3b-tinycc-static.pkg: pkgs/2b3-gnumake.pkg +pkgs/3b-tinycc-static.pkg: downloads/tinycc-mob-af1abf1.tar.gz + +pkgs/3b-nix.pkg: pkgs/2b0-musl.pkg +pkgs/3b-nix.pkg: pkgs/2b1-clang.pkg +pkgs/3b-nix.pkg: pkgs/2b2-busybox.pkg +pkgs/3b-nix.pkg: pkgs/2b3-gnumake.pkg +pkgs/3b-nix.pkg: pkgs/2a6-linux-headers.pkg +pkgs/3b-nix.pkg: pkgs/3a-sqlite.pkg +pkgs/3b-nix.pkg: pkgs/3a-boost.pkg +pkgs/3b-nix.pkg: pkgs/3a-pkg-config.pkg +pkgs/3b-nix.pkg: pkgs/3a-curl.pkg +pkgs/3b-nix.pkg: pkgs/3a-editline.pkg +pkgs/3b-nix.pkg: pkgs/3a-brotli.pkg +pkgs/3b-nix.pkg: pkgs/3a-seccomp.pkg +pkgs/3b-nix.pkg: pkgs/3a-libarchive.pkg +pkgs/3b-nix.pkg: pkgs/3a-libsodium.pkg +pkgs/3b-nix.pkg: pkgs/3a-lowdown.pkg +pkgs/3b-nix.pkg: pkgs/3a-nlohmann-json.pkg +pkgs/3b-nix.pkg: pkgs/3b-busybox-static.pkg +pkgs/3b-nix.pkg: downloads/queue.h +pkgs/3b-nix.pkg: downloads/nix-2.17.0-zilched.tar.xz + +pkgs/4-rebootstrap-using-nix.pkg: pkgs/2b0-musl.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/2b1-clang.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/2b2-busybox.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-boost.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-pkg-config.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-sqlite.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-curl.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-editline.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-brotli.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-seccomp.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-libarchive.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-libsodium.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-lowdown.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3a-nlohmann-json.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3b-tinycc-static.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3b-busybox-static.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/3b-nix.pkg +### +pkgs/4-rebootstrap-using-nix.pkg: stage/protosrc +### +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1.c +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1/seed.host-executed.sh +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1/syscall.h +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1/protobusybox.c +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1/protobusybox.h +pkgs/4-rebootstrap-using-nix.pkg: recipes/1-stage1/hello.c +### +pkgs/4-rebootstrap-using-nix.pkg: default.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/1-stage1.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a0-static-gnumake.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a1-static-binutils.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a2-static-gnugcc4-c.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a3-intermediate-musl.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a4-gnugcc4-cpp.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a5-gnugcc10.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a6-linux-headers.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a7-cmake.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a8-python.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2a9-intermediate-clang.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2b0-musl.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2b1-clang.nix +pkgs/4-rebootstrap-using-nix.pkg: using-nix/2b2-busybox.nix +### +pkgs/4-rebootstrap-using-nix.pkg: downloads/make-4.4.1.tar.gz +pkgs/4-rebootstrap-using-nix.pkg: downloads/binutils-2.39.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/gcc-4.7.4.tar.bz2 +pkgs/4-rebootstrap-using-nix.pkg: downloads/gmp-4.3.2.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/mpfr-2.4.2.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/mpc-0.8.1.tar.gz +pkgs/4-rebootstrap-using-nix.pkg: downloads/musl-1.2.4.tar.gz +pkgs/4-rebootstrap-using-nix.pkg: downloads/gcc-10.5.0.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/gmp-6.1.0.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/mpfr-3.1.4.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/mpc-1.0.3.tar.gz +pkgs/4-rebootstrap-using-nix.pkg: downloads/isl-0.18.tar.bz2 +pkgs/4-rebootstrap-using-nix.pkg: downloads/linux-6.4.12.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/cmake-3.27.4.tar.gz +pkgs/4-rebootstrap-using-nix.pkg: downloads/Python-3.12.0.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/llvm-project-17.0.1.src.tar.xz +pkgs/4-rebootstrap-using-nix.pkg: downloads/busybox-1.36.1.tar.bz2 + +pkgs/5-go-beyond-using-nix.pkg: pkgs/2b0-musl.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/2b1-clang.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/2b2-busybox.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-boost.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-pkg-config.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-sqlite.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-curl.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-editline.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-brotli.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-seccomp.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-libarchive.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-libsodium.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-lowdown.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3a-nlohmann-json.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3b-tinycc-static.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3b-busybox-static.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/3b-nix.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/4-rebootstrap-using-nix.pkg +### +pkgs/5-go-beyond-using-nix.pkg: stage/protosrc +### +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1.c +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1/seed.host-executed.sh +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1/syscall.h +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1/protobusybox.c +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1/protobusybox.h +pkgs/5-go-beyond-using-nix.pkg: recipes/1-stage1/hello.c +### +pkgs/5-go-beyond-using-nix.pkg: default.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/1-stage1.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a0-static-gnumake.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a1-static-binutils.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a2-static-gnugcc4-c.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a3-intermediate-musl.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a4-gnugcc4-cpp.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a5-gnugcc10.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a6-linux-headers.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a7-cmake.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a8-python.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2a9-intermediate-clang.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2b0-musl.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2b1-clang.nix +pkgs/5-go-beyond-using-nix.pkg: using-nix/2b2-busybox.nix +### +pkgs/5-go-beyond-using-nix.pkg: downloads/make-4.4.1.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/binutils-2.39.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/gcc-4.7.4.tar.bz2 +pkgs/5-go-beyond-using-nix.pkg: downloads/gmp-4.3.2.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/mpfr-2.4.2.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/mpc-0.8.1.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/musl-1.2.4.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/gcc-10.5.0.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/gmp-6.1.0.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/mpfr-3.1.4.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/mpc-1.0.3.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/isl-0.18.tar.bz2 +pkgs/5-go-beyond-using-nix.pkg: downloads/linux-6.4.12.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/cmake-3.27.4.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/Python-3.11.5.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/llvm-project-17.0.1.src.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/curl-8.2.1.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/mbedtls-3.4.1.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/boost_1_83_0.tar.bz2 +pkgs/5-go-beyond-using-nix.pkg: downloads/editline-1.17.1.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/brotli-1.0.9.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/gperf-3.1.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/libsodium-1.0.18.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/libarchive-3.7.1.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/lowdown-1.0.2.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/libseccomp-2.5.4.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/nlohmann-json-3.11.2.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/nix-2.17.0-zilched.tar.xz +pkgs/5-go-beyond-using-nix.pkg: flake.nix +pkgs/5-go-beyond-using-nix.pkg: downloads/queue.h +pkgs/5-go-beyond-using-nix.pkg: downloads/ZilchOS-core-2023.10.1.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/limine-5.20230830.0.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/patchelf-0.18.0.tar.bz2 +pkgs/5-go-beyond-using-nix.pkg: downloads/pkg-config-0.29.2.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/sqlite-autoconf-3430000.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/bison-3.8.2.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/m4-1.4.19.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/flex-2.6.4.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/mtools-4.0.43.tar.bz2 +pkgs/5-go-beyond-using-nix.pkg: downloads/xorriso-1.5.6.pl02.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/nasm-2.16.01.tar.xz +pkgs/5-go-beyond-using-nix.pkg: downloads/zstd-1.5.5.tar.gz +pkgs/5-go-beyond-using-nix.pkg: downloads/cacert-2023-08-22.pem + +iso: ZilchOS-core.iso + +ZilchOS-core.iso: pkgs/5-go-beyond-using-nix.pkg + tar --strip-components=2 -xf pkgs/5-go-beyond-using-nix.pkg \ + store/5-go-beyond-using-nix/ZilchOS-core.iso + sha256sum -c <<<"$(ISO_CHECKSUM) ZilchOS-core.iso" + +################################################################################ + +# Separate one for tests to help readability of the above + +pkgs/_1.test.pkg: pkgs/1-stage1.pkg + +pkgs/_2a3.test.pkg: pkgs/1-stage1.pkg +pkgs/_2a3.test.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2a3.test.pkg: pkgs/2a1-static-binutils.pkg +pkgs/_2a3.test.pkg: pkgs/2a2-static-gnugcc4-c.pkg +pkgs/_2a3.test.pkg: pkgs/2a3-intermediate-musl.pkg + +pkgs/_2a4.test.pkg: pkgs/1-stage1.pkg +pkgs/_2a4.test.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2a4.test.pkg: pkgs/2a1-static-binutils.pkg +pkgs/_2a4.test.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/_2a4.test.pkg: pkgs/2a4-gnugcc4-cpp.pkg + +pkgs/_2a5.test.pkg: pkgs/1-stage1.pkg +pkgs/_2a5.test.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2a5.test.pkg: pkgs/2a1-static-binutils.pkg +pkgs/_2a5.test.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/_2a5.test.pkg: pkgs/2a5-gnugcc10.pkg + +pkgs/_2a9.test.pkg: pkgs/1-stage1.pkg +pkgs/_2a9.test.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2a9.test.pkg: pkgs/2a3-intermediate-musl.pkg +pkgs/_2a9.test.pkg: pkgs/2a9-intermediate-clang.pkg + +pkgs/_2b1.test.pkg: pkgs/1-stage1.pkg +pkgs/_2b1.test.pkg: pkgs/2a0-static-gnumake.pkg +pkgs/_2b1.test.pkg: pkgs/2b0-musl.pkg +pkgs/_2b1.test.pkg: pkgs/2b1-clang.pkg + +pkgs/_3b.test.pkg: pkgs/2b0-musl.pkg +pkgs/_3b.test.pkg: pkgs/2b1-clang.pkg +pkgs/_3b.test.pkg: pkgs/2b2-busybox.pkg +pkgs/_3b.test.pkg: pkgs/3a-boost.pkg +pkgs/_3b.test.pkg: pkgs/3a-pkg-config.pkg +pkgs/_3b.test.pkg: pkgs/3a-sqlite.pkg +pkgs/_3b.test.pkg: pkgs/3a-curl.pkg +pkgs/_3b.test.pkg: pkgs/3a-editline.pkg +pkgs/_3b.test.pkg: pkgs/3a-brotli.pkg +pkgs/_3b.test.pkg: pkgs/3a-seccomp.pkg +pkgs/_3b.test.pkg: pkgs/3a-libarchive.pkg +pkgs/_3b.test.pkg: pkgs/3a-libsodium.pkg +pkgs/_3b.test.pkg: pkgs/3a-lowdown.pkg +pkgs/_3b.test.pkg: pkgs/3b-nix.pkg + +all-tests: pkgs/_1.test.pkg +all-tests: pkgs/_2a3.test.pkg +all-tests: pkgs/_2a4.test.pkg +all-tests: pkgs/_2a5.test.pkg +all-tests: pkgs/_2a9.test.pkg +all-tests: pkgs/_2b1.test.pkg +all-tests: pkgs/_3b.test.pkg + +################################################################################ + +.PHONY: all-pkgs +all-pkgs: pkgs/0-tcc-seed.pkg +all-pkgs: pkgs/1-stage1.pkg +all-pkgs: pkgs/2a0-static-gnumake.pkg +all-pkgs: pkgs/2a1-static-binutils.pkg +all-pkgs: pkgs/2a2-static-gnugcc4-c.pkg +all-pkgs: pkgs/2a3-intermediate-musl.pkg +all-pkgs: pkgs/2a4-gnugcc4-cpp.pkg +all-pkgs: pkgs/2a5-gnugcc10.pkg +all-pkgs: pkgs/2a6-linux-headers.pkg +all-pkgs: pkgs/2a7-cmake.pkg +all-pkgs: pkgs/2a8-python.pkg +all-pkgs: pkgs/2a9-intermediate-clang.pkg +all-pkgs: pkgs/2b0-musl.pkg +all-pkgs: pkgs/2b1-clang.pkg +all-pkgs: pkgs/2b2-busybox.pkg +all-pkgs: pkgs/2b3-gnumake.pkg +all-pkgs: pkgs/3a-sqlite.pkg +all-pkgs: pkgs/3a-boost.pkg +all-pkgs: pkgs/3a-mbedtls.pkg +all-pkgs: pkgs/3a-pkg-config.pkg +all-pkgs: pkgs/3a-curl.pkg +all-pkgs: pkgs/3a-editline.pkg +all-pkgs: pkgs/3a-brotli.pkg +all-pkgs: pkgs/3a-gnugperf.pkg +all-pkgs: pkgs/3a-seccomp.pkg +all-pkgs: pkgs/3a-libarchive.pkg +all-pkgs: pkgs/3a-libsodium.pkg +all-pkgs: pkgs/3a-lowdown.pkg +all-pkgs: pkgs/3a-nlohmann-json.pkg +all-pkgs: pkgs/3b-busybox-static.pkg +all-pkgs: pkgs/3b-tinycc-static.pkg +all-pkgs: pkgs/3b-nix.pkg +all-pkgs: pkgs/4-rebootstrap-using-nix.pkg +all-pkgs: pkgs/5-go-beyond-using-nix.pkg + +################################################################################ + +ifeq ($(USE_CCACHE), 1) +pkgs/2a1-static-binutils.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a2-static-gnugcc4-c.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a3-intermediate-musl.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a4-gnugcc4-cpp.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a5-gnugcc10.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a6-linux-headers.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a7-cmake.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a8-python.pkg: pkgs/_2a0-ccache.pkg +pkgs/2a9-intermediate-clang.pkg: pkgs/_2a0-ccache.pkg +pkgs/2b0-musl.pkg: pkgs/_2a0-ccache.pkg +pkgs/2b1-clang.pkg: pkgs/_2a0-ccache.pkg +pkgs/2b2-busybox.pkg: pkgs/_2a0-ccache.pkg +pkgs/2b3-gnumake.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-sqlite.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-boost.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-mbedtls.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-pkg-config.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-curl.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-editline.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-brotli.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-gnugperf.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-seccomp.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-libarchive.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-libsodium.pkg: pkgs/_2a0-ccache.pkg +pkgs/3a-lowdown.pkg: pkgs/_2a0-ccache.pkg +pkgs/3b-busybox-static.pkg: pkgs/_2a0-ccache.pkg +pkgs/3b-tinycc-static.pkg: pkgs/_2a0-ccache.pkg +pkgs/3b-nix.pkg: pkgs/_2a0-ccache.pkg +pkgs/4-rebootstrap-using-nix.pkg: pkgs/_2a0-ccache.pkg +pkgs/5-go-beyond-using-nix.pkg: pkgs/_2a0-ccache.pkg +endif + +################################################################################ + +.PHONY: verify-pkgs-checksums verify-all-pkgs-checksums update-pkgs-checksums +verify-pkgs-checksums: + @status=true; \ + while read expected_csum pkgname; do \ + pkg=$${pkgname%%.tar}.pkg; \ + if [[ ! -e "$$pkg" ]]; then \ + status=false; \ + echo "MISSING $$pkgname"; \ + continue; \ + fi; \ + computed_csum=$$(zstd -qcd "$$pkg" | sha256sum); \ + computed_csum=$$(<<<$$computed_csum tr ' ' '\t' | cut -f1); \ + short_csum=$$(<<<$$computed_csum head -c7); \ + if [[ "$$pkg" == pkgs/0-tcc-seed.pkg ]]; then \ + if ! sha256sum -c <<<"$(TCC_CHECKSUM) tcc-seed" \ + >/dev/null; then \ + echo "$$short_csum pkgs/0.tar CUSTOM"; \ + continue; \ + fi; \ + fi; \ + if make -sq "$$pkg"; then \ + dated=''; \ + else \ + status=false; \ + dated=" OUTDATED"; \ + fi; \ + if [[ "$$expected_csum" == "$$computed_csum" ]]; then \ + echo "$$short_csum $$pkgname OK$$dated"; \ + else \ + status=false; \ + echo "$$short_csum $$pkgname NOT OK$$dated"; \ + echo " computed: $$computed_csum"; \ + echo " expected: $$expected_csum"; \ + fi; \ + done < verify.pkgs.sha256; $$status\ + +verify-all-pkgs-checksums: all-pkgs + $(MAKE) verify-pkgs-checksums + +update-pkgs-checksums: + @:> verify.pkgs.sha256 + @find pkgs | grep '\.pkg$$' | grep -v '\/_' | sort | \ + while read p; do \ + name=$${p%%.pkg}.tar; \ + csum=$$(zstd -qcd "$$p" | sha256sum | tr ' ' '\t' | cut -f1); \ + short_csum=$$(<<<$$csum head -c7); \ + echo "$$csum $$name" >> verify.pkgs.sha256; \ + echo "$$short_csum $$name"; \ + done +verify.pkgs.sha256: all-pkgs update-pkgs-checksums + +nix-checksums-stage4: pkgs/4-rebootstrap-using-nix.pkg + tar tf pkgs/4-rebootstrap-using-nix.pkg store \ + | grep -E 'store/[a-z0-9]{32}-[^/]*/?$$' \ + | sed -E 's|.*/([a-z0-9]{32}-[^/]*)/?|\1|' \ + | sort \ + > nix-checksums-stage4 + +nix-checksums-stage5: pkgs/5-go-beyond-using-nix.pkg + tar Oxf pkgs/5-go-beyond-using-nix.pkg \ + store/5-go-beyond-using-nix/hashes \ + > nix-checksums-stage5 + +verify-all-nix-stage4-checksums: nix-checksums-stage4 verify.nix + @status=true; \ + while IFS=" " read ref_hash pkg; do \ + if grep -Fq "$$ref_hash-bootstrap" nix-checksums-stage4; then \ + echo " $$ref_hash $$pkg"; \ + else \ + status=false; \ + echo "! $$ref_hash $$pkg MISSING"; \ + fi; \ + done < verify.nix; $$status + +verify-all-nix-stage5-checksums: downloads/ZilchOS-core-2023.10.1.tar.gz +verify-all-nix-stage5-checksums: nix-checksums-stage5 verify.nix + @status=true; \ + tar -Oxf downloads/ZilchOS-core-2023.10.1.tar.gz \ + --wildcards */.maint/hashes | \ + while IFS=' ' read ref_hash pkg; do \ + stage5_hash=$$(grep " $$pkg$$" nix-checksums-stage5 \ + | sed -E 's|^([a-z0-9]{32}) .*|\1|'); \ + if [[ "$$ref_hash" == "$$stage5_hash" ]]; then \ + echo " $$ref_hash $$pkg"; \ + else \ + status=false; \ + echo "- $$ref_hash $$pkg"; \ + echo "+ $$stage5_hash $$pkg"; \ + fi; \ + done; $$status +NIX_BUILD_X = nix build --no-warn-dirty --option substitute false --no-link +verify-nix-plain-checksums: verify.nix + @status=true; \ + while IFS=" " read ref_hash pkg; do \ + plain_hash=$$($(NIX_BUILD_X) ".#$$pkg" --print-out-paths \ + | sed -E 's|.*/([a-z0-9]{32})-.*|\1|'); \ + if [[ "$$ref_hash" == "$$plain_hash" ]]; then \ + echo " $$ref_hash $$pkg"; \ + else \ + status=false; \ + echo "- $$ref_hash $$pkg"; \ + echo "+ $$plain_hash $$pkg"; \ + fi; \ + done < verify.nix; $$status + +verify-all-nix-plain-checksums: verify.nix + @$(NIX_BUILD_X) '.#toolchain' '.#libc' '.#musl' + @$(MAKE) verify-nix-plain-checksums + +################################################################################ + +clean-tmp: + @echo "### Makefile: removing tmp, keeping stage, pkgs and downloads..." + rm -rf tmp + +clean-stage: + @echo "### Makefile: removing stage, keeping tmp, pkgs and downloads..." + rm -rf stage + +clean: + @echo "### Makefile: removing stage, tmp, pkgs, iso, keeping downloads..." + rm -rf stage tmp pkgs \ + nix-checksums-stage4 nix-checksums-stage5 \ + nix-checksums-stage5-custom \ + ZilchOS-core.iso ZilchOS-core-raw.iso + +deepclean: + @echo "### Makefile: removing stage, tmp, pkgs, iso and downloads..." + rm -rf stage tmp pkgs downloads \ + nix-checksums-stage4 nix-checksums-stage5 \ + nix-checksums-stage5-custom \ + ZilchOS-core.iso ZilchOS-core-raw.iso diff --git a/06/README.md b/06/README.md new file mode 100644 index 0000000..769549a --- /dev/null +++ b/06/README.md @@ -0,0 +1,212 @@ +# `bootstrap-from-tcc` + +## What + +Bootstrap a modern toolchain for [ZilchOS Core](https://github.com/ZilchOS/core) +starting from a random trusted statically linked seed tcc +(+ trusted kernel on trusted hardware, of course). + +~320 KB binary + gigs of sources = a modern Clang + musl toolchain, +usable for building much more serious stuff. + +My goal is to beeline for bootstrapping Nix package manager, +then bootstrap a usable toolchain using Nix. +But even if you don't care about Nix, +this repo might be of some interest for minimal binary seed bootstrappers. + +Separate packages aren't just dumped into `/`, they're properly managed, +each one residing in its own prefix under `/store`. + +`x86_64`-only for now, possibly forever. + +## Why + +I wanted to build a minimal distro to understand NixOS better, +so I decided to have a decent trusted binary core bootstrap as well. + +Could be of use for bootstrapping other distributions. + +I'm aware of https://savannah.nongnu.org/projects/stage0 which does even better, +but I'm not as hardcore as them, so, let's start small. + +## How + +### In brief + +Compiler chain so far (`recipes`): +input TinyCC -> stable TinyCC -> GNU GCC 4 -> GNU GCC 10 -> -> Clang + +`recipes/1-stage1.c` is the most fun, since we don't have libc yet. + +Then I build Nix and start the entire bootstrapping chain all over again, +but now using that Nix I've built (`using-nix`). + +### Outlined bootstrap order + +* stage 0: seeded binary `tcc` +* stage 1 (`recipes/1-stage1.c` / `using-nix/1-stage1.nix`, no libc): + * `libtcc1` + * `protomusl` + * `tcc` + * `libtcc1` + * `protomusl` + * `tcc` that is gonna be the final one + * `libtcc1` + * `protomusl` + * `tcc` that we build just to prove the finality of the previous one + * `protobusybox` +* stage 2 "compiler ascension" part (`recipes/2a*.sh` / `using-nix/2a*.nix`): + * `gnumake` + * `binutils` + * `gnugcc4` + * `musl` + * `gnugcc4` + * `gnugcc10` + * `linux-headers` + * `cmake` + * `python` + * `clang` +* stage 2 "build with the new compiler" part (`recipes/2b*.sh`): + * `musl` + * `clang` + * `busybox` + * `gnumake` +* stage 3 "dependencies of useful stuff" (`recipes/3a*.sh`): ??? + * `sqlite` + * `boost` + * `mbedtls` + * `pkg-config` + * `curl` + * `editline` + * `brotli` + * `gnugperf` + * `seccomp` + * `libarchive` + * `libsodium` + * `lowdown` +* stage 3 "useful stuff" (`recipes/3b*.sh`): ??? + * `busybox-static` + * `tinycc-static` (1st time only) + * `nix` + +Then repeat stage 1 and most of stage 2 all over again, but under Nix. +The final exports of this flake are musl, clang toolchain and a busybox +that ZilchOS Core later bootstraps from. + +* stage 4 "rebootstrap with nix" (`recipes/4-rebootstrap-using-nix.sh`): + build the toolchain again from scratch, but using nix (`using-nix/`) + +* stage 5 "go beyond using nix" (`recipes/5-go-beyond-using-nix.sh`): + build some stale version of [ZilchOS Core](https://github.com/ZilchOS/core) + with the nix we've built, culminating with a bootable ZilchOS ISO. + +### In more detail + +given: + +* **statically linked target tcc (`tcc-seed`, you have to provide it)** +* host `unshare` for `chroot`ing and isolation +* host `wget`, `tar`, `gzip`, `bzip2`, `sha256sum`, `tar` + for optional convenient fetching of source files in stage 0 +* host `sed` to preprocess the sources needed for stage 1, unfortunately +* a replacement for `musl/arch/x86_64/syscall_arch.h` that works with tcc + (`syscall.h`) +* a bunch of sources to execute along the way + +`download.sh" downloads a ton of sources, scraping hashes/URLs from recipes + +`seed.sh` seeds: + +* unpacks sources into the stage area +* FIXME: uses host `sed`/`rm` for preprocessing stage 1 source code, + unfortunately +* copies `seed-tcc`, the only starting binary, into the stage area + +At the end of it we obtain +a ton of sources and a single externally seeded `tcc` binary. + +`recipes/1-stage1.c`, executed with `tcc -run`: + +* compiles a `libtcc1.a` from `tinycc` sources +* compiles a protomusl `libc.a` and others from `musl` sources +* compiles the first `tcc` that comes from our sources +* recompiles `libtcc1.a` from `tinycc` sources +* recompiles protomusl `libc.a` and others from `musl` sources +* recompiles our `tcc` with our `tcc` +* recompiles `libtcc1.a` from `tinycc` sources just in case +* recompiles protomusl `libc.a` and others from `musl` sources just in case +* compiles and links standalone applets out of busybox, notably `ash` +* copies over protomusl include files +* recompiles `tcc` once again + and verifies that we've previously reached a stability point + +At the end of stage 1 we have, all linked statically: + +* a `tcc` (+ `libtcc` + `libtcc1`) that recompiles to same binary +* a protomusl `libc.a` (+ crt stuff) +* select standalone busybox applets, most notably `ash` + +`stage2.sh`, executed with protobusybox `ash`: + +* Performs 'compiler ascension' from tcc to GNU GCC 4: + * `gnumake`, intermediate, built without make + * `gnumake`, statically linked + * `binutils`, statically linked + * `gnugcc4`, statically linked + * `musl`, now a shared library as well + * `gnugcc4` with C++ support and linking to a shared musl + * `gnugcc10` + * `linux-headers` (clang & cmake dependency) + * `cmake` (clang dependency) + * `python` (clang dependency, presumably) + * `clang`, intermediate, 2-stage + +* Recompile the world with clang, free of GNU runtime libs: + * `musl`, final + * `clang`, final + * `busybox`, final + * `gnumake`, final + +* Build a bunch of Nix dependencies +* Build Nix + +* Start over, build toolchain, build ZilchOS Core + +### Building options + +There are three major ways to build it. + +If you have Nix and want to skip the first half that bootstraps Nix, +you can just `nix build`, but what's the fun in taking shortcuts =). +You'll need `experimental-features = nix-command flakes ca-derivations`. + +If you want to do a full bootstrap with all imaginable speedups enabled, +try something to the tune of +`make all-pkgs all-tests verify-all-pkgs-checksums -j2 NPROC=$(nproc) USE_CCACHE=1 USE_NIX_CACHE=1`. +Dependencies: host GNU Make, host zstd, basic host stuff like sed and bash, +a target TinyCC you supply or Nix to build you one. +This is the recommended way, especially shining when you +iteratively debug reproducibility-unrelated build problems. +Consider mounting `tmp/build` as tmpfs with 8G size. + +Finally, the least-dependency way is `NPROC=$(nproc) ./build.sh`. +This one doesn't even need GNU Make or zstd, +but there are zero intermediate checkpoints, you always start all over. +Very impractical, this is for increased portability only. + +### Reproducibility + +Reproducibility is deeply cared about, +but it's a constant struggle and one cannot foresee everything. + +Hashes are checked for intermediate steps for both `make` and `nix` builds. +`raw` builds only verify the resulting ZilchOS Core ISO built during stage5. +I try to build on different machines and note down the results in `git notes`. +Commits require a specific (but adjustable) amount of successful +`make`, `raw` and `nix` before getting into the main branch. +Refer to `make all-with-make`, `make all-raw` and `make all-with-nix` +to see what exactly is being tested. + +For hard mode, you can try `USE_DISORDERFS`. + +For ZilchOS/core, see `.maint/hashes` and `.maint/tools/hashes`. diff --git a/06/build-using-nix.sh b/06/build-using-nix.sh new file mode 100755 index 0000000..21d25e1 --- /dev/null +++ b/06/build-using-nix.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# this is entirely optional and for development purposes only +# just use `nix-build` and you should be fine + +# build with ccache and without /bin/sh present +# your nix needs experimental-options = ca-derivations +# and you need root access / to be a trusted user + +set -ue + +CCACHE_HOST=/var/cache/ccache +mkdir -p $CCACHE_HOST/data +sudo chgrp nixbld $CCACHE_HOST $CCACHE_HOST/data +sudo chmod g+ws $CCACHE_HOST $CCACHE_HOST/data + +if [[ ! -e $CCACHE_HOST/bin/ccache ]]; then + nix build 'nixpkgs#pkgsStatic.ccache' --out-link $CCACHE_HOST/result + mkdir -p $CCACHE_HOST/bin + cp --reflink=auto $CCACHE_HOST/result/bin/ccache $CCACHE_HOST/bin/ccache + rm $CCACHE_HOST/result +fi + +[[ -e $CCACHE_HOST/setup ]] || cat > $CCACHE_HOST/setup <<\EOF +mkdir -p .ccache-wrappers +for prefix in '' x86_64-linux- x86_64-linux-musl- x86_64-linux-unknown-; do + for name in cc c++ gcc g++ clang clang++ tcc; do + if command -v $prefix$name; then + ln -s /ccache/bin/ccache .ccache-wrappers/$prefix$name + fi + done +done +export PATH="$(pwd)/.ccache-wrappers:/ccache/bin:$PATH" +export CCACHE_DIR="/ccache/data/$1" +export CCACHE_COMPILERCHECK=content +export CCACHE_SLOPPINESS=include_file_ctime,include_file_mtime +export CCACHE_MAXSIZE=0 +export CCACHE_UMASK=005 +export CCACHE_NOHASHDIR=1 +export CCACHE_BASEDIR="$(pwd)" +EOF +chmod +x $CCACHE_HOST/setup + +nix-build -A stage1.protomusl +nix-build -A stage1.protobusybox +nix-build -A stage1.tinycc +sudo env "NIX_CONFIG=sandbox-paths = /ccache=$CCACHE_HOST" nix-build "$@" diff --git a/06/build.sh b/06/build.sh new file mode 100755 index 0000000..5f896b7 --- /dev/null +++ b/06/build.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# This is the straigthforward bootstrapping way. +# Prepare a directory with the initial TinyCC compiler, and a ton of sources. +# Then exec into it and let it bootstrap itself. + +# You can refer to the Makefile for a more refined, totally optional approach +# with incremental builds, better build isolation etc. + +set -uex + +export NPROC=${NPROC:-${1:-1}} + +cp ../05/tcc-final/tcc tcc-seed + +if [[ ! -e tcc-seed ]]; then + echo 'You need to supply a statically linked TinyCC as `tcc-seed`.' + echo -n 'You can `./compile-tcc-seed-with-nix.sh` ' + echo 'if you have `nix` and trust in me.' + exit 1 +fi + +# Create a stage directory +mkdir -p stage + +# Download all the required source files +./download.sh + +# Inject initial tcc and our scripts; pre-unpack and patch stage 1 sources, +# in a separate file because it makes sense to run it separately sometimes. +./seed.sh + +# Exec into stage1.c inside stage with env unset, +# without network, with EUID=EGID=0 and with /dev/null being a /dev/null. +# See helpers/chroot and helpers/chroot-inner for more explanations +# Alternatively, you can chroot if you're not a fan of user namespaces. +MOUNT=$(command -v mount) +if [[ -e /run/wrappers/bin/mount.real ]]; then # NixOS wrapper might be buggy + MOUNT=$(cat /run/wrappers/bin/mount.real) +fi +MKDIR=$(command -v mkdir) +CHROOT=$(command -v chroot) + +exec env -i "NPROC=$NPROC" unshare -nrm bash -uexs < stage/dev/null + $MOUNT --bind /dev/null stage/dev/null + + exec $CHROOT stage \ + /store/0-tcc-seed -I /protosrc/tinycc/include -nostdinc -nostdlib -Werror -run \ + -DCHAINLOAD='"/recipes/all-past-stage1.sh"' \ + /recipes/1-stage1.c +EOF + +# There's no next step, +# upon completion stage1.c will exec into recipes/all-past-stage1.sh diff --git a/06/compile-tcc-seed-with-nix.sh b/06/compile-tcc-seed-with-nix.sh new file mode 100755 index 0000000..7054e28 --- /dev/null +++ b/06/compile-tcc-seed-with-nix.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -uexo pipefail + +NIXPKGS_HASH=21f524672f25f8c3e7a0b5775e6505fee8fe43ce +TCC_CHECKSUM=05aad934985939e9997127e93d63d6a94c88739313c496f10a90176688cc9167 +TCC=$(nix build "nixpkgs/$NIXPKGS_HASH#pkgsStatic.tinycc.out" \ + --no-link --print-out-paths) +cat $TCC/bin/tcc > tcc-seed +chmod +x tcc-seed +S="$TCC_CHECKSUM tcc-seed" +sha256sum tcc-seed +sha256sum -c <<<$S diff --git a/06/default.nix b/06/default.nix new file mode 100644 index 0000000..f4c36d9 --- /dev/null +++ b/06/default.nix @@ -0,0 +1,144 @@ +let + # stage 0 + + # these two use nixpkgs, but are fixed-output derivations with no dependencies + tcc-seed = (import ./using-nix/0.nix).tinycc; + protosrc = (import ./using-nix/0.nix).protosrc; + # in bootstrapping builds, + # 0.nix is different and they're not coming from nixpkgs, + # see recipes/4-rebootstrap-using-nix.sh + + # stage 1 + + stage1 = (import ./using-nix/1-stage1.nix) { + inherit tcc-seed protosrc; + recipesStage1ExtrasPath = ./recipes/1-stage1; + stage1cPath = ./recipes/1-stage1.c; + }; # multioutput, offers .protobusybox, .protomusl and .tinycc + + # stage 2 + + mkCaDerivation = args: derivation (args // { + system = "x86_64-linux"; + __contentAddressed = true; + outputHashAlgo = "sha256"; outputHashMode = "recursive"; + }); + + mkDerivationStage2 = + {name, script, buildInputPaths, extra ? {}}: mkCaDerivation { + inherit name; + builder = "${stage1.protobusybox}/bin/ash"; + args = [ "-uexc" ( + '' + export PATH=${builtins.concatStringsSep ":" buildInputPaths} + + if [ -e /ccache/setup ]; then + . /ccache/setup bootstrap-from-tcc/${name} + fi + + unpack() (tar --strip-components=1 -xf "$@") + + if [ -n "$NIX_BUILD_CORES" ] && [ "$NIX_BUILD_CORES" != 0 ]; then + NPROC=$NIX_BUILD_CORES + elif [ "$NIX_BUILD_CORES" == 0 ] && [ -r /proc/cpuinfo ]; then + NPROC=$(grep -c processor /proc/cpuinfo) + else + NPROC=1 + fi + '' + script + ) ]; + } // extra; + + fetchurl = { url, sha256 }: derivation { + name = builtins.baseNameOf url; + inherit url; + urls = [ url ]; + unpack = false; + + builder = "builtin:fetchurl"; + system = "builtin"; + outputHashMode = "flat"; outputHashAlgo = "sha256"; + preferLocalBuild = true; + outputHash = sha256; + }; + + static-gnumake = (import using-nix/2a0-static-gnumake.nix) { + inherit fetchurl mkDerivationStage2 stage1; + }; + + static-binutils = (import using-nix/2a1-static-binutils.nix) { + inherit fetchurl mkDerivationStage2 stage1 static-gnumake; + }; + + static-gnugcc4-c = (import using-nix/2a2-static-gnugcc4-c.nix) { + inherit fetchurl mkDerivationStage2 stage1 static-gnumake static-binutils; + }; + + intermediate-musl = (import using-nix/2a3-intermediate-musl.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils static-gnugcc4-c; + }; + + gnugcc4-cpp = (import using-nix/2a4-gnugcc4-cpp.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils static-gnugcc4-c; + inherit intermediate-musl; + }; + + gnugcc10 = (import using-nix/2a5-gnugcc10.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils gnugcc4-cpp intermediate-musl; + }; + + linux-headers = (import using-nix/2a6-linux-headers.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils gnugcc10; + }; + + cmake = (import using-nix/2a7-cmake.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils gnugcc10 linux-headers; + }; + + python = (import using-nix/2a8-python.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils gnugcc10; + }; + + intermediate-clang = (import using-nix/2a9-intermediate-clang.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake static-binutils intermediate-musl gnugcc10; + inherit linux-headers cmake python; + }; + + musl = (import using-nix/2b0-musl.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake intermediate-clang; + }; + + clang = (import using-nix/2b1-clang.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake musl intermediate-clang; + inherit linux-headers cmake python; + }; + + busybox = (import using-nix/2b2-busybox.nix) { + inherit fetchurl mkDerivationStage2; + inherit stage1 static-gnumake musl clang linux-headers; + }; + +in + { + # exposed just because; don't rely on these + inherit protosrc tcc-seed; + inherit stage1; + inherit static-gnumake static-binutils static-gnugcc4-c; + inherit intermediate-musl gnugcc4-cpp gnugcc10; + inherit linux-headers cmake python intermediate-clang; + inherit musl clang; + + # public interface: + libc = musl; # some libc that TODO: doesn't depend on anything else + toolchain = clang; # some modern C/C++ compiler targeting this libc + busybox = busybox; # a freebie busybox TODO: depending on just libc + } diff --git a/06/download.sh b/06/download.sh new file mode 100755 index 0000000..5e352fb --- /dev/null +++ b/06/download.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Receives files as arguments, scans them for lines like +# #> FETCH dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3 +# #> FROM http://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz +# #> AS make.tar.gz +# or +# #local = "/downloads/make.tar.gz"; +# url = "http://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz"; +# sha256 = "dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3"; +# downloads to ./downloads if file's not present there yet, verifies hash, +# copies file over to $DESTDIR. + +set -ue + +: ${DESTDIR:=stage/downloads} # final location of putting the file +: ${ONLY:=all} # allow to limit to just a single file +mkdir -p downloads # first cached there, so that stage can be cleaned freely + +fetch() { + hash=$1; url=$2; filename=${3:-$(basename "$url")} + if [[ -e "downloads/$filename" ]]; then + pushd downloads >/dev/null + echo "$hash $filename" | sha256sum -c + popd >/dev/null + else + mkdir -p downloads/.tmp$$ + pushd downloads/.tmp$$ >/dev/null + wget -nv --show-progress "$url" -O "$filename" + echo "$hash $filename" | sha256sum -c --quiet + popd >/dev/null + mv "downloads/.tmp$$/$filename" downloads/ + rm -d downloads/.tmp$$ + fi + if [[ "${DESTDIR:-}" != downloads ]]; then + mkdir -p "$DESTDIR" + cp -a --reflink=auto "downloads/$filename" \ + "$DESTDIR/$filename" + fi +} + +REGEX_MAGIC='^#> ' +REGEX_FETCH='^#> FETCH' +REGEX_FROM='^#> FROM' +REGEX_AS='^#> AS' +NIX_REGEX_FETCH='^[[:blank:]]*sha256[[:blank:]]*=[[:blank:]]*"(.*)";$' +NIX_REGEX_FROM='^[[:blank:]]*url[[:blank:]]*=[[:blank:]]*"(.*)";$' +NIX_REGEX_AS='^[[:blank:]]*#[[:blank:]]local[[:blank:]]*=[[:blank:]]*/downloads/(.*);$' +process_commands_in() { + hash=''; url=''; filename='' + while read -r line; do + if [[ "$line" =~ $REGEX_MAGIC ]]; then + if [[ "$line" =~ $REGEX_FETCH ]]; then + hash="${line##"#> FETCH"}" + elif [[ "$line" =~ $REGEX_FROM ]]; then + url="${line##'#> FROM '}" + elif [[ "$line" =~ $REGEX_AS ]]; then + filename="${line##'#> AS '}" + else + echo "### $0: malformed line '$line' in '$1'" + exit 2 + fi + elif [[ "$line" =~ $NIX_REGEX_FETCH ]]; then + hash=${BASH_REMATCH[1]} + elif [[ "$line" =~ $NIX_REGEX_FROM ]]; then + url=${BASH_REMATCH[1]} + elif [[ "$line" =~ $NIX_REGEX_AS ]]; then + filename=${BASH_REMATCH[1]} + else + if [[ -n "$hash" && -n "$url" ]]; then + filename=${filename:-$(basename $url)} + if [[ "$ONLY" == all || \ + "$ONLY" == "$filename" ]]; then + fetch "$hash" "$url" "$filename" + fi + fi + hash=''; url=''; filename='' + fi + done < $1 +} + +[[ $# == 0 ]] && files='recipes/*.sh recipes/*/*.sh' || files="$@" +for f in $files; do + process_commands_in $f +done diff --git a/06/flake.nix b/06/flake.nix new file mode 100644 index 0000000..360ce1b --- /dev/null +++ b/06/flake.nix @@ -0,0 +1,15 @@ +{ + description = "bootstrap-from-tcc"; + + outputs = { self }: + let + allPkgs = (import ./default.nix); + in + { + packages.x86_64-linux = allPkgs; + + # TODO: expose only the most usable outputs + # TODO: solve fetching: https://discourse.nixos.org/t/17105 + hydraJobs = builtins.mapAttrs (_: drv: { x86_64-linux = drv; }) allPkgs; + }; +} diff --git a/06/helpers/builddir b/06/helpers/builddir new file mode 100755 index 0000000..c8f68b7 --- /dev/null +++ b/06/helpers/builddir @@ -0,0 +1,70 @@ +#!/bin/sh + +: ${DISORDER=0} + +set -uex + +verb=$1 +front=$2 +back=$front-back + +[ "tmp/build/${front#tmp/build/}" = "$front" ] +[ "tmp/build/${back#tmp/build/}" = "$back" ] + +remove_hard() { + if [ -e "$1" ]; then + sudo umount "$1" 2>/dev/null || true + if ! rm -rf "$1" 2>/dev/null; then + chmod -R +w "$1" + rm -rf "$1" + fi + fi +} + +if [ "$verb" = create ]; then + echo "### helpers/builddir: creating $front..." + remove_hard "$front"; remove_hard "$back" + mkdir -p "$front" + if [ "$DISORDER" = 1 ]; then + sudo umount "$back" || true + rm -rf "$back" + mkdir -p "$front" "$back" + sudo mount -o size=16G -t tmpfs tmpfs "$back" + sudo mount --bind "$back" "$front" + [ $(findmnt -no FSTYPE "$front") = tmpfs ] + fi +elif [ "$verb" = pre-build ]; then + [ -e "$front" ] + if [ "$DISORDER" = 1 ]; then + echo "### helpers/builddir: disordering $front..." + [ -e "$back" ] + [ $(findmnt -no FSTYPE "$back") = tmpfs ] + sudo umount "$front" + sudo disorderfs --shuffle-dirents=yes \ + -o allow_other --multi-user=yes \ + "$back" "$front" + [ $(findmnt -no FSTYPE "$front") = fuse.disorderfs ] + fi +elif [ "$verb" = post-build ]; then + if [ "$DISORDER" = 1 ]; then + echo "### helpers/builddir: ordering $front..." + [ ! -e "$front" ] && [ ! -e "$back" ] + [ $(findmnt -no FSTYPE "$front") = fuse.disorderfs ] + [ $(findmnt -no FSTYPE "$back") = tmpfs ] + sudo umount "$front" + sudo mount --bind "$back" "$front" + fi +elif [ "$verb" = remove ]; then + echo "### helpers/builddir: removing $front..." + if [ "$DISORDER" = 1 ]; then + [ $(findmnt -no FSTYPE "$back") = tmpfs ] + sudo umount "$front" + sudo umount "$back" + rm -d "$front" "$back" + else + remove_hard "$front"; remove_hard "$back" + fi + [ ! -e "$front" ] && [ ! -e "$back" ] +else + exit 9 +fi diff --git a/06/helpers/cheat b/06/helpers/cheat new file mode 100755 index 0000000..a8edb7f --- /dev/null +++ b/06/helpers/cheat @@ -0,0 +1,49 @@ +#!/bin/sh +set -ue + +NIXPKGS=nixpkgs/21f524672f25f8c3e7a0b5775e6505fee8fe43ce +: ${DESTDIR:=stage} + +mkdir -p $DESTDIR/cheat + +if [ ! -e $DESTDIR/cheat/make ]; then + nix build "$NIXPKGS#pkgsStatic.gnumake" + cp result/bin/make $DESTDIR/cheat/make + rm result +fi + +if [ ! -e $DESTDIR/cheat/bash ]; then + nix build "$NIXPKGS#pkgsStatic.bash" + cp result/bin/bash $DESTDIR/cheat/bash + rm result +fi + +if [ ! -e $DESTDIR/cheat/strace ]; then + nix build "$NIXPKGS#pkgsStatic.strace" + cp result/bin/strace $DESTDIR/cheat/ + rm result +fi + +if [ ! -e $DESTDIR/cheat/busybox ]; then + nix build "$NIXPKGS#pkgsStatic.busybox" + cp result/bin/busybox $DESTDIR/cheat/busybox + for f in $(ls result/bin/); do + [ $(basename $f) = busybox ] || + ln -s /cheat/busybox $DESTDIR/cheat/$(basename $f) + done + rm result +fi + +if [ -z "$@" ]; then + _PATH='' + for bindir in $DESTDIR/store/*/bin $DESTDIR/store/*/*/bin; do + _PATH="${bindir##$DESTDIR}:$_PATH" + done + LIBC=$(find $DESTDIR/store/*/lib/libc.so | tail -n1) + if [ -n "$LIBC" ] && [ ! -h $DESTDIR/cheat/ldd ]; then + ln -s "${LIBC##$DESTDIR}" $DESTDIR/cheat/ldd + fi + helpers/chroot /cheat/env "PATH=$_PATH" /cheat/ash +else + helpers/chroot "$@" +fi diff --git a/06/helpers/chroot b/06/helpers/chroot new file mode 100755 index 0000000..b8cdd65 --- /dev/null +++ b/06/helpers/chroot @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Run a command chrooted inside $DESTDIR w/o network, with /dev/null, outline: +# +# [helpers/chroot, outer script] +# / unshare +# | -n # without network +# | -r # with EUID=EGID=0 +# \ -m # separate mount namespace +# [helpers/chroot-inner, this script] +# mount --bind /dev/null $DESTDIR/dev/null # unprivileged /dev/null! +# && +# env -i # with env unset +# chroot $DESTDIR # unprivileged chroot! + +set -uex + +exec unshare -nrm helpers/chroot-inner "$@" diff --git a/06/helpers/chroot-inner b/06/helpers/chroot-inner new file mode 100755 index 0000000..e13ae2b --- /dev/null +++ b/06/helpers/chroot-inner @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# Run a command chrooted inside $DESTDIR w/o network, with /dev/null, outline: +# +# [helpers/chroot, outer script] +# unshare +# -n # without network +# -r # with EUID=EGID=0 +# -m # separate mount namespace +# [helpers/chroot-inner, this script] +# / mount --bind /dev/null $DESTDIR/dev/null # unprivileged /dev/null! +# | && +# | env -i # with env unset +# \ chroot $DESTDIR # unprivileged chroot! + +set -uex + +: ${DESTDIR:=stage} +: ${NPROC:=1} +: ${SOURCE_DATE_EPOCH:=0} + +CHROOT=$(command -v chroot) +if [[ ! -x "$CHROOT" ]]; then + if [[ -x /sbin/chroot ]]; then + CHROOT=/sbin/chroot + elif [[ -x /usr/sbin/chroot ]]; then + CHROOT=/usr/sbin/chroot + fi +fi + +if [[ -e /run/wrappers/bin/mount.real ]]; then + MOUNT=$(cat /run/wrappers/bin/mount.real) +else + MOUNT=mount +fi +mkdir -p "$DESTDIR/dev"; :> "$DESTDIR/dev/null" +$MOUNT --bind /dev/null "$DESTDIR/dev/null" + +exec env -i "NPROC=$NPROC" "SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH" \ + $CHROOT "$DESTDIR" "$@" diff --git a/06/helpers/inject b/06/helpers/inject new file mode 100755 index 0000000..1a3beb6 --- /dev/null +++ b/06/helpers/inject @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -uex + +DESTDIR=$1 +shift + +for arg; do + if [[ "$arg" =~ .*\.pkg ]]; then + # That one's for package dependencies + tar -xf "$arg" -Izstd -C "$DESTDIR" + else + # That one's for copying over downloads and sources + if [[ ! -e "./$DESTDIR/$arg" || "$arg" -nt "./$DESTDIR/$arg" ]] + then + echo "Copying $arg into $DESTDIR..." + mkdir -p "$DESTDIR/$(dirname "$arg")" + cp -a --reflink=auto "$arg" "$DESTDIR/$arg" + fi + fi +done diff --git a/06/helpers/maint/build-custom-stage5 b/06/helpers/maint/build-custom-stage5 new file mode 100755 index 0000000..470b955 --- /dev/null +++ b/06/helpers/maint/build-custom-stage5 @@ -0,0 +1,97 @@ +#!/usr/bin/env bash +set -uexo pipefail + +CUSTOM_CORE_DIR=$1 + +# Determine where to start from +if [[ -e pkgs/custom-stage5.pkg ]]; then + BASE=pkgs/custom-stage5.pkg +elif [[ -e pkgs/5-go-beyond-using-nix.pkg ]]; then + BASE=pkgs/5-go-beyond-using-nix.pkg +elif [[ -e pkgs/4-rebootstrap-using-nix.pkg ]]; then + BASE=pkgs/4-rebootstrap-using-nix.pkg +else + [[ "${USE_CCACHE-}" = 1 ]] && FLAGS='USE_CCACHE=1' || FLAGS='' + [[ -n "${NPROC-}" ]] && FLAGS="$FLAGS NPROC=$NPROC" || FLAGS='' + make $FLAGS pkgs/5-go-beyond-using-nix.pkg + BASE=pkgs/5-rebootstrap-using-nix.pkg +fi + +# Inject stage5 pkg dependencies +DESTDIR=tmp/build/custom-stage5 +helpers/builddir create "$DESTDIR" +grep -E '^pkgs/5-go-beyond-using-nix.pkg:' Makefile \ + | grep -v '^pkgs/5-go-beyond-using-nix.pkg: downloads/' \ + | grep -v 'pkgs/5-go-beyond-using-nix.pkg: pkgs/_2a0-ccache.pkg$' \ + | sed 's|^pkgs/5-go-beyond-using-nix.pkg: ||' \ + | while IFS= read -r dep; do helpers/inject "$DESTDIR" "$dep"; done +helpers/inject "$DESTDIR" recipes/5-go-beyond-using-nix.sh + +# Inject BASE and its nixdb +helpers/inject "$DESTDIR" "$BASE" +mkdir -p "$DESTDIR/prev/" +tar --strip-components=2 -xf $BASE -C "$DESTDIR/prev/" +rm -f "$DESTDIR/store/5-go-beyond-using-nix/ZilchOS-core.iso" + +# Inject ccache data, all stage5 ccache data we can find +if [[ "${USE_CCACHE-}" = 1 ]]; then + helpers/inject "$DESTDIR" pkgs/_2a0-ccache.pkg + unshare -nr chroot "$DESTDIR" /store/_2a0-ccache/bin/ccache -z + if [[ -e tmp/ccache/5-go-beyond-using-nix.tar.zstd ]]; then + tar -Izstd -xf tmp/ccache/5-go-beyond-using-nix.tar.zstd \ + -C "$DESTDIR/ccache" + fi + if [[ -e tmp/ccache/custom-stage5.tar.zstd ]]; then + tar -Izstd -xf tmp/ccache/custom-stage5.tar.zstd \ + -C "$DESTDIR/ccache" + fi + ln -sf /store/_2a0-ccache/wrap-available "$DESTDIR/ccache/setup" + ln -sf /store/_2a0-ccache/bin "$DESTDIR/ccache/bin" +fi +helpers/builddir pre-build "$DESTDIR" + +# Inject custom ZilchOS Core code +DESTCORE="$DESTDIR/tmp/5-go-beyond-using-nix/ZilchOS-core" +mkdir -p "$DESTCORE" +rm -rf "$DESTCORE" # TODO: REMOVE +cp -r "$CUSTOM_CORE_DIR" "$DESTCORE" +rm -rf "$DESTCORE/.git" +[[ -e $DESTCORE/flake.nix ]] +hashes=$(cat $CUSTOM_CORE_DIR/.maint/hashes) + +# Inject custom required downloads +DESTDIR="$DESTDIR/downloads" ./download.sh $(find $DESTCORE -name '*.nix') + +DESTDIR="$DESTDIR" NPROC="${NPROC-}" \ + ./helpers/chroot /recipes/5-go-beyond-using-nix.sh + +cat tmp/build/custom-stage5/store/5-go-beyond-using-nix/hashes \ + > nix-checksums-stage5-custom + +# Collect results back +tar -Izstd -cf "pkgs/custom-stage5.pkg" \ + -C "$DESTDIR" "store/5-go-beyond-using-nix" + +# Collect ccache back +if [[ "${USE_CCACHE-}" = 1 ]]; then + unshare -nr chroot "$DESTDIR" /store/_2a0-ccache/bin/ccache -sz + tar -Izstd -cf "tmp/ccache/custom-stage5.tar.zstd" \ + -C "$DESTDIR/ccache" . +fi + +helpers/builddir post-build "$DESTDIR" +helpers/builddir remove "$DESTDIR" + +set +x +status=true +while IFS=' ' read ref_hash pkg; do + stage5_hash=$(grep " $pkg$" nix-checksums-stage5-custom \ + | sed -E 's|^([a-z0-9]{32}) .*|\1|'); + if [[ "$ref_hash" == "$stage5_hash" ]]; then + echo " $ref_hash $pkg"; + else + status=false; + echo "- $ref_hash $pkg"; + echo "+ $stage5_hash $pkg"; + fi +done <<<"$hashes"; $status diff --git a/06/helpers/maint/is-tested-enough b/06/helpers/maint/is-tested-enough new file mode 100755 index 0000000..faf61f9 --- /dev/null +++ b/06/helpers/maint/is-tested-enough @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -ueo pipefail + +COMMIT=${1-HEAD} + +commit=$(git show -s --no-notes "$COMMIT") +echo "$commit" +if grep -q '^\s*Builds-required: none$' <<<"$commit"; then + echo '---' + echo '`Builds-required: none` in commit message, skipping commit' + exit 0 +fi +echo '---' + +if grep -q '^\s*Builds-required: ' <<<"$commit"; then + verification_line=$(grep '^\s*Builds-required:' <<<"$commit") + verspec=$(sed 's|^\s*Builds-required:||' <<<"$verification_line") + if ! grep -Eq '^ make=[0-9]+ raw=[0-9]+ nix=[0-9]+$' <<<"$verspec"; then + echo 'Malformed `Builds-required:` line' >&2 + exit 7 + fi + required_make=$(sed -E 's|.* make=([0-9]+).*|\1|' <<<"$verspec") + (( required_make >= 0 )) + required_raw=$(sed -E 's|.* raw=([0-9]+).*|\1|' <<<"$verspec") + (( required_raw >= 0 )) + required_nix=$(sed -E 's|.* nix=([0-9]+).*|\1|' <<<"$verspec") + (( required_nix >= 0 )) +else + required_make=2 + required_raw=1 + required_nix=2 +fi + +git fetch origin refs/notes/commits:refs/notes/commits +notes=$(git notes show "$COMMIT" \ + | grep ^Built-on: \ + | grep -v USE_CCACHE \ + | sort -u) +using_make=$(grep -Fw how=make <<<"$notes" | wc -l) || true +using_raw=$(grep -Fw how=raw <<<"$notes" | wc -l) || true +using_nix=$(grep -Fw how=nix <<<"$notes" | wc -l) || true +echo "$notes" + +status=true +text="" +if (( using_make < required_make )); then + text+="Not enough how=make commits: $using_make < $required_make\n" + status=false +fi +if (( using_raw < required_raw )); then + text+="Not enough how=raw commits: $using_raw < $required_raw\n" + status=false +fi +if (( using_nix < required_nix )); then + text+="Not enough how=nix commits: $using_nix < $required_nix\n" + status=false +fi + +echo '---' +echo "${using_make} out of ${required_make} required how=make builds" +echo "${using_raw} out of ${required_raw} required how=raw builds" +echo "${using_nix} out of ${required_nix} required how=nix builds" +if ! $status; then + echo -ne "---\n$text" +fi +$status diff --git a/06/helpers/maint/notes b/06/helpers/maint/notes new file mode 100755 index 0000000..41a9956 --- /dev/null +++ b/06/helpers/maint/notes @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -ueo pipefail +if [[ $# == 0 || "$1" == 'show' ]]; then + exec git tree --show-notes --decorate=short --color=always \ + | grep -v '^|\s*$' \ + | grep -v 'Notes:$' \ + | sed 's/ Built-on: /^ Built-on: /' \ + | less +elif [[ "$1" == 'mark-built' ]] && (( $# >= 3 )) ; then + commit=$2; hostname=$3; how=$4; shift 4; extra="$@" + git fetch origin refs/notes/commits:refs/notes/commits + if ! grep -Eqx 'how=(raw|make|nix)' <<<$how; then + echo 'how must be one of: raw, make, nix' >/dev/stderr + exit 1 + fi + msg="Built-on: $hostname $how $extra" + if grep -Fqx "$msg" <(git notes show "$commit" 2>/dev/null); then + echo "$commit is already marked with '$msg'" >/dev/stderr + exit + fi + git notes append -m "$msg" "$commit" + git push origin refs/notes/commits +else + echo 'Usage: ' >/dev/stderr + echo ' helpers/notes [show]' >/dev/stderr + echo -n ' helpers/notes mark-built ' >/dev/stderr + echo ' how=[raw|make|nix] ' >/dev/stderr + exit 1 +fi diff --git a/06/helpers/maint/release b/06/helpers/maint/release new file mode 100755 index 0000000..f5e2a39 --- /dev/null +++ b/06/helpers/maint/release @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -uex + +# check that two extra files have not been modified + +seeder_path=$(nix eval --impure --expr '"${recipes/1-stage1/seed.host-executed.sh}"') +grep "stage1_seeder_reference = $seeder_path;$" using-nix/0.nix +syscall_h_path=$(nix eval --impure --expr '"${recipes/1-stage1/syscall.h}"') +grep "syscall_h_reference = $syscall_h_path;$" using-nix/0.nix + + +# check that both downloads in using-nix/0-prebuilt refer to the same tag + +lines=$(grep 'seeding-files-r[0-9]*' using-nix/0-prebuilt.nix \ + | sed 's/.*r\([0-9][0-9][0-9]\).*/\1/') +sort <<<"$lines" +[[ $(wc -l <<<"$lines") == 2 ]] +[[ $(sort <<<"$lines" | uniq | wc -l) == 1 ]] + + +# build nars, calculate hashes, check both 0-from-nixpkgs and 0-prebuilt + +[[ ! -L result* ]] + + +tinycc_=$(nix-build using-nix/0-from-nixpkgs.nix -A tinycc --no-out-link) +tinycc=$(nix-build using-nix/0-from-nixpkgs.nix -A tinycc --no-out-link --check) +[[ "$tinycc_" == "$tinycc" ]] +nix store dump-path $tinycc > tinycc-liberated.nar +tinycc_hash=$(nix hash file tinycc-liberated.nar) +grep "outputHash = \"$tinycc_hash\";$" using-nix/0-from-nixpkgs.nix +grep "sha256 = \"$tinycc_hash\";$" using-nix/0-prebuilt.nix + +protosrc_=$(nix-build using-nix/0-from-nixpkgs.nix -A protosrc --no-out-link) +protosrc=$(nix-build using-nix/0-from-nixpkgs.nix -A protosrc --no-out-link \ + --check) +[[ "$protosrc_" == "$protosrc" ]] +nix store dump-path $protosrc > protosrc.nar +protosrc_hash=$(nix hash file protosrc.nar) +grep "outputHash = \"$protosrc_hash\";$" using-nix/0-from-nixpkgs.nix +grep "sha256 = \"$protosrc_hash\";$" using-nix/0-prebuilt.nix + + +[[ ! -L result* ]] + + +# print release notes + +set +x + +cat <<\EOF +protosrc (patched sources of stage1 tinycc/protomusl/protobusybox) has to come from somewhere, and there are three main options: build as part of bootstrap, build using nixpkgs or take them from here. + +You don't need these files neither when you do the whole bootstrap-Nix-included route using ./build.sh/make, nor when you can afford pulling nixpkgs to build them. But there's at least a case for building in Hydra under restricted-eval mode where you can neither inject stuff externally nor IFD. These allow kickstarting Hydra builds as long as recipes/1-stage1/seed.host-executed.sh and recipes/1-stage1/syscall.h weren't modified. + +See using-nix/0.nix for more explanations of all three seeding options, using-nix/0-from-nixpkgs for how these were built. + +EOF + +echo "$tinycc_hash" tinycc-liberated.nar +echo "$protosrc_hash" protosrc.nar diff --git a/06/recipes/0-tcc-seed/seed.host-executed.sh b/06/recipes/0-tcc-seed/seed.host-executed.sh new file mode 100755 index 0000000..59d660f --- /dev/null +++ b/06/recipes/0-tcc-seed/seed.host-executed.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -uex + +cp tcc-seed stage/store/0-tcc-seed diff --git a/06/recipes/1-stage1.c b/06/recipes/1-stage1.c new file mode 100644 index 0000000..b78c079 --- /dev/null +++ b/06/recipes/1-stage1.c @@ -0,0 +1,933 @@ +// SPDX-FileCopyrightText: 2021 Alexander Sosedkin +// SPDX-License-Identifier: MIT + +// syscalls (x86_64) /////////////////////////////////////////////////////////// + +#ifndef INSIDE_NIX +#include "1-stage1/syscall.h" +#define TCC_SEED "/store/0-tcc-seed" +#define PROTOSRC "/protosrc" +#define RECIPES_STAGE1 "/recipes/1-stage1" +#define TMP_STAGE1 "/tmp/1-stage1" +#define STORE_PROTOBUSYBOX "/store/1-stage1/protobusybox" +#define STORE_PROTOMUSL "/store/1-stage1/protomusl" +#define STORE_TINYCC "/store/1-stage1/tinycc" +#define EXTRA_HELLO_ARGS +#else +#include "syscall.h" +#define EXTRA_HELLO_ARGS \ + "-DRECIPES_STAGE1=\"" RECIPES_STAGE1"\"", +#endif + +#define SYS_write 1 +#define SYS_open 2 +#define SYS_fork 57 +#define SYS_execve 59 +#define SYS_exit 60 +#define SYS_wait4 61 +#define SYS_getdents 78 +#define SYS_mkdir 83 + +long write(int fd, const void* buf, long cnt) { + return __syscall3(SYS_write, fd, (long) buf, cnt); +} + +int execve(const char* fname, + const char* const argv[], const char* const envp[]) { + return __syscall3(SYS_execve, (long) fname, (long) argv, (long) envp); +} + +void exit(int code) { __syscall1(SYS_exit, code); }; + +int fork() { return __syscall0(SYS_fork); } + +int wait4(int pid, int* status, int options, void* rusage) { + return __syscall4( + SYS_wait4, + pid, (long) status, options, (long) rusage + ); +} + +int mkdir(const char *pathname, unsigned mode) { + return __syscall2(SYS_mkdir, (long) pathname, mode); +} + +int open(const char *pathname, int flags, int mode) { + return __syscall3(SYS_open, (long) pathname, flags, mode); +} + +struct linux_dirent { + long d_ino; + long d_off; + unsigned short d_reclen; + char d_name[]; +}; +int getdents(unsigned int fd, struct linux_dirent *dirp, + unsigned int count) { + return __syscall3(SYS_getdents, fd, (long) dirp, count); +} + + +// random defines ////////////////////////////////////////////////////////////// + +#define NULL ((void*) 0) +#define STDOUT 1 +#define STDERR 2 +#define O_RDONLY 0 +#define O_DIRECTORY 0200000 +#define DT_REG 8 + + +// basic QoL /////////////////////////////////////////////////////////////////// + +unsigned strlen(const char* s) { + unsigned l; + for (l = 0; s[l]; l++); + return l; +} + +int write_(int fd, const char* msg) { + return write(fd, msg, strlen(msg)); +} + +#define __quote(x) #x +#define _quote(x) __quote(x) +// real assert calls abort() -> 128 + SIGABRT = 134 +#define assert(v) \ + while (!(v)) { \ + write_(STDERR, "Assertion "); \ + write_(STDERR, _quote(v)); write_(STDERR, " failed at "); \ + write_(STDERR, __FILE__); write_(STDERR, ":"); \ + write_(STDERR, __func__); write_(STDERR, ":"); \ + write_(STDERR, _quote(__LINE__)); write_(STDERR, "!\n"); \ + exit(134); \ + } + +void err(const char* msg) { assert(write_(STDERR, msg) == strlen(msg)); } + +void log_begin_line(const char* msg) { + assert(write_(STDOUT, "### 1-stage1.c: ") == 16); + assert(write_(STDOUT, msg) == strlen(msg)); +} +void log_continue_line(const char* msg) { + assert(write_(STDOUT, msg) == strlen(msg)); +} +void log_end_line() { assert(write_(STDOUT, "\n") == 1); } +void log(const char* msg) { log_begin_line(msg); log_end_line(); }; + + +// more library function substitutes /////////////////////////////////////////// + +void memset(char* ptr, int with, long len) { + long i; + for (i = 0; i < len; i++) + ptr[i] = with; +} + +char* strcpy(char* dest, const char* src) { + while (*src) + *dest++ = *src++; + *dest = 0; + return dest; +} + +int strcmp(const char* a, const char* b) { + for (; *a && *b; a++, b++) + if (*a != *b) + return (*a < *b) ? -1 : 1; + return !a && !b; +} + + +// my convenience functions: mkdir'ing ///////////////////////////////////////// + + +void mkreqdirs(const char* path) { + char b[128], *p; + strcpy(b, path); + for (p = b + 1; *p; p++) + if (*p == '/') { *p = '\0'; mkdir(b, 0777); *p = '/'; } +} +void mkreqdirs_at(const char* at, const char* subpath) { + char b[128], *p; + p = strcpy(b, at); + p = strcpy(strcpy(strcpy(p, "/"), subpath), "/"); + mkreqdirs(b); +} +#define mkdirs_at(at, args...) \ + do { \ + const char* const* p; \ + for (p = (char*[]) { "/", ## args, NULL }; *p; p++) \ + mkreqdirs_at(at, *p); \ + } while (0) + + +// my convenience functions: fork + exec /////////////////////////////////////// + +int run_(const char* cmd, const char* const args[], const char* const env[]) { + int pid, status, termsig; + if (pid = fork()) { + assert(wait4(pid, &status, 0, NULL) == pid); + termsig = status & 0x7f; // WTERMSIG + if (!termsig) { + return (status & 0xff00) >> 8; // WEXITSTATUS + } else { + err("child has been killed"); + exit(termsig); + } + } else { + exit(execve(cmd, args, env)); + } + return 0; // unreacheable +} + +#define run(expected_retcode, first_arg, args...) \ + do { \ + const char const* __env[] = {NULL}; \ + const char const* __args[] = {(first_arg), ##args, NULL}; \ + int __i; \ + log_begin_line("run() running: "); \ + for(__i = 0; __args[__i]; __i++) { \ + log_continue_line(__args[__i]); \ + log_continue_line(" "); \ + } \ + log_end_line(); \ + assert(run_(first_arg, __args, __env) == (expected_retcode)); \ + } while (0) +#define run0(first_arg, args...) run(0, (first_arg), ## args) + + +// my convenience functions: dynamic args accumulation / command execution ///// + +struct args_accumulator { + char* pointers[4096]; + char storage[262144]; + char** ptr_curr; + char* char_curr; +}; +void _aa_init(struct args_accumulator* aa) { + aa->char_curr = aa->storage; + aa->ptr_curr = aa->pointers; + *aa->ptr_curr = NULL; +} +void aa_append(struct args_accumulator* aa, const char* new_arg) { + *aa->ptr_curr = aa->char_curr; + *++aa->ptr_curr = NULL; + aa->char_curr = strcpy(aa->char_curr, new_arg); + aa->char_curr++; +} +void _aa_extend_from_arr(struct args_accumulator* aa, const char* const* p) { + for (; *p; p++) + aa_append(aa, *p); +} +void aa_extend_from(struct args_accumulator* aa, const void* from) { + // Cheat a little with void* to accept + // both struct args_accumulator* and null-terminated string arrays. + // Qualifiers could be stricter, but then declaring get cumbersome. + _aa_extend_from_arr(aa, (const char* const*) from); +} +#define aa_extend(aa_ptr, args...) \ + _aa_extend_from_arr(aa_ptr, (const char*[]) { NULL, ## args, NULL } + 1) +#define aa_init(aa_ptr, args...) \ + do { _aa_init(aa_ptr); aa_extend(aa_ptr, ## args); } while (0) +void aa_sort(struct args_accumulator* aa) { + int changes; + char **p, **n, *t; + if (!aa->pointers[0]) + return; + if (!aa->pointers[1]) + return; + do { + changes = 0; + for (p = aa->pointers, n = p + 1; *n; p++, n++) { + if (strcmp(*p, *n) > 0) { + t = *p; *p = *n; *n = t; + changes = 1; + } + } + } while (changes); +} +int aa_run(const struct args_accumulator* aa) { + int i; + log_begin_line("aa_run() running: "); + for (i = 0; aa->pointers[i]; i++) { + log_continue_line(aa->pointers[i]); + log_continue_line(" "); + } + log_end_line(STDOUT, "\n"); + return run_(aa->pointers[0], aa->pointers, (char*[]) { NULL }); +} +#define aa_run0(aa_ptr) do { assert(aa_run(aa_ptr) == 0); } while (0) + + +// my convenience functions: compiling whole directories worth of files //////// + +_Bool is_compileable(char* fname) { + int i = 0; + while (fname[i]) + i++; + if (i > 2) + if (fname[i - 2] == '.') + if (fname[i - 1] == 'c' || fname[i-1] == 's') + return 1; + return 0; +} + +void aa_extend_from_dir(struct args_accumulator* aa_out, + unsigned short keep_components, const char* dir_path) { + struct args_accumulator aa; + char d_buf[256]; + char buf[256]; + const char* prefix; + char* out_subpath; + struct linux_dirent* d; + int fd, r; + char d_type; + + aa_init(&aa); + + prefix = dir_path + strlen(dir_path); + while (keep_components) { + while (*prefix != '/') + prefix--; + keep_components--; + prefix += keep_components ? -1 : 1; + } + + fd = open(dir_path, O_RDONLY | O_DIRECTORY, 0); + assert(fd != -1); + + while (1) { + d = (struct linux_dirent*) d_buf; + r = getdents(fd, d, 256); + assert(r != -1); + if (!r) + break; + while ((char*) d - d_buf < r) { + d_type = *((char*) d + d->d_reclen - 1); + if ((d_type == DT_REG || !d_type) + && is_compileable(d->d_name)) { + out_subpath = strcpy(buf, prefix); + out_subpath = strcpy(out_subpath, "/"); + out_subpath = strcpy(out_subpath, d->d_name); + aa_append(&aa, buf); + } + d = (struct linux_dirent*) ((char*) d + d->d_reclen); + } + } + aa_sort(&aa); // iteration order isn't guaranteed, make stable + aa_extend_from(aa_out, &aa); +} + + +void mass_compile(const char* cc, const void* compile_args, + const char* in_dir_path, const void* fnames /* NULL=auto */, + const char* out_obj_dir_path, const char* out_lib_file_path) { + // qualifiers could've been stricter + // const void* could be struct args_accumulator*, + // NULL-terminated arrays or even just NULLs for fnames + struct args_accumulator aa, aa_link, aa_sources; + char in_file_path_buf[128], out_file_path_buf[128]; + char* in_file_path; + char* out_file_path; + char** p; + + aa_init(&aa_sources); + if (!fnames) + aa_extend_from_dir(&aa_sources, 0, in_dir_path); + else + aa_extend_from(&aa_sources, fnames); + + mkreqdirs(out_lib_file_path); + aa_init(&aa_link, cc, "-ar", "rc", out_lib_file_path); + + for (p = (char**) &aa_sources; *p; p++) { + in_file_path = strcpy(in_file_path_buf, in_dir_path); + in_file_path = strcpy(in_file_path, "/"); + in_file_path = strcpy(in_file_path, *p); + + out_file_path = strcpy(out_file_path_buf, out_obj_dir_path); + out_file_path = strcpy(out_file_path, "/"); + out_file_path = strcpy(out_file_path, *p); + out_file_path = strcpy(out_file_path, ".o"); + mkreqdirs(out_file_path_buf); + + aa_init(&aa, cc); + aa_extend_from(&aa, compile_args); + aa_extend(&aa, "-c", in_file_path_buf, "-o", out_file_path_buf); + aa_run0(&aa); + + aa_append(&aa_link, out_file_path_buf); + } + aa_run0(&aa_link); +} + + +// Kinda boring parts ////////////////////////////////////////////////////////// + +#define TCC_ARGS_NOSTD "-nostdlib", "-nostdinc", "-I", "/protosrc/tinycc/include" + + +void sanity_test() { + struct args_accumulator aa1, aa2; + + log("sanity-testing run()..."); + log("* testing run() -> retcode 0..."); + run0(TCC_SEED, "--help"); + log("* testing run() -> retcode 1..."); + run(1, TCC_SEED, "-ar", "--help"); + log("run() seems to work OK"); + + log("sanity-testing args accumulator..."); + log("* testing aa_append, aa_extend, aa_sort and aa_run0..."); + aa_init(&aa1); + aa_init(&aa2); + aa_append(&aa1, TCC_SEED); + aa_append(&aa2, "-ar"); + aa_extend(&aa2, "help-must-precede-ar", "--help"); + aa_sort(&aa2); + aa_extend_from(&aa1, &aa2); + assert(!strcmp(((char**) &aa1)[0], TCC_SEED)); + assert(!strcmp(((char**) &aa1)[1], "--help")); + assert(!strcmp(((char**) &aa1)[2], "-ar")); + assert(!strcmp(((char**) &aa1)[3], "help-must-precede-ar")); + assert(NULL == ((char**) &aa1)[4]); + aa_run0(&aa1); + + log("* testing aa_multi and aa_run for 1..."); + aa_init(&aa1, TCC_SEED, "-ar", "--help"); + assert(aa_run(&aa1) == 1); +} + + +// Interesting parts: libtcc1 ////////////////////////////////////////////////// + + +void compile_libtcc1_1st_time_nostd(const char* cc) { + log("compiling our first libtcc1.a..."); + mass_compile(cc, (char* []) { TCC_ARGS_NOSTD, "-DTCC_MUSL", NULL }, + PROTOSRC"/tinycc/lib", (char* []) { + "libtcc1.c", "alloca.S", + "dsohandle.c", "stdatomic.c", "va_list.c", + 0}, + TMP_STAGE1"/tinycc/libtcc1", + STORE_TINYCC"/lib/libtcc1.a"); +} // see also compile_libtcc1 far below + + +// Interesting parts: protomusl //////////////////////////////////////////////// + +#define PROTOMUSL_EXTRA_CFLAGS \ + "-std=c99", \ + "-D_XOPEN_SOURCE=700" +#define PROTOMUSL_INTERNAL_INCLUDES \ + "-I" PROTOSRC"/protomusl/src/include", \ + "-I" PROTOSRC"/protomusl/arch/x86_64", \ + "-I" PROTOSRC"/protomusl/host-generated/sed1", \ + "-I" PROTOSRC"/protomusl/host-generated/sed2", \ + "-I" PROTOSRC"/protomusl/arch/generic", \ + "-I" PROTOSRC"/protomusl/src/internal", \ + "-I" PROTOSRC"/protomusl/include" +#define PROTOMUSL_NOSTD_LDFLAGS_PRE \ + "-static", \ + STORE_PROTOMUSL"/lib/crt1.o", \ + STORE_PROTOMUSL"/lib/crti.o" +#define PROTOMUSL_NOSTD_LDFLAGS_POST \ + STORE_PROTOMUSL"/lib/libc.a", \ + STORE_PROTOMUSL"/lib/crtn.o" +#define PROTOMUSL_INCLUDES \ + "-I" PROTOSRC"/protomusl/include", \ + "-I" PROTOSRC"/protomusl/arch/x86_64", \ + "-I" PROTOSRC"/protomusl/arch/generic", \ + "-I" PROTOSRC"/protomusl/host-generated/sed1", \ + "-I" PROTOSRC"/protomusl/host-generated/sed2" + +void compile_protomusl(const char* cc) { + struct args_accumulator aa; + aa_init(&aa); + + log("compiling part of musl (protomusl)..."); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/conf"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/ctype"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/dirent"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/env"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/errno"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/exit"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/fcntl"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/fenv"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/internal"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/ldso"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/legacy"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/linux"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/locale"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/malloc"); + aa_extend_from_dir(&aa, 2, PROTOSRC"/protomusl/src/malloc/mallocng"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/math"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/misc"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/mman"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/multibyte"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/network"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/passwd"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/prng"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/process"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/regex"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/select"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/setjmp"); + aa_extend_from_dir(&aa, 2, PROTOSRC"/protomusl/src/setjmp/x86_64"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/signal"); + aa_extend_from_dir(&aa, 2, PROTOSRC"/protomusl/src/signal/x86_64"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/stat"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/stdio"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/stdlib"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/string"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/temp"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/termios"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/thread"); + aa_extend_from_dir(&aa, 2, PROTOSRC"/protomusl/src/thread/x86_64"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/time"); + aa_extend_from_dir(&aa, 1, PROTOSRC"/protomusl/src/unistd"); + mass_compile(cc, (char*[]) { + TCC_ARGS_NOSTD, + PROTOMUSL_EXTRA_CFLAGS, + PROTOMUSL_INTERNAL_INCLUDES, + 0}, + PROTOSRC"/protomusl/src", &aa, + TMP_STAGE1"/protomusl", + STORE_PROTOMUSL"/lib/libc.a"); + + log("compiling crt bits of protomusl..."); + run0(cc, TCC_ARGS_NOSTD, PROTOMUSL_INTERNAL_INCLUDES, "-DCRT", + "-c", PROTOSRC"/protomusl/crt/crt1.c", + "-o", STORE_PROTOMUSL"/lib/crt1.o"); + run0(cc, TCC_ARGS_NOSTD, "-DCRT", + "-c", PROTOSRC"/protomusl/crt/crti.c", + "-o", STORE_PROTOMUSL"/lib/crti.o"); + run0(cc, TCC_ARGS_NOSTD, "-DCRT", + "-c", PROTOSRC"/protomusl/crt/crtn.c", + "-o", STORE_PROTOMUSL"/lib/crtn.o"); +} + +void test_example_1st_time_nostd(const char* cc) { + log("linking an example (1st time)..."); + run0(cc, TCC_ARGS_NOSTD, PROTOMUSL_INCLUDES, + PROTOMUSL_NOSTD_LDFLAGS_PRE, + RECIPES_STAGE1"/hello.c", EXTRA_HELLO_ARGS + PROTOMUSL_NOSTD_LDFLAGS_POST, + STORE_TINYCC"/lib/libtcc1.a", + "-o", TMP_STAGE1"/protomusl-hello"); + + log("executing an example..."); + run(42, TMP_STAGE1"/protomusl-hello"); +} + + +// Interesting parts: recompiling tcc ////////////////////////////////////////// + +void compile_libtcc1(const char* cc) { + log("recompiling libtcc1.a..."); + mass_compile(cc, (char*[]) { "-DTCC_MUSL", PROTOMUSL_INCLUDES, 0}, + PROTOSRC"/tinycc/lib", (char*[]) { + "libtcc1.c", "alloca.S", + "dsohandle.c", "stdatomic.c", "va_list.c", + // now we can compile more + "tcov.c", "alloca-bt.S", + // bcheck.c is excluded, as it references __FILE__ + 0}, + TMP_STAGE1"/tinycc/libtcc1", + STORE_TINYCC"/lib/libtcc1.a"); +} + +#define TCC_CFLAGS \ + "-I"PROTOSRC"/tinycc", \ + "-I"PROTOSRC"/tinycc/include", \ + "-I"TMP_STAGE1"/tinycc/gen", \ + "-DTCC_VERSION=\"mob-af1abf1\"", \ + "-DTCC_GITHASH=\"mob:af1abf1\"", \ + "-DTCC_TARGET_X86_64", \ + "-DTCC_MUSL", \ + "-DONE_SOURCE=0", \ + "-DCONFIG_TCCDIR=\""STORE_TINYCC"/lib\"", \ + "-DCONFIG_TCC_SYSINCLUDEPATHS="\ + "\""STORE_PROTOMUSL"/include\"", \ + "-DCONFIG_TCC_LIBPATHS=\""STORE_PROTOMUSL"/lib\"", \ + "-DCONFIG_TCC_CRTPREFIX=\""STORE_PROTOMUSL"/lib\"", \ + "-DCONFIG_TCC_ELFINTERP=\"/sorry/not/yet\"", \ + "-DCONFIG_TCC_PREDEFS=1" + +void compile_tcc_1st_time_nostd(const char* cc) { + log("compiling tcc's conftest..."); + mkdirs_at(TMP_STAGE1"/tinycc", "gen", "lib", "bin"); + mkdirs_at(STORE_TINYCC"", "lib", "bin"); + run0(cc, TCC_ARGS_NOSTD, PROTOMUSL_INCLUDES, + PROTOMUSL_NOSTD_LDFLAGS_PRE, + "-DC2STR", PROTOSRC"/tinycc/conftest.c", + PROTOMUSL_NOSTD_LDFLAGS_POST, + STORE_TINYCC"/lib/libtcc1.a", + "-o", TMP_STAGE1"/tinycc/conftest" + ); + log("generating tccdefs_.h with conftest..."); + run0(TMP_STAGE1"/tinycc/conftest", + PROTOSRC"/tinycc/include/tccdefs.h", + TMP_STAGE1"/tinycc/gen/tccdefs_.h"); + + log("compiling libtcc..."); + mass_compile(cc, (char*[]) { + TCC_ARGS_NOSTD, + PROTOMUSL_INCLUDES, + TCC_CFLAGS, + 0}, + PROTOSRC"/tinycc", (char*[]) { + "libtcc.c", "tccpp.c", "tccgen.c", "tccelf.c", + "tccdbg.c", "tccasm.c", "tccrun.c", + "x86_64-gen.c", "x86_64-link.c", "i386-asm.c", + 0}, + TMP_STAGE1"/tinycc/libtcc", + STORE_TINYCC"/lib/libtcc.a"); + run0(cc, TCC_ARGS_NOSTD, PROTOMUSL_INCLUDES, TCC_CFLAGS, + PROTOMUSL_NOSTD_LDFLAGS_PRE, + PROTOSRC"/tinycc/tcc.c", + STORE_TINYCC"/lib/libtcc.a", + PROTOMUSL_NOSTD_LDFLAGS_POST, + STORE_TINYCC"/lib/libtcc1.a", + "-o", STORE_TINYCC"/bin/tcc"); + run0(STORE_TINYCC"/bin/tcc", "-print-search-dirs"); +} + + +void compile_tcc(const char* cc) { + log("recompiling libtcc..."); + mass_compile(cc, (char*[]) { PROTOMUSL_INCLUDES, TCC_CFLAGS, 0}, + PROTOSRC"/tinycc", (char*[]) { + "libtcc.c", "tccpp.c", "tccgen.c", "tccelf.c", + "tccdbg.c", "tccasm.c", "tccrun.c", + "x86_64-gen.c", "x86_64-link.c", "i386-asm.c", + 0}, + TMP_STAGE1"/tinycc/libtcc", + STORE_TINYCC"/lib/libtcc.a"); + run0(cc, PROTOMUSL_INCLUDES, TCC_CFLAGS, "-static", + PROTOSRC"/tinycc/tcc.c", + STORE_TINYCC"/lib/libtcc.a", + "-o", STORE_TINYCC"/bin/tcc"); +} + +void test_example_intermediate(const char* cc) { + log("linking an example (our tcc, includes not installed)..."); + run0(cc, PROTOMUSL_INCLUDES, "-static", + RECIPES_STAGE1"/hello.c", EXTRA_HELLO_ARGS + "-o", TMP_STAGE1"/protomusl-hello"); + + log("executing an example..."); + run(42, TMP_STAGE1"/protomusl-hello"); +} + +void test_example_final(const char* cc_wrapper) { + log("linking an example (wrapped tcc, includes installed)..."); + run0(cc_wrapper, RECIPES_STAGE1"/hello.c", EXTRA_HELLO_ARGS + "-o", TMP_STAGE1"/protomusl-hello"); + + log("executing an example..."); + run(42, TMP_STAGE1"/protomusl-hello"); +} + + +// Interesting parts: hacky standalone busybox applets ///////////////////////// + +void compile_standalone_busybox_applets(const char* cc) { + log("compiling protolibbb..."); + mass_compile(cc, (char*[]) { + PROTOMUSL_INCLUDES, + "-I"PROTOSRC"/protobusybox/include/", + "-I"PROTOSRC"/protobusybox/libbb/", + "-include", RECIPES_STAGE1"/protobusybox.h", + 0}, + PROTOSRC"/protobusybox/libbb", (char*[]) { + "ask_confirmation.c", + "auto_string.c", + "bb_cat.c", + "bb_getgroups.c", + "bb_pwd.c", + "bb_strtonum.c", + "compare_string_array.c", + "concat_path_file.c", + "concat_subpath_file.c", + "copy_file.c", + "copyfd.c", + "crc32.c", + "default_error_retval.c", + "dump.c", + "endofname.c", + "executable.c", + "fclose_nonstdin.c", + "fflush_stdout_and_exit.c", + "full_write.c", + "get_last_path_component.c", + "get_line_from_file.c", + "getopt32.c", + "inode_hash.c", + "isdirectory.c", + "isqrt.c", + "last_char_is.c", + "llist.c", + "make_directory.c", + "messages.c", + "mode_string.c", + "parse_mode.c", + "perror_msg.c", + "perror_nomsg_and_die.c", + "printable_string.c", + "process_escape_sequence.c", + "procps.c", + "ptr_to_globals.c", + "read.c", + "read_printf.c", + "recursive_action.c", + "remove_file.c", + "safe_poll.c", + "safe_strncpy.c", + "safe_write.c", + "signals.c", + "single_argv.c", + "skip_whitespace.c", + "sysconf.c", + "time.c", + "u_signal_names.c", + "verror_msg.c", + "vfork_daemon_rexec.c", + "wfopen.c", + "wfopen_input.c", + "xatonum.c", + "xfunc_die.c", + "xfuncs.c", + "xfuncs_printf.c", + "xgetcwd.c", + "xreadlink.c", + "xrealloc_vector.c", + "xregcomp.c", + 0}, + TMP_STAGE1"/protobusybox/libbb", + TMP_STAGE1"/protobusybox/libbb.a"); + + + log("compiling standalone protobusybox applets..."); + mkreqdirs(STORE_PROTOBUSYBOX"/bin/"); + #define compile_applet(applet_name, files...) \ + run0(cc, PROTOMUSL_INCLUDES, \ + "-D__GNUC__=2", "-D__GNUC_MINOR__=7", \ + "-static", \ + "-I"PROTOSRC"/protobusybox/include", \ + "-include", RECIPES_STAGE1"/protobusybox.h", \ + "-DAPPLET_MAIN=" applet_name "_main", \ + RECIPES_STAGE1"/protobusybox.c", \ + ## files, \ + TMP_STAGE1"/protobusybox/libbb.a", \ + "-o", STORE_PROTOBUSYBOX"/bin/" applet_name); + compile_applet("echo", PROTOSRC"/protobusybox/coreutils/echo.c") + run0(STORE_PROTOBUSYBOX"/bin/echo", + "Hello from protobusybox!"); + + compile_applet("ash", + PROTOSRC"/protobusybox/shell/shell_common.c", + PROTOSRC"/protobusybox/shell/ash_ptr_hack.c", + PROTOSRC"/protobusybox/shell/math.c", + PROTOSRC"/protobusybox/coreutils/printf.c", + PROTOSRC"/protobusybox/coreutils/test_ptr_hack.c", + PROTOSRC"/protobusybox/coreutils/test.c", + PROTOSRC"/protobusybox/shell/ash.c") + run(42, STORE_PROTOBUSYBOX"/bin/ash", "-c", + "printf 'Hello from ash!\n'; exit 42"); + + compile_applet("basename", + PROTOSRC"/protobusybox/coreutils/basename.c") + compile_applet("cat", PROTOSRC"/protobusybox/coreutils/cat.c") + compile_applet("chmod", PROTOSRC"/protobusybox/coreutils/chmod.c") + compile_applet("cp", + PROTOSRC"/protobusybox/coreutils/libcoreutils/cp_mv_stat.c", + PROTOSRC"/protobusybox/coreutils/cp.c"); + compile_applet("cut", PROTOSRC"/protobusybox/coreutils/cut.c"); + compile_applet("dirname", PROTOSRC"/protobusybox/coreutils/dirname.c") + compile_applet("env", PROTOSRC"/protobusybox/coreutils/env.c"); + compile_applet("expr", PROTOSRC"/protobusybox/coreutils/expr.c"); + compile_applet("head", PROTOSRC"/protobusybox/coreutils/head.c"); + compile_applet("install", PROTOSRC"/protobusybox/coreutils/install.c"); + compile_applet("ln", PROTOSRC"/protobusybox/coreutils/ln.c"); + compile_applet("ls", PROTOSRC"/protobusybox/coreutils/ls.c"); + compile_applet("mkdir", PROTOSRC"/protobusybox/coreutils/mkdir.c"); + compile_applet("mktemp", PROTOSRC"/protobusybox/coreutils/mktemp.c"); + compile_applet("mv", + PROTOSRC"/protobusybox/coreutils/libcoreutils/cp_mv_stat.c", + PROTOSRC"/protobusybox/coreutils/mv.c"); + compile_applet("od", PROTOSRC"/protobusybox/coreutils/od.c"); + compile_applet("pwd", PROTOSRC"/protobusybox/coreutils/pwd.c"); + compile_applet("rm", PROTOSRC"/protobusybox/coreutils/rm.c"); + compile_applet("rmdir", PROTOSRC"/protobusybox/coreutils/rmdir.c"); + compile_applet("sleep", PROTOSRC"/protobusybox/coreutils/sleep.c"); + compile_applet("sort", PROTOSRC"/protobusybox/coreutils/sort.c"); + compile_applet("touch", PROTOSRC"/protobusybox/coreutils/touch.c"); + compile_applet("tr", PROTOSRC"/protobusybox/coreutils/tr.c"); + compile_applet("true", PROTOSRC"/protobusybox/coreutils/true.c"); + compile_applet("uname", PROTOSRC"/protobusybox/coreutils/uname.c"); + compile_applet("uniq", PROTOSRC"/protobusybox/coreutils/uniq.c"); + compile_applet("wc", PROTOSRC"/protobusybox/coreutils/wc.c"); + + #define LIBARCHIVE PROTOSRC"/protobusybox/archival/libarchive" + compile_applet("tar", + LIBARCHIVE "/data_align.c", + LIBARCHIVE "/data_extract_all.c", + LIBARCHIVE "/data_extract_to_stdout.c", + LIBARCHIVE "/data_skip.c", + LIBARCHIVE "/decompress_bunzip2.c", + LIBARCHIVE "/decompress_gunzip.c", + LIBARCHIVE "/decompress_unxz.c", + LIBARCHIVE "/filter_accept_all.c", + LIBARCHIVE "/filter_accept_reject_list.c", + LIBARCHIVE "/find_list_entry.c", + LIBARCHIVE "/get_header_tar.c", + LIBARCHIVE "/header_list.c", + LIBARCHIVE "/header_skip.c", + LIBARCHIVE "/header_verbose_list.c", + LIBARCHIVE "/init_handle.c", + LIBARCHIVE "/open_transformer.c", + LIBARCHIVE "/seek_by_jump.c", + LIBARCHIVE "/seek_by_read.c", + LIBARCHIVE "/unsafe_prefix.c", + LIBARCHIVE "/unsafe_symlink_target.c", + PROTOSRC"/protobusybox/archival/chksum_and_xwrite_tar_header.c", + PROTOSRC"/protobusybox/archival/tar.c"); + + compile_applet("bzip2", PROTOSRC"/protobusybox/archival/bzip2.c", + PROTOSRC"/protobusybox/archival/bbunzip.c", + LIBARCHIVE "/decompress_bunzip2.c", + LIBARCHIVE "/decompress_gunzip.c", + LIBARCHIVE "/decompress_unxz.c", + LIBARCHIVE "/open_transformer.c" + ); + + compile_applet("awk", PROTOSRC"/protobusybox/editors/awk.c"); + compile_applet("cmp", PROTOSRC"/protobusybox/editors/cmp.c"); + compile_applet("diff", PROTOSRC"/protobusybox/editors/diff.c"); + compile_applet("sed", PROTOSRC"/protobusybox/editors/sed.c"); + + compile_applet("grep", PROTOSRC"/protobusybox/findutils/grep.c"); + compile_applet("find", PROTOSRC"/protobusybox/findutils/find.c"); + compile_applet("xargs", PROTOSRC"/protobusybox/findutils/xargs.c"); +} + + +// Little things we'll do now when we have a shell ///////////////////////////// + +void verify_tcc_stability(void) { + run0(STORE_PROTOBUSYBOX"/bin/cp", + STORE_TINYCC"/bin/tcc", TMP_STAGE1"/tcc-bak"); + compile_tcc(STORE_TINYCC"/bin/tcc"); + run0(STORE_PROTOBUSYBOX"/bin/diff", + STORE_TINYCC"/bin/tcc", TMP_STAGE1"/tcc-bak"); +} + +void tweak_output_in_store(void) { + run0(STORE_PROTOBUSYBOX"/bin/ash", "-uexvc", + ":> "TMP_STAGE1"/empty.c\n" + STORE_TINYCC"/bin/tcc -c "TMP_STAGE1"/empty.c " + "-o "TMP_STAGE1"/empty.o\n" + STORE_TINYCC"/bin/tcc -ar "TMP_STAGE1"/empty.a " + TMP_STAGE1"/empty.o\n" + STORE_PROTOBUSYBOX"/bin/cp "TMP_STAGE1"/empty.a " + STORE_PROTOMUSL"/lib/libm.a\n" + STORE_PROTOBUSYBOX"/bin/cp "TMP_STAGE1"/empty.a " + STORE_PROTOMUSL"/lib/libpthread.a\n" + + STORE_PROTOBUSYBOX"/bin/rm -rf " + STORE_PROTOMUSL"/include\n" + STORE_PROTOBUSYBOX"/bin/mkdir -p " + STORE_PROTOMUSL"/include/bits\n" + STORE_PROTOBUSYBOX"/bin/cp -rf " + PROTOSRC"/protomusl/host-generated/sed1/bits " + PROTOSRC"/protomusl/host-generated/sed2/bits " + PROTOSRC"/protomusl/arch/generic/* " + PROTOSRC"/protomusl/arch/x86_64/* " + PROTOSRC"/protomusl/include/* " + STORE_PROTOMUSL"/include/\n" + ); +} + + +void wrap_tcc_tools(void) { + #define EXECTCC "#!"STORE_PROTOBUSYBOX"/bin/ash\n" \ + "exec "STORE_TINYCC"/bin/tcc" + #define PASSTHROUGH "\\\"\\$@\\\"" // i.e., \"\$@\", i.e, "$@" + run0(STORE_PROTOBUSYBOX"/bin/ash", "-uexvc", + "PATH="STORE_PROTOBUSYBOX"/bin\n" + "mkdir -p "STORE_TINYCC"/wrappers\n" + "cd "STORE_TINYCC"/wrappers\n" + "_CPP_ARGS=\"-I"STORE_PROTOMUSL"/include\"\n" + "_LD_ARGS='-static'\n" + "echo -e \"" EXECTCC " $_LD_ARGS " PASSTHROUGH"\" > cc\n" + "echo -e \"" EXECTCC " -E $_CPP_ARGS " PASSTHROUGH"\" > cpp\n" + "echo -e \"" EXECTCC " $_LD_ARGS " PASSTHROUGH"\" > ld\n" + "echo -e \"" EXECTCC " -ar " PASSTHROUGH "\" > ar\n" + "chmod +x cc cpp ld ar\n" + ); +} + + +// The main plot /////////////////////////////////////////////////////////////// + +int _start() { + struct args_accumulator aa_cmd; + struct args_accumulator aa_link_objs; + + log("hello from stage1!"); +#ifdef INSIDE_NIX + log("executed inside nix"); + log("TCC_SEED=" TCC_SEED); + log("PROTOSRC=" PROTOSRC); + log("RECIPES_STAGE1=" RECIPES_STAGE1); + log("TMP_STAGE1=" TMP_STAGE1); + log("STORE_PROTOBUSYBOX=" STORE_PROTOBUSYBOX); + log("STORE_PROTOMUSL=" STORE_PROTOMUSL); + log("STORE_TINYCC=" STORE_TINYCC); +#endif + + log("creating directories..."); + mkdirs_at("/", + TMP_STAGE1, STORE_PROTOBUSYBOX, STORE_PROTOMUSL, STORE_TINYCC); + + sanity_test(); + + // starting with the seeded TCC + compile_libtcc1_1st_time_nostd(TCC_SEED); + compile_protomusl(TCC_SEED); + test_example_1st_time_nostd(TCC_SEED); + + // build the first TCC that comes from our sources + compile_tcc_1st_time_nostd(TCC_SEED); + test_example_intermediate(STORE_TINYCC"/bin/tcc"); + // rebuild everything with it + compile_libtcc1(STORE_TINYCC"/bin/tcc"); + compile_protomusl(STORE_TINYCC"/bin/tcc"); + test_example_intermediate(STORE_TINYCC"/bin/tcc"); + + // this is the final tcc we'll build, should not be worth repeating + compile_tcc(STORE_TINYCC"/bin/tcc"); + // recompile everything else with the final tcc (could be an overkill) + compile_libtcc1(STORE_TINYCC"/bin/tcc"); + compile_protomusl(STORE_TINYCC"/bin/tcc"); + test_example_intermediate(STORE_TINYCC"/bin/tcc"); + + compile_standalone_busybox_applets(STORE_TINYCC"/bin/tcc"); + + verify_tcc_stability(); + tweak_output_in_store(); + wrap_tcc_tools(); + test_example_final(STORE_TINYCC"/wrappers/cc"); + + log("done"); + +#ifndef CHAINLOAD + return 0; +#else + assert(execve(CHAINLOAD, (char*[]) {CHAINLOAD, 0}, NULL)); + + log("could not exec into next stages (ok when building with make)"); + return 99; +#endif +} diff --git a/06/recipes/1-stage1/hello.c b/06/recipes/1-stage1/hello.c new file mode 100644 index 0000000..e1e8aa7 --- /dev/null +++ b/06/recipes/1-stage1/hello.c @@ -0,0 +1,21 @@ +#include + +#ifndef RECIPES_STAGE1 +#define RECIPES_STAGE1 "/recipes/1-stage1" +#endif +#define SOURCE_PATH RECIPES_STAGE1"/hello.c" + +int main(int argc, char** argv) { + printf("Hello world!\n2*2=%d\n", 2*2); + + printf("Own source (%s):\n", SOURCE_PATH); + FILE* f = fopen(SOURCE_PATH, "r"); + while (!feof(f)) { + fputc(fgetc(f), stdout); + } + if (ferror(f)) + return 99; + fclose(f); + + return 42; +} diff --git a/06/recipes/1-stage1/protobusybox.c b/06/recipes/1-stage1/protobusybox.c new file mode 100644 index 0000000..47f4389 --- /dev/null +++ b/06/recipes/1-stage1/protobusybox.c @@ -0,0 +1,46 @@ +extern int APPLET_MAIN(int argc, char** argv); // templated in + +#include +#include + +#include +static inline int *get_perrno(void) { return &errno; } +int *const bb_errno; + +char bb_common_bufsiz1[1024]; + +const char *applet_name; +int _argc; +const char **_argv; + +int main(int argc, char** argv) { + int** bb_errno_ptr = &((int*) bb_errno); + *bb_errno_ptr = ((int*) get_perrno()); + asm volatile ("":::"memory"); // counter optimizations + + _argc = argc; _argv = argv; + + applet_name = strrchr(argv[0], '/') \ + ? strrchr(argv[0], '/') + 1 \ + : argv[0]; + return APPLET_MAIN(argc, argv); +} + +void bb_show_usage(void) { + int i; + write(2 /* STDERR */, "protobusybox's show_usage stub\n", 31); + write(2 /* STDERR */, "ho help for you, sorry. argv[]: \n", 33); + for (i < 0; i < _argc; i++) { + write(2 /* STDERR */, "* `", 3); + write(2 /* STDERR */, _argv[i], strlen(_argv[i])); + write(2 /* STDERR */, "`\n", 2); + } + exit(1); +} + +// appletlib replacement +unsigned string_array_len(char **argv) { + unsigned i; + for (i = 0; argv[i]; i++); + return i; +} diff --git a/06/recipes/1-stage1/protobusybox.h b/06/recipes/1-stage1/protobusybox.h new file mode 100644 index 0000000..2729b35 --- /dev/null +++ b/06/recipes/1-stage1/protobusybox.h @@ -0,0 +1,240 @@ +#define NUM_APPLETS 1 +#define BB_GLOBAL_CONST +#define BB_VER "1.36.1" +#define AUTOCONF_TIMESTAMP +#define _GNU_SOURCE + +extern char bb_common_bufsiz1[]; +#define setup_common_bufsiz() ((void)0) +enum { COMMON_BUFSIZE = 1024 }; + +#define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe" +#define CONFIG_FEATURE_COPYBUF_KB 256 +#define CONFIG_FEATURE_EDITING_MAX_LEN 1024 +#define CONFIG_GZIP_FAST 2 +#define CONFIG_UNAME_OSNAME "Linux" + +#define ENABLE_ASH_ALIAS 0 +#define ENABLE_ASH_BASH_COMPAT 0 +#define ENABLE_ASH_CMDCMD 1 +#define ENABLE_ASH_ECHO 0 +#define ENABLE_ASH_GETOPTS 1 +#define ENABLE_ASH_JOB_CONTROL 0 +#define ENABLE_ASH_MAIL 0 +#define ENABLE_ASH_PRINTF 1 +#define ENABLE_ASH_SLEEP 0 +#define ENABLE_ASH_TEST 1 +#define ENABLE_BB_ARCH 1 +#define ENABLE_BUNZIP2 0 +#define ENABLE_BZCAT 0 +#define ENABLE_DEBUG 0 +#define ENABLE_DESKTOP 1 +#define ENABLE_EGREP 0 +#define ENABLE_FEATURE_ALLOW_EXEC 0 +#define ENABLE_FEATURE_AWK_LIBM 0 +#define ENABLE_FEATURE_BZIP2_DECOMPRESS 1 +#define ENABLE_FEATURE_CLEAN_UP 0 +#define ENABLE_FEATURE_CP_REFLINK 0 +#define ENABLE_FEATURE_CROND_D 0 +#define ENABLE_FEATURE_CUT_REGEX 0 +#define ENABLE_FEATURE_EDITING 0 +#define ENABLE_FEATURE_FANCY_ECHO 1 +#define ENABLE_FEATURE_FIND_NOT 1 +#define ENABLE_FEATURE_FIND_PAREN 1 +#define ENABLE_FEATURE_FIND_PRUNE 1 +#define ENABLE_FEATURE_FIND_TYPE 1 +#define ENABLE_FEATURE_GZIP_DECOMPRESS 1 +#define ENABLE_FEATURE_HUMAN_READABLE 0 +#define ENABLE_FEATURE_LS_COLOR 0 +#define ENABLE_FEATURE_LS_FILETYPES 0 +#define ENABLE_FEATURE_LS_FOLLOWLINKS 0 +#define ENABLE_FEATURE_LS_RECURSIVE 0 +#define ENABLE_FEATURE_LS_SORTFILES 0 +#define ENABLE_FEATURE_LS_TIMESTAMPS 1 +#define ENABLE_FEATURE_LS_WIDTH 0 +#define ENABLE_FEATURE_NON_POSIX_CP 0 +#define ENABLE_FEATURE_PRESERVE_HARDLINKS 0 +#define ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS 0 +#define ENABLE_FEATURE_SEAMLESS_BZ2 1 +#define ENABLE_FEATURE_SEAMLESS_GZ 1 +#define ENABLE_FEATURE_SEAMLESS_LZMA 0 +#define ENABLE_FEATURE_SEAMLESS_XZ 1 +#define ENABLE_FEATURE_SEAMLESS_Z 0 +#define ENABLE_FEATURE_SHOW_THREADS 0 +#define ENABLE_FEATURE_SH_MATH 1 +#define ENABLE_FEATURE_SH_READ_FRAC 0 +#define ENABLE_FEATURE_SYSLOG 0 +#define ENABLE_FEATURE_TAR_AUTODETECT 1 +#define ENABLE_FEATURE_TAR_CREATE 1 +#define ENABLE_FEATURE_TAR_GNU_EXTENSIONS 1 +#define ENABLE_FEATURE_TAR_LONG_OPTIONS 1 +#define ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY 1 +#define ENABLE_FEATURE_TAR_OLDSUN_COMPATIBILITY 0 +#define ENABLE_FEATURE_TOPMEM 1 +#define ENABLE_FEATURE_TOP_SMP_PROCESS 0 +#define ENABLE_FEATURE_TOUCH_SUSV3 1 +#define ENABLE_FEATURE_TR_CLASSES 0 +#define ENABLE_FEATURE_TR_EQUIV 0 +#define ENABLE_FEATURE_USE_SENDFILE 0 +#define ENABLE_FEATURE_VERBOSE 0 +#define ENABLE_FGREP 0 +#define ENABLE_FTPD 0 +#define ENABLE_HUSH_PRINTF 0 +#define ENABLE_HUSH_TEST 0 +#define ENABLE_KILLALL 0 +#define ENABLE_LOCALE_SUPPORT 1 +#define ENABLE_LONG_OPTS 1 +#define ENABLE_LZCAT 0 +#define ENABLE_PGREP 0 +#define ENABLE_PIDOF 0 +#define ENABLE_PKILL 0 +#define ENABLE_SELINUX 0 +#define ENABLE_SESTATUS 0 +#define ENABLE_TAR 1 +#define ENABLE_TEST1 0 +#define ENABLE_TEST2 0 +#define ENABLE_UNAME 0 +#define ENABLE_UNLZMA 0 +#define ENABLE_ZCAT 0 + +#define IF_AR(...) +#define IF_ASH_ALIAS(...) +#define IF_ASH_BASH_COMPAT(...) +#define IF_ASH_EXPAND_PRMT(...) +#define IF_ASH_HELP(...) +#define IF_ASH_OPTIMIZE_FOR_SIZE(...) +#define IF_BASENAME(...) +#define IF_BUNZIP2(...) +#define IF_BZCAT(...) +#define IF_BZIP2(...) __VA_ARGS__ +#define IF_CAT(...) +#define IF_CHGRP(...) +#define IF_CHMOD(...) +#define IF_CHOWN(...) +#define IF_CHROOT(...) +#define IF_CHVT(...) +#define IF_CKSUM(...) +#define IF_CLEAR(...) +#define IF_CPIO(...) +#define IF_DEALLOCVT(...) +#define IF_DESKTOP(...) __VA_ARGS__ +#define IF_DPKG(...) +#define IF_DPKG_DEB(...) +#define IF_DUMPKMAP(...) +#define IF_ECHO(...) __VA_ARGS__ +#define IF_EXTRA_COMPAT(...) +#define IF_FEATURE_AWK_GNU_EXTENSIONS(...) +#define IF_FEATURE_BZIP2_DECOMPRESS(...) __VA_ARGS__ +#define IF_FEATURE_CATN(...) +#define IF_FEATURE_CATV(...) +#define IF_FEATURE_CP_REFLINK(...) +#define IF_FEATURE_CUT_REGEX(...) +#define IF_FEATURE_FIND_AMIN(...) +#define IF_FEATURE_FIND_ATIME(...) +#define IF_FEATURE_FIND_CMIN(...) +#define IF_FEATURE_FIND_CONTEXT(...) +#define IF_FEATURE_FIND_CTIME(...) +#define IF_FEATURE_FIND_DELETE(...) +#define IF_FEATURE_FIND_DEPTH(...) +#define IF_FEATURE_FIND_EMPTY(...) +#define IF_FEATURE_FIND_EXEC(...) +#define IF_FEATURE_FIND_EXECUTABLE(...) +#define IF_FEATURE_FIND_EXEC_PLUS(...) +#define IF_FEATURE_FIND_GROUP(...) +#define IF_FEATURE_FIND_INUM(...) +#define IF_FEATURE_FIND_LINKS(...) +#define IF_FEATURE_FIND_MAXDEPTH(...) +#define IF_FEATURE_FIND_MMIN(...) +#define IF_FEATURE_FIND_MTIME(...) +#define IF_FEATURE_FIND_NEWER(...) +#define IF_FEATURE_FIND_NOT(...) __VA_ARGS__ +#define IF_FEATURE_FIND_PAREN(...) __VA_ARGS__ +#define IF_FEATURE_FIND_PATH(...) +#define IF_FEATURE_FIND_PERM(...) +#define IF_FEATURE_FIND_PRINT0(...) +#define IF_FEATURE_FIND_PRUNE(...) __VA_ARGS__ +#define IF_FEATURE_FIND_QUIT(...) +#define IF_FEATURE_FIND_REGEX(...) +#define IF_FEATURE_FIND_SAMEFILE(...) +#define IF_FEATURE_FIND_SIZE(...) +#define IF_FEATURE_FIND_TYPE(...) __VA_ARGS__ +#define IF_FEATURE_FIND_USER(...) +#define IF_FEATURE_FIND_XDEV(...) +#define IF_FEATURE_GREP_CONTEXT(...) +#define IF_FEATURE_GZIP_DECOMPRESS(...) __VA_ARGS__ +#define IF_FEATURE_HUMAN_READABLE(...) +#define IF_FEATURE_INSTALL_LONG_OPTIONS(...) +#define IF_FEATURE_LS_COLOR(...) +#define IF_FEATURE_LS_FILETYPES(...) +#define IF_FEATURE_LS_FOLLOWLINKS(...) +#define IF_FEATURE_LS_RECURSIVE(...) +#define IF_FEATURE_LS_SORTFILES(...) +#define IF_FEATURE_LS_TIMESTAMPS(...) __VA_ARGS__ +#define IF_FEATURE_LS_WIDTH(...) +#define IF_FEATURE_SEAMLESS_BZ2(...) __VA_ARGS__ +#define IF_FEATURE_SEAMLESS_GZ(...) __VA_ARGS__ +#define IF_FEATURE_SEAMLESS_LZMA(...) +#define IF_FEATURE_SEAMLESS_XZ(...) __VA_ARGS__ +#define IF_FEATURE_SEAMLESS_Z(...) +#define IF_FEATURE_SHOW_THREADS(...) +#define IF_FEATURE_SH_MATH(...) __VA_ARGS__ +#define IF_FEATURE_TAR_AUTODETECT(...) __VA_ARGS__ +#define IF_FEATURE_TAR_CREATE(...) __VA_ARGS__ +#define IF_FEATURE_TAR_FROM(...) __VA_ARGS__ +#define IF_FEATURE_TAR_LONG_OPTIONS(...) __VA_ARGS__ +#define IF_FEATURE_TAR_NOPRESERVE_TIME(...) __VA_ARGS__ +#define IF_FEATURE_TAR_OLDGNU_COMPATIBILITY(...) __VA_ARGS__ +#define IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(...) +#define IF_FEATURE_TAR_TO_COMMAND(...) +#define IF_FEATURE_TIMEZONE(...) +#define IF_FEATURE_TOUCH_SUSV3(...) __VA_ARGS__ +#define IF_FEATURE_VERBOSE(...) +#define IF_FEATURE_XARGS_SUPPORT_ARGS_FILE(...) +#define IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(...) +#define IF_FEATURE_XARGS_SUPPORT_PARALLEL(...) +#define IF_FEATURE_XARGS_SUPPORT_QUOTES(...) +#define IF_FEATURE_XARGS_SUPPORT_REPL_STR(...) +#define IF_FEATURE_XARGS_SUPPORT_TERMOPT(...) +#define IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(...) +#define IF_FGCONSOLE(...) +#define IF_GUNZIP(...) __VA_ARGS__ +#define IF_GZIP(...) __VA_ARGS__ +#define IF_KBD_MODE(...) +#define IF_LOADFONT(...) +#define IF_LOADKMAP(...) +#define IF_LONG_OPTS(...) __VA_ARGS__ +#define IF_LS(...) __VA_ARGS__ +#define IF_LZCAT(...) +#define IF_LZMA(...) +#define IF_LZOP(...) +#define IF_LZOPCAT(...) +#define IF_NOT_ASH_OPTIMIZE_FOR_SIZE(...) __VA_ARGS__ +#define IF_NOT_DESKTOP(...) +#define IF_NOT_FEATURE_FIND_MAXDEPTH(...) __VA_ARGS__ +#define IF_NOT_FEATURE_TAR_CREATE(...) +#define IF_NOT_FEATURE_TOUCH_SUSV3(...) +#define IF_OPENVT(...) +#define IF_PRINTF(...) __VA_ARGS__ +#define IF_RESET(...) +#define IF_RESIZE(...) +#define IF_RPM(...) +#define IF_RPM2CPIO(...) +#define IF_SELINUX(...) +#define IF_SETCONSOLE(...) +#define IF_SETFONT(...) +#define IF_SETKEYCODES(...) +#define IF_SETLOGCONS(...) +#define IF_SHELL_ASH(...) __VA_ARGS__ +#define IF_SHELL_HUSH(...) +#define IF_SHOWKEY(...) +#define IF_SLEEP(...) +#define IF_TAR(...) +#define IF_UNAME(...) __VA_ARGS__ +#define IF_UNCOMPRESS(...) +#define IF_UNLZMA(...) +#define IF_UNLZOP(...) +#define IF_UNXZ(...) __VA_ARGS__ +#define IF_UNZIP(...) +#define IF_XZ(...) +#define IF_XZCAT(...) +#define IF_ZCAT(...) diff --git a/06/recipes/1-stage1/seed.host-executed.sh b/06/recipes/1-stage1/seed.host-executed.sh new file mode 100755 index 0000000..62125a3 --- /dev/null +++ b/06/recipes/1-stage1/seed.host-executed.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash + +# 1st stage is special +# in that we don't have any semblance of a system to start with, +# meaning we can't even unpack sources, let alone patch them or something. +# For stage 1, we pre-unpack sources on the host and then fix them up with +# host's sed. + +#> FETCH 7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039 +#> FROM http://musl.libc.org/releases/musl-1.2.4.tar.gz + +#> FETCH f5a71d05664340ae46cda9579c6079a0f2fa809d24386d284f0d091e4d576a4e +#> FROM https://github.com/TinyCC/tinycc/archive/af1abf1f45d45b34f0b02437f559f4dfdba7d23c.tar.gz +#> AS tinycc-mob-af1abf1.tar.gz + +#> FETCH b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314 +#> FROM https://busybox.net/downloads/busybox-1.36.1.tar.bz2 + +set -ueo pipefail +TGT="$DESTDIR/tmp/1-stage1" + +echo "### $0: unpacking protomusl sources..." +mkdir -p "$DESTDIR/protosrc/protomusl" +tar --strip-components=1 -xzf downloads/musl-1.2.4.tar.gz \ + -C "$DESTDIR/protosrc/protomusl" + +echo "### $0: unpacking tinycc sources..." +mkdir -p "$DESTDIR/protosrc/tinycc" +tar --strip-components=1 -xzf downloads/tinycc-mob-af1abf1.tar.gz \ + -C $DESTDIR/protosrc/tinycc + +echo "### $0: unpacking protobusybox sources..." +mkdir -p "$DESTDIR/protosrc/protobusybox" +tar --strip-components=1 -xjf downloads/busybox-1.36.1.tar.bz2 \ + -C "$DESTDIR/protosrc/protobusybox" + +echo "### $0: patching up protomusl stage 1 sources..." +# original syscall_arch.h is not tcc-compatible, our syscall.h is dual-role +cp recipes/1-stage1/syscall.h \ + "$DESTDIR/protosrc/protomusl/arch/x86_64/syscall_arch.h" +pushd "$DESTDIR/protosrc/protomusl/" >/dev/null + # eliminiate a source path reference + sed -i 's/__FILE__/"__FILE__"/' include/assert.h + # two files have to be generated with host sed + mkdir -p host-generated/{sed1,sed2}/bits + sed -f ./tools/mkalltypes.sed \ + ./arch/x86_64/bits/alltypes.h.in \ + ./include/alltypes.h.in \ + > host-generated/sed1/bits/alltypes.h + sed -n -e s/__NR_/SYS_/p \ + < arch/x86_64/bits/syscall.h.in \ + > host-generated/sed2/bits/syscall.h + # more frivolous patching + echo '#define VERSION "1.2.2"' > src/internal/version.h + sed -i 's/@PLT//' src/signal/x86_64/sigsetjmp.s + rm -f src/signal/restore.c # *BIG URGH* + rm -f src/thread/clone.c # *BIG URGH #2* + rm -f src/thread/__set_thread_area.c # possible double-define + rm -f src/thread/__unmapself.c # double-define + rm -f src/math/sqrtl.c # tcc-incompatible + rm -f src/math/{acoshl,acosl,asinhl,asinl,hypotl}.c # sqrtl dep + sed -i 's|posix_spawn(&pid, "/bin/sh",|posix_spawnp(\&pid, "sh",|' \ + src/stdio/popen.c src/process/system.c + sed -i 's|execl("/bin/sh", "sh", "-c",|execlp("sh", "-c",|'\ + src/misc/wordexp.c +popd >/dev/null + +echo "### $0: patching up tinycc stage 1 sources..." +pushd "$DESTDIR/protosrc/tinycc" >/dev/null + :> config.h + # eliminate a source path reference + sed -i 's/__FILE__/"__FILE__"/' tcc.h + # don't hardcode paths + sed -i 's/SHN_ABS, filename);/SHN_ABS, "FILE stub");/' tccdbg.c + # break a circular dependency + sed -i 's/abort();//' lib/va_list.c +popd >/dev/null + +echo "### $0: patching up protobusybox stage 1 sources..." +pushd "$DESTDIR/protosrc/protobusybox" >/dev/null + :> include/NUM_APPLETS.h + :> include/common_bufsiz.h + # eliminate a source path reference + sed -i 's/__FILE__/"__FILE__"/' miscutils/fbsplash.c include/libbb.h + # already fixed in an unreleased version + sed -i 's/extern struct test_statics \*const test_ptr_to_statics/extern struct test_statics *BB_GLOBAL_CONST test_ptr_to_statics/' coreutils/test.c +popd >/dev/null + +echo "### $0: done" diff --git a/06/recipes/1-stage1/syscall.h b/06/recipes/1-stage1/syscall.h new file mode 100644 index 0000000..4426819 --- /dev/null +++ b/06/recipes/1-stage1/syscall.h @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2021 Alexander Sosedkin +// SPDX-License-Identifier: MIT + + +// constants/macro for this file to serve as a drop-in replacement +// for musl-1.2.2's arch/x86_64/syscall_arch.h + +#define __SYSCALL_LL_E(x) (x) +#define __SYSCALL_LL_O(x) (x) + +#define VDSO_USEFUL +#define VDSO_CGT_SYM "__vdso_clock_gettime" +#define VDSO_CGT_VER "LINUX_2.6" +#define VDSO_GETCPU_SYM "__vdso_getcpu" +#define VDSO_GETCPU_VER "LINUX_2.6" + +#define IPC_64 0 + + +// a different, tcc-compatible implementation of syscall invocations functions + +static long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6); +asm ( + //".globl __syscall6;" + ".type __syscall6, @function;" + "__syscall6:;" + "movq %rdi, %rax;" + "movq %rsi, %rdi;" + "movq %rdx, %rsi;" + "movq %rcx, %rdx;" + "movq %r8, %r10;" + "movq %r9, %r8;" + "movq 8(%rsp),%r9;" + "syscall;" + "ret" +); + +static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) { + return __syscall6(n, a1, a2, a3, a4, a5, 0); +} + +static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) { + return __syscall6(n, a1, a2, a3, a4, 0, 0); +} + +static __inline long __syscall3(long n, long a1, long a2, long a3) { + return __syscall6(n, a1, a2, a3, 0, 0, 0); +} + +static __inline long __syscall2(long n, long a1, long a2) { + return __syscall6(n, a1, a2, 0, 0, 0, 0); +} + +static __inline long __syscall1(long n, long a1) { + return __syscall6(n, a1, 0, 0, 0, 0, 0); +} + +static __inline long __syscall0(long n) { + return __syscall6(n, 0, 0, 0, 0, 0, 0); +} diff --git a/06/recipes/2a0-static-gnumake.sh b/06/recipes/2a0-static-gnumake.sh new file mode 100755 index 0000000..94e43e7 --- /dev/null +++ b/06/recipes/2a0-static-gnumake.sh @@ -0,0 +1,54 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3 +#> FROM http://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz + +set -uex + +export PATH=/store/1-stage1/tinycc/wrappers:/store/1-stage1/protobusybox/bin + +mkdir -p /store/2a0-static-gnumake /tmp/2a0-static-gnumake +cd /tmp/2a0-static-gnumake + +echo "### $0: unpacking static GNU Make sources..." +tar --strip-components=1 -xf /downloads/make-4.4.1.tar.gz + +echo "### $0: fixing up static GNU Make sources..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + src/job.c build-aux/install-sh po/Makefile.in.in +# this is part of stdlib, no idea how it's supposed to not clash +rm src/getopt.h +for f in src/getopt.c src/getopt1.c; do :> $f; done +for f in lib/fnmatch.c lib/glob.c lib/xmalloc.c lib/error.c; do :> $f; done +# embrace chaos +shuffle_comment='\/\* Handle shuffle mode argument. \*\/' +shuffle_default='if (!shuffle_mode) shuffle_mode = xstrdup(\"random\");' +sed -i "s|$shuffle_comment|$shuffle_comment\n$shuffle_default|" src/main.c +grep 'if (!shuffle_mode) shuffle_mode = xstrdup("random");' src/main.c + +echo "### $0: building static GNU Make..." +ash ./configure \ + --build x86_64-linux \ + --disable-dependency-tracking \ + --prefix=/store/2a0-static-gnumake \ + CONFIG_SHELL='/store/1-stage1/protobusybox/bin/ash' \ + SHELL='/store/1-stage1/protobusybox/bin/ash' +ash ./build.sh + +echo "### $0: testing static GNU Make by remaking it with itself..." +mv make make-intermediate +./make-intermediate -j $NPROC clean +./make-intermediate -j $NPROC CFLAGS=-O2 + +echo "### $0: installing static GNU Make..." +./make -j $NPROC install + +echo "### $0: creating a wrapper that respects \$SHELL..." +# FIXME: patch make to use getenv? +mkdir /store/2a0-static-gnumake/wrappers; cd /store/2a0-static-gnumake/wrappers +echo "#!/store/1-stage1/protobusybox/bin/ash" > make +echo "exec /store/2a0-static-gnumake/bin/make SHELL=\$SHELL \"\$@\"" \ >> make +chmod +x make + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a0 /store/2a0-static-gnumake ) diff --git a/06/recipes/2a1-static-binutils.sh b/06/recipes/2a1-static-binutils.sh new file mode 100755 index 0000000..d5a6e85 --- /dev/null +++ b/06/recipes/2a1-static-binutils.sh @@ -0,0 +1,47 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 645c25f563b8adc0a81dbd6a41cffbf4d37083a382e02d5d3df4f65c09516d00 +#> FROM https://ftp.gnu.org/gnu/binutils/binutils-2.39.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/1-stage1/tinycc/wrappers" +export PATH="$PATH:/store/2a0-static-gnumake/bin" + +mkdir -p /tmp/2a1-static-binutils; cd /tmp/2a1-static-binutils +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking binutils sources..." +tar --strip-components=1 -xf /downloads/binutils-2.39.tar.xz + +echo "### $0: building static binutils..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + missing install-sh mkinstalldirs +mkdir aliases +ln -s /store/1-stage1/protobusybox/bin/true aliases/makeinfo +PATH="/tmp/2a1-static-binutils/aliases:$PATH" +export lt_cv_sys_max_cmd_len=32768 +# see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 +sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh + +ash configure \ + CONFIG_SHELL=/store/1-stage1/protobusybox/bin/ash \ + SHELL=/store/1-stage1/protobusybox/bin/ash \ + CFLAGS='-O2 -D__LITTLE_ENDIAN__=1' \ + CFLAGS_FOR_TARGET=-O2 \ + MAKEINFO=/store/1-stage1/protobusybox/bin/true \ + --disable-gprofng \ + --enable-deterministic-archives \ + --host x86_64-linux --build x86_64-linux \ + --prefix=/store/2a1-static-binutils +make -j $NPROC all-libiberty all-gas all-bfd all-libctf all-zlib all-gprof +make all-ld # race condition on ld/.deps/ldwrite.Po, serialize +make -j $NPROC + +echo "### $0: installing static binutils..." +make -j $NPROC install +rm /store/2a1-static-binutils/lib/*.la # broken, reference builddir + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a1 /store/2a1-static-binutils ) diff --git a/06/recipes/2a2-static-gnugcc4-c.sh b/06/recipes/2a2-static-gnugcc4-c.sh new file mode 100755 index 0000000..3ca528f --- /dev/null +++ b/06/recipes/2a2-static-gnugcc4-c.sh @@ -0,0 +1,71 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH f69eff1bc3d15d4e59011d587c57462a8d3d32cf2378d32d30d008a42a863325 +#> FROM https://gmplib.org/download/gmp/archive/gmp-4.3.2.tar.xz + +#> FETCH d7271bbfbc9ddf387d3919df8318cd7192c67b232919bfa1cb3202d07843da1b +#> FROM https://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.xz + +#> FETCH e664603757251fd8a352848276497a4c79b7f8b21fd8aedd5cc0598a38fee3e4 +#> FROM http://www.multiprecision.org/downloads/mpc-0.8.1.tar.gz + +#> FETCH 92e61c6dc3a0a449e62d72a38185fda550168a86702dea07125ebd3ec3996282 +#> FROM https://ftp.gnu.org/gnu/gcc/gcc-4.7.4/gcc-4.7.4.tar.bz2 + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/1-stage1/tinycc/wrappers" +export PATH="$PATH:/store/2a0-static-gnumake/bin" + +mkdir -p /tmp/2a2-static-gnugcc4-c; cd /tmp/2a2-static-gnugcc4-c +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/1-stage1/protobusybox/bin/ash aliases/sh +export PATH="/tmp/2a2-static-gnugcc4-c/aliases:$PATH" + +echo "### $0: unpacking GNU GCC sources..." +mkdir mpfr mpc gmp +tar --strip-components=1 -xf /downloads/gcc-4.7.4.tar.bz2 +tar --strip-components=1 -xf /downloads/mpfr-2.4.2.tar.xz -C mpfr +tar --strip-components=1 -xf /downloads/mpc-0.8.1.tar.gz -C mpc +tar --strip-components=1 -xf /downloads/gmp-4.3.2.tar.xz -C gmp + +echo "### $0: building static GNU GCC 4 (statically linked, C only)" +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree \ + gcc/genmultilib */*.sh gcc/exec-tool.in \ + install-sh */install-sh +sed -i 's|^\(\s*\)sh |\1/store/1-stage1/protobusybox/bin/ash |' \ + Makefile* */Makefile* +sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in +# see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 +sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh +ash configure \ + CONFIG_SHELL='/store/1-stage1/protobusybox/bin/ash' \ + SHELL='/store/1-stage1/protobusybox/bin/ash' \ + CFLAGS=-O2 CFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=/store/1-stage1/protomusl \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=/store/2a1-static-binutils/bin \ + --prefix=/store/2a2-static-gnugcc4-c \ + --enable-languages=c \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --host x86_64-linux --build x86_64-linux +make -j $NPROC + +echo "### $0: installing static GNU GCC 4 (statically linked, C only)" +make -j $NPROC install + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a2 /store/2a2-static-gnugcc4-c ) diff --git a/06/recipes/2a3-intermediate-musl.sh b/06/recipes/2a3-intermediate-musl.sh new file mode 100755 index 0000000..afe7d73 --- /dev/null +++ b/06/recipes/2a3-intermediate-musl.sh @@ -0,0 +1,36 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039 +#> FROM http://musl.libc.org/releases/musl-1.2.4.tar.gz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a2-static-gnugcc4-c/bin" + +mkdir -p /tmp/2a3-intermediate-musl; cd /tmp/2a3-intermediate-musl +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking musl sources..." +tar --strip-components=1 -xf /downloads/musl-1.2.4.tar.gz + +echo "### $0: building musl with GNU GCC..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + tools/*.sh \ +# patch popen/system to search in PATH instead of hardcoding /bin/sh +sed -i 's|posix_spawn(&pid, "/bin/sh",|posix_spawnp(\&pid, "sh",|' \ + src/stdio/popen.c src/process/system.c +sed -i 's|execl("/bin/sh", "sh", "-c",|execlp("sh", "-c",|'\ + src/misc/wordexp.c +# eliminiate a source path reference +sed -i 's/__FILE__/"__FILE__"/' include/assert.h +ash ./configure --prefix=/store/2a3-intermediate-musl +make -j $NPROC + +echo "### $0: installing musl..." +make -j $NPROC install + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a3 /store/2a3-intermediate-musl ) diff --git a/06/recipes/2a4-gnugcc4-cpp.sh b/06/recipes/2a4-gnugcc4-cpp.sh new file mode 100755 index 0000000..d30a974 --- /dev/null +++ b/06/recipes/2a4-gnugcc4-cpp.sh @@ -0,0 +1,97 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH f69eff1bc3d15d4e59011d587c57462a8d3d32cf2378d32d30d008a42a863325 +#> FROM https://gmplib.org/download/gmp/archive/gmp-4.3.2.tar.xz + +#> FETCH d7271bbfbc9ddf387d3919df8318cd7192c67b232919bfa1cb3202d07843da1b +#> FROM https://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.xz + +#> FETCH e664603757251fd8a352848276497a4c79b7f8b21fd8aedd5cc0598a38fee3e4 +#> FROM http://www.multiprecision.org/downloads/mpc-0.8.1.tar.gz + +#> FETCH 92e61c6dc3a0a449e62d72a38185fda550168a86702dea07125ebd3ec3996282 +#> FROM https://ftp.gnu.org/gnu/gcc/gcc-4.7.4/gcc-4.7.4.tar.bz2 + +set -uex + +export PATH='/store/_2a0-ccache/wrappers/c' # may or may not exist +export PATH="$PATH:/store/1-stage1/protobusybox/bin" +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a2-static-gnugcc4-c/bin" + +mkdir -p /tmp/2a4-gnugcc4-cpp; cd /tmp/2a4-gnugcc4-cpp +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/1-stage1/protobusybox/bin/ash aliases/sh +export PATH="/tmp/2a4-gnugcc4-cpp/aliases:$PATH" + +echo "### $0: creating wrappers that make previous GNU GCC target new musl..." +SYSROOT=/store/2a3-intermediate-musl +export _SYSROOT="--sysroot $SYSROOT" +export _LDFLAG="--dynamic-linker=$SYSROOT/lib/libc.so" +export _NEWINC="-I$SYSROOT/include" +export _REALCC="-I$SYSROOT/include" +mkdir wrappers +echo '#!/store/1-stage1/protobusybox/bin/ash' > wrappers/cc +echo '#!/store/1-stage1/protobusybox/bin/ash' > wrappers/cpp +echo '#!/store/1-stage1/protobusybox/bin/ash' > wrappers/ld +echo 'exec gcc $_SYSROOT -Wl,$_LDFLAG "$@"' >> wrappers/cc +echo 'exec /store/2a2-static-gnugcc4-c/bin/cpp $_NEWINC "$@"' >> wrappers/cpp +echo 'exec /store/2a1-static-binutils/bin/ld $_LDFLAG "$@"' >> wrappers/ld +chmod +x wrappers/cc wrappers/cpp wrappers/ld +export PATH="/tmp/2a4-gnugcc4-cpp/wrappers:$PATH" + +echo "### $0: unpacking GNU GCC 4 sources..." +mkdir mpfr mpc gmp +tar --strip-components=1 -xf /downloads/gcc-4.7.4.tar.bz2 +tar --strip-components=1 -xf /downloads/mpfr-2.4.2.tar.xz -C mpfr +tar --strip-components=1 -xf /downloads/mpc-0.8.1.tar.gz -C mpc +tar --strip-components=1 -xf /downloads/gmp-4.3.2.tar.xz -C gmp + +echo "### $0: fixing up GNU GCC 4 sources..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree \ + gcc/genmultilib */*.sh gcc/exec-tool.in \ + install-sh */install-sh +sed -i 's|^\(\s*\)sh |\1/store/1-stage1/protobusybox/bin/ash |' \ + Makefile* */Makefile* +sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in +sed -i "s|/lib64/ld-linux-x86-64.so.2|$SYSROOT/lib/libc.so|" \ + gcc/config/i386/linux64.h +sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host +# see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 +sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh + +echo "### $0: building GNU GCC 4 (dynamically linked, with C++ support)" +ash configure \ + cache_file=nonex \ + CONFIG_SHELL='/store/1-stage1/protobusybox/bin/ash' \ + SHELL='/store/1-stage1/protobusybox/bin/ash' \ + CC=cc CPP=cpp LD=ld \ + CFLAGS=-O2 CFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=$SYSROOT \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=/store/2a1-static-binutils/bin \ + --prefix=/store/2a4-gnugcc4-cpp \ + --with-specs='%{!static:%x{-rpath=/store/2a4-gnugcc4-cpp/lib64}}' \ + --enable-languages=c,c++ \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --disable-libitm \ + --host x86_64-linux --build x86_64-linux +make -j $NPROC +echo "### $0: installing GNU GCC 4 (dynamically linked, with C++ support)" +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a4 /store/2a4-gnugcc4-cpp ) diff --git a/06/recipes/2a5-gnugcc10.sh b/06/recipes/2a5-gnugcc10.sh new file mode 100755 index 0000000..cbc4b6a --- /dev/null +++ b/06/recipes/2a5-gnugcc10.sh @@ -0,0 +1,90 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 68dadacce515b0f8a54f510edf07c1b636492bcdb8e8d54c56eb216225d16989 +#> FROM https://gmplib.org/download/gmp/gmp-6.1.0.tar.xz + +#> FETCH 761413b16d749c53e2bfd2b1dfaa3b027b0e793e404b90b5fbaeef60af6517f5 +#> FROM https://www.mpfr.org/mpfr-3.1.4/mpfr-3.1.4.tar.xz + +#> FETCH 617decc6ea09889fb08ede330917a00b16809b8db88c29c31bfbb49cbf88ecc3 +#> FROM http://www.multiprecision.org/downloads/mpc-1.0.3.tar.gz + +#> FETCH 6b8b0fd7f81d0a957beb3679c81bbb34ccc7568d5682844d8924424a0dadcb1b +#> FROM http://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2 + +#> FETCH 25109543fdf46f397c347b5d8b7a2c7e5694a5a51cce4b9c6e1ea8a71ca307c1 +#> FROM https://ftp.gnu.org/gnu/gcc/gcc-10.5.0/gcc-10.5.0.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a4-gnugcc4-cpp/bin" + +mkdir -p /tmp/2a5-gnugcc10; cd /tmp/2a5-gnugcc10 +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/1-stage1/protobusybox/bin/ash aliases/sh +export PATH="/tmp/2a5-gnugcc10/aliases:$PATH" + +SYSROOT=/store/2a3-intermediate-musl + +echo "### $0: unpacking GNU GCC 10 sources..." +mkdir gmp mpfr mpc isl +tar --strip-components=1 -xf /downloads/gcc-10.5.0.tar.xz +tar --strip-components=1 -xf /downloads/gmp-6.1.0.tar.xz -C gmp +tar --strip-components=1 -xf /downloads/mpfr-3.1.4.tar.xz -C mpfr +tar --strip-components=1 -xf /downloads/mpc-1.0.3.tar.gz -C mpc +tar --strip-components=1 -xf /downloads/isl-0.18.tar.bz2 -C isl + +echo "### $0: fixing up GNU GCC 10 sources..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree install-sh \ + gcc/exec-tool.in libgcc/mkheader.sh +sed -i 's|^\(\s*\)sh |\1/store/1-stage1/protobusybox/bin/ash |' \ + libgcc/Makefile.in +sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in +sed -i "s|/lib/ld-musl-x86_64.so.1|$SYSROOT/lib/libc.so|" \ + gcc/config/i386/linux64.h +sed -i 's|m64=../lib64|m64=../lib|' gcc/config/i386/t-linux64 +sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host +# see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 +sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh + +echo "### $0: building GNU GCC 10" +ash configure \ + CONFIG_SHELL='/store/1-stage1/protobusybox/bin/ash' \ + SHELL='/store/1-stage1/protobusybox/bin/ash' \ + CFLAGS=-O2 CXX_FLAGS=-O2 \ + CFLAGS_FOR_TARGET=-O2 CXXFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=$SYSROOT \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=/store/2a1-static-binutils/bin \ + --prefix=/store/2a5-gnugcc10 \ + --with-specs='%{!static:%x{-rpath=/store/2a5-gnugcc10/lib}}' \ + --enable-languages=c,c++ \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --disable-libitm \ + --disable-libsanitizer \ + --disable-cet \ + --disable-gnu-unique-object \ + --disable-gcov \ + --disable-checking \ + --host x86_64-linux-musl --build x86_64-linux-musl +make -j $NPROC +echo "### $0: installing GNU GCC 10" +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a5 /store/2a5-gnugcc10 ) diff --git a/06/recipes/2a6-linux-headers.sh b/06/recipes/2a6-linux-headers.sh new file mode 100755 index 0000000..c074bd9 --- /dev/null +++ b/06/recipes/2a6-linux-headers.sh @@ -0,0 +1,36 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH cca91be956fe081f8f6da72034cded96fe35a50be4bfb7e103e354aa2159a674 +#> FROM https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.4.12.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a5-gnugcc10/bin" + +mkdir -p /tmp/2a6-linux-headers; cd /tmp/2a6-linux-headers +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking Linux sources..." +tar --strip-components=1 -xf /downloads/linux-6.4.12.tar.xz \ + linux-6.4.12/Makefile \ + linux-6.4.12/arch/x86 \ + linux-6.4.12/include \ + linux-6.4.12/scripts \ + linux-6.4.12/tools + +echo "### $0: building Linux headers..." +make -j $NPROC \ + CONFIG_SHELL=/store/1-stage1/protobusybox/bin/ash \ + CC=gcc HOSTCC=gcc ARCH=x86_64 \ + headers + +echo "### $0: installing Linux headers..." +mkdir -p /store/2a6-linux-headers/ +find usr/include -name '.*' | xargs rm +cp -rv usr/include /store/2a6-linux-headers/ + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a6 /store/2a6-linux-headers ) diff --git a/06/recipes/2a7-cmake.sh b/06/recipes/2a7-cmake.sh new file mode 100755 index 0000000..f99d3b8 --- /dev/null +++ b/06/recipes/2a7-cmake.sh @@ -0,0 +1,48 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 0a905ca8635ca81aa152e123bdde7e54cbe764fdd9a70d62af44cad8b92967af +#> FROM https://github.com/Kitware/CMake/releases/download/v3.27.4/cmake-3.27.4.tar.gz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin/' +export PATH="$PATH:/store/2a0-static-gnumake/wrappers" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a5-gnugcc10/bin" + +export SHELL=/store/1-stage1/protobusybox/bin/ash + +mkdir -p /tmp/2a7-cmake; cd /tmp/2a7-cmake +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking CMake sources..." +tar --strip-components=1 -xf /downloads/cmake-3.27.4.tar.gz + +echo "### $0: fixing up CMake sources..." +sed -i "s|/bin/sh|$SHELL|" bootstrap +sed -i 's|__FILE__|"__FILE__"|' \ + Source/CPack/IFW/cmCPackIFWCommon.h \ + Source/CPack/cmCPack*.h \ + Source/cmCTest.h + +echo "### $0: bundling libraries..." +# poor man's static linking, a way for cmake to be self-contained later +mkdir -p /store/2a7-cmake/bundled-runtime +cp -H /store/2a5-gnugcc10/lib/libstdc++.so.6 /store/2a7-cmake/bundled-runtime/ +cp -H /store/2a5-gnugcc10/lib/libgcc_s.so.1 /store/2a7-cmake/bundled-runtime/ + +echo "### $0: building CMake..." +ash configure \ + CFLAGS="-DCPU_SETSIZE=128 -D_GNU_SOURCE" \ + CXXFLAGS="-isystem /store/2a6-linux-headers/include" \ + LDFLAGS="-Wl,-rpath /store/2a7-cmake/bundled-runtime" \ + --prefix=/store/2a7-cmake \ + --parallel=$NPROC \ + -- \ + -DCMAKE_USE_OPENSSL=OFF +make -j $NPROC +echo "### $0: installing CMake..." +make -j $NPROC install/strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a7 /store/2a7-cmake ) diff --git a/06/recipes/2a8-python.sh b/06/recipes/2a8-python.sh new file mode 100755 index 0000000..fe15f7e --- /dev/null +++ b/06/recipes/2a8-python.sh @@ -0,0 +1,70 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 795c34f44df45a0e9b9710c8c71c15c671871524cd412ca14def212e8ccb155d +#> FROM https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin/' +export PATH="$PATH:/store/2a0-static-gnumake/wrappers" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a5-gnugcc10/bin" + +export SHELL=/store/1-stage1/protobusybox/bin/ash + +mkdir -p /tmp/2a8-python; cd /tmp/2a8-python +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/1-stage1/protobusybox/bin/ash aliases/sh +export PATH="/tmp/2a8-python/aliases:$PATH" + +echo "### $0: unpacking CPython sources..." +tar --strip-components=1 -xf /downloads/Python-3.12.0.tar.xz + +echo "### $0: fixing up CPython sources..." +sed -i "s|/bin/sh|$SHELL|" configure install-sh +sed -i 's|ac_sys_system=`uname -s`|ac_sys_system=Linux|' configure +# the precompiled pyc files aren't reproducible, +# but it's not like I need to waste time on them anyway. +# break their generation +mv Lib/compileall.py Lib/compileall.py.bak +echo 'import sys; sys.exit(0)' > Lib/compileall.py; chmod +x Lib/compileall.py +sed -i 's|__FILE__|"__FILE__"|' \ + Python/errors.c \ + Include/pyerrors.h \ + Include/cpython/object.h \ + Modules/pyexpat.c +sed -i 's|TIME __TIME__|TIME "xx:xx:xx"|' Modules/getbuildinfo.c +sed -i 's|DATE __DATE__|DATE "xx/xx/xx"|' Modules/getbuildinfo.c +# different build path length leads to different wrapping. avoid +sed -i 's|vars, stream=f|vars, stream=f, width=2**24|' Lib/sysconfig.py + +echo "### $0: building CPython..." +mkdir -p /store/2a8-python/lib +ash configure \ + ac_cv_broken_sem_getvalue=yes \ + ac_cv_posix_semaphores_enabled=no \ + OPT='-DNDEBUG -fwrapv -O3 -Wall' \ + LDFLAGS='-Wl,-rpath /store/2a8-python/lib' \ + --without-static-libpython \ + --build x86_64-linux-musl \ + --prefix=/store/2a8-python \ + --enable-shared \ + --with-ensurepip=no +# ensure reproducibility in case of no /dev/shm +grep 'define POSIX_SEMAPHORES_NOT_ENABLED 1' pyconfig.h +grep 'define HAVE_BROKEN_SEM_GETVALUE 1' pyconfig.h +make -j $NPROC + +echo "### $0: installing CPython..." +make -j $NPROC install +# strip builddir mentions +sed -i "s|/tmp/2a8-python|...|g" \ + /store/2a8-python/lib/python3.*/_sysconfigdata__*.py \ + /store/2a8-python/lib/python3.*/config-3.*-x86_64-linux-musl/Makefile +# restore compileall just in case +cat Lib/compileall.py.bak > /store/2a8-python/lib/python3.12/compileall.py + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a8 /store/2a8-python ) diff --git a/06/recipes/2a9-intermediate-clang.sh b/06/recipes/2a9-intermediate-clang.sh new file mode 100755 index 0000000..c036504 --- /dev/null +++ b/06/recipes/2a9-intermediate-clang.sh @@ -0,0 +1,142 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH b0e42aafc01ece2ca2b42e3526f54bebc4b1f1dc8de6e34f46a0446a13e882b9 +#> FROM https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.1/llvm-project-17.0.1.src.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin/' +export PATH="$PATH:/store/2a0-static-gnumake/wrappers" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a5-gnugcc10/bin" +export PATH="$PATH:/store/2a7-cmake/bin" +export PATH="$PATH:/store/2a8-python/bin" + +export SHELL=/store/1-stage1/protobusybox/bin/ash +GCC_PATH=/store/2a5-gnugcc10 + +mkdir -p /tmp/2a9-intermediate-clang; cd /tmp/2a9-intermediate-clang +# clang's cmake configuration should pick up ccache automatically from PATH +#if [ -e /ccache/setup ]; then . /ccache/setup; fi +export PATH="$PATH:/ccache/bin" +command -v ccache && USE_CCACHE=YES || USE_CCACHE=NO + +echo "### $0: preparing future sysroot..." +OUT=/store/2a9-intermediate-clang +SYSROOT=$OUT/sysroot +mkdir -p $SYSROOT/lib $SYSROOT/include +ln -s /store/2a3-intermediate-musl/lib/* $SYSROOT/lib/ +ln -s /store/2a3-intermediate-musl/include/* $SYSROOT/include/ + +echo "### $0: unpacking LLVM/Clang sources..." +tar --strip-components=1 -xf /downloads/llvm-project-17.0.1.src.tar.xz + +echo "### $0: fixing up LLVM/Clang sources..." +sed -i "s|COMMAND sh|COMMAND $SHELL|" \ + llvm/cmake/modules/GetHostTriple.cmake clang/CMakeLists.txt +echo 'echo x86_64-unknown-linux-musl' > llvm/cmake/config.guess +LOADER=/store/2a3-intermediate-musl/lib/libc.so +sed -i "s|/lib/ld-musl-\" + ArchName + \".so.1|$LOADER|" \ + clang/lib/Driver/ToolChains/Linux.cpp +BEGINEND='const bool HasCRTBeginEndFiles' +sed -i "s|${BEGINEND} =|${BEGINEND} = false; ${BEGINEND}_unused =|" \ + clang/lib/Driver/ToolChains/Gnu.cpp +REL_ORIGIN='_install_rpath \"\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}\"' +sed -i "s|_install_rpath \"\\\\\$ORIGIN/..|_install_rpath \"$OUT|" \ + llvm/cmake/modules/AddLLVM.cmake +sed -i 's|numShards = 32;|numShards = 1;|' lld/*/SyntheticSections.* +sed -i 's|numShards = 256;|numShards = 1;|' lld/*/ICF.cpp +sed -i 's|__FILE__|"__FILE__"|' compiler-rt/lib/builtins/int_util.h +sed -i 's|"@LLVM_SRC_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in +sed -i 's|"@LLVM_OBJ_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + +echo "### $0: building LLVM/Clang (stage 1)..." +export LD_LIBRARY_PATH='/store/2a5-gnugcc10/lib' + +EXTRA_INCL='/tmp/2a9-intermediate-clang/extra_includes' +mkdir -p $EXTRA_INCL +cp clang/lib/Headers/*intrin*.h $EXTRA_INCL/ +cp clang/lib/Headers/mm_malloc.h $EXTRA_INCL/ +[ -e $EXTRA_INCL/immintrin.h ] + +BOTH_STAGES_OPTS='' +add_opt() { + BOTH_STAGES_OPTS="$BOTH_STAGES_OPTS -D$1 -DBOOTSTRAP_$1" +} +add_opt CMAKE_BUILD_TYPE=MinSizeRel +add_opt LLVM_OPTIMIZED_TABLEGEN=YES +add_opt LLVM_CCACHE_BUILD=$USE_CCACHE +add_opt DEFAULT_SYSROOT=$SYSROOT +add_opt CMAKE_INSTALL_PREFIX=$OUT +add_opt LLVM_INSTALL_BINUTILS_SYMLINKS=YES +add_opt LLVM_INSTALL_CCTOOLS_SYMLINKS=YES +add_opt CMAKE_INSTALL_DO_STRIP=YES +add_opt LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=YES +add_opt LLVM_TARGET_ARCH=X86 +add_opt LLVM_TARGETS_TO_BUILD=Native +add_opt LLVM_BUILTIN_TARGETS=x86_64-unknown-linux-musl +add_opt LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl +add_opt LLVM_HOST_TRIPLE=x86_64-unknown-linux-musl +add_opt COMPILER_RT_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl +add_opt LLVM_APPEND_VC_REV=NO +add_opt LLVM_INCLUDE_TESTS=NO +add_opt LLVM_INCLUDE_EXAMPLES=NO +add_opt LLVM_INCLUDE_BENCHMARKS=NO +add_opt LLVM_ENABLE_BACKTRACES=NO +add_opt LLVM_ENABLE_EH=YES +add_opt LLVM_ENABLE_RTTI=YES +add_opt CLANG_ENABLE_ARCMT=NO +add_opt CLANG_ENABLE_STATIC_ANALYZER=NO +add_opt COMPILER_RT_BUILD_SANITIZERS=NO +add_opt COMPILER_RT_BUILD_XRAY=NO +add_opt COMPILER_RT_BUILD_LIBFUZZER=NO +add_opt COMPILER_RT_BUILD_PROFILE=NO +add_opt COMPILER_RT_BUILD_MEMPROF=NO +add_opt COMPILER_RT_BUILD_ORC=NO +add_opt COMPILER_RT_USE_BUILTINS_LIBRARY=YES +add_opt CLANG_DEFAULT_CXX_STDLIB=libc++ +add_opt CLANG_DEFAULT_LINKER=lld +add_opt CLANG_DEFAULT_RTLIB=compiler-rt +add_opt LIBCXX_HAS_MUSL_LIBC=YES +add_opt LIBCXX_USE_COMPILER_RT=YES +add_opt LIBCXX_INCLUDE_BENCHMARKS=NO +add_opt LIBCXX_CXX_ABI=libcxxabi +add_opt LIBCXX_ADDITIONAL_COMPILE_FLAGS=-I/store/2a6-linux-headers/include +add_opt LIBCXXABI_USE_COMPILER_RT=YES +add_opt LIBCXXABI_USE_LLVM_UNWINDER=YES +add_opt LLVM_INSTALL_TOOLCHAIN_ONLY=YES +add_opt LIBUNWIND_USE_COMPILER_RT=YES +add_opt LLVM_ENABLE_THREADS=NO + +cmake -S llvm -B build -G 'Unix Makefiles' \ + -DLLVM_ENABLE_PROJECTS='clang;lld' \ + -DLLVM_ENABLE_RUNTIMES='compiler-rt;libcxx;libcxxabi;libunwind' \ + -DGCC_INSTALL_PREFIX=$GCC_PATH \ + -DCMAKE_C_FLAGS=--sysroot=$SYSROOT \ + "-DBOOTSTRAP_CMAKE_C_FLAGS=-isystem $EXTRA_INCL" \ + "-DBOOTSTRAP_CMAKE_CXX_FLAGS=-isystem $EXTRA_INCL" \ + -DCLANG_ENABLE_BOOTSTRAP=YES $BOTH_STAGES_OPTS + +make -C build -j $NPROC clang lld runtimes + +echo "### $0: building LLVM/Clang (stage 2)..." +NEW_LIB_DIR="$(pwd)/build/lib/x86_64-unknown-linux-musl" +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$NEW_LIB_DIR" +make -C build -j $NPROC stage2 + +echo "### $0: installing LLVM/Clang..." +make -C build -j $NPROC stage2-install +ln -s $OUT/lib/x86_64-unknown-linux-musl/* $OUT/lib/ + +echo "### $0: setting up generic names..." +mkdir $OUT/bin/generic-names +ln -s $OUT/bin/clang $OUT/bin/generic-names/cc +ln -s $OUT/bin/clang++ $OUT/bin/generic-names/c++ +ln -s $OUT/bin/clang-cpp $OUT/bin/generic-names/cpp + +echo "### $0: mixing new stuff into sysroot..." +ln -s $OUT/lib/* $OUT/sysroot/lib/ + +echo "### $0: NOT checking for build path leaks - see _2a9.test.sh" diff --git a/06/recipes/2b0-musl.sh b/06/recipes/2b0-musl.sh new file mode 100755 index 0000000..52faa6a --- /dev/null +++ b/06/recipes/2b0-musl.sh @@ -0,0 +1,36 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH 7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039 +#> FROM http://musl.libc.org/releases/musl-1.2.4.tar.gz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a9-intermediate-clang/bin/generic-names" + +mkdir -p /tmp/2b0-musl; cd /tmp/2b0-musl +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking musl sources..." +tar --strip-components=1 -xf /downloads/musl-1.2.4.tar.gz + +echo "### $0: building musl..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' \ + tools/*.sh \ +# patch popen/system to search in PATH instead of hardcoding /bin/sh +sed -i 's|posix_spawn(&pid, "/bin/sh",|posix_spawnp(\&pid, "sh",|' \ + src/stdio/popen.c src/process/system.c +# avoid absolute path references +sed -i 's/__FILE__/__FILE_NAME__/' include/assert.h +ash ./configure --prefix=/store/2b0-musl CFLAGS=-O2 +make -j $NPROC + +echo "### $0: installing musl..." +make -j $NPROC install +mkdir /store/2b0-musl/bin +ln -s /store/2b0-musl/lib/libc.so /store/2b0-musl/bin/ldd + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2b0 /store/2b0-musl ) diff --git a/06/recipes/2b1-clang.sh b/06/recipes/2b1-clang.sh new file mode 100755 index 0000000..6c05336 --- /dev/null +++ b/06/recipes/2b1-clang.sh @@ -0,0 +1,153 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH b0e42aafc01ece2ca2b42e3526f54bebc4b1f1dc8de6e34f46a0446a13e882b9 +#> FROM https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.1/llvm-project-17.0.1.src.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin/' +export PATH="$PATH:/store/2a0-static-gnumake/wrappers" +export PATH="$PATH:/store/2a7-cmake/bin" +export PATH="$PATH:/store/2a8-python/bin" +# 2a9-intermediate-clang intentionally not added to $PATH to prevent confusion + +export SHELL=/store/1-stage1/protobusybox/bin/ash +PREV_CLANG=/store/2a9-intermediate-clang + +mkdir -p /tmp/2b1-clang; cd /tmp/2b1-clang +# clang's cmake configuration should pick up ccache automatically from PATH +#if [ -e /ccache/setup ]; then . /ccache/setup; fi +export PATH="$PATH:/ccache/bin" +command -v ccache && USE_CCACHE=YES || USE_CCACHE=NO + +echo "### $0: preparing future sysroot..." +OUT=/store/2b1-clang +SYSROOT=$OUT/sysroot +mkdir -p $SYSROOT/lib $SYSROOT/include +ln -s /store/2b0-musl/lib/* $SYSROOT/lib/ +ln -s /store/2b0-musl/include/* $SYSROOT/include/ + +echo "### $0: unpacking LLVM/Clang sources..." +tar --strip-components=1 -xf /downloads/llvm-project-17.0.1.src.tar.xz + +echo "### $0: fixing up LLVM/Clang sources..." +sed -i "s|COMMAND sh|COMMAND $SHELL|" \ + llvm/cmake/modules/GetHostTriple.cmake clang/CMakeLists.txt +echo 'echo x86_64-unknown-linux-musl' > llvm/cmake/config.guess +LOADER=/store/2b0-musl/lib/libc.so +sed -i "s|/lib/ld-musl-\" + ArchName + \".so.1|$LOADER|" \ + clang/lib/Driver/ToolChains/Linux.cpp +BEGINEND='const bool HasCRTBeginEndFiles' +sed -i "s|${BEGINEND} =|${BEGINEND} = false; ${BEGINEND}_unused =|" \ + clang/lib/Driver/ToolChains/Gnu.cpp +REL_ORIGIN='_install_rpath \"\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}\"' +sed -i "s|_install_rpath \"\\\\\$ORIGIN/..|_install_rpath \"$OUT|" \ + llvm/cmake/modules/AddLLVM.cmake +sed -i 's|numShards = 32;|numShards = 1;|' lld/*/SyntheticSections.* +sed -i 's|numShards = 256;|numShards = 1;|' lld/*/ICF.cpp +sed -i 's|__FILE__|__FILE_NAME__|' compiler-rt/lib/builtins/int_util.h +sed -i 's|"@LLVM_SRC_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in +sed -i 's|"@LLVM_OBJ_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + +echo "### $0: building LLVM/Clang..." +export LD_LIBRARY_PATH="/store/2b0-musl/lib:$PREV_CLANG/lib" +export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/tmp/2b1-clang/build/lib" # libLLVM + +EXTRA_INCL='/tmp/2b1-clang/extra_includes' +mkdir -p $EXTRA_INCL +cp clang/lib/Headers/*intrin*.h $EXTRA_INCL/ +cp clang/lib/Headers/mm_malloc.h $EXTRA_INCL/ +[ -e $EXTRA_INCL/immintrin.h ] + +OPTS='' +add_opt() { + OPTS="$OPTS -D$1" +} +add_opt CMAKE_BUILD_TYPE=Release +add_opt LLVM_OPTIMIZED_TABLEGEN=YES +add_opt LLVM_CCACHE_BUILD=$USE_CCACHE +add_opt DEFAULT_SYSROOT=$SYSROOT +add_opt CMAKE_INSTALL_PREFIX=$OUT +add_opt LLVM_INSTALL_BINUTILS_SYMLINKS=YES +add_opt LLVM_INSTALL_CCTOOLS_SYMLINKS=YES +add_opt CMAKE_INSTALL_DO_STRIP=YES +add_opt LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=YES +add_opt LLVM_TARGET_ARCH=X86 +add_opt LLVM_TARGETS_TO_BUILD=Native +add_opt LLVM_BUILTIN_TARGETS=x86_64-unknown-linux-musl +add_opt LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl +add_opt LLVM_HOST_TRIPLE=x86_64-unknown-linux-musl +add_opt COMPILER_RT_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl +add_opt LLVM_APPEND_VC_REV=NO +add_opt LLVM_INCLUDE_TESTS=NO +add_opt LLVM_INCLUDE_EXAMPLES=NO +add_opt LLVM_INCLUDE_BENCHMARKS=NO +add_opt LLVM_ENABLE_BACKTRACES=NO +add_opt LLVM_ENABLE_EH=YES +add_opt LLVM_ENABLE_RTTI=YES +add_opt CLANG_ENABLE_ARCMT=NO +add_opt CLANG_ENABLE_STATIC_ANALYZER=NO +add_opt COMPILER_RT_BUILD_SANITIZERS=NO +add_opt COMPILER_RT_BUILD_XRAY=NO +add_opt COMPILER_RT_BUILD_LIBFUZZER=NO +add_opt COMPILER_RT_BUILD_PROFILE=NO +add_opt COMPILER_RT_BUILD_MEMPROF=NO +add_opt COMPILER_RT_BUILD_ORC=NO +add_opt COMPILER_RT_USE_BUILTINS_LIBRARY=YES +add_opt CLANG_DEFAULT_CXX_STDLIB=libc++ +add_opt CLANG_DEFAULT_LINKER=lld +add_opt CLANG_DEFAULT_RTLIB=compiler-rt +add_opt LIBCXX_HAS_MUSL_LIBC=YES +add_opt LIBCXX_USE_COMPILER_RT=YES +add_opt LIBCXX_INCLUDE_BENCHMARKS=NO +add_opt LIBCXX_CXX_ABI=libcxxabi +add_opt LIBCXXABI_USE_COMPILER_RT=YES +add_opt LIBCXXABI_USE_LLVM_UNWINDER=YES +add_opt LIBCXX_ADDITIONAL_COMPILE_FLAGS=-I/store/2a6-linux-headers/include +add_opt LLVM_INSTALL_TOOLCHAIN_ONLY=YES +add_opt LIBUNWIND_USE_COMPILER_RT=YES +add_opt LLVM_ENABLE_THREADS=NO + +REWRITE="-ffile-prefix-map=$(pwd)=/builddir/" +CFLAGS="--sysroot=$SYSROOT -I$EXTRA_INCL $REWRITE" +LDFLAGS="-Wl,--dynamic-linker=$LOADER" +cmake -S llvm -B build -G 'Unix Makefiles' \ + -DCMAKE_ASM_COMPILER=$PREV_CLANG/bin/clang \ + -DCMAKE_C_COMPILER=$PREV_CLANG/bin/clang \ + -DCMAKE_CXX_COMPILER=$PREV_CLANG/bin/clang++ \ + -DLLVM_ENABLE_PROJECTS='clang;lld' \ + -DLLVM_ENABLE_RUNTIMES='compiler-rt;libcxx;libcxxabi;libunwind' \ + -DCMAKE_C_FLAGS="$CFLAGS" \ + -DCMAKE_CXX_FLAGS="$CFLAGS" \ + -DCMAKE_C_LINK_FLAGS="$LDFLAGS" \ + -DCMAKE_CXX_LINK_FLAGS="$LDFLAGS" \ + -DLLVM_BUILD_LLVM_DYLIB=YES \ + -DLLVM_LINK_LLVM_DYLIB=YES \ + -DCLANG_LINK_LLVM_DYLIB=YES \ + $OPTS + +make -C build -j $NPROC clang lld runtimes + +echo "### $0: installing LLVM/Clang..." +make -C build -j $NPROC install/strip +ln -s $OUT/lib/x86_64-unknown-linux-musl/* $OUT/lib/ + +echo "### $0: setting up generic names..." +ln -s $OUT/bin/clang $OUT/bin/cc +ln -s $OUT/bin/clang++ $OUT/bin/c++ +ln -s $OUT/bin/clang-cpp $OUT/bin/cpp +ln -s $OUT/bin/lld $OUT/bin/ld + +echo "### $0: HACK making linux target work..." +# FIXME boost wants it at lib/clang/17/lib/linux/libclang_rt.builtins-x86_64.a +OUTLIB=$OUT/lib/clang/17/lib +ln -s $OUTLIB/x86_64-unknown-linux-musl $OUTLIB/linux +ln -s $OUTLIB/x86_64-unknown-linux-musl/libclang_rt.builtins.a \ + $OUTLIB/x86_64-unknown-linux-musl/libclang_rt.builtins-x86_64.a + +echo "### $0: mixing new stuff into sysroot..." +ln -s $OUT/lib/* $OUT/sysroot/lib/ + +echo "### $0: NOT checking for build path leaks - see _2b1.test.sh" diff --git a/06/recipes/2b2-busybox.sh b/06/recipes/2b2-busybox.sh new file mode 100755 index 0000000..4b48394 --- /dev/null +++ b/06/recipes/2b2-busybox.sh @@ -0,0 +1,48 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314 +#> FROM https://busybox.net/downloads/busybox-1.36.1.tar.bz2 + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2b1-clang/bin" + +mkdir -p /tmp/2b2-busybox; cd /tmp/2b2-busybox +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/1-stage1/protobusybox/bin/ash aliases/sh +export PATH="/tmp/2b2-busybox/aliases:$PATH" + +echo "### $0: unpacking busybox sources..." +tar --strip-components=1 -xf /downloads/busybox-1.36.1.tar.bz2 + +echo "### $0: configuring busybox..." +BUSYBOX_FLAGS='CONFIG_SHELL=/store/1-stage1/protobusybox/bin/ash' +BUSYBOX_FLAGS="$BUSYBOX_FLAGS CC=cc HOSTCC=cc" +BUSYBOX_FLAGS="$BUSYBOX_FLAGS KCONFIG_NOTIMESTAMP=y" +BUSYBOX_CFLAGS='CFLAGS=-O2 -isystem /store/2a6-linux-headers/include' +echo -e '#!/store/1-stage1/protobusybox/bin/ash\nprintf 9999' \ + > scripts/gcc-version.sh +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|g' \ + scripts/gen_build_files.sh \ + scripts/mkconfigs scripts/embedded_scripts scripts/trylink \ + scripts/generate_BUFSIZ.sh \ + applets/usage_compressed applets/busybox.mkscripts applets/install.sh +make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" defconfig +sed -i 's|CONFIG_INSTALL_NO_USR=y|CONFIG_INSTALL_NO_USR=n|' .config +sed -i 's|CONFIG_FEATURE_COMPRESS_USAGE=y|CONFIG_FEATURE_COMPRESS_USAGE=n|' \ + .config + +echo "### $0: building busybox..." +make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" busybox busybox.links +sed -i 's|^/usr/s\?bin/|/bin/|' busybox.links + +echo "### $0: installing busybox..." +make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" \ + install CONFIG_PREFIX=/store/2b2-busybox + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2b2 /store/2b2-busybox ) diff --git a/06/recipes/2b3-gnumake.sh b/06/recipes/2b3-gnumake.sh new file mode 100755 index 0000000..b9d563c --- /dev/null +++ b/06/recipes/2b3-gnumake.sh @@ -0,0 +1,45 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3 +#> FROM http://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2b1-clang/bin" + +mkdir -p /tmp/2b3-gnumake; cd /tmp/2b3-gnumake +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking GNU Make sources..." +tar --strip-components=1 -xf /downloads/make-4.4.1.tar.gz + +echo "### $0: fixing up GNU Make sources..." +# embrace chaos +shuffle_comment='\/\* Handle shuffle mode argument. \*\/' +shuffle_default='if (!shuffle_mode) shuffle_mode = xstrdup(\"random\");' +sed -i "s|$shuffle_comment|$shuffle_comment\n$shuffle_default|" src/main.c +grep 'if (!shuffle_mode) shuffle_mode = xstrdup("random");' src/main.c + +echo "### $0: building GNU Make..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' build-aux/install-sh +ash ./configure \ + CONFIG_SHELL=ash SHELL=ash MAKEINFO=true \ + --build x86_64-linux \ + --prefix=/store/2b3-gnumake \ + --disable-dependency-tracking +make -j $NPROC CFLAGS=-O2 + +echo "### $0: installing GNU Make with itself to test it..." +./make -j $NPROC SHELL=ash install-strip + +echo "### $0: creating a wrapper that respects \$SHELL..." +# FIXME: patch make to use getenv? +mkdir /store/2b3-gnumake/wrappers; cd /store/2b3-gnumake/wrappers +echo "#!/store/2b2-busybox/bin/ash" > make +echo "exec /store/2b3-gnumake/bin/make SHELL=\$SHELL \"\$@\"" \ >> make +chmod +x make + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2b3 /store/2b3-gnumake ) diff --git a/06/recipes/3a-boost.sh b/06/recipes/3a-boost.sh new file mode 100755 index 0000000..4927a2d --- /dev/null +++ b/06/recipes/3a-boost.sh @@ -0,0 +1,50 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 6478edfe2f3305127cffe8caf73ea0176c53769f4bf1585be237eb30798c3b8e +#> FROM https://archives.boost.io/release/1.83.0/source/boost_1_83_0.tar.bz2 + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" +export LD_LIBRARY_PATH=/store/2b1-clang/lib + +mkdir -p /tmp/3a-boost; cd /tmp/3a-boost +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/2b2-busybox/bin/ash aliases/sh +export PATH="/tmp/3a-boost/aliases:$PATH" + +echo "### $0: unpacking Boost sources..." +tar --strip-components=1 -xf /downloads/boost_1_83_0.tar.bz2 + +echo "### $0: patching up Boost sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' \ + bootstrap.sh +sed -i 's|/usr/bin/env sh|/store/2b2-busybox/bin/ash|' \ + tools/build/src/engine/build.sh +sed -i 's|/bin/sh|sh|' \ + tools/build/src/engine/execunix.cpp \ + boost/process/detail/posix/shell_path.hpp +EXTRA_INCL='/tmp/3a-boost/extra_includes' +mkdir -p $EXTRA_INCL +cp /store/2b1-clang/lib/clang/17/include/*intrin*.h $EXTRA_INCL/ +cp /store/2b1-clang/lib/clang/17/include/mm_malloc.h $EXTRA_INCL/ +cp /store/2b1-clang/lib/clang/17/include/unwind.h $EXTRA_INCL/ + +echo "### $0: building Boost..." +ash bootstrap.sh +./b2 -j $NPROC \ + include=/store/2a6-linux-headers/include \ + include=$EXTRA_INCL \ + include=/store/2b1-clang/include/x86_64-unknown-linux-musl/c++/v1 \ + --with-context --with-thread --with-system + +echo "### $0: installing Boost..." +./b2 install --prefix=/store/3a-boost \ + --with-context --with-thread --with-system + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-boost ) diff --git a/06/recipes/3a-brotli.sh b/06/recipes/3a-brotli.sh new file mode 100755 index 0000000..16ccbdf --- /dev/null +++ b/06/recipes/3a-brotli.sh @@ -0,0 +1,46 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46 +#> FROM https://github.com/google/brotli/archive/refs/tags/v1.0.9.tar.gz +#> AS brotli-1.0.9.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-brotli; cd /tmp/3a-brotli +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking brotli sources..." +tar --strip-components=1 -xf /downloads/brotli-1.0.9.tar.gz + +echo "### $0: building brotli..." +ash configure --prefix=/store/3a-brotli --help #--disable-dependency-tracking +CFLAGS='-fPIC' +CFLAGS="$CFLAGS -DBROTLICOMMON_SHARED_COMPILATION" +CFLAGS="$CFLAGS -DBROTLI_SHARED_COMPILATION" +make -j $NPROC lib CFLAGS="$CFLAGS" +clang -shared bin/obj/c/common/*.o -o libbrotlicommon.so +clang -shared bin/obj/c/enc/*.o libbrotlicommon.so -o libbrotlienc.so +clang -shared bin/obj/c/dec/*.o libbrotlicommon.so -o libbrotlidec.so + +echo "### $0: installing brotli..." +mkdir -p /store/3a-brotli/lib /store/3a-brotli/include +cp libbrotlicommon.so libbrotlienc.so libbrotlidec.so /store/3a-brotli/lib/ +cp -r c/include/brotli /store/3a-brotli/include/ +mkdir -p /store/3a-brotli/lib/pkgconfig +for l in common enc dec; do + sed < scripts/libbrotli${l}.pc.in \ + -e 's|@PACKAGE_VERSION@|1.0.9|g' \ + -e 's|@prefix@|/store/3a-brotli|g' \ + -e 's|@exec_prefix@|/store/3a-brotli/bin|g' \ + -e 's|@includedir@|/store/3a-brotli/include|g' \ + -e 's|@libdir@|/store/3a-brotli/lib|g' \ + -e 's|-R|-Wl,-rpath=|g' \ + > /store/3a-brotli/lib/pkgconfig/libbrotli${l}.pc +done + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-brotli ) diff --git a/06/recipes/3a-curl.sh b/06/recipes/3a-curl.sh new file mode 100755 index 0000000..632d3b8 --- /dev/null +++ b/06/recipes/3a-curl.sh @@ -0,0 +1,31 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894 +#> FROM https://curl.se/download/curl-8.2.1.tar.xz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" +export PATH="$PATH:/store/3a-pkg-config/bin" + +mkdir -p /tmp/3a-curl; cd /tmp/3a-curl +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking curl sources..." +tar --strip-components=1 -xf /downloads/curl-8.2.1.tar.xz + +echo "### $0: building curl..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure install-sh + +ash configure --prefix=/store/3a-curl \ + --with-mbedtls=/store/3a-mbedtls \ + --disable-dependency-tracking +make -j $NPROC + +echo "### $0: installing curl..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-curl ) diff --git a/06/recipes/3a-editline.sh b/06/recipes/3a-editline.sh new file mode 100755 index 0000000..41240bb --- /dev/null +++ b/06/recipes/3a-editline.sh @@ -0,0 +1,29 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH df223b3333a545fddbc67b49ded3d242c66fadf7a04beb3ada20957fcd1ffc0e +#> FROM https://github.com/troglobit/editline/releases/download/1.17.1/editline-1.17.1.tar.xz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-editline; cd /tmp/3a-editline +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking editline sources..." +tar --strip-components=1 -xf /downloads/editline-1.17.1.tar.xz + +echo "### $0: fixing up editline sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure aux/install-sh + +echo "### $0: building editline..." +ash configure --prefix=/store/3a-editline --disable-dependency-tracking +make -j $NPROC + +echo "### $0: installing editline..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-editline ) diff --git a/06/recipes/3a-gnugperf.sh b/06/recipes/3a-gnugperf.sh new file mode 100755 index 0000000..6928e0e --- /dev/null +++ b/06/recipes/3a-gnugperf.sh @@ -0,0 +1,33 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 588546b945bba4b70b6a3a616e80b4ab466e3f33024a352fc2198112cdbb3ae2 +#> FROM http://ftp.gnu.org/pub/gnu/gperf/gperf-3.1.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-gnugperf; cd /tmp/3a-gnugperf +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking GNU gperf sources..." +tar --strip-components=1 -xf /downloads/gperf-3.1.tar.gz + +echo "### $0: patching up GNU gperf sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' \ + configure lib/configure src/configure tests/configure doc/configure \ + Makefile.in src/Makefile.in doc/Makefile.in + +echo "### $0: building GNU gperf..." +REWRITE="-ffile-prefix-map=$(pwd)=/builddir/" +ash configure --prefix=/store/3a-gnugperf \ + CFLAGS=$REWRITE CXXFLAGS="$REWRITE -Wno-register" +make -j $NPROC + +echo "### $0: installing GNU gperf..." +make -j $NPROC install + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-gnugperf ) diff --git a/06/recipes/3a-libarchive.sh b/06/recipes/3a-libarchive.sh new file mode 100755 index 0000000..4ebe643 --- /dev/null +++ b/06/recipes/3a-libarchive.sh @@ -0,0 +1,33 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH b17403ce670ff18d8e06fea05a9ea9accf70678c88f1b9392a2e29b51127895f +#> FROM http://libarchive.org/downloads/libarchive-3.7.1.tar.xz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" +export PATH="$PATH:/store/3a-pkg-config/bin" + +mkdir -p /tmp/3a-libarchive; cd /tmp/3a-libarchive +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking libarchive sources..." +tar --strip-components=1 -xf /downloads/libarchive-3.7.1.tar.xz + +echo "### $0: fixing up libarchive sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' \ + configure build/autoconf/install-sh + +echo "### $0: building libarchive..." +ash configure --prefix=/store/3a-libarchive \ + --disable-dependency-tracking \ + --without-openssl +make -j $NPROC + +echo "### $0: installing libarchive..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-libarchive ) diff --git a/06/recipes/3a-libsodium.sh b/06/recipes/3a-libsodium.sh new file mode 100755 index 0000000..ae80ed8 --- /dev/null +++ b/06/recipes/3a-libsodium.sh @@ -0,0 +1,34 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1 +#> FROM https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz + + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" +export PATH="$PATH:/store/3a-pkg-config/bin" +export PKG_CONFIG_PATH='/store/3a-openssl/lib64/pkgconfig' + +mkdir -p /tmp/3a-libsodium; cd /tmp/3a-libsodium +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking libsodium sources..." +tar --strip-components=1 -xf /downloads/libsodium-1.0.18.tar.gz + +echo "### $0: fixing up libsodium sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' \ + configure build-aux/install-sh + +echo "### $0: building libsodium..." +ash configure --prefix=/store/3a-libsodium \ + --disable-dependency-tracking +make -j $NPROC + +echo "### $0: installing libsodium..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-libsodium ) diff --git a/06/recipes/3a-lowdown.sh b/06/recipes/3a-lowdown.sh new file mode 100755 index 0000000..2cfd514 --- /dev/null +++ b/06/recipes/3a-lowdown.sh @@ -0,0 +1,33 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 049b7883874f8a8e528dc7c4ed7b27cf7ceeb9ecf8fe71c3a8d51d574fddf84b +#> FROM https://github.com/kristapsdz/lowdown/archive/refs/tags/VERSION_1_0_2.tar.gz +#> AS lowdown-1.0.2.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/wrappers" +export PATH="$PATH:/store/3a-pkg-config/bin" +export PKG_CONFIG_PATH='/store/3a-openssl/lib64/pkgconfig' +export SHELL='/store/2b2-busybox/bin/ash' + +mkdir -p /tmp/3a-lowdown; cd /tmp/3a-lowdown +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking lowdown sources..." +tar --strip-components=1 -xf /downloads/lowdown-1.0.2.tar.gz + +echo "### $0: fixing up lowdown sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure + +echo "### $0: building lowdown..." +ash configure PREFIX=/store/3a-lowdown +make -j $NPROC CFLAGS=-ffile-prefix-map=$(pwd)=/builddir/ + +echo "### $0: installing lowdown..." +make -j $NPROC install_shared + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-lowdown ) diff --git a/06/recipes/3a-mbedtls.sh b/06/recipes/3a-mbedtls.sh new file mode 100755 index 0000000..5fa5413 --- /dev/null +++ b/06/recipes/3a-mbedtls.sh @@ -0,0 +1,32 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH a420fcf7103e54e775c383e3751729b8fb2dcd087f6165befd13f28315f754f5 +#> FROM https://github.com/Mbed-TLS/mbedtls/archive/refs/tags/v3.4.1.tar.gz +#> AS mbedtls-3.4.1.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/wrappers" +export SHELL=/store/2b2-busybox/bin/ash + +mkdir -p /tmp/3a-mbedtls; cd /tmp/3a-mbedtls +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking mbedtls sources..." +tar --strip-components=1 -xf /downloads/mbedtls-3.4.1.tar.gz + +echo "### $0: fixing up mbedtls sources..." +sed -i 's|^DESTDIR=.*|DESTDIR=/store/3a-mbedtls|' Makefile +sed -i 's|programs: lib mbedtls_test|programs: lib|' Makefile +sed -i 's|install: no_test|install: lib|' Makefile + +echo "### $0: building mbedtls..." +make -j $NPROC lib + +echo "### $0: installing mbedtls..." +make -j $NPROC install + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-mbedtls ) diff --git a/06/recipes/3a-nlohmann-json.sh b/06/recipes/3a-nlohmann-json.sh new file mode 100755 index 0000000..37f0545 --- /dev/null +++ b/06/recipes/3a-nlohmann-json.sh @@ -0,0 +1,29 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 8c4b26bf4b422252e13f332bc5e388ec0ab5c3443d24399acb675e68278d341f +#> FROM https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz +#> AS nlohmann-json-3.11.2.tar.xz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-nlohmann-json; cd /tmp/3a-nlohmann-json + +echo "### $0: unpacking nlohmann-json sources..." +tar --strip-components=1 -xf /downloads/nlohmann-json-3.11.2.tar.xz + +echo "### $0: installing nlohmann-json..." +mkdir /store/3a-nlohmann-json +cp -rv include /store/3a-nlohmann-json +mkdir -p /store/3a-nlohmann-json/lib/pkgconfig +sed < cmake/pkg-config.pc.in \ + -e 's|${PROJECT_NAME}|nlohmann_json|' \ + -e 's|${PROJECT_VERSION}|3.11.2|' \ + -e 's|${CMAKE_INSTALL_FULL_INCLUDEDIR}|/store/3a-nlohmann-json/include|' \ + > /store/3a-nlohmann-json/lib/pkgconfig/nlohmann_json.pc + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-nlohmann-json ) diff --git a/06/recipes/3a-pkg-config.sh b/06/recipes/3a-pkg-config.sh new file mode 100755 index 0000000..399006b --- /dev/null +++ b/06/recipes/3a-pkg-config.sh @@ -0,0 +1,32 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 6fc69c01688c9458a57eb9a1664c9aba372ccda420a02bf4429fe610e7e7d591 +#> FROM https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-pkg-config; cd /tmp/3a-pkg-config +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking pkg-config sources..." +tar --strip-components=1 -xf /downloads/pkg-config-0.29.2.tar.gz + +echo "### $0: patching pkg-config..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' \ + configure glib/configure \ + install-sh glib/install-sh + +echo "### $0: building pkg-config..." +ash configure --prefix=/store/3a-pkg-config --with-internal-glib \ + CFLAGS=-Wno-int-conversion +make -j $NPROC + +echo "### $0: installing pkg-config..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-pkg-config ) diff --git a/06/recipes/3a-seccomp.sh b/06/recipes/3a-seccomp.sh new file mode 100755 index 0000000..1840f8f --- /dev/null +++ b/06/recipes/3a-seccomp.sh @@ -0,0 +1,31 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH d82902400405cf0068574ef3dc1fe5f5926207543ba1ae6f8e7a1576351dcbdb +#> FROM https://github.com/seccomp/libseccomp/releases/download/v2.5.4/libseccomp-2.5.4.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" +export PATH="$PATH:/store/3a-gnugperf/bin" + +mkdir -p /tmp/3a-seccomp; cd /tmp/3a-seccomp +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking seccomp sources..." +tar --strip-components=1 -xf /downloads/libseccomp-2.5.4.tar.gz + +echo "### $0: patching up seccomp sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure build-aux/install-sh + +echo "### $0: building seccomp..." +ash configure --prefix=/store/3a-seccomp --disable-dependency-tracking \ + CFLAGS=-I/store/2a6-linux-headers/include +make -j $NPROC + +echo "### $0: installing seccomp..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-seccomp ) diff --git a/06/recipes/3a-sqlite.sh b/06/recipes/3a-sqlite.sh new file mode 100755 index 0000000..5907762 --- /dev/null +++ b/06/recipes/3a-sqlite.sh @@ -0,0 +1,28 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH 49008dbf3afc04d4edc8ecfc34e4ead196973034293c997adad2f63f01762ae1 +#> FROM https://sqlite.org/2023/sqlite-autoconf-3430000.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" + +mkdir -p /tmp/3a-sqlite; cd /tmp/3a-sqlite +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking SQLite archive..." +tar --strip-components=1 -xf /downloads/sqlite-autoconf-3430000.tar.gz + +echo "### $0: building SQLite..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure install-sh + +ash configure --prefix=/store/3a-sqlite +make -j $NPROC + +echo "### $0: installing SQLite..." +make -j $NPROC install-strip + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3a /store/3a-sqlite ) diff --git a/06/recipes/3b-busybox-static.sh b/06/recipes/3b-busybox-static.sh new file mode 100755 index 0000000..c2ae42c --- /dev/null +++ b/06/recipes/3b-busybox-static.sh @@ -0,0 +1,49 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314 +#> FROM https://busybox.net/downloads/busybox-1.36.1.tar.bz2 + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/wrappers" + +mkdir -p /tmp/3b-busybox-static; cd /tmp/3b-busybox-static +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: aliasing ash to sh..." +mkdir aliases; ln -s /store/2b2-busybox/bin/ash aliases/sh +export PATH="/tmp/3b-busybox-static/aliases:$PATH" + +echo "### $0: unpacking busybox sources..." +tar --strip-components=1 -xf /downloads/busybox-1.36.1.tar.bz2 + +echo "### $0: configuring busybox..." +BUSYBOX_FLAGS='CONFIG_SHELL=/store/2b2-busybox/bin/ash' +BUSYBOX_FLAGS='SHELL=/store/2b2-busybox/bin/ash' +BUSYBOX_FLAGS="$BUSYBOX_FLAGS CC=cc HOSTCC=cc" +BUSYBOX_FLAGS="$BUSYBOX_FLAGS KCONFIG_NOTIMESTAMP=y" +BUSYBOX_CFLAGS='CFLAGS=-O2 -isystem /store/2a6-linux-headers/include' +echo -e '#!/store/2b2-busybox/bin/ash\nprintf 9999' \ + > scripts/gcc-version.sh +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|g' \ + scripts/gen_build_files.sh \ + scripts/mkconfigs scripts/embedded_scripts scripts/trylink \ + scripts/generate_BUFSIZ.sh \ + applets/usage_compressed applets/busybox.mkscripts applets/install.sh +make -j $NPROC $BUSYBOX_FLAGS defconfig +sed -i 's|CONFIG_INSTALL_NO_USR=y|CONFIG_INSTALL_NO_USR=n|' .config +sed -i 's|CONFIG_FEATURE_SHARED_BUSYBOX=y|CONFIG_FEATURE_SHARED_BUSYBOX=n|' \ + .config + +echo "### $0: building busybox..." +make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" busybox busybox.links +sed -i 's|^/usr/s\?bin/|/bin/|' busybox.links + +echo "### $0: installing busybox..." +make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" \ + install CONFIG_PREFIX=/store/3b-busybox-static + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3b /store/3b-busybox-static ) diff --git a/06/recipes/3b-nix.sh b/06/recipes/3b-nix.sh new file mode 100755 index 0000000..71a6a49 --- /dev/null +++ b/06/recipes/3b-nix.sh @@ -0,0 +1,100 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH f3f8016621cf3971e0768404f05b89d4a7fc1911dddae5a9a7ed4bf62519302c +#> FROM https://github.com/ZilchOS/nix/releases/download/nix-2.17.0-zilched/nix-2.17.0-zilched.tar.xz + +#> FETCH 3659cd137c320991a78413dd370a92fd18e0a8bc36d017d554f08677a37d7d5a +#> FROM https://raw.githubusercontent.com/somasis/musl-compat/c12ea3af4e6ee53158a175d992049c2148db5ff6/include/sys/queue.h + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/wrappers" +export PATH="$PATH:/store/3a-pkg-config/bin" +export PATH="$PATH:/store/3a-lowdown/bin" + +export SHELL='/store/2b2-busybox/bin/ash' + +#export PKG_CONFIG_PATH='/store/3a-openssl/lib64/pkgconfig' +export PKG_CONFIG_PATH='' +#export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-bzip2/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-sqlite/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-curl/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-editline/lib/pkgconfig" +#export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-xz/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-brotli/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-seccomp/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libarchive/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libsodium/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-lowdown/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-nlohmann-json/lib/pkgconfig" +#LIBDIRS="$(pkg-config --variable=libdir openssl)" +LIBDIRS="" +#LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir bzip2)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir sqlite3)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libeditline)" +#LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir liblzma)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libbrotlicommon)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libseccomp)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libarchive)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libsodium)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir lowdown)" +export LD_LIBRARY_PATH=$LIBDIRS + +export BOOST_ROOT=/store/3a-boost/include + +mkdir -p /tmp/3b-nix; cd /tmp/3b-nix +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking Nix sources..." +tar --strip-components=1 \ + -xf /downloads/nix-2.17.0-zilched.tar.xz + +echo "### $0: copying queue.h..." +mkdir -p compat-includes/sys +cp /downloads/queue.h compat-includes/sys/ + +echo "### $0: stubbing out commands..." +mkdir stubs; export PATH="$(pwd)/stubs:$PATH" +ln -s /store/2b2-busybox/bin/true stubs/jq +ln -s /store/2b2-busybox/bin/true stubs/expr +ln -s /store/2b2-busybox/bin/ash stubs/bash + +echo "### $0: patching up Nix sources..." +sed -i 's|/bin/sh|/store/2b2-busybox/bin/ash|' configure +sed -i 's|/bin/sh|${stdenv.busybox}/bin/ash|' configure +# avoid an expression confusing ash +nl configure | grep 7217 | tee configure-problematic-line +grep -F "'X\(//\)$'" configure-problematic-line +sed -i '7217d' configure +nl configure | grep 7217 | tee configure-problematic-line +! grep -F "'X\(//\)$'" configure-problematic-line +# replace the declare confusing ash +sed -i 's|declare \$name=.*|:|' configure + +echo "### $0: building Nix..." +PCDEPS='libbrotlicommon libbrotlienc libbrotlidec sqlite3 libseccomp lowdown' +PCDEPS="$PCDEPS nlohmann_json" +INC="-I/store/2a6-linux-headers/include -I$(pwd)/compat-includes" +REWRITE="-ffile-prefix-map=$(pwd)=/builddir/" +export CFLAGS="$(pkg-config --cflags $PCDEPS) $INC $REWRITE" +export CXXFLAGS="$CFLAGS" +export GLOBAL_CXXFLAGS="$CFLAGS" +export LDFLAGS="$(pkg-config --libs $PCDEPS) -L/store/3a-boost/lib -v" +ash configure --prefix=/store/3b-nix \ + --with-boost=$BOOST_ROOT \ + --disable-doc-gen \ + --disable-gc \ + --disable-cpuid \ + --disable-gtest \ + --with-sandbox-shell=/store/3b-busybox-static/bin/busybox +sed -i "s|\${prefix}|/store/3b-nix|g" config.status +sed -i "s|\${exec_prefix}|/store/3b-nix|g" config.status +make -j $NPROC V=1 + +echo "### $0: installing Nix..." +make -j $NPROC install + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3b /store/3b-nix ) diff --git a/06/recipes/3b-tinycc-static.sh b/06/recipes/3b-tinycc-static.sh new file mode 100755 index 0000000..562a430 --- /dev/null +++ b/06/recipes/3b-tinycc-static.sh @@ -0,0 +1,42 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH f5a71d05664340ae46cda9579c6079a0f2fa809d24386d284f0d091e4d576a4e +#> FROM https://github.com/TinyCC/tinycc/archive/af1abf1f45d45b34f0b02437f559f4dfdba7d23c.tar.gz +#> AS tinycc-mob-af1abf1.tar.gz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/wrappers" +export SHELL="/store/2b2-busybox/bin/ash" + +mkdir -p /tmp/3b-tinycc-static; cd /tmp/3b-tinycc-static +if [ -e /ccache/setup ]; then . /ccache/setup; fi + +echo "### $0: unpacking TinyCC sources..." +tar --strip-components=1 -xf /downloads/tinycc-mob-af1abf1.tar.gz + +#echo "### $0: fixing up TinyCC sources..." +sed -i "s|^VERSION = .*|VERSION = mob-af1abf1|" configure +sed -i "s|^GITHASH := .*|GITHASH = mob:af1abf1|" configure + +echo "### $0: configuring TinyCC..." +$SHELL configure \ + --prefix=/store/3b-tinycc-static \ + --cc=cc \ + --extra-cflags="-O3 -static" \ + --extra-ldflags="-static" \ + --enable-static \ + --config-musl + +echo "### $0: building TinyCC..." + +make -j $NPROC tcc + +echo "### $0: installing TinyCC..." +mkdir -p /store/3b-tinycc-static/bin +cp tcc /store/3b-tinycc-static/bin/ + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/3b /store/3b-tinycc-static ) diff --git a/06/recipes/3b-zig.sh b/06/recipes/3b-zig.sh new file mode 100644 index 0000000..6e6c472 --- /dev/null +++ b/06/recipes/3b-zig.sh @@ -0,0 +1,14 @@ +#!/store/2b2-busybox/bin/ash + +#> FETCH +#> FROM https://github.com/ziglang/zig-bootstrap/archive/refs/tags/0.14.0.tar.gz +#> AS zig-bootstrap-0.14.0.tar.gz + +mkdir -p /tmp/3a-zig; cd /tmp/3a-zig + +echo "### $0: unpacking zig-boostrap sources..." +tar --strip-components=1 -xf /downloads/zig-bootstrap-0.14.0.tar.gz + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/2b1-clang/bin" +export PATH="$PATH:/store/2b3-gnumake/bin" diff --git a/06/recipes/4-rebootstrap-using-nix.sh b/06/recipes/4-rebootstrap-using-nix.sh new file mode 100755 index 0000000..1d89aea --- /dev/null +++ b/06/recipes/4-rebootstrap-using-nix.sh @@ -0,0 +1,98 @@ +#!/store/2b2-busybox/bin/ash + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/3a-pkg-config/bin" +export PATH="$PATH:/store/3a-sqlite/bin" +export PATH="$PATH:/store/3b-nix/bin" + +export SHELL='/store/2b2-busybox/bin/ash' + +export PKG_CONFIG_PATH='' +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-sqlite/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-curl/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-editline/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-seccomp/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libarchive/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libsodium/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-lowdown/lib/pkgconfig" +LIBDIRS='' +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir sqlite3)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libcurl)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libeditline)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libseccomp)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libarchive)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libsodium)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir lowdown)" +LIBDIRS="$LIBDIRS:/store/3a-boost/lib" +LIBDIRS="$LIBDIRS:/store/2b1-clang/lib" +export LD_LIBRARY_PATH=$LIBDIRS + +mkdir -p /tmp/4-rebootstrap-using-nix; cd /tmp/4-rebootstrap-using-nix + +echo "### $0: preparing stuff for nix to work..." +mkdir -p /dev/pts +mount -t devpts devpts /dev/pts +ln -s /dev/pts/ptmx /dev/ptmx + +echo "### $0: faking lots of stuff for nix to work..." +mkdir shelter +export HOME=/tmp/4-rebootstrap-using-nix/shelter +export USER=notauser +echo 'oh come on' >/dev/urandom + +echo "### $0: fixing up paths to shell..." +cp -a --reflink=auto /using-nix /default.nix /recipes ./ +sed -i 's|/bin/sh|/store/3b-busybox-static/bin/ash|' using-nix/1-stage1.nix + +echo "### $0: pointing to local downloads..." +sed -i 's| url =| #remote_url =|' using-nix/*.nix +sed -i 's|# local = \(.*\);|url = "file://\1";|' using-nix/*.nix + +if [ -e /prev/nix/store ] && [ -e /prev/nix-db.tar ]; then + echo "### $0: restoring nix store & db from previous build..." + mkdir -p /nix + cp -a --reflink=auto /prev/nix/store /nix + tar -xf /prev/nix-db.tar -C / + sqlite3 /nix/var/nix/db/db.sqlite \ + < /nix/var/nix/db/db.sqlite.dump + rm /nix/var/nix/db/db.sqlite.dump +fi + +echo "### $0: writing a 0.nix that simply injects what we've built..." +# Makefile bootstrap injects it as /stage/protosrc, regular --- as /protosrc +[ -e /protosrc ] && PROTOSRC="/protosrc" || PROTOSRC=/stage/protosrc +echo "{ tinycc = /store/3b-tinycc-static/bin/tcc; protosrc = $PROTOSRC; }" \ + > using-nix/0.nix + +echo "### $0: rebuilding everything using nix..." +nix-build \ + --extra-experimental-features ca-derivations \ + --option build-users-group '' \ + --option compress-build-log false \ + --no-substitute \ + --cores $NPROC \ + --keep-failed \ + -vvv \ + default.nix +rm -f /dev/urandom +rm /dev/ptmx +umount /dev/pts +umount /dev/pts || true +rm -r /dev/pts +rm -r shelter +rm -rf /build + +# this one is special wrt how the results are saved, see Makefile/USE_NIX_CACHE +echo "### $0: exporting resulting /nix/store (reproducible)..." +mkdir -p /store/4-rebootstrap-using-nix/nix +cp -a --reflink=auto /nix/store /store/4-rebootstrap-using-nix/nix/ + +echo "### $0: exporting /nix/var/nix/db to restore it (non-reproducible)..." +cp /nix/var/nix/db/db.sqlite db.sqlite +sqlite3 db.sqlite 'UPDATE ValidPaths SET registrationTime = 1;' +sqlite3 db.sqlite .dump > /nix/var/nix/db/db.sqlite.dump +tar --exclude nix/var/nix/db/db.sqlite \ + -cf /store/4-rebootstrap-using-nix/nix-db.tar /nix/var/nix/db +rm /nix/var/nix/db/db.sqlite.dump diff --git a/06/recipes/5-go-beyond-using-nix.sh b/06/recipes/5-go-beyond-using-nix.sh new file mode 100755 index 0000000..66133e3 --- /dev/null +++ b/06/recipes/5-go-beyond-using-nix.sh @@ -0,0 +1,203 @@ +#!/store/2b2-busybox/bin/ash +#> FETCH 10fa524294f58c805411ddd6e5522c02a0b69ad14e036b141cc80fb53a3ef1a0 +#> FROM https://github.com/ZilchOS/core/archive/2023.10.1.tar.gz +#> AS ZilchOS-core-2023.10.1.tar.gz + +#> FETCH ddd417f9caab3ef0f3031b938815a5c33367c3a50c09830138d208bd3126c98f +#> FROM https://github.com/limine-bootloader/limine/releases/download/v5.20230830.0/limine-5.20230830.0.tar.xz + +#> FETCH 1952b2a782ba576279c211ee942e341748fdb44997f704dd53def46cd055470b +#> FROM https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0.tar.bz2 + +#> FETCH 9bba0214ccf7f1079c5d59210045227bcf619519840ebfa80cd3849cff5a5bf2 +#> FROM https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz + +#> FETCH 63aede5c6d33b6d9b13511cd0be2cac046f2e70fd0a07aa9573a04a82783af96 +#> FROM https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.xz + +#> FETCH e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995 +#> FROM https://github.com/westes/flex/files/981163/flex-2.6.4.tar.gz + +#> FETCH 541e179665dc4e272b9602f2074243591a157da89cc47064da8c5829dbd2b339 +#> FROM http://ftp.gnu.org/gnu/mtools/mtools-4.0.43.tar.bz2 + +#> FETCH 786f9f5df9865cc5b0c1fecee3d2c0f5e04cab8c9a859bd1c9c7ccd4964fdae1 +#> FROM https://www.gnu.org/software/xorriso/xorriso-1.5.6.pl02.tar.gz + +#> FETCH 9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4 +#> FROM https://github.com/facebook/zstd/releases/download/v1.5.5/zstd-1.5.5.tar.gz + +#> FETCH 23c2469e2a568362a62eecf1b49ed90a15621e6fa30e29947ded3436422de9b9 +#> FROM https://curl.se/ca/cacert-2023-08-22.pem + +#> FETCH 85cd12e9cf1d6d5a45f17f7afe1cebe7ee628d3282281c492e86adf636defa3f +#> FROM https://www.python.org/ftp/python/3.11.5/Python-3.11.5.tar.xz + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/3a-pkg-config/bin" +export PATH="$PATH:/store/3a-sqlite/bin" +export PATH="$PATH:/store/3b-nix/bin" + +export SHELL='/store/2b2-busybox/bin/ash' + +export PKG_CONFIG_PATH='' +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-sqlite/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-curl/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-editline/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-seccomp/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libarchive/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libsodium/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-lowdown/lib/pkgconfig" +LIBDIRS='' +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir sqlite3)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libcurl)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libeditline)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libseccomp)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libarchive)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libsodium)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir lowdown)" +LIBDIRS="$LIBDIRS:/store/3a-boost/lib" +LIBDIRS="$LIBDIRS:/store/2b1-clang/lib" +export LD_LIBRARY_PATH=$LIBDIRS + +mkdir -p /tmp/5-go-beyond-using-nix; cd /tmp/5-go-beyond-using-nix + +echo "### $0: preparing stuff for nix to work..." +mkdir -p /dev/pts +mount -t devpts devpts /dev/pts +ln -s /dev/pts/ptmx /dev/ptmx + +echo "### $0: faking lots of stuff for nix to work..." +mkdir shelter +export HOME=/tmp/5-go-beyond-using-nix/shelter +export USER=notauser +echo 'oh come on' >/dev/urandom +printf '\0\0\0\0\0\0\0\0\0\0' > 10x0 +cat 10x0 10x0 10x0 10x0 10x0 10x0 10x0 10x0 10x0 10x0 > 100x0 +cat 100x0 100x0 100x0 100x0 100x0 100x0 100x0 100x0 100x0 100x0 > 1Kx0 +cat 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 1Kx0 > 10Kx0 +cat 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 10Kx0 > 100Kx0 +cat 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 100Kx0 \ + > 1Mx0 +cat 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 1Mx0 > 10Mx0 +mv 10Mx0 /dev/zero +rm *x0 + +echo "### $0: fixing up paths to shell..." +sed -i 's|/bin/sh|/store/3b-busybox-static/bin/ash|' /using-nix/1-stage1.nix + +if [ -e /prev/nix/store ] && [ -e /prev/nix-db.tar ]; then + echo "### $0: restoring nix store & db from previous build..." + mkdir -p /nix + mv /prev/nix/store /nix + tar -xf /prev/nix-db.tar -C / + sqlite3 /nix/var/nix/db/db.sqlite \ + < /nix/var/nix/db/db.sqlite.dump + rm /nix/var/nix/db/db.sqlite.dump +elif [ ! -e /nix/store ]; then + echo "### $0: restoring nix store & db from previous stage..." + mkdir -p /nix + cp -a /store/4-rebootstrap-using-nix/nix/store /nix/ + tar -xf /store/4-rebootstrap-using-nix/nix-db.tar -C / + sqlite3 /nix/var/nix/db/db.sqlite \ + < /nix/var/nix/db/db.sqlite.dump + rm /nix/var/nix/db/db.sqlite.dump +fi + + +echo "### $0: creating a ZilchOS/bootstrap flake..." +mkdir ZilchOS-bootstrap +cp -r /flake.nix /default.nix /using-nix /recipes \ + ZilchOS-bootstrap/ + +echo "### $0: pointing to local files..." +sed -i 's| url =| #remote_url =|' ZilchOS-bootstrap/using-nix/*.nix +sed -i 's|# local = \(.*\);|url = "file://\1";|' ZilchOS-bootstrap/using-nix/*.nix +echo "### $0: writing a 0.nix that simply injects what we've built..." +# Makefile bootstrap injects it as /stage/protosrc, regular --- as /protosrc +[ -e /protosrc ] && PROTOSRC="/protosrc" || PROTOSRC=/stage/protosrc +echo "{ tinycc = /store/3b-tinycc-static/bin/tcc; protosrc = $PROTOSRC; }" \ + > ZilchOS-bootstrap/using-nix/0.nix + +if [[ ! -e ZilchOS-core ]]; then + echo "### $0: unpacking ZilchOS/core archive..." + mkdir ZilchOS-core + tar -xf /downloads/ZilchOS-core-2023.10.1.tar.gz --strip-components=1 \ + -C ZilchOS-core +fi +[[ -e ZilchOS-core/flake.nix ]] +cd ZilchOS-core +nix flake lock \ + --extra-experimental-features 'ca-derivations flakes nix-command' \ + --update-input bootstrap-from-tcc \ + --override-input bootstrap-from-tcc path:../ZilchOS-bootstrap +pwd +cd .. +ls -l ZilchOS-core + +echo "### $0: pointing to local downloads..." +sed -i 's| url =| #remote_url =|' \ + ZilchOS-core/*/*.nix ZilchOS-core/*/*/*.nix +sed -i 's|# local = \(.*\);|url = "file://\1";|' \ + ZilchOS-core/*/*.nix ZilchOS-core/*/*/*.nix + +if [ -e /ccache/setup ]; then + echo "### $0: configuring ccache..." + export CCACHE_COMPILERCHECK=content + export CCACHE_SLOPPINESS=include_file_ctime,include_file_mtime + export CCACHE_MAXSIZE=0 + export CCACHE_DIR=/ccache + MAYBE_CCACHE='ccachedPackages.' +else + MAYBE_CCACHE='' +fi + +echo "### $0: building ZilchOS/core using nix..." +mkdir -p /store/5-go-beyond-using-nix +: > /store/5-go-beyond-using-nix/hashes +while IFS=' ' read -r _unused_old_hash pkg; do + # can't have sandbox, need deterministic build paths + nix build \ + --extra-experimental-features 'ca-derivations flakes nix-command' \ + --option build-users-group '' \ + --option compress-build-log false \ + --no-substitute \ + --cores $NPROC \ + --keep-failed \ + --show-trace \ + -L \ + -vvv \ + -o .tmp \ + "./ZilchOS-core#${MAYBE_CCACHE}${pkg}" + new_path=$(readlink .tmp*) + new_hash=$(echo $new_path | sed -E 's|.*/([a-z0-9]{32})-.*|\1|') + if [ "$pkg" != 'live-cd^iso' ]; then rm .tmp*; fi + echo "$new_hash $pkg" >> /store/5-go-beyond-using-nix/hashes +done < ./ZilchOS-core/.maint/hashes +sha256sum .tmp*-iso # the last one is the iso +rm -f /dev/urandom +rm -f /dev/zero +rm /dev/ptmx +umount /dev/pts +umount /dev/pts || true +rm -r /dev/pts +rm -r shelter +rm -rf /build + +# this one is special wrt how the results are saved, see Makefile/USE_NIX_CACHE +echo "### $0: exporting resulting /nix/store (reproducible)..." +mkdir -p /store/5-go-beyond-using-nix/nix +cp -a --reflink=auto /nix/store /store/5-go-beyond-using-nix/nix/ + +echo "### $0: exporting /nix/var/nix/db to restore it (non-reproducible)..." +cp /nix/var/nix/db/db.sqlite db.sqlite +sqlite3 db.sqlite 'UPDATE ValidPaths SET registrationTime = 1;' +sqlite3 db.sqlite .dump > /nix/var/nix/db/db.sqlite.dump +tar --exclude nix/var/nix/db/db.sqlite \ + -cf /store/5-go-beyond-using-nix/nix-db.tar /nix/var/nix/db +rm /nix/var/nix/db/db.sqlite.dump + +echo "### $0: exporting the iso as well..." +cat .tmp*-iso > /store/5-go-beyond-using-nix/ZilchOS-core.iso diff --git a/06/recipes/_1.test.sh b/06/recipes/_1.test.sh new file mode 100755 index 0000000..06c45b3 --- /dev/null +++ b/06/recipes/_1.test.sh @@ -0,0 +1,40 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH=/store/1-stage1/tinycc/wrappers:/store/1-stage1/protobusybox/bin + +mkdir -p /tmp/_1.test; cd /tmp/_1.test + + +echo "### $0: checking that /protosrc has not leaked into outputs..." +! grep -rF /protosrc /store/1-stage1 + +echo "### $0: checking compilation..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c +cc -o va_test.o va_test.c +cc -o va_test va_test.c +( ! grep /store/2a3-intermediate-musl/lib/libc.so va_test.o va_test ) +( ! grep ld-linux va_test.o va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: checking that we've got bzip2..." + +hello=$(echo hello | bzip2 -1 | bzip2 -d) +[ "$hello" == hello ] + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/_1.test . ) +( ! grep -rF /tmp/1-stage1 . ) +( ! grep -rF /store/1-stage1 . ) +( ! grep -rF va_test . ) +( ! grep -rF /tmp/1-stage1 /store/1-stage1 ) +( ! grep -rF /tmp/_1.test /store/1-stage1 ) + +touch /store/_1.test # indicator of successful completion diff --git a/06/recipes/_2a0-ccache.sh b/06/recipes/_2a0-ccache.sh new file mode 100755 index 0000000..e78c8d7 --- /dev/null +++ b/06/recipes/_2a0-ccache.sh @@ -0,0 +1,65 @@ +#!/store/1-stage1/protobusybox/bin/ash + +#> FETCH a02f4e8360dc6618bc494ca35b0ae21cea080f804a4898eab1ad3fcd108eb400 +#> FROM https://github.com/ccache/ccache/releases/download/v3.7.12/ccache-3.7.12.tar.xz + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/1-stage1/tinycc/wrappers" +export PATH="$PATH:/store/2a0-static-gnumake/bin" + +echo "### $0: unpacking ccache sources..." +mkdir -p /tmp/_2a0-ccache; cd /tmp/_2a0-ccache +tar --strip-components=1 -xf /downloads/ccache-3.7.12.tar.xz + +echo "### $0: building ccache..." +sed -i 's|/bin/sh|/store/1-stage1/protobusybox/bin/ash|' configure +ash configure \ + --host x86_64-linux --build x86_64-linux \ + --prefix=/store/_2a0-ccache +make -j $NPROC + +echo "### $0: installing ccache..." +make -j $NPROC install + +cat > /store/_2a0-ccache/wrap-available <<\EOF +mkdir -p .ccache-wrappers +for prefix in '' x86_64-linux- x86_64-linux-musl- x86_64-linux-unknown-; do + for name in cc c++ gcc g++ clang clang++ tcc; do + if command -v $prefix$name; then + ln -s /store/_2a0-ccache/bin/ccache \ + .ccache-wrappers/$prefix$name + fi + done +done +pwd +export PATH="$(pwd)/.ccache-wrappers:$PATH" +EOF +chmod +x /store/_2a0-ccache/wrap-available + +. /store/_2a0-ccache/wrap-available + +mkdir /store/_2a0-ccache/etc +cat > /store/_2a0-ccache/etc/ccache.conf <<\EOF +cache_dir = /ccache +compiler_check = content +compression = false +sloppiness = include_file_ctime,include_file_mtime +max_size = 0 +EOF +export PATH="/store/_2a0-ccache/wrappers/cc-only:$PATH" + +echo "### $0: testing ccache on itself..." +/store/_2a0-ccache/bin/ccache -z +/store/_2a0-ccache/bin/ccache -s > _stats; cat _stats +grep '^cache miss 0$' _stats +grep '^cache hit rate 0.00 %$' _stats +ash configure --host x86_64-linux --build x86_64-linux CC=cc +make -j $NPROC -B +/store/_2a0-ccache/bin/ccache -z +make -j $NPROC -B +/store/_2a0-ccache/bin/ccache -s > _stats; cat _stats +grep '^cache miss 0$' _stats +grep '^cache hit rate 100.00 %' _stats +/store/_2a0-ccache/bin/ccache -z diff --git a/06/recipes/_2a3.test.sh b/06/recipes/_2a3.test.sh new file mode 100755 index 0000000..33b5ba4 --- /dev/null +++ b/06/recipes/_2a3.test.sh @@ -0,0 +1,37 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH='/store/2a0-static-gnumake/bin' +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a2-static-gnugcc4-c/bin" +export PATH="$PATH:/store/1-stage1/protobusybox/bin" + +mkdir -p /tmp/_2a3.test; cd /tmp/_2a3.test + +echo "### $0: preparing..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c + +echo "### $0: testing (dynamic)..." +SYSROOT=/store/2a3-intermediate-musl +make va_test \ + CC=gcc \ + LDFLAGS="-Wl,--dynamic-linker=$SYSROOT/lib/libc.so --sysroot $SYSROOT" +grep /store/2a3-intermediate-musl/lib/libc.so va_test +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (static)..." +make -B va_test CC=gcc LDFLAGS="-static --sysroot $SYSROOT" +( ! grep /store/2a3-intermediate-musl/lib/libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +touch /store/_2a3.test # indicator of successful completion diff --git a/06/recipes/_2a4.test.sh b/06/recipes/_2a4.test.sh new file mode 100755 index 0000000..3e14775 --- /dev/null +++ b/06/recipes/_2a4.test.sh @@ -0,0 +1,46 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH='/store/2a0-static-gnumake/bin' +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a4-gnugcc4-cpp/bin" +export PATH="$PATH:/store/1-stage1/protobusybox/bin" + +mkdir -p /tmp/_2a4.test; cd /tmp/_2a4.test + +echo "### $0: preparing..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c + +echo "### $0: testing (dynamic)..." +make va_test CC=gcc # neither linker nor sysroot need to be specified now +grep /store/2a3-intermediate-musl/lib/libc.so va_test +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (static)..." +make -B va_test CC=gcc LDFLAGS=-static # no specifying sysroot anymore +( ! grep /store/2a3-intermediate-musl/lib/libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (dynamic C++)..." +cat > cpp_test.cpp <<\EOF +#include +using namespace std; +int main() { cout << "this is c+" << "+" << endl; return 0; } +EOF +make cpp_test +grep /store/2a3-intermediate-musl/lib/libc.so cpp_test +( ! grep ld-linux cpp_test ) +./cpp_test +[ "$(./cpp_test)" == 'this is c++' ] + +touch /store/_2a4.test # indicator of successful completion diff --git a/06/recipes/_2a5.test.sh b/06/recipes/_2a5.test.sh new file mode 100755 index 0000000..2811964 --- /dev/null +++ b/06/recipes/_2a5.test.sh @@ -0,0 +1,46 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a1-static-binutils/bin" +export PATH="$PATH:/store/2a5-gnugcc10/bin" + +mkdir -p /tmp/_2a5.test; cd /tmp/_2a5.test + +echo "### $0: preparing..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c + +echo "### $0: testing (dynamic)..." +make va_test CC=gcc +grep /store/2a3-intermediate-musl/lib/libc.so va_test +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (static)..." +make -B va_test CC=gcc LDFLAGS=-static +( ! grep /store/2a3-intermediate-musl/lib/libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (dynamic C++)..." +cat > cpp_test.cpp <<\EOF +#include +using namespace std; +int main() { cout << "this is c+" << "+" << endl; return 0; } +EOF +make cpp_test +grep /store/2a3-intermediate-musl/lib/libc.so cpp_test +( ! grep ld-linux cpp_test ) +./cpp_test +[ "$(./cpp_test)" == 'this is c++' ] + +touch /store/_2a5.test # indicator of successful completion diff --git a/06/recipes/_2a9.test.sh b/06/recipes/_2a9.test.sh new file mode 100755 index 0000000..e12ad29 --- /dev/null +++ b/06/recipes/_2a9.test.sh @@ -0,0 +1,49 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2a9-intermediate-clang/bin/generic-names" + +mkdir -p /tmp/_2a9.test; cd /tmp/_2a9.test + +echo "### $0: preparing..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c + +echo "### $0: testing (dynamic)..." +make va_test +grep /store/2a3-intermediate-musl/lib/libc.so va_test +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (static)..." +make -B va_test LDFLAGS=-static +( ! grep libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (dynamic C++)..." +cat > cpp_test.cpp <<\EOF +#include +using namespace std; +int main() { cout << "this is c+" << "+" << endl; return 0; } +EOF +# FIXME flags! +make cpp_test CXX=c++ LDFLAGS='-rpath /store/2a9-intermediate-clang/lib' +grep /store/2a3-intermediate-musl/lib/libc.so cpp_test +( ! grep ld-linux cpp_test ) +./cpp_test +[ "$(./cpp_test)" == 'this is c++' ] + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2a9 /store/2a9-intermediate-clang ) + +touch /store/_2a9.test # indicator of successful completion diff --git a/06/recipes/_2b1.test.sh b/06/recipes/_2b1.test.sh new file mode 100755 index 0000000..15377d1 --- /dev/null +++ b/06/recipes/_2b1.test.sh @@ -0,0 +1,51 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export PATH='/store/1-stage1/protobusybox/bin' +export PATH="$PATH:/store/2a0-static-gnumake/bin" +export PATH="$PATH:/store/2b1-clang/bin" + +mkdir -p /tmp/_2b1.test; cd /tmp/_2b1.test + +echo "### $0: preparing..." +cat > va_test.c <<\EOF +#include +int main(int _, char* argv[]) { printf("%sargs\n", argv[1]); return 0; } +EOF + +cat va_test.c + +echo "### $0: testing (dynamic)..." +make va_test +grep /store/2b0-musl/lib/libc.so va_test +( ! grep /store/2a3-intermediate-musl/lib/libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (static)..." +make -B va_test LDFLAGS=-static +( ! grep libc.so va_test ) +( ! grep ld-linux va_test ) +./va_test var +[ "$(./va_test var)" == varargs ] + +echo "### $0: testing (dynamic C++)..." +cat > cpp_test.cpp <<\EOF +#include +using namespace std; +int main() { cout << "this is c+" << "+" << endl; return 0; } +EOF +# FIXME flags! +make cpp_test CXX=c++ LDFLAGS='-rpath /store/2b1-clang/lib' +grep /store/2b0-musl/lib/libc.so cpp_test +( ! grep /store/2a3-intermediate-musl/lib/libc.so cpp_test ) +( ! grep ld-linux cpp_test ) +./cpp_test +[ "$(./cpp_test)" == 'this is c++' ] + +echo "### $0: checking for build path leaks..." +( ! grep -rF /tmp/2b1 /store/2b1-clang ) + +touch /store/_2b1.test # indicator of successful completion diff --git a/06/recipes/_3b.test.sh b/06/recipes/_3b.test.sh new file mode 100755 index 0000000..bfc1af7 --- /dev/null +++ b/06/recipes/_3b.test.sh @@ -0,0 +1,54 @@ +#!/store/2b2-busybox/bin/ash + +set -uex + +export PATH='/store/2b2-busybox/bin' +export PATH="$PATH:/store/3a-pkg-config/bin" +export PATH="$PATH:/store/3b-nix/bin" + +export SHELL='/store/2b2-busybox/bin/ash' + +export PKG_CONFIG_PATH='' +#export PKG_CONFIG_PATH='/store/3a-openssl/lib64/pkgconfig' +#export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-bzip2/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-sqlite/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-curl/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-editline/lib/pkgconfig" +#export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-xz/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-seccomp/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libarchive/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-libsodium/lib/pkgconfig" +export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/store/3a-lowdown/lib/pkgconfig" +LIBDIRS='' +#LIBDIRS="$(pkg-config --variable=libdir openssl)" +#LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir bzip2)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir sqlite3)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libcurl)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libeditline)" +#LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir liblzma)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libseccomp)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libarchive)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir libsodium)" +LIBDIRS="$LIBDIRS:$(pkg-config --variable=libdir lowdown)" +LIBDIRS="$LIBDIRS:/store/3a-boost/lib" +LIBDIRS="$LIBDIRS:/store/2b1-clang/lib" +export LD_LIBRARY_PATH=$LIBDIRS + +mkdir -p /tmp/_3b.test; cd /tmp/_3b.test + +echo "### $0: faking lots of stuff for nix to work..." +mkdir shelter +export HOME=/tmp/_3b.test/shelter +export USER=notauser +echo 'oh come on' >/dev/urandom + +echo "### $0: testing that derivation assumes a known input hash..." +nix repl > known-drv-hash.output <<\EOF + # see https://nixos.org/guides/nix-pills/our-first-derivation.html + derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; } +EOF +grep -Fx '«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»' \ + known-drv-hash.output + +rm -f /dev/urandom +touch /store/_3b.test # indicator of successful completion diff --git a/06/recipes/all-past-stage1.sh b/06/recipes/all-past-stage1.sh new file mode 100755 index 0000000..5853a31 --- /dev/null +++ b/06/recipes/all-past-stage1.sh @@ -0,0 +1,39 @@ +#!/store/1-stage1/protobusybox/bin/ash + +set -uex + +export SOURCE_DATE_EPOCH=0 + +/recipes/2a0-static-gnumake.sh +/recipes/2a1-static-binutils.sh +/recipes/2a2-static-gnugcc4-c.sh +/recipes/2a3-intermediate-musl.sh +/recipes/2a4-gnugcc4-cpp.sh +/recipes/2a5-gnugcc10.sh +/recipes/2a6-linux-headers.sh +/recipes/2a7-cmake.sh +/recipes/2a8-python.sh +/recipes/2a9-intermediate-clang.sh +/recipes/2b0-musl.sh +/recipes/2b1-clang.sh +/recipes/2b2-busybox.sh +/recipes/2b3-gnumake.sh +/recipes/3a-sqlite.sh +/recipes/3a-boost.sh +/recipes/3a-mbedtls.sh +/recipes/3a-pkg-config.sh +/recipes/3a-curl.sh +/recipes/3a-editline.sh +/recipes/3a-brotli.sh +/recipes/3a-gnugperf.sh +/recipes/3a-seccomp.sh +/recipes/3a-libarchive.sh +/recipes/3a-libsodium.sh +/recipes/3a-lowdown.sh +/recipes/3a-nlohmann-json.sh +/recipes/3b-busybox-static.sh +/recipes/3b-tinycc-static.sh +/recipes/3b-zig.sh +# /recipes/3b-nix.sh +# /recipes/4-rebootstrap-using-nix.sh +# /recipes/5-go-beyond-using-nix.sh diff --git a/06/seed.sh b/06/seed.sh new file mode 100755 index 0000000..fde76df --- /dev/null +++ b/06/seed.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -uex + +if [[ ! -e ./tcc-seed ]]; then + echo 'You need to supply a statically linked TinyCC as `tcc-seed`.' + echo -n 'You can `./compile-tcc-seed-with-nix.sh` ' + echo 'if you have `nix` and trust in me.' + exit 1 +fi + +rm -rf stage +mkdir -p stage/store +cp -raL --reflink=auto downloads recipes default.nix flake.nix stage/ + +# I'm too lazy to pass it through stage1 +sed -i "s|\$NPROC|$NPROC|" stage/recipes/*.sh + +DESTDIR=stage recipes/0-tcc-seed/seed.host-executed.sh # copy tcc-seed +DESTDIR=stage recipes/1-stage1/seed.host-executed.sh # unpack stage1 sources +# Everything past stage1 will unpack sources from downloads/ all by itself +# all the way until +cp -r using-nix stage/ diff --git a/06/using-nix/0-from-nixpkgs.nix b/06/using-nix/0-from-nixpkgs.nix new file mode 100644 index 0000000..71ebe41 --- /dev/null +++ b/06/using-nix/0-from-nixpkgs.nix @@ -0,0 +1,77 @@ +# This is to support building protosrc/tinycc from nixpkgs, see comment in 0.nix + +let + nixpkgs = import (builtins.fetchTarball { + name = "pinned-nixpkgs"; + url = "https://github.com/nixos/nixpkgs/archive/21f524672f25f8c3e7a0b5775e6505fee8fe43ce.tar.gz"; + sha256 = "sha256:00pwazjld0bj2sp33gwiz1h8krkyf2nyid7injv5cqz5bz5jjw99"; + }) { system = "x86_64-linux"; }; + + tinycc-unliberated = nixpkgs.pkgsStatic.tinycc; + + tinycc-liberated = derivation { + name = "tinycc-liberated"; + builder = "/bin/sh"; + args = [ "-uexc" '' + ${nixpkgs.pkgs.gnused}/bin/sed \ + 's|/nix/store/.\{32\}-|!nix!store/................................-|g' \ + < ${tinycc-unliberated}/bin/tcc \ + > $out + ! ${nixpkgs.pkgs.gnugrep}/bin/grep -i /nix/store $out + ${nixpkgs.pkgs.coreutils}/bin/chmod +x $out + '']; + allowedReferences = [ ]; + allowedRequisites = [ ]; + system = "x86_64-linux"; + __contentAddressed = true; + outputHashAlgo = "sha256"; outputHashMode = "recursive"; + outputHash = "sha256-oqeOU6SFYDwpdIj8MjcQ+bMuU63CHyoV9NYdyPLFxEQ="; + }; + + source-tarball-musl = builtins.fetchurl { + url = "http://musl.libc.org/releases/musl-1.2.4.tar.gz"; + sha256 = "7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039"; + }; + + source-tarball-busybox = builtins.fetchurl { + url = "https://busybox.net/downloads/busybox-1.36.1.tar.bz2"; + sha256 = "b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314"; + }; + + source-tarball-tinycc = builtins.fetchurl { + url = "https://github.com/TinyCC/tinycc/archive/af1abf1f45d45b34f0b02437f559f4dfdba7d23c.tar.gz"; + sha256 = "sha256:0kkaax6iw28d9wl6sf14kn0gmwm0g5h9qmx9rm3awh23cq2iv9zm"; + }; + + protosrc = derivation { + name = "protosrc"; + builder = "/bin/sh"; + args = [ "-uexc" '' + PATH=${nixpkgs.coreutils}/bin + PATH=$PATH:${nixpkgs.gnused}/bin + PATH=$PATH:${nixpkgs.gnutar}/bin + PATH=$PATH:${nixpkgs.gzip}/bin + PATH=$PATH:${nixpkgs.bzip2}/bin + export PATH + mkdir downloads/ + cp ${source-tarball-musl} downloads/musl-1.2.4.tar.gz + cp ${source-tarball-busybox} downloads/busybox-1.36.1.tar.bz2 + cp ${source-tarball-tinycc} downloads/tinycc-mob-af1abf1.tar.gz + mkdir -p recipes + cp -r ${../recipes/1-stage1} recipes/1-stage1 + DESTDIR=$out ${nixpkgs.bash}/bin/bash \ + ${../recipes/1-stage1/seed.host-executed.sh} + mv $out/protosrc/* $out/; rm -d $out/protosrc + '']; + allowedReferences = [ ]; + allowedRequisites = [ ]; + system = "x86_64-linux"; + __contentAddressed = true; + outputHashAlgo = "sha256"; outputHashMode = "recursive"; + outputHash = "sha256-upUZTTumJgBY16waF6L8ZeWbflSuQL9TMmwLw0YEDqM="; + }; +in + { + tinycc = tinycc-liberated; + inherit protosrc; + } diff --git a/06/using-nix/0-prebuilt.nix b/06/using-nix/0-prebuilt.nix new file mode 100644 index 0000000..952e20e --- /dev/null +++ b/06/using-nix/0-prebuilt.nix @@ -0,0 +1,28 @@ +# This is to prefetch protosrc/tinycc from github, see comment in 0.nix + +let + fetchTarball = { name, url, sha256 }: derivation { + inherit name url; + urls = [ url ]; + unpack = true; + + builder = "builtin:fetchurl"; + system = "builtin"; + outputHashMode = "recursive"; outputHashAlgo = "sha256"; + preferLocalBuild = true; + outputHash = sha256; + }; +in + { + protosrc = fetchTarball { + name = "protosrc"; + url = "https://github.com/ZilchOS/bootstrap-from-tcc/releases/download/seeding-files-r004/protosrc.nar"; + sha256 = "sha256-upUZTTumJgBY16waF6L8ZeWbflSuQL9TMmwLw0YEDqM="; + }; + + tinycc = fetchTarball { + name = "tinycc-liberated"; + url = "https://github.com/ZilchOS/bootstrap-from-tcc/releases/download/seeding-files-r004/tinycc-liberated.nar"; + sha256 = "sha256-oqeOU6SFYDwpdIj8MjcQ+bMuU63CHyoV9NYdyPLFxEQ="; + }; + } diff --git a/06/using-nix/0.nix b/06/using-nix/0.nix new file mode 100644 index 0000000..9852426 --- /dev/null +++ b/06/using-nix/0.nix @@ -0,0 +1,35 @@ +# Where do tcc-seed and protosrc come from if you build with Nix? + +# When building with `make` or `build.sh` you'll have tcc-seed and protosrc +# long long before you have Nix, +# so there's no question of where to take them from, you just inject'em. +# In this case this file isn't used at all and a simpler 0.nix is generated, +# see recipes/4-rebootstrap-using-nix.sh + +# But not everyone wants to go the full bootstrap route. +# This file is for when you already have Nix and want to jump into the middle, +# starting from the second, `using-nix` half of the bootstrap. +# Cases like hydra or flake-building. + +# One option is to build them using nixpkgs (see 0-from-nixpkgs.nix), +# but then you need nixpkgs, IFD and stuff. + +# Alternatively we could download them prebuilt from github:ZilchOS, +# but then there's the question of falling back to another method +# when recipes/1-stage1/seed.host-executed.sh or recipes/1-stage1/syscall.h +# are updated. + +# Here's one weird combined approach: + +let + and = builtins.all (x: x); + syscall_h_ours = "${../recipes/1-stage1/syscall.h}"; + syscall_h_reference = "/nix/store/678g5j997qzp0srprfg4gqqxcp8mr3g9-syscall.h"; + syscall_h_is_unmodified = (syscall_h_ours == syscall_h_reference); + stage1_seeder_ours = "${../recipes/1-stage1/seed.host-executed.sh}"; + stage1_seeder_reference = "/nix/store/qv4rmbdclws5nrx3m1vw1pb98qacw226-seed.host-executed.sh"; + stage1_seeder_is_unmodified = (stage1_seeder_ours == stage1_seeder_reference); +in + if (and [ syscall_h_is_unmodified stage1_seeder_is_unmodified ]) + then import ./0-prebuilt.nix + else import ./0-from-nixpkgs.nix diff --git a/06/using-nix/1-stage1.nix b/06/using-nix/1-stage1.nix new file mode 100644 index 0000000..4ae0b7c --- /dev/null +++ b/06/using-nix/1-stage1.nix @@ -0,0 +1,26 @@ +{ tcc-seed, protosrc, recipesStage1ExtrasPath, stage1cPath }: + +derivation { + name = "bootstrap-1-stage1"; + builder = "/bin/sh"; # purely to pass $vars, which is silly + args = [ "-c" '' + ${tcc-seed} \ + -nostdinc -nostdlib -Werror \ + -I${recipesStage1ExtrasPath} \ + -DINSIDE_NIX \ + -DPROTOSRC='"'${protosrc}'"' \ + -DTCC_SEED='"'${tcc-seed}'"' \ + -DRECIPES_STAGE1='"'${recipesStage1ExtrasPath}'"' \ + -DTMP_STAGE1='"'$TMPDIR/tmp'"' \ + -DSTORE_PROTOBUSYBOX='"'$protobusybox/'"' \ + -DSTORE_PROTOMUSL='"'$protomusl'"' \ + -DSTORE_TINYCC='"'$tinycc'"' \ + -run ${stage1cPath} + '']; + outputs = [ "protobusybox" "protomusl" "tinycc" ]; + allowedReferences = [ "protobusybox" "protomusl" "tinycc" ]; + allowedRequisites = [ "protobusybox" "protomusl" "tinycc" ]; + system = "x86_64-linux"; + __contentAddressed = true; + outputHashAlgo = "sha256"; outputHashMode = "recursive"; +} diff --git a/06/using-nix/2a0-static-gnumake.nix b/06/using-nix/2a0-static-gnumake.nix new file mode 100644 index 0000000..b32448d --- /dev/null +++ b/06/using-nix/2a0-static-gnumake.nix @@ -0,0 +1,70 @@ +{ fetchurl, mkDerivationStage2, stage1 }: + +let + source-tarball-gnumake = fetchurl { + # local = /downloads/make-4.4.1.tar.gz; + url = "http://ftp.gnu.org/gnu/make/make-4.4.1.tar.gz"; + sha256 = "dd16fb1d67bfab79a72f5e8390735c49e3e8e70b4945a15ab1f81ddb78658fb3"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a0-static-gnumake"; + buildInputPaths = [ + "${stage1.tinycc}/wrappers" + "${stage1.protobusybox}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # unpack: + unpack ${source-tarball-gnumake} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + src/job.c build-aux/install-sh po/Makefile.in.in + # this is part of stdlib, no idea how it's supposed to not clash + rm src/getopt.h + for f in src/getopt.c src/getopt1.c lib/fnmatch.c; do :> $f; done + for f in lib/glob.c lib/xmalloc.c lib/error.c; do :> $f; done + # embrace chaos + shuffle_comment='\/\* Handle shuffle mode argument. \*\/' + shuffle_default='if (!shuffle_mode) shuffle_mode = xstrdup(\"random\");' + sed -i "s|$shuffle_comment|$shuffle_comment\n$shuffle_default|" \ + src/main.c + grep 'if (!shuffle_mode) shuffle_mode = xstrdup("random");' src/main.c + # configure: + ash ./configure \ + --build x86_64-linux \ + --disable-dependency-tracking \ + --prefix=$out \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' + # bootstrap build: + ash ./build.sh + # test static GNU Make by remaking it with itself: + mv make make-intermediate + ./make-intermediate -j $NPROC clean + ./make-intermediate -j $NPROC + # reconfigure: + ash ./configure \ + --build x86_64-linux \ + --disable-dependency-tracking \ + --prefix=$out \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' + # rebuild: + ash ./build.sh + # test: + mv make make-intermediate + ./make-intermediate -j $NPROC clean + ./make-intermediate -j $NPROC CFLAGS=-O2 + # install: + ./make -j $NPROC install + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + # wrap: + # FIXME: patch make to use getenv? + mkdir -p $out/wrappers; cd $out/wrappers + echo "#!${stage1.protobusybox}/bin/ash" > make + echo "exec $out/bin/make SHELL=\$SHELL \"\$@\"" \ >> make + chmod +x make + ''; + } diff --git a/06/using-nix/2a1-static-binutils.nix b/06/using-nix/2a1-static-binutils.nix new file mode 100644 index 0000000..e98189b --- /dev/null +++ b/06/using-nix/2a1-static-binutils.nix @@ -0,0 +1,56 @@ +{ fetchurl, mkDerivationStage2, stage1, static-gnumake }: + +let + source-tarball-binutils = fetchurl { + # local = /downloads/binutils-2.39.tar.xz; + url = "https://ftp.gnu.org/gnu/binutils/binutils-2.39.tar.xz"; + sha256 = "645c25f563b8adc0a81dbd6a41cffbf4d37083a382e02d5d3df4f65c09516d00"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a1-static-binutils"; + buildInputPaths = [ + "${stage1.tinycc}/wrappers" + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # unpack: + unpack ${source-tarball-binutils} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + missing install-sh mkinstalldirs + # see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 + sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh + sed -i 's|__FILE__|"__FILE__"|' \ + ld/*.c ld/*.h bfd/*.* libctf/*.* opcodes/*.* + sed -i 's| -g | |' ld/Makefile* + # alias makeinfo to true + mkdir aliases + ln -s ${stage1.protobusybox}/bin/true aliases/makeinfo + PATH="$(pwd)/aliases/:$PATH" + # configure: + export lt_cv_sys_max_cmd_len=32768 + export ac_cv_func_strncmp_works=no + ash ./configure \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' \ + CFLAGS='-O2 -D__LITTLE_ENDIAN__=1' \ + CFLAGS_FOR_TARGET=-O2 \ + --enable-deterministic-archives \ + --disable-gprofng \ + --host x86_64-linux --build x86_64-linux \ + --prefix=$out + # build: + make -j $NPROC \ + all-libiberty all-gas all-bfd all-libctf all-zlib all-gprof + make all-ld # race condition on ld/.deps/ldwrite.Po, serialize + make -j $NPROC + # install: + make -j $NPROC install + rm $out/lib/*.la # broken, reference builddir + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a2-static-gnugcc4-c.nix b/06/using-nix/2a2-static-gnugcc4-c.nix new file mode 100644 index 0000000..45dea0e --- /dev/null +++ b/06/using-nix/2a2-static-gnugcc4-c.nix @@ -0,0 +1,85 @@ +{ fetchurl, mkDerivationStage2, stage1, static-gnumake, static-binutils }: + +let + source-tarball-gcc = fetchurl { + # local = /downloads/gcc-4.7.4.tar.bz2; + url = "https://ftp.gnu.org/gnu/gcc/gcc-4.7.4/gcc-4.7.4.tar.bz2"; + sha256 = "92e61c6dc3a0a449e62d72a38185fda550168a86702dea07125ebd3ec3996282"; + }; + source-tarball-gmp = fetchurl { + # local = /downloads/gmp-4.3.2.tar.xz; + url = "https://gmplib.org/download/gmp/archive/gmp-4.3.2.tar.xz"; + sha256 = "f69eff1bc3d15d4e59011d587c57462a8d3d32cf2378d32d30d008a42a863325"; + }; + source-tarball-mpfr = fetchurl { + # local = /downloads/mpfr-2.4.2.tar.xz; + url = "https://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.xz"; + sha256 = "d7271bbfbc9ddf387d3919df8318cd7192c67b232919bfa1cb3202d07843da1b"; + }; + source-tarball-mpc = fetchurl { + # local = /downloads/mpc-0.8.1.tar.gz; + url = "http://www.multiprecision.org/downloads/mpc-0.8.1.tar.gz"; + sha256 = "e664603757251fd8a352848276497a4c79b7f8b21fd8aedd5cc0598a38fee3e4"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a2-static-gnugcc4-c"; + buildInputPaths = [ + "${stage1.tinycc}/wrappers" + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # alias ash to sh: + mkdir aliases; ln -s ${stage1.protobusybox}/bin/ash aliases/sh + export PATH="$(pwd)/aliases:$PATH" + # unpack: + unpack ${source-tarball-gcc} + mkdir mpfr mpc gmp + unpack ${source-tarball-mpfr} -C mpfr + unpack ${source-tarball-mpc} -C mpc + unpack ${source-tarball-gmp} -C gmp + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree \ + gcc/genmultilib */*.sh gcc/exec-tool.in \ + install-sh */install-sh + sed -i 's|^\(\s*\)sh |\1${stage1.protobusybox}/bin/ash |' \ + Makefile* */Makefile* + sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in + # see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 + sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh + sed -i 's|#define HAVE_HOST_CORE2 1||' mpfr/configure + # configure: + export ac_cv_func_strncmp_works=no + export ac_cv_func_alloca_works=no + export ac_cv_prog_make_make_set=no + ash configure \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' \ + CFLAGS=-O2 CFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=${stage1.protomusl} \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=${static-binutils}/bin \ + --prefix=$out \ + --enable-languages=c \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --host x86_64-linux --build x86_64-linux + # build: + make -j $NPROC + # install: + make -j $NPROC install + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a3-intermediate-musl.nix b/06/using-nix/2a3-intermediate-musl.nix new file mode 100644 index 0000000..794bf22 --- /dev/null +++ b/06/using-nix/2a3-intermediate-musl.nix @@ -0,0 +1,42 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, static-binutils, static-gnugcc4-c }: + +let + source-tarball-musl = fetchurl { + # local = /downloads/musl-1.2.4.tar.gz; + url = "http://musl.libc.org/releases/musl-1.2.4.tar.gz"; + sha256 = "7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a3-intermediate-musl"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${static-binutils}/bin" + "${static-gnugcc4-c}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # unpack: + unpack ${source-tarball-musl} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + tools/*.sh \ + # patch popen/system to search in PATH instead of hardcoding /bin/sh + sed -i 's|posix_spawn(&pid, "/bin/sh",|posix_spawnp(\&pid, "sh",|' \ + src/stdio/popen.c src/process/system.c + sed -i 's|execl("/bin/sh", "sh", "-c",|execlp("sh", "-c",|'\ + src/misc/wordexp.c + # eliminate a source path reference + sed -i 's/__FILE__/"__FILE__"/' include/assert.h + # configure: + ash ./configure --prefix=$out + # build: + make -j $NPROC + # install: + make -j $NPROC install + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a4-gnugcc4-cpp.nix b/06/using-nix/2a4-gnugcc4-cpp.nix new file mode 100644 index 0000000..038ab20 --- /dev/null +++ b/06/using-nix/2a4-gnugcc4-cpp.nix @@ -0,0 +1,113 @@ +{ fetchurl, mkDerivationStage2 +, stage1 +, static-gnumake, static-binutils, static-gnugcc4-c, intermediate-musl }: + +let + source-tarball-gcc = fetchurl { + # local = /downloads/gcc-4.7.4.tar.bz2; + url = "https://ftp.gnu.org/gnu/gcc/gcc-4.7.4/gcc-4.7.4.tar.bz2"; + sha256 = "92e61c6dc3a0a449e62d72a38185fda550168a86702dea07125ebd3ec3996282"; + }; + source-tarball-gmp = fetchurl { + # local = /downloads/gmp-4.3.2.tar.xz; + url = "https://gmplib.org/download/gmp/archive/gmp-4.3.2.tar.xz"; + sha256 = "f69eff1bc3d15d4e59011d587c57462a8d3d32cf2378d32d30d008a42a863325"; + }; + source-tarball-mpfr = fetchurl { + # local = /downloads/mpfr-2.4.2.tar.xz; + url = "https://www.mpfr.org/mpfr-2.4.2/mpfr-2.4.2.tar.xz"; + sha256 = "d7271bbfbc9ddf387d3919df8318cd7192c67b232919bfa1cb3202d07843da1b"; + }; + source-tarball-mpc = fetchurl { + # local = /downloads/mpc-0.8.1.tar.gz; + url = "http://www.multiprecision.org/downloads/mpc-0.8.1.tar.gz"; + sha256 = "e664603757251fd8a352848276497a4c79b7f8b21fd8aedd5cc0598a38fee3e4"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a4-gnugcc4-cpp"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${static-binutils}/bin" + "${static-gnugcc4-c}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # alias ash to sh: + mkdir aliases; ln -s ${stage1.protobusybox}/bin/ash aliases/sh + export PATH="$(pwd)/aliases:$PATH" + # create wrappers that make previous GNU GCC target new musl: + SYSROOT=${intermediate-musl} + export _SYSROOT="--sysroot $SYSROOT" + export _LDFLAG="--dynamic-linker=$SYSROOT/lib/libc.so" + export _NEWINC="-I$SYSROOT/include" + export _REALCC="-I$SYSROOT/include" + mkdir wrappers + echo '#!${stage1.protobusybox}/bin/ash' > wrappers/cc + echo '#!${stage1.protobusybox}/bin/ash' > wrappers/cpp + echo '#!${stage1.protobusybox}/bin/ash' > wrappers/ld + echo 'exec gcc $_SYSROOT -Wl,$_LDFLAG "$@"' >> wrappers/cc + echo 'exec ${static-gnugcc4-c}/bin/cpp $_NEWINC "$@"' \ + >> wrappers/cpp + echo 'exec ${static-binutils}/bin/ld $_LDFLAG "$@"' \ + >> wrappers/ld + chmod +x wrappers/cc wrappers/cpp wrappers/ld + export PATH="$(pwd)/wrappers:$PATH" + # unpack: + unpack ${source-tarball-gcc} + mkdir mpfr mpc gmp + unpack ${source-tarball-mpfr} -C mpfr + unpack ${source-tarball-mpc} -C mpc + unpack ${source-tarball-gmp} -C gmp + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree \ + gcc/genmultilib */*.sh gcc/exec-tool.in \ + install-sh */install-sh + sed -i 's|^\(\s*\)sh |\1${stage1.protobusybox}/bin/ash |' \ + Makefile* */Makefile* + sed -i "s|/lib64/ld-linux-x86-64.so.2|$SYSROOT/lib/libc.so|" \ + gcc/config/i386/linux64.h + sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host + sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in + # see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 + sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh + sed -i 's|#define HAVE_HOST_CORE2 1||' mpfr/configure + # configure: + export ac_cv_func_strncmp_works=no + export ac_cv_func_alloca_works=no + export ac_cv_prog_make_make_set=no + export glibcxx_cv_random_tr1=no + ash configure \ + cache_file=nonex \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' \ + CC=cc CPP=cpp LD=ld \ + CFLAGS=-O2 CFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=$SYSROOT \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=${static-binutils}/bin \ + --prefix=$out \ + --with-specs='%{!static:%x{-rpath=$out/lib64}}' \ + --enable-languages=c,c++ \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --disable-libitm \ + --host x86_64-linux --build x86_64-linux + # build: + make -j $NPROC + # install: + make -j $NPROC install + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a5-gnugcc10.nix b/06/using-nix/2a5-gnugcc10.nix new file mode 100644 index 0000000..3b71b23 --- /dev/null +++ b/06/using-nix/2a5-gnugcc10.nix @@ -0,0 +1,104 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, static-binutils, intermediate-musl, gnugcc4-cpp }: + +let + source-tarball-gcc = fetchurl { + # local = /downloads/gcc-10.5.0.tar.xz; + url = "https://ftp.gnu.org/gnu/gcc/gcc-10.5.0/gcc-10.5.0.tar.xz"; + sha256 = "25109543fdf46f397c347b5d8b7a2c7e5694a5a51cce4b9c6e1ea8a71ca307c1"; + }; + source-tarball-gmp = fetchurl { + # local = /downloads/gmp-6.1.0.tar.xz; + url = "https://gmplib.org/download/gmp/gmp-6.1.0.tar.xz"; + sha256 = "68dadacce515b0f8a54f510edf07c1b636492bcdb8e8d54c56eb216225d16989"; + }; + source-tarball-mpfr = fetchurl { + # local = /downloads/mpfr-3.1.4.tar.xz; + url = "https://www.mpfr.org/mpfr-3.1.4/mpfr-3.1.4.tar.xz"; + sha256 = "761413b16d749c53e2bfd2b1dfaa3b027b0e793e404b90b5fbaeef60af6517f5"; + }; + source-tarball-mpc = fetchurl { + # local = /downloads/mpc-1.0.3.tar.gz; + url = "http://www.multiprecision.org/downloads/mpc-1.0.3.tar.gz"; + sha256 = "617decc6ea09889fb08ede330917a00b16809b8db88c29c31bfbb49cbf88ecc3"; + }; + source-tarball-isl = fetchurl { + # local = /downloads/isl-0.18.tar.bz2; + url = "http://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2"; + sha256 = "6b8b0fd7f81d0a957beb3679c81bbb34ccc7568d5682844d8924424a0dadcb1b"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a5-gnugcc10"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${static-binutils}/bin" + "${gnugcc4-cpp}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # alias ash to sh: + mkdir aliases; ln -s ${stage1.protobusybox}/bin/ash aliases/sh + export PATH="$(pwd)/aliases:$PATH" + # unpack: + unpack ${source-tarball-gcc} + mkdir mpfr mpc gmp isl + unpack ${source-tarball-mpfr} -C mpfr + unpack ${source-tarball-mpc} -C mpc + unpack ${source-tarball-gmp} -C gmp + unpack ${source-tarball-isl} -C isl + # fixup: + SYSROOT=${intermediate-musl} + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' \ + missing move-if-change mkdep mkinstalldirs symlink-tree install-sh \ + gcc/exec-tool.in gcc/genmultilib libgcc/mkheader.sh + sed -i 's|^\(\s*\)sh |\1${stage1.protobusybox}/bin/ash |' \ + libgcc/Makefile.in + sed -i "s|/lib/ld-musl-x86_64.so.1|$SYSROOT/lib/libc.so|" \ + gcc/config/i386/linux64.h + sed -i 's|m64=../lib64|m64=../lib|' gcc/config/i386/t-linux64 + sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host + sed -i 's|LIBGCC2_DEBUG_CFLAGS = -g|LIBGCC2_DEBUG_CFLAGS = |' \ + libgcc/Makefile.in + # see libtool's 74c8993c178a1386ea5e2363a01d919738402f30 + sed -i 's/| \$NL2SP/| sort | $NL2SP/' ltmain.sh */ltmain.sh + # configure: + export ac_cv_func_strncmp_works=no + export ac_cv_prog_make_make_set=no + export glibcxx_cv_dev_random=no + ash configure \ + CONFIG_SHELL='${stage1.protobusybox}/bin/ash' \ + SHELL='${stage1.protobusybox}/bin/ash' \ + CFLAGS=-O2 CXXFLAGS=-O2 \ + CFLAGS_FOR_TARGET=-O2 CXXFLAGS_FOR_TARGET=-O2 \ + --with-sysroot=$SYSROOT \ + --with-native-system-header-dir=/include \ + --with-build-time-tools=${static-binutils}/bin \ + --prefix=$out \ + --with-specs='%{!static:%x{-rpath=$out/lib}}' \ + --enable-languages=c,c++ \ + --disable-bootstrap \ + --disable-libquadmath --disable-decimal-float --disable-fixed-point \ + --disable-lto \ + --disable-libgomp \ + --disable-multilib \ + --disable-multiarch \ + --disable-libmudflap \ + --disable-libssp \ + --disable-nls \ + --disable-libitm \ + --disable-libsanitizer \ + --disable-cet \ + --disable-gnu-unique-object \ + --disable-gcov \ + --disable-checking \ + --host x86_64-linux-musl --build x86_64-linux-musl + # build: + make -j $NPROC + # install: + make -j $NPROC install + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a6-linux-headers.nix b/06/using-nix/2a6-linux-headers.nix new file mode 100644 index 0000000..72344fa --- /dev/null +++ b/06/using-nix/2a6-linux-headers.nix @@ -0,0 +1,39 @@ +{ fetchurl, mkDerivationStage2, stage1, static-gnumake, static-binutils, gnugcc10 }: + +let + source-tarball-linux = fetchurl { + # local = /downloads/linux-6.4.12.tar.xz; + url = "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.4.12.tar.xz"; + sha256 = "cca91be956fe081f8f6da72034cded96fe35a50be4bfb7e103e354aa2159a674"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a6-linux-headers"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${static-binutils}/bin" + "${gnugcc10}/bin" + ]; + script = '' + # unpack: + mkdir build-dir; cd build-dir + unpack ${source-tarball-linux} \ + linux-6.4.12/Makefile \ + linux-6.4.12/arch/x86 \ + linux-6.4.12/include \ + linux-6.4.12/scripts \ + linux-6.4.12/tools + # build: + make -j $NPROC \ + CONFIG_SHELL=${stage1.protobusybox}/bin/ash \ + CC=gcc HOSTCC=gcc ARCH=x86_64 \ + headers + # install: + find usr/include -name '.*' | xargs rm + mkdir -p $out + cp -rv usr/include $out/ + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a7-cmake.nix b/06/using-nix/2a7-cmake.nix new file mode 100644 index 0000000..90d3706 --- /dev/null +++ b/06/using-nix/2a7-cmake.nix @@ -0,0 +1,51 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, static-binutils, gnugcc10, linux-headers }: + +let + source-tarball-cmake = fetchurl { + # local = /downloads/cmake-3.27.4.tar.gz; + url = "https://github.com/Kitware/CMake/releases/download/v3.27.4/cmake-3.27.4.tar.gz"; + sha256 = "0a905ca8635ca81aa152e123bdde7e54cbe764fdd9a70d62af44cad8b92967af"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a7-cmake"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/wrappers" + "${static-binutils}/bin" + "${gnugcc10}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + export SHELL=${stage1.protobusybox}/bin/ash + # unpack: + unpack ${source-tarball-cmake} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' bootstrap + sed -i 's|__FILE__|"__FILE__"|' \ + Source/CPack/IFW/cmCPackIFWCommon.h \ + Source/CPack/cmCPack*.h \ + Source/cmCTest.h + # bundle libraries: + # poor man's static linking, a way for cmake to be self-contained later + mkdir -p $out/bundled-runtime + cp -H ${gnugcc10}/lib/libstdc++.so.6 $out/bundled-runtime/ + cp -H ${gnugcc10}/lib/libgcc_s.so.1 $out/bundled-runtime/ + # configure: + ash configure \ + CFLAGS="-DCPU_SETSIZE=128 -D_GNU_SOURCE" \ + CXXFLAGS="-isystem ${linux-headers}/include" \ + LDFLAGS="-Wl,-rpath $out/bundled-runtime" \ + --prefix=$out \ + --parallel=$NPROC \ + -- \ + -DCMAKE_USE_OPENSSL=OFF + # build: + make -j $NPROC + # install: + make -j $NPROC install/strip + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2a8-python.nix b/06/using-nix/2a8-python.nix new file mode 100644 index 0000000..f8ae622 --- /dev/null +++ b/06/using-nix/2a8-python.nix @@ -0,0 +1,74 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, static-binutils, gnugcc10 }: + +let + source-tarball-python = fetchurl { + # local = /downloads/Python-3.12.0.tar.xz; + url = "https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tar.xz"; + sha256 = "795c34f44df45a0e9b9710c8c71c15c671871524cd412ca14def212e8ccb155d"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a8-python"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/wrappers" + "${static-binutils}/bin" + "${gnugcc10}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + export SHELL=${stage1.protobusybox}/bin/ash + # alias ash to sh: + mkdir aliases; ln -s ${stage1.protobusybox}/bin/ash aliases/sh + export PATH="$(pwd)/aliases:$PATH" + # unpack: + unpack ${source-tarball-python} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' configure install-sh + sed -i 's|ac_sys_system=`uname -s`|ac_sys_system=Linux|' configure + # the precompiled pyc files aren't reproducible, + # but it's not like I need to waste time on them anyway. + # break their generation + mv Lib/compileall.py Lib/compileall.py.bak + echo 'import sys; sys.exit(0)' > Lib/compileall.py + chmod +x Lib/compileall.py + sed -i 's|__FILE__|"__FILE__"|' \ + Python/errors.c \ + Include/pyerrors.h \ + Include/cpython/object.h \ + Modules/pyexpat.c + sed -i 's|TIME __TIME__|TIME "xx:xx:xx"|' Modules/getbuildinfo.c + sed -i 's|DATE __DATE__|DATE "xx/xx/xx"|' Modules/getbuildinfo.c + # different build path length leads to different wrapping. avoid + sed -i 's|vars, stream=f|vars, stream=f, width=2**24|' Lib/sysconfig.py + # configure: + mkdir -p $out/lib + ash configure \ + ac_cv_broken_sem_getvalue=yes \ + ac_cv_posix_semaphores_enabled=no \ + OPT='-DNDEBUG -fwrapv -O3 -Wall' \ + LDFLAGS="-Wl,-rpath $out/lib" \ + --without-static-libpython \ + --build x86_64-linux-musl \ + --prefix=$out \ + --enable-shared \ + --with-ensurepip=no + # ensure reproducibility in case of no /dev/shm + grep 'define POSIX_SEMAPHORES_NOT_ENABLED 1' pyconfig.h + grep 'define HAVE_BROKEN_SEM_GETVALUE 1' pyconfig.h + # build: + make -j $NPROC + # install: + make -j $NPROC install + # strip builddir mentions: + sed -i "s|$(pwd)|...|g" \ + $out/lib/python3.*/_sysconfigdata__*.py \ + $out/lib/python3.*/config-3.*-x86_64-linux-musl/Makefile + # restore compileall just in case + cat Lib/compileall.py.bak > $out/lib/python3.12/compileall.py + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } + diff --git a/06/using-nix/2a9-intermediate-clang.nix b/06/using-nix/2a9-intermediate-clang.nix new file mode 100644 index 0000000..7d3696d --- /dev/null +++ b/06/using-nix/2a9-intermediate-clang.nix @@ -0,0 +1,145 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, static-binutils, intermediate-musl, gnugcc10 +, linux-headers, cmake, python}: + +let + source-tarball-llvm = fetchurl { + # local = /downloads/llvm-project-17.0.1.src.tar.xz; + url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.1/llvm-project-17.0.1.src.tar.xz"; + sha256 = "b0e42aafc01ece2ca2b42e3526f54bebc4b1f1dc8de6e34f46a0446a13e882b9"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2a9-intermediate-clang"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/wrappers" + "${static-binutils}/bin" + "${gnugcc10}/bin" + "${cmake}/bin" + "${python}/bin" + ]; + script = '' + # Shared libs are not relinked on install. Instead, their rpath + # is erased with RPATH_SET: `Set runtime path of + # "/nix/store/.../lib/x86_64-unknown-linux-musl/libc++.so.1.0" to ""` + # One (hacky) workaround to that is using a constant-len build-dir. + build_dir=build-dir; expr "$(pwd)/$build_dir)" '<=' 128 + while ! echo "$(pwd)/$build_dir" | wc -c | grep -Fqx 128; do + build_dir="$build_dir." + done; expr "$(echo $(pwd)/$build_dir | wc -c)" '==' 128 + mkdir $build_dir; cd $build_dir + export SHELL=${stage1.protobusybox}/bin/ash + # llvm cmake configuration should pick up ccache automatically from PATH + export PATH="$PATH:/ccache/bin" + command -v ccache && USE_CCACHE=YES || USE_CCACHE=NO + # prepare future sysroot: + SYSROOT=$out/sysroot + mkdir -p $SYSROOT/lib $SYSROOT/include + ln -s ${intermediate-musl}/lib/* $SYSROOT/lib/ + ln -s ${intermediate-musl}/include/* $SYSROOT/include/ + # unpack: + unpack ${source-tarball-llvm} + # fixup: + sed -i "s|COMMAND sh|COMMAND ${stage1.protobusybox}/bin/ash|" \ + llvm/cmake/modules/GetHostTriple.cmake clang/CMakeLists.txt + echo 'echo x86_64-unknown-linux-musl' > llvm/cmake/config.guess + LOADER=${intermediate-musl}/lib/libc.so + sed -i "s|/lib/ld-musl-\" + ArchName + \".so.1|$LOADER|" \ + clang/lib/Driver/ToolChains/Linux.cpp + BEGINEND='const bool HasCRTBeginEndFiles' + sed -i "s|$BEGINEND =|$BEGINEND = false; ''${BEGINEND}_unused =|" \ + clang/lib/Driver/ToolChains/Gnu.cpp + REL_ORIGIN='_install_rpath \"\$ORIGIN/../lib''${LLVM_LIBDIR_SUFFIX}\"' + sed -i "s|_install_rpath \"\\\\\$ORIGIN/..|_install_rpath \"$out|" \ + llvm/cmake/modules/AddLLVM.cmake + sed -i 's|numShards = 32;|numShards = 1;|' lld/*/SyntheticSections.* + sed -i 's|numShards = 256;|numShards = 1;|' lld/*/ICF.cpp + sed -i 's|__FILE__|"__FILE__"|' \ + libcxx/src/verbose_abort.cpp \ + libcxxabi/src/abort_message.cpp \ + compiler-rt/lib/builtins/int_util.h + sed -i 's|"@LLVM_SRC_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + sed -i 's|"@LLVM_OBJ_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + # figure out includes: + EXTRA_INCL="$(pwd)/extra_includes" + mkdir -p $EXTRA_INCL + cp clang/lib/Headers/*intrin*.h $EXTRA_INCL/ + cp clang/lib/Headers/mm_malloc.h $EXTRA_INCL/ + [ -e $EXTRA_INCL/immintrin.h ] + # configure: + export LD_LIBRARY_PATH=${gnugcc10}/lib + BOTH_STAGES_OPTS="" + add_opt() { + BOTH_STAGES_OPTS="$BOTH_STAGES_OPTS -D$1 -DBOOTSTRAP_$1" + } + add_opt CMAKE_BUILD_TYPE=MinSizeRel + add_opt LLVM_OPTIMIZED_TABLEGEN=YES + add_opt LLVM_CCACHE_BUILD=$USE_CCACHE + add_opt DEFAULT_SYSROOT=$SYSROOT + add_opt CMAKE_INSTALL_PREFIX=$out + add_opt LLVM_INSTALL_BINUTILS_SYMLINKS=YES + add_opt LLVM_INSTALL_CCTOOLS_SYMLINKS=YES + add_opt CMAKE_INSTALL_DO_STRIP=YES + add_opt LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=YES + add_opt LLVM_TARGET_ARCH=X86 + add_opt LLVM_TARGETS_TO_BUILD=Native + add_opt LLVM_BUILTIN_TARGETS=x86_64-unknown-linux-musl + add_opt LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl + add_opt LLVM_HOST_TRIPLE=x86_64-unknown-linux-musl + add_opt COMPILER_RT_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl + add_opt LLVM_APPEND_VC_REV=NO + add_opt LLVM_INCLUDE_TESTS=NO + add_opt LLVM_INCLUDE_EXAMPLES=NO + add_opt LLVM_INCLUDE_BENCHMARKS=NO + add_opt LLVM_ENABLE_BACKTRACES=NO + add_opt LLVM_ENABLE_EH=YES + add_opt LLVM_ENABLE_RTTI=YES + add_opt CLANG_ENABLE_ARCMT=NO + add_opt CLANG_ENABLE_STATIC_ANALYZER=NO + add_opt COMPILER_RT_BUILD_SANITIZERS=NO + add_opt COMPILER_RT_BUILD_XRAY=NO + add_opt COMPILER_RT_BUILD_LIBFUZZER=NO + add_opt COMPILER_RT_BUILD_PROFILE=NO + add_opt COMPILER_RT_BUILD_MEMPROF=NO + add_opt COMPILER_RT_BUILD_ORC=NO + add_opt COMPILER_RT_USE_BUILTINS_LIBRARY=YES + add_opt CLANG_DEFAULT_CXX_STDLIB=libc++ + add_opt CLANG_DEFAULT_LINKER=lld + add_opt CLANG_DEFAULT_RTLIB=compiler-rt + add_opt LIBCXX_HAS_MUSL_LIBC=YES + add_opt LIBCXX_USE_COMPILER_RT=YES + add_opt LIBCXX_INCLUDE_BENCHMARKS=NO + add_opt LIBCXX_CXX_ABI=libcxxabi + add_opt LIBCXXABI_USE_COMPILER_RT=YES + add_opt LIBCXXABI_USE_LLVM_UNWINDER=YES + add_opt LIBCXX_ADDITIONAL_COMPILE_FLAGS=-I${linux-headers}/include + add_opt LLVM_INSTALL_TOOLCHAIN_ONLY=YES + add_opt LIBUNWIND_USE_COMPILER_RT=YES + add_opt LLVM_ENABLE_THREADS=NO + cmake -S llvm -B build -G 'Unix Makefiles' \ + -DLLVM_ENABLE_PROJECTS='clang;lld' \ + -DLLVM_ENABLE_RUNTIMES='compiler-rt;libcxx;libcxxabi;libunwind' \ + -DGCC_INSTALL_PREFIX=${gnugcc10} \ + "-DBOOTSTRAP_CMAKE_C_FLAGS=-isystem $EXTRA_INCL" \ + "-DBOOTSTRAP_CMAKE_CXX_FLAGS=-isystem $EXTRA_INCL" \ + -DCLANG_ENABLE_BOOTSTRAP=YES $BOTH_STAGES_OPTS + # build (stage1): + make -C build -j $NPROC clang lld runtimes + # build/install (stage2): + NEW_LIB_DIR="$(pwd)/build/lib/x86_64-unknown-linux-musl" + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$NEW_LIB_DIR" + make -C build -j $NPROC stage2 stage2-install + ln -s $out/lib/x86_64-unknown-linux-musl/* $out/lib/ + mkdir -p $out/bin/generic-names + ln -s $out/bin/clang $out/bin/generic-names/cc + ln -s $out/bin/clang++ $out/bin/generic-names/c++ + ln -s $out/bin/clang-cpp $out/bin/generic-names/cpp + # mix new stuff into sysroot + ln -s $out/lib/* $out/sysroot/lib/ + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + } diff --git a/06/using-nix/2b0-musl.nix b/06/using-nix/2b0-musl.nix new file mode 100644 index 0000000..ac74359 --- /dev/null +++ b/06/using-nix/2b0-musl.nix @@ -0,0 +1,45 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, intermediate-clang }: + +let + source-tarball-musl = fetchurl { + # local = /downloads/musl-1.2.4.tar.gz; + url = "http://musl.libc.org/releases/musl-1.2.4.tar.gz"; + sha256 = "7a35eae33d5372a7c0da1188de798726f68825513b7ae3ebe97aaaa52114f039"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2b0-musl"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${intermediate-clang}/bin" + "${intermediate-clang}/bin/generic-names" + ]; + script = '' + # unpack: + mkdir build-dir; cd build-dir + unpack ${source-tarball-musl} + # fixup: + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|' tools/*.sh \ + # patch popen/system to search in PATH instead of hardcoding /bin/sh + sed -i 's|posix_spawn(&pid, "/bin/sh",|posix_spawnp(\&pid, "sh",|' \ + src/stdio/popen.c src/process/system.c + sed -i 's|execl("/bin/sh", "sh", "-c",|execlp("sh", "-c",|'\ + src/misc/wordexp.c + # avoid absolute path references + sed -i 's/__FILE__/__FILE_NAME__/' include/assert.h + # configure: + ash ./configure --prefix=$out CFLAGS=-O2 + # build: + make -j $NPROC + # install: + make -j $NPROC install + mkdir $out/bin + ln -s $out/lib/libc.so $out/bin/ldd + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + extra.allowedRequisites = [ "out" ]; + extra.allowedReferences = [ "out" ]; + } diff --git a/06/using-nix/2b1-clang.nix b/06/using-nix/2b1-clang.nix new file mode 100644 index 0000000..e7bf2be --- /dev/null +++ b/06/using-nix/2b1-clang.nix @@ -0,0 +1,157 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, musl, intermediate-clang +, linux-headers, cmake, python}: + +let + source-tarball-llvm = fetchurl { + # local = /downloads/llvm-project-17.0.1.src.tar.xz; + url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.1/llvm-project-17.0.1.src.tar.xz"; + sha256 = "b0e42aafc01ece2ca2b42e3526f54bebc4b1f1dc8de6e34f46a0446a13e882b9"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2b1-clang"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/wrappers" + "${cmake}/bin" + "${python}/bin" + # 2a9-intermediate-clang intentionally not added to $PATH + # to prevent confusion + ]; + script = '' + # Shared libs are not relinked on install. Instead, their rpath + # is erased with RPATH_SET: `Set runtime path of + # "/nix/store/.../lib/x86_64-unknown-linux-musl/libc++.so.1.0" to ""` + # One (hacky) workaround to that is using a constant-len build-dir. + build_dir=build-dir; expr "$(pwd)/$build_dir)" '<=' 128 + while ! echo "$(pwd)/$build_dir" | wc -c | grep -Fqx 128; do + build_dir="$build_dir." + done; expr "$(echo $(pwd)/$build_dir | wc -c)" '==' 128 + mkdir $build_dir; cd $build_dir + export SHELL=${stage1.protobusybox}/bin/ash + # llvm cmake configuration should pick up ccache automatically from PATH + export PATH="$PATH:/ccache/bin" + command -v ccache && USE_CCACHE=YES || USE_CCACHE=NO + # prepare future sysroot: + SYSROOT=$out/sysroot + mkdir -p $SYSROOT/lib $SYSROOT/include + ln -s ${musl}/lib/* $SYSROOT/lib/ + ln -s ${musl}/include/* $SYSROOT/include/ + # unpack: + unpack ${source-tarball-llvm} + # fixup: + sed -i "s|COMMAND sh|COMMAND ${stage1.protobusybox}/bin/ash|" \ + llvm/cmake/modules/GetHostTriple.cmake clang/CMakeLists.txt + echo 'echo x86_64-unknown-linux-musl' > llvm/cmake/config.guess + LOADER=${musl}/lib/libc.so + sed -i "s|/lib/ld-musl-\" + ArchName + \".so.1|$LOADER|" \ + clang/lib/Driver/ToolChains/Linux.cpp + BEGINEND='const bool HasCRTBeginEndFiles' + sed -i "s|$BEGINEND =|$BEGINEND = false; ''${BEGINEND}_unused =|" \ + clang/lib/Driver/ToolChains/Gnu.cpp + REL_ORIGIN='_install_rpath \"\$ORIGIN/../lib''${LLVM_LIBDIR_SUFFIX}\"' + sed -i "s|_install_rpath \"\\\\\$ORIGIN/..|_install_rpath \"$out|" \ + llvm/cmake/modules/AddLLVM.cmake + sed -i 's|numShards = 32;|numShards = 1;|' lld/*/SyntheticSections.* + sed -i 's|numShards = 256;|numShards = 1;|' lld/*/ICF.cpp + sed -i 's|__FILE__|"__FILE__"|' \ + libcxx/src/verbose_abort.cpp \ + libcxxabi/src/abort_message.cpp \ + compiler-rt/lib/builtins/int_util.h + sed -i 's|"@LLVM_SRC_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + sed -i 's|"@LLVM_OBJ_ROOT@"|"REDACTED"|' \ + llvm/tools/llvm-config/BuildVariables.inc.in + # figure out includes: + EXTRA_INCL="$(pwd)/extra_includes" + mkdir -p $EXTRA_INCL + cp clang/lib/Headers/*intrin*.h $EXTRA_INCL/ + cp clang/lib/Headers/mm_malloc.h $EXTRA_INCL/ + [ -e $EXTRA_INCL/immintrin.h ] + # configure: + export LD_LIBRARY_PATH="${musl}/lib:${intermediate-clang}/lib" + export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$(pwd)/build/lib" # libLLVM + OPTS="" + add_opt() { + OPTS="$OPTS -D$1" + } + add_opt CMAKE_BUILD_TYPE=Release + add_opt LLVM_OPTIMIZED_TABLEGEN=YES + add_opt LLVM_CCACHE_BUILD=$USE_CCACHE + add_opt DEFAULT_SYSROOT=$SYSROOT + add_opt CMAKE_INSTALL_PREFIX=$out + add_opt LLVM_INSTALL_BINUTILS_SYMLINKS=YES + add_opt LLVM_INSTALL_CCTOOLS_SYMLINKS=YES + add_opt CMAKE_INSTALL_DO_STRIP=YES + add_opt LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=YES + add_opt LLVM_TARGET_ARCH=X86 + add_opt LLVM_TARGETS_TO_BUILD=Native + add_opt LLVM_BUILTIN_TARGETS=x86_64-unknown-linux-musl + add_opt LLVM_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl + add_opt LLVM_HOST_TRIPLE=x86_64-unknown-linux-musl + add_opt COMPILER_RT_DEFAULT_TARGET_TRIPLE=x86_64-unknown-linux-musl + add_opt LLVM_APPEND_VC_REV=NO + add_opt LLVM_INCLUDE_TESTS=NO + add_opt LLVM_INCLUDE_EXAMPLES=NO + add_opt LLVM_INCLUDE_BENCHMARKS=NO + add_opt LLVM_ENABLE_BACKTRACES=NO + add_opt LLVM_ENABLE_EH=YES + add_opt LLVM_ENABLE_RTTI=YES + add_opt CLANG_ENABLE_ARCMT=NO + add_opt CLANG_ENABLE_STATIC_ANALYZER=NO + add_opt COMPILER_RT_BUILD_SANITIZERS=NO + add_opt COMPILER_RT_BUILD_XRAY=NO + add_opt COMPILER_RT_BUILD_LIBFUZZER=NO + add_opt COMPILER_RT_BUILD_PROFILE=NO + add_opt COMPILER_RT_BUILD_MEMPROF=NO + add_opt COMPILER_RT_BUILD_ORC=NO + add_opt COMPILER_RT_USE_BUILTINS_LIBRARY=YES + add_opt CLANG_DEFAULT_CXX_STDLIB=libc++ + add_opt CLANG_DEFAULT_LINKER=lld + add_opt CLANG_DEFAULT_RTLIB=compiler-rt + add_opt LIBCXX_HAS_MUSL_LIBC=YES + add_opt LIBCXX_USE_COMPILER_RT=YES + add_opt LIBCXX_INCLUDE_BENCHMARKS=NO + add_opt LIBCXX_CXX_ABI=libcxxabi + add_opt LIBCXX_ADDITIONAL_COMPILE_FLAGS=-I${linux-headers}/include + add_opt LIBCXXABI_USE_COMPILER_RT=YES + add_opt LIBCXXABI_USE_LLVM_UNWINDER=YES + add_opt LLVM_INSTALL_TOOLCHAIN_ONLY=YES + add_opt LIBUNWIND_USE_COMPILER_RT=YES + add_opt LLVM_ENABLE_THREADS=NO + REWRITE="-ffile-prefix-map=$(pwd)=/builddir/" + CFLAGS="--sysroot=$SYSROOT -I$EXTRA_INCL $REWRITE" + LDFLAGS="-Wl,--dynamic-linker=$LOADER" + cmake -S llvm -B build -G 'Unix Makefiles' \ + -DCMAKE_ASM_COMPILER=${intermediate-clang}/bin/clang \ + -DCMAKE_C_COMPILER=${intermediate-clang}/bin/clang \ + -DCMAKE_CXX_COMPILER=${intermediate-clang}/bin/clang++ \ + -DLLVM_ENABLE_PROJECTS='clang;lld' \ + -DLLVM_ENABLE_RUNTIMES='compiler-rt;libcxx;libcxxabi;libunwind' \ + -DCMAKE_C_FLAGS="$CFLAGS" \ + -DCMAKE_CXX_FLAGS="$CFLAGS" \ + -DCMAKE_C_LINK_FLAGS="$LDFLAGS" \ + -DCMAKE_CXX_LINK_FLAGS="$LDFLAGS" \ + -DLLVM_BUILD_LLVM_DYLIB=YES \ + -DLLVM_LINK_LLVM_DYLIB=YES \ + -DCLANG_LINK_LLVM_DYLIB=YES \ + $OPTS + # build: + make -C build -j $NPROC + # install: + make -C build install/strip + ln -s $out/lib/x86_64-unknown-linux-musl/* $out/lib/ + mkdir -p $out/bin + ln -s $out/bin/clang $out/bin/cc + ln -s $out/bin/clang++ $out/bin/c++ + ln -s $out/bin/clang-cpp $out/bin/cpp + ln -s $out/bin/lld $out/bin/ld + # mix new stuff into sysroot: + ln -s $out/lib/* $out/sysroot/lib/ + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + extra.allowedRequisites = [ "out" musl ]; + extra.allowedReferences = [ "out" musl ]; + } diff --git a/06/using-nix/2b2-busybox.nix b/06/using-nix/2b2-busybox.nix new file mode 100644 index 0000000..78dc2b1 --- /dev/null +++ b/06/using-nix/2b2-busybox.nix @@ -0,0 +1,52 @@ +{ fetchurl, mkDerivationStage2 +, stage1, static-gnumake, musl, clang, linux-headers }: + +let + source-tarball-busybox = fetchurl { + # local = /downloads/busybox-1.36.1.tar.bz2; + url = "https://busybox.net/downloads/busybox-1.36.1.tar.bz2"; + sha256 = "b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314"; + }; +in + mkDerivationStage2 { + name = "bootstrap-2b2-busybox"; + buildInputPaths = [ + "${stage1.protobusybox}/bin" + "${static-gnumake}/bin" + "${clang}/bin" + ]; + script = '' + mkdir build-dir; cd build-dir + # alias ash to sh: + mkdir aliases; ln -s ${stage1.protobusybox}/bin/ash aliases/sh + export PATH="$(pwd)/aliases:$PATH" + # unpack: + unpack ${source-tarball-busybox} + # fixup: + echo -e '#!${stage1.protobusybox}/bin/ash\nprintf 9999' \ + > scripts/gcc-version.sh + sed -i 's|/bin/sh|${stage1.protobusybox}/bin/ash|g' \ + scripts/gen_build_files.sh \ + scripts/mkconfigs scripts/embedded_scripts scripts/trylink \ + scripts/generate_BUFSIZ.sh \ + applets/usage_compressed applets/busybox.mkscripts applets/install.sh + # configure: + echo "### $0: configuring busybox..." + BUSYBOX_FLAGS='CONFIG_SHELL=${stage1.protobusybox}/bin/ash' + BUSYBOX_FLAGS="$BUSYBOX_FLAGS CC=cc HOSTCC=cc" + BUSYBOX_FLAGS="$BUSYBOX_FLAGS KCONFIG_NOTIMESTAMP=y" + BUSYBOX_CFLAGS="CFLAGS=-I${linux-headers}/include" + make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" defconfig + sed -i 's|CONFIG_INSTALL_NO_USR=y|CONFIG_INSTALL_NO_USR=n|' .config + # build: + make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" busybox busybox.links + sed -i 's|^/usr/s\?bin/|/bin/|' busybox.links + # install: + make -j $NPROC $BUSYBOX_FLAGS "$BUSYBOX_CFLAGS" \ + install CONFIG_PREFIX=$out + # check for build path leaks: + ( ! grep -rF $(pwd) $out ) + ''; + extra.allowedRequisites = [ "out" musl clang ]; + extra.allowedReferences = [ "out" musl clang ]; + } diff --git a/06/verify.nix b/06/verify.nix new file mode 100644 index 0000000..177e6ed --- /dev/null +++ b/06/verify.nix @@ -0,0 +1,16 @@ +amhpqf61g19sw80gcxkx9i385b497hzh stage1^tinycc +r5jb6ydqlphvh33kqynvnxbqqrsy9vlm stage1^protobusybox +45fx2ls8ikc8whr03plslhjir844f7ax stage1^protomusl +xapj0c7basdkkacrng50ayxy9xbklaj2 static-gnumake +xc3db7c3rpfqpp11y2ms4v5cgkq7dzyj static-binutils +x58bd1awpbmd2iaxwcmb269anvhb9bbm static-gnugcc4-c +mhbvszfvvryvnd46xawvsbd0bnbpmw9v intermediate-musl +ghh0kin5896hc5wqcll4s0axgn540jgy gnugcc4-cpp +6vnz5a78ahy1762s5wbvaq3jifsnf18f gnugcc10 +wgg3p19hv7ji265gcm6mclrlqxays1v0 linux-headers +mdavw6g21ysjrp9wxidl9vpbfy2hqqdj cmake +3ivma9103vx1192kqkw6vvbcg161gvz1 python +z3qlri49m9v9zhf1f5pyfbm5jdbk9wiz intermediate-clang +5hasqad9ih2fmn6ma9vww2jdjqjgzvxs musl +cr1bxa6hjz1baygh7kdwmhgxvypqcvag clang +2f7xfn3x1bgpy1wdrnn48z3c1bagwggh busybox diff --git a/06/verify.pkgs.sha256 b/06/verify.pkgs.sha256 new file mode 100644 index 0000000..1a623c7 --- /dev/null +++ b/06/verify.pkgs.sha256 @@ -0,0 +1,32 @@ +da4da9d48bb65e68a8095efb3f439e5b92bddd360e60578219932f813eb05ec1 pkgs/0-tcc-seed.tar +8347995cd00d16f1564d19ed045aaf9c7c500c417574d28dde7c2254a089d36a pkgs/1-stage1.tar +c825a49166b6a382002136d0cd3510477c2e50b55172af6679db2090debdf520 pkgs/2a0-static-gnumake.tar +ac3ca80644a351c75c5ac7bb03c0c8d6b33fdb677e11663fef247c670d81edc4 pkgs/2a1-static-binutils.tar +86915ff0e41e21086a71a89729bb75cb3ddf6e32f7a06f3ea1fb66e4c8cada33 pkgs/2a2-static-gnugcc4-c.tar +bf7d15658210e0fa8a8d1b5ea44c16af1b8a5d5223475812e4a395542440b98d pkgs/2a3-intermediate-musl.tar +2d9759bcba6170d9cf8a750df3db94746d7e778f3414a72aaaa570508219ebf3 pkgs/2a4-gnugcc4-cpp.tar +b2028c82e05dc8858f2c5ccb7b93eae169f9f397ef4b6fe755ad3f1e6c4c857d pkgs/2a5-gnugcc10.tar +d5703b484fe95c7c8a617f29329cc87c0ad852a8ff2597e167c6766e0ce5980a pkgs/2a6-linux-headers.tar +969031fdf9f7df5c5039e5d04b5a9cc76928f3558097e40555157a13e08ee6c0 pkgs/2a7-cmake.tar +a4b89542ef2ae8af348df98c7bbb8aafa1692dec65a46e1e58be5b47b819a749 pkgs/2a8-python.tar +236f41af85e539484f4845a5cf8cb751f5a957bae2b4a1ff13c35bacbbcd8276 pkgs/2a9-intermediate-clang.tar +89e7aa57ab169b4ce6498294b67926d0d09a9cf7f6d108d958f0d207c546930e pkgs/2b0-musl.tar +f804d4d19a1437eda38dfc532407f21524a99897906f0df9b51a2bf2d1b192d4 pkgs/2b1-clang.tar +15b9751b6f102007243250d95a58e686c8d1564d92d1c5708be2b657019453a9 pkgs/2b2-busybox.tar +c9c5a533f70c10dc659e79638d24b00a35aac51d875b85fec21a8f0da6507217 pkgs/2b3-gnumake.tar +2f05779ae73ef59950b1ded356da891a9a5e0d02f153567d9e85fa1cb926966b pkgs/3a-boost.tar +1fbde76654b4879687a02435470afbc248e7d4f6717f01432ed9cf7205161287 pkgs/3a-brotli.tar +60e4454d2e9b7d127af0e4e1967cc4eccdd386480c2e9eae32f1c5ee7e7d442d pkgs/3a-curl.tar +0e19d7d952ff9a4a3971a804e20463e422ec9a5de54438deda69065d7e67bf79 pkgs/3a-editline.tar +442bde8dafed0d7b5571394e13a4f8bbf1d4e0dffa41306d19e73e8e32854820 pkgs/3a-gnugperf.tar +04eeff2024984df8204dd8718bf4db00c1223a6d9d4dc08591be13594127a293 pkgs/3a-libarchive.tar +0fa4c6c75e2974a4a6b8cb61ebc419130ac866f0da4539412fb2bc1e6252be58 pkgs/3a-libsodium.tar +6f1be37aa2fa121e90ccb49308634165f96e2eb03d841f563245bae7736c83d7 pkgs/3a-lowdown.tar +3d7282686a98e6a5e2b3655ae02c1aae1dc1d3c20ac53fadef90cd8408a4eed7 pkgs/3a-mbedtls.tar +3e3796d38d685334cc6d88c79e573257b8ce834308a793571f45e4d657330f3f pkgs/3a-nlohmann-json.tar +47e7dbb47b13f0348e0403ea6ac70c45e4ddb1536f3e05ef2b777c8b7fc8b027 pkgs/3a-pkg-config.tar +fb353622c346831fdea82d74801e27bcda482ad72221d9be51a5372fc1234daf pkgs/3a-seccomp.tar +73e2efe1845ca550762ddcce2103164839c02ed6777356af833c594a2a1e1d76 pkgs/3a-sqlite.tar +846525ebdfb81858963530cae2977b7fcb29381112119059690e7f916ce8c397 pkgs/3b-busybox-static.tar +8df17ee6e1e7f19f7118d17cd9ff7f25dbc4b05b9f9bbab9b78f40e1b4667672 pkgs/3b-nix.tar +c9d0fb338b81db4184f84eb1f71687391edded2e937dec77ac9f353fa526e70d pkgs/3b-tinycc-static.tar diff --git a/BOOSTRAP.md b/BOOSTRAP.md new file mode 100644 index 0000000..00a7bf1 --- /dev/null +++ b/BOOSTRAP.md @@ -0,0 +1,241 @@ +# boostrapping a (Linux x86-64) C compiler + +Compilers nowadays are written in languages like C, which themselves need to be +compiled. But then, you need a C compiler to compile your C compiler! Of course, +the very first C compiler was not written in C. +First, people made assemblers, then simple programming languages, +then, eventually, it was possible to make a C compiler. +In this repository, we'll explore how that's done. Each directory here +is a "stage" in the process. The first one, `00`, is a hand-written +executable, and the last one, `05`, is a C compiler. Each directory has its own +README explaining what's going on. + +You can run `bootstrap.sh` to run through and test every stage. +To get HTML versions of all README pages, run `make`. + +Note that the executables produced in this series will only run on +64-bit Linux, because each OS/architecture combination would need its own separate +executable. + +## table of contents + +- [stage 00](00/README.md) - a program converting a text file with +hexadecimal digit pairs to a binary file. +- [stage 01](01/README.md) - a language with comments, and 2-character +command codes. +- [stage 02](02/README.md) - a language with labels +- [stage 03](03/README.md) - a language with longer labels, better error messages, and less register manipulation +- [stage 04](04/README.md) - a language with nice functions and local variables +- [stage 04a](04a/README.md) - (interlude) a simple preprocessor +- [stage 05](05/README.md) - a C compiler capable of compiling TCC +- [stage 06](06/README.md) - an interpreter capable of executing zig + +## prerequisite knowledge + +If you want to follow along with this series, you'll probably want to know about: + +- number bases -- if a number is preceded by 0x, 0o, or 0b in this series, that +means hexadecimal/octal/binary respectively. So 0xff = FF hexadecimal = 255 +decimal. +- bits, bytes, kilobytes, etc. +- bitwise operations (not, or, and, xor, left shift, right shift) +- 2's complement +- ASCII, null-terminated strings +- how pointers work +- how floating-point numbers work +- what a compiler is +- what an executable file is +- what a system call is +- what a CPU is +- what a CPU architecture is +- what a CPU register is +- what the (call) stack is + +If you're unfamiliar with x86-64 assembly, you should take a look at the instruction list below. + +## principles + +- as simple as possible + +Bootstrapping a compiler is not an easy task, so we're trying to make it as easy +as possible. We don't even necessarily need a standard-compliant C compiler, we +only need enough to compile someone else's C compiler. Specifically, we'll be +using [tcc](https://bellard.org/tcc/) since it's written (mostly) in C89. + +- efficiency is not a concern + +We will create big and slow executables, and that's okay. It doesn't really +matter if compiling TCC takes 30 as opposed to 0.01 seconds; once +we compile it with itself, we should get the same executable either way. + +## reflections on trusting trust + +In 1984, Ken Thompson wrote the well-known article +[Reflections on Trusting Trust](http://users.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf). +This is one of the inspirations for this project. A brief summary is: +it's possible to create a malicious C compiler which will +replicate its own malicious functionalities (e.g. detecting password-checking +routines to make them also accept another password the attacker knows) when used +to compile other C compilers. For all we know, such a compiler was used to +compile gcc, say, and so all programs around today could be compromised. Of +course, this is practically definitely not the case, but it's still an +interesting experiment to try to create a fully trustable compiler. This +project can't necessarily even do that though, because the Linux kernel, which +we depend on, is compiled from C, so we can't fully trust *it*. To +create a *fully* trustable compiler, you'd need to manually write +an operating system to a USB key with a circuit or something, +assuming you trust your CPU... +I'll leave that to someone else. + +## instruction set + +x86-64 has a *gigantic* instruction set. The manual for it is over 2,000 pages +long! To make things simpler, we will only use a small subset. + +Here are all the instructions we'll be using. If you're not familiar with +x86-64 assembly, you might want to look over these. + +x86-64 has 16 integer registers: rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15. +We will almost entirely be using the first 8 of these. +al refers to the bottom 8 bits of rax, likewise with bl, cl, dl; +ax refers to the bottom 16 bits of rax, likewise with bx, cx, dx; +eax refers to the bottom 32 bits of rax, likewise with ebx, ecx, edx. + +x86-64 also has 16 floating-point registers: xmm0 through xmm15. We'll only be using +xmm0 and xmm1. These registers can hold either four 32-bit floating-point numbers (`float`s) or +two 64-bit floating-point numbers (`double`s), but we'll only be using them to hold either one +`float` or one `double`. + +In the table below, `IMM64` means a 64-bit *immediate* (a constant number). +`rdx:rax` refers to the 128-bit number you get by combining `rdx` and `rax`. + +``` +ax bx cx dx sp bp si di +0 3 1 2 4 5 6 7 + +┌──────────────────────┬───────────────────┬────────────────────────────────────────┠+│ Instruction │ Encoding │ Description │ +├──────────────────────┼───────────────────┼────────────────────────────────────────┤ +│ mov rax, IMM64 │ 48 b8 IMM64 │ set rax to the 64-bit value IMM64 │ +│ mov rbx, IMM64 │ 48 bb IMM64 │ set rbx to the 64-bit value IMM64 │ +| add rax, IMM32 | 48 05 IMM32 | add IMM32 (signed) to rax | +│ xor eax, eax │ 31 c0 │ set rax to 0 (shorter than mov rax, 0) │ +│ xor edx, edx │ 31 d2 │ set rdx to 0 │ +│ mov RDEST, RSRC │ 48 89 (DEST|SRC<<3|0xc0) │ set register DEST to current │ +│ │ │ value of register SRC │ +│ mov r8, rax │ 49 89 c0 │ set r8 to rax (only used for syscalls) │ +│ mov r9, rax │ 49 89 c1 │ set r9 to rax (only used for syscalls) │ +│ mov r10, rax │ 49 89 c2 │ set r10 to rax (only used for syscalls)│ +| movsx rax, al | 48 0f be c0 | sign-extend al to rax | +| movsx rax, ax | 48 0f bf c0 | sign-extend ax to rax | +| movsx rax, eax | 48 63 c0 | sign-extend eax to rax | +| movzx rax, al | 48 0f b6 c0 | zero-extend al to rax | +| movzx rax, ax | 48 0f b7 c0 | zero-extend ax to rax | +| mov eax, eax | 89 c0 | zero-extend eax to rax | +│ xchg rax, rbx │ 48 93 │ exchange the values of rax and rbx │ +│ mov [rbx], rax │ 48 89 03 │ store rax as 8 bytes at address rbx │ +│ mov rax, [rbx] │ 48 8b 03 │ load 8 bytes from address rbx into rax │ +│ mov [rbx], eax │ 89 03 │ store eax as 4 bytes at address rbx │ +│ mov eax, [rbx] │ 8b 03 │ load 4 bytes from address rbx into eax │ +│ mov [rbx], ax │ 66 89 03 │ store ax as 2 bytes at address rbx │ +│ mov ax, [rbx] │ 66 8b 03 │ load 2 bytes from address rbx into eax │ +│ mov [rbx], al │ 88 03 │ store al as 1 byte at address rbx │ +│ mov al, [rbx] │ 8a 03 │ load 1 byte from address rbx into al │ +│ mov rax, [rbp+IMM32] │ 48 8b 85 IMM32 │ load 8 bytes from address rbp+IMM32 │ +│ │ │ into rax (note: IMM32 may be negative) │ +│ mov rax, [rsp+IMM32] │ 48 8b 84 24 IMM32 │ load 8 bytes from rsp+IMM32 into rax │ +│ mov [rbp+IMM32], rax │ 48 89 85 IMM32 │ store rax in 8 bytes at rbp+IMM32 │ +│ mov [rsp+IMM32], rax │ 48 89 84 24 IMM32 │ store rax in 8 bytes at rsp+IMM32 │ +│ mov [rsp], rbp │ 48 89 2c 24 │ store rbp in 8 bytes at rsp │ +│ mov rbp, [rsp] │ 48 8b 2c 24 │ load 8 bytes from rsp into rbp │ +│ lea rax, [rbp+IMM32] │ 48 8d 85 IMM32 │ set rax to rbp+IMM32 │ +│ lea rsp, [rbp+IMM32] │ 48 8d a5 IMM32 │ set rsp to rbp+IMM32 │ +| int3 | cc | raise trap signal -useful for debugging| +| movsq | 48 a5 | copy 8 bytes from rsi to rdi | +| rep movsb | f3 a4 | copy rcx bytes from rsi to rdi | +│ push rax │ 50 │ push rax onto the stack │ +│ pop rax │ 58 │ pop a value off the stack into rax │ +│ neg rax │ 48 f7 d8 │ set rax to -rax │ +│ add rax, rbx │ 48 01 d8 │ add rbx to rax │ +│ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │ +│ imul rbx │ 48 f7 eb │ set rdx:rax to rax * rbx (signed) │ +│ cqo │ 48 99 │ sign-extend rax to rdx:rax | +│ idiv rbx │ 48 f7 fb │ divide rdx:rax by rbx (signed); put │ +│ │ │ quotient in rax, remainder in rdx │ +│ mul rbx │ 48 f7 e3 │ like imul, but unsigned │ +│ div rbx │ 48 f7 f3 │ like idiv, but unsigned │ +│ not rax │ 48 f7 d0 │ set rax to ~rax (bitwise not) │ +│ and rax, rbx │ 48 21 d8 │ set rax to rax & rbx (bitwise and) │ +│ or rax, rbx │ 48 09 d8 │ set rax to rax | rbx (bitwise or) │ +│ xor rax, rbx │ 48 31 d8 │ set rax to rax ^ rbx (bitwise xor) │ +│ shl rax, cl │ 48 d3 e0 │ set rax to rax << cl (left shift) │ +│ shl rax, IMM8 │ 48 c1 e0 IMM8 │ set rax to rax << IMM8 │ +│ shr rax, cl │ 48 d3 e8 │ set rax to rax >> cl (unsigned) │ +│ shr rax, IMM8 │ 48 c1 e8 IMM8 │ set rax to rax >> IMM8 (unsigned) │ +│ sar rax, cl │ 48 d3 f8 │ set rax to rax >> cl (signed) │ +│ sar rax, IMM8 │ 48 c1 f8 IMM8 │ set rax to rax >> IMM8 (signed) │ +│ sub rsp, IMM32 │ 48 81 ec IMM32 │ subtract IMM32 from rsp │ +│ add rsp, IMM32 │ 48 81 c4 IMM32 │ add IMM32 to rsp │ +│ cmp rax, rbx │ 48 39 d8 │ compare rax with rbx (see je, jl, etc.)│ +│ test rax, rax │ 48 85 c0 │ equivalent to cmp rax, 0 │ +│ jmp IMM32 │ e9 IMM32 │ jump to offset IMM32 from here │ +│ je IMM32 │ 0f 84 IMM32 │ jump to IMM32 if equal │ +│ jne IMM32 │ 0f 85 IMM32 │ jump if not equal │ +│ jl IMM32 │ 0f 8c IMM32 │ jump if less than │ +│ jg IMM32 │ 0f 8f IMM32 │ jump if greater than │ +│ jle IMM32 │ 0f 8e IMM32 │ jump if less than or equal to │ +│ jge IMM32 │ 0f 8d IMM32 │ jump if greater than or equal to │ +│ jb IMM32 │ 0f 82 IMM32 │ jump if "below" (like jl but unsigned) │ +│ ja IMM32 │ 0f 87 IMM32 │ jump if "above" (like jg but unsigned) │ +│ jbe IMM32 │ 0f 86 IMM32 │ jump if below or equal to │ +│ jae IMM32 │ 0f 83 IMM32 │ jump if above or equal to │ +│ sete al │ 0f 94 c0 │ set al to 1 if equal; 0 otherwise │ +│ setne al │ 0f 95 c0 │ set al to 1 if not equal │ +│ setl al │ 0f 9c c0 │ set al to 1 if less than │ +│ setg al │ 0f 9f c0 │ set al to 1 if greater than │ +│ setle al │ 0f 9e c0 │ set al to 1 if less than or equal to │ +│ setge al │ 0f 9d c0 │ set al to 1 if greater than or equal to│ +│ setb al │ 0f 92 c0 │ set al to 1 if below │ +│ seta al │ 0f 97 c0 │ set al to 1 if above │ +│ setbe al │ 0f 96 c0 │ set al to 1 if below or equal to │ +│ setae al │ 0f 93 c0 │ set al to 1 if above or equal to │ +| movq rax, xmm0 | 66 48 0f 7e c0 | set rax to xmm0 | +| movq xmm0, rax | 66 48 0f 6e c0 | set xmm0 to rax | +| movq xmm1, rax | 66 48 0f 6e c8 | set xmm1 to rax | +| movq xmm1, xmm0 | f3 0f 7e c8 | set xmm1 to xmm0 | +| cvtss2sd xmm0, xmm0 | f3 0f 5a c0 | convert xmm0 from float to double | +| cvtsd2ss xmm0, xmm0 | f2 0f 5a c0 | convert xmm0 from double to float | +| cvttsd2si rax, xmm0 | f2 48 0f 2c c0 | convert double in xmm0 to int in rax | +| cvtsi2sd xmm0, rax | f2 48 0f 2a c0 | convert int in rax to double in xmm0 | +| comisd xmm0, xmm1 | 66 0f 2f c1 | compare xmm0 and xmm1 | +| addsd xmm0, xmm1 | f2 0f 58 c1 | add xmm1 to xmm0 | +| subsd xmm0, xmm1 | f2 0f 5c c1 | subtract xmm1 from xmm0 | +| mulsd xmm0, xmm1 | f2 0f 59 c1 | multiply xmm0 by xmm1 | +| divsd xmm0, xmm1 | f2 0f 5e c1 | divide xmm0 by xmm1 | +│ call rax │ ff d0 │ call the function at address rax │ +│ ret │ c3 │ return from function │ +│ syscall │ 0f 05 │ execute a system call │ +│ nop │ 90 │ do nothing │ +└──────────────────────┴───────────────────┴────────────────────────────────────────┘ + +SYSCALLS +Arguments are passed in + rdi, rsi, rdx, r10, r8, r9 +The return value is placed in rax. +The values of rsp, rbp and rbx are preserved, but other registers might change. +``` + +## license + +This does not apply to tcc's or musl's source code. + +``` +This project is in the public domain. Any copyright protections from any law +are forfeited by the author(s). No warranty is provided, and the author(s) +shall not be held liable in connection with it. +``` + +## contributing + +If you notice a mistake/want to clarify something, you can submit a pull request +via GitHub, or email `pommicket at pommicket.com`. diff --git a/README.md b/README.md index 00a7bf1..6f63bff 100644 --- a/README.md +++ b/README.md @@ -1,241 +1,5 @@ -# boostrapping a (Linux x86-64) C compiler +## Documentation -Compilers nowadays are written in languages like C, which themselves need to be -compiled. But then, you need a C compiler to compile your C compiler! Of course, -the very first C compiler was not written in C. -First, people made assemblers, then simple programming languages, -then, eventually, it was possible to make a C compiler. -In this repository, we'll explore how that's done. Each directory here -is a "stage" in the process. The first one, `00`, is a hand-written -executable, and the last one, `05`, is a C compiler. Each directory has its own -README explaining what's going on. +- [TinyCC Boostrap (stages 1-5)](./BOOSTRAP.md) +- [TinyCC -> Clang (stage 6)](./06/README.md) -You can run `bootstrap.sh` to run through and test every stage. -To get HTML versions of all README pages, run `make`. - -Note that the executables produced in this series will only run on -64-bit Linux, because each OS/architecture combination would need its own separate -executable. - -## table of contents - -- [stage 00](00/README.md) - a program converting a text file with -hexadecimal digit pairs to a binary file. -- [stage 01](01/README.md) - a language with comments, and 2-character -command codes. -- [stage 02](02/README.md) - a language with labels -- [stage 03](03/README.md) - a language with longer labels, better error messages, and less register manipulation -- [stage 04](04/README.md) - a language with nice functions and local variables -- [stage 04a](04a/README.md) - (interlude) a simple preprocessor -- [stage 05](05/README.md) - a C compiler capable of compiling TCC -- [stage 06](06/README.md) - an interpreter capable of executing zig - -## prerequisite knowledge - -If you want to follow along with this series, you'll probably want to know about: - -- number bases -- if a number is preceded by 0x, 0o, or 0b in this series, that -means hexadecimal/octal/binary respectively. So 0xff = FF hexadecimal = 255 -decimal. -- bits, bytes, kilobytes, etc. -- bitwise operations (not, or, and, xor, left shift, right shift) -- 2's complement -- ASCII, null-terminated strings -- how pointers work -- how floating-point numbers work -- what a compiler is -- what an executable file is -- what a system call is -- what a CPU is -- what a CPU architecture is -- what a CPU register is -- what the (call) stack is - -If you're unfamiliar with x86-64 assembly, you should take a look at the instruction list below. - -## principles - -- as simple as possible - -Bootstrapping a compiler is not an easy task, so we're trying to make it as easy -as possible. We don't even necessarily need a standard-compliant C compiler, we -only need enough to compile someone else's C compiler. Specifically, we'll be -using [tcc](https://bellard.org/tcc/) since it's written (mostly) in C89. - -- efficiency is not a concern - -We will create big and slow executables, and that's okay. It doesn't really -matter if compiling TCC takes 30 as opposed to 0.01 seconds; once -we compile it with itself, we should get the same executable either way. - -## reflections on trusting trust - -In 1984, Ken Thompson wrote the well-known article -[Reflections on Trusting Trust](http://users.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf). -This is one of the inspirations for this project. A brief summary is: -it's possible to create a malicious C compiler which will -replicate its own malicious functionalities (e.g. detecting password-checking -routines to make them also accept another password the attacker knows) when used -to compile other C compilers. For all we know, such a compiler was used to -compile gcc, say, and so all programs around today could be compromised. Of -course, this is practically definitely not the case, but it's still an -interesting experiment to try to create a fully trustable compiler. This -project can't necessarily even do that though, because the Linux kernel, which -we depend on, is compiled from C, so we can't fully trust *it*. To -create a *fully* trustable compiler, you'd need to manually write -an operating system to a USB key with a circuit or something, -assuming you trust your CPU... -I'll leave that to someone else. - -## instruction set - -x86-64 has a *gigantic* instruction set. The manual for it is over 2,000 pages -long! To make things simpler, we will only use a small subset. - -Here are all the instructions we'll be using. If you're not familiar with -x86-64 assembly, you might want to look over these. - -x86-64 has 16 integer registers: rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15. -We will almost entirely be using the first 8 of these. -al refers to the bottom 8 bits of rax, likewise with bl, cl, dl; -ax refers to the bottom 16 bits of rax, likewise with bx, cx, dx; -eax refers to the bottom 32 bits of rax, likewise with ebx, ecx, edx. - -x86-64 also has 16 floating-point registers: xmm0 through xmm15. We'll only be using -xmm0 and xmm1. These registers can hold either four 32-bit floating-point numbers (`float`s) or -two 64-bit floating-point numbers (`double`s), but we'll only be using them to hold either one -`float` or one `double`. - -In the table below, `IMM64` means a 64-bit *immediate* (a constant number). -`rdx:rax` refers to the 128-bit number you get by combining `rdx` and `rax`. - -``` -ax bx cx dx sp bp si di -0 3 1 2 4 5 6 7 - -┌──────────────────────┬───────────────────┬────────────────────────────────────────┠-│ Instruction │ Encoding │ Description │ -├──────────────────────┼───────────────────┼────────────────────────────────────────┤ -│ mov rax, IMM64 │ 48 b8 IMM64 │ set rax to the 64-bit value IMM64 │ -│ mov rbx, IMM64 │ 48 bb IMM64 │ set rbx to the 64-bit value IMM64 │ -| add rax, IMM32 | 48 05 IMM32 | add IMM32 (signed) to rax | -│ xor eax, eax │ 31 c0 │ set rax to 0 (shorter than mov rax, 0) │ -│ xor edx, edx │ 31 d2 │ set rdx to 0 │ -│ mov RDEST, RSRC │ 48 89 (DEST|SRC<<3|0xc0) │ set register DEST to current │ -│ │ │ value of register SRC │ -│ mov r8, rax │ 49 89 c0 │ set r8 to rax (only used for syscalls) │ -│ mov r9, rax │ 49 89 c1 │ set r9 to rax (only used for syscalls) │ -│ mov r10, rax │ 49 89 c2 │ set r10 to rax (only used for syscalls)│ -| movsx rax, al | 48 0f be c0 | sign-extend al to rax | -| movsx rax, ax | 48 0f bf c0 | sign-extend ax to rax | -| movsx rax, eax | 48 63 c0 | sign-extend eax to rax | -| movzx rax, al | 48 0f b6 c0 | zero-extend al to rax | -| movzx rax, ax | 48 0f b7 c0 | zero-extend ax to rax | -| mov eax, eax | 89 c0 | zero-extend eax to rax | -│ xchg rax, rbx │ 48 93 │ exchange the values of rax and rbx │ -│ mov [rbx], rax │ 48 89 03 │ store rax as 8 bytes at address rbx │ -│ mov rax, [rbx] │ 48 8b 03 │ load 8 bytes from address rbx into rax │ -│ mov [rbx], eax │ 89 03 │ store eax as 4 bytes at address rbx │ -│ mov eax, [rbx] │ 8b 03 │ load 4 bytes from address rbx into eax │ -│ mov [rbx], ax │ 66 89 03 │ store ax as 2 bytes at address rbx │ -│ mov ax, [rbx] │ 66 8b 03 │ load 2 bytes from address rbx into eax │ -│ mov [rbx], al │ 88 03 │ store al as 1 byte at address rbx │ -│ mov al, [rbx] │ 8a 03 │ load 1 byte from address rbx into al │ -│ mov rax, [rbp+IMM32] │ 48 8b 85 IMM32 │ load 8 bytes from address rbp+IMM32 │ -│ │ │ into rax (note: IMM32 may be negative) │ -│ mov rax, [rsp+IMM32] │ 48 8b 84 24 IMM32 │ load 8 bytes from rsp+IMM32 into rax │ -│ mov [rbp+IMM32], rax │ 48 89 85 IMM32 │ store rax in 8 bytes at rbp+IMM32 │ -│ mov [rsp+IMM32], rax │ 48 89 84 24 IMM32 │ store rax in 8 bytes at rsp+IMM32 │ -│ mov [rsp], rbp │ 48 89 2c 24 │ store rbp in 8 bytes at rsp │ -│ mov rbp, [rsp] │ 48 8b 2c 24 │ load 8 bytes from rsp into rbp │ -│ lea rax, [rbp+IMM32] │ 48 8d 85 IMM32 │ set rax to rbp+IMM32 │ -│ lea rsp, [rbp+IMM32] │ 48 8d a5 IMM32 │ set rsp to rbp+IMM32 │ -| int3 | cc | raise trap signal -useful for debugging| -| movsq | 48 a5 | copy 8 bytes from rsi to rdi | -| rep movsb | f3 a4 | copy rcx bytes from rsi to rdi | -│ push rax │ 50 │ push rax onto the stack │ -│ pop rax │ 58 │ pop a value off the stack into rax │ -│ neg rax │ 48 f7 d8 │ set rax to -rax │ -│ add rax, rbx │ 48 01 d8 │ add rbx to rax │ -│ sub rax, rbx │ 48 29 d8 │ subtract rbx from rax │ -│ imul rbx │ 48 f7 eb │ set rdx:rax to rax * rbx (signed) │ -│ cqo │ 48 99 │ sign-extend rax to rdx:rax | -│ idiv rbx │ 48 f7 fb │ divide rdx:rax by rbx (signed); put │ -│ │ │ quotient in rax, remainder in rdx │ -│ mul rbx │ 48 f7 e3 │ like imul, but unsigned │ -│ div rbx │ 48 f7 f3 │ like idiv, but unsigned │ -│ not rax │ 48 f7 d0 │ set rax to ~rax (bitwise not) │ -│ and rax, rbx │ 48 21 d8 │ set rax to rax & rbx (bitwise and) │ -│ or rax, rbx │ 48 09 d8 │ set rax to rax | rbx (bitwise or) │ -│ xor rax, rbx │ 48 31 d8 │ set rax to rax ^ rbx (bitwise xor) │ -│ shl rax, cl │ 48 d3 e0 │ set rax to rax << cl (left shift) │ -│ shl rax, IMM8 │ 48 c1 e0 IMM8 │ set rax to rax << IMM8 │ -│ shr rax, cl │ 48 d3 e8 │ set rax to rax >> cl (unsigned) │ -│ shr rax, IMM8 │ 48 c1 e8 IMM8 │ set rax to rax >> IMM8 (unsigned) │ -│ sar rax, cl │ 48 d3 f8 │ set rax to rax >> cl (signed) │ -│ sar rax, IMM8 │ 48 c1 f8 IMM8 │ set rax to rax >> IMM8 (signed) │ -│ sub rsp, IMM32 │ 48 81 ec IMM32 │ subtract IMM32 from rsp │ -│ add rsp, IMM32 │ 48 81 c4 IMM32 │ add IMM32 to rsp │ -│ cmp rax, rbx │ 48 39 d8 │ compare rax with rbx (see je, jl, etc.)│ -│ test rax, rax │ 48 85 c0 │ equivalent to cmp rax, 0 │ -│ jmp IMM32 │ e9 IMM32 │ jump to offset IMM32 from here │ -│ je IMM32 │ 0f 84 IMM32 │ jump to IMM32 if equal │ -│ jne IMM32 │ 0f 85 IMM32 │ jump if not equal │ -│ jl IMM32 │ 0f 8c IMM32 │ jump if less than │ -│ jg IMM32 │ 0f 8f IMM32 │ jump if greater than │ -│ jle IMM32 │ 0f 8e IMM32 │ jump if less than or equal to │ -│ jge IMM32 │ 0f 8d IMM32 │ jump if greater than or equal to │ -│ jb IMM32 │ 0f 82 IMM32 │ jump if "below" (like jl but unsigned) │ -│ ja IMM32 │ 0f 87 IMM32 │ jump if "above" (like jg but unsigned) │ -│ jbe IMM32 │ 0f 86 IMM32 │ jump if below or equal to │ -│ jae IMM32 │ 0f 83 IMM32 │ jump if above or equal to │ -│ sete al │ 0f 94 c0 │ set al to 1 if equal; 0 otherwise │ -│ setne al │ 0f 95 c0 │ set al to 1 if not equal │ -│ setl al │ 0f 9c c0 │ set al to 1 if less than │ -│ setg al │ 0f 9f c0 │ set al to 1 if greater than │ -│ setle al │ 0f 9e c0 │ set al to 1 if less than or equal to │ -│ setge al │ 0f 9d c0 │ set al to 1 if greater than or equal to│ -│ setb al │ 0f 92 c0 │ set al to 1 if below │ -│ seta al │ 0f 97 c0 │ set al to 1 if above │ -│ setbe al │ 0f 96 c0 │ set al to 1 if below or equal to │ -│ setae al │ 0f 93 c0 │ set al to 1 if above or equal to │ -| movq rax, xmm0 | 66 48 0f 7e c0 | set rax to xmm0 | -| movq xmm0, rax | 66 48 0f 6e c0 | set xmm0 to rax | -| movq xmm1, rax | 66 48 0f 6e c8 | set xmm1 to rax | -| movq xmm1, xmm0 | f3 0f 7e c8 | set xmm1 to xmm0 | -| cvtss2sd xmm0, xmm0 | f3 0f 5a c0 | convert xmm0 from float to double | -| cvtsd2ss xmm0, xmm0 | f2 0f 5a c0 | convert xmm0 from double to float | -| cvttsd2si rax, xmm0 | f2 48 0f 2c c0 | convert double in xmm0 to int in rax | -| cvtsi2sd xmm0, rax | f2 48 0f 2a c0 | convert int in rax to double in xmm0 | -| comisd xmm0, xmm1 | 66 0f 2f c1 | compare xmm0 and xmm1 | -| addsd xmm0, xmm1 | f2 0f 58 c1 | add xmm1 to xmm0 | -| subsd xmm0, xmm1 | f2 0f 5c c1 | subtract xmm1 from xmm0 | -| mulsd xmm0, xmm1 | f2 0f 59 c1 | multiply xmm0 by xmm1 | -| divsd xmm0, xmm1 | f2 0f 5e c1 | divide xmm0 by xmm1 | -│ call rax │ ff d0 │ call the function at address rax │ -│ ret │ c3 │ return from function │ -│ syscall │ 0f 05 │ execute a system call │ -│ nop │ 90 │ do nothing │ -└──────────────────────┴───────────────────┴────────────────────────────────────────┘ - -SYSCALLS -Arguments are passed in - rdi, rsi, rdx, r10, r8, r9 -The return value is placed in rax. -The values of rsp, rbp and rbx are preserved, but other registers might change. -``` - -## license - -This does not apply to tcc's or musl's source code. - -``` -This project is in the public domain. Any copyright protections from any law -are forfeited by the author(s). No warranty is provided, and the author(s) -shall not be held liable in connection with it. -``` - -## contributing - -If you notice a mistake/want to clarify something, you can submit a pull request -via GitHub, or email `pommicket at pommicket.com`.