::printObjectUnwindSection(bool showFunctionNames)
+ {
+- printf("Arch: %s, Section: __LD,__compact_unwind (size=0x%08llX, => %lld entries)\n",
++ printf("Arch: %s, Section: __LD,__compact_unwind (size=0x%08lX, => %ld entries)\n",
+ archName(), fUnwindSection->size(), fUnwindSection->size() / sizeof(macho_compact_unwind_entry));
+
+ const macho_compact_unwind_entry
* const entriesStart = (macho_compact_unwind_entry
*)((uint8_t*)fHeader + fUnwindSection->offset());
+ const macho_compact_unwind_entry
* const entriesEnd = (macho_compact_unwind_entry
*)((uint8_t*)fHeader + fUnwindSection->offset() + fUnwindSection->size());
+ for (const macho_compact_unwind_entry
* entry=entriesStart; entry < entriesEnd; ++entry) {
+ uint64_t entryAddress = ((char*)entry - (char*)entriesStart) + fUnwindSection->addr();
+- printf("0x%08llX:\n", entryAddress);
++ printf("0x%08lX:\n", entryAddress);
+ const char* functionNameStr;
+ pint_t funcAddress;
+ uint32_t offsetInFunction;
+@@ -923,11 +923,11 @@
+ funcAddress = entry->codeStart();
+ }
+ if ( offsetInFunction == 0 )
+- printf(" start: 0x%08llX %s\n", (uint64_t)funcAddress, functionNameStr);
++ printf(" start: 0x%08lX %s\n", (uint64_t)funcAddress, functionNameStr);
+ else
+- printf(" start: 0x%08llX %s+0x%X\n", (uint64_t)funcAddress+offsetInFunction, functionNameStr, offsetInFunction);
++ printf(" start: 0x%08lX %s+0x%X\n", (uint64_t)funcAddress+offsetInFunction, functionNameStr, offsetInFunction);
+
+- printf(" end: 0x%08llX (len=0x%08X)\n", (uint64_t)(funcAddress+offsetInFunction+entry->codeLen()), entry->codeLen());
++ printf(" end: 0x%08lX (len=0x%08X)\n", (uint64_t)(funcAddress+offsetInFunction+entry->codeLen()), entry->codeLen());
+
+ char encodingString[200];
+ this->decode(entry->compactUnwindInfo(), ((const uint8_t*)fHeader), encodingString);
+@@ -947,9 +947,9 @@
+ uint32_t lsdaOffset;
+ const char* lsdaName = this->functionName(entry->lsda(), &lsdaOffset);
+ if ( lsdaOffset == 0 )
+- printf(" lsda: 0x%08llX %s\n", (uint64_t)entry->lsda(), lsdaName);
++ printf(" lsda: 0x%08lX %s\n", (uint64_t)entry->lsda(), lsdaName);
+ else
+- printf(" lsda: 0x%08llX %s+0x%X\n", (uint64_t)entry->lsda(), lsdaName, lsdaOffset);
++ printf(" lsda: 0x%08lX %s+0x%X\n", (uint64_t)entry->lsda(), lsdaName, lsdaOffset);
+ }
+ }
+ }
+@@ -962,7 +962,7 @@
+ const uint8_t* sectionContent = (uint8_t*)fHeader + fUnwindSection->offset();
+ macho_unwind_info_section_header
* sectionHeader = (macho_unwind_info_section_header
*)(sectionContent);
+
+- printf("Arch: %s, Section: __TEXT,__unwind_info (addr=0x%08llX, size=0x%08llX, fileOffset=0x%08X)\n",
++ printf("Arch: %s, Section: __TEXT,__unwind_info (addr=0x%08lX, size=0x%08lX, fileOffset=0x%08X)\n",
+ archName(), fUnwindSection->addr(), fUnwindSection->size(), fUnwindSection->offset());
+ printf("\tversion=0x%08X\n", sectionHeader->version());
+ printf("\tcommonEncodingsArraySectionOffset=0x%08X\n", sectionHeader->commonEncodingsArraySectionOffset());
+diff -ur cctools-port-c1cc758/cctools/libstuff/ofile.c cctools-port-format/cctools/libstuff/ofile.c
+--- cctools-port-c1cc758/cctools/libstuff/ofile.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-format/cctools/libstuff/ofile.c 2017-11-10 19:38:34.511211634 -0800
+@@ -3108,7 +3108,7 @@
+ }
+ if(offset %
+ (1 << align) != 0){
+- error("fat file: %s offset: %llu for cputype (%d) cpusubtype "
++ error("fat file: %s offset: %lu for cputype (%d) cpusubtype "
+ "(%d)) not aligned on it's alignment (2^%u)",
+ ofile->file_name, offset, cputype,
+ cpusubtype & ~CPU_SUBTYPE_MASK, align);
+@@ -3210,7 +3210,7 @@
+ return(CHECK_BAD);
+ }
+ if(offset % (1 << align) != 0){
+- archive_member_error(ofile, "fat file's offset: %llu for "
++ archive_member_error(ofile, "fat file's offset: %lu for "
+ "cputype (%d) cpusubtype (%d) not aligned on it's "
+ "alignment (2^%u)", offset, cputype,
+ cpusubtype & ~CPU_SUBTYPE_MASK, align);
+diff -ur cctools-port-c1cc758/cctools/libstuff/writeout.c cctools-port-format/cctools/libstuff/writeout.c
+--- cctools-port-c1cc758/cctools/libstuff/writeout.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-format/cctools/libstuff/writeout.c 2017-11-10 19:40:56.792695079 -0800
+@@ -421,7 +421,7 @@
+ if((r = vm_allocate(mach_task_self(), (vm_address_t *)&file,
+ file_size, TRUE)) != KERN_SUCCESS)
+ mach_fatal(r, "can't vm_allocate() buffer for output file: %s of "
+- "size %llu", filename, file_size);
++ "size %lu", filename, file_size);
+
+ /*
+ * If there is more than one architecture then fill in the fat file
+@@ -460,7 +460,7 @@
+ if(offset > UINT32_MAX && archs[i].fat_arch64 == NULL){
+ error("file too large to create as a fat file because "
+ "offset field in struct fat_arch is only 32-bits and "
+- "offset (%llu) to architecture %s exceeds that",
++ "offset (%lu) to architecture %s exceeds that",
+ offset, archs[i].fat_arch_name);
+ return;
+ }
+diff -ur cctools-port-c1cc758/cctools/misc/libtool.c cctools-port-format/cctools/misc/libtool.c
+--- cctools-port-c1cc758/cctools/misc/libtool.c 2017-11-10 19:22:01.790476705 -0800
++++ cctools-port-format/cctools/misc/libtool.c 2017-11-10 19:24:48.435607249 -0800
+@@ -2545,7 +2545,7 @@
+ if((r = vm_allocate(mach_task_self(), (vm_address_t *)&library,
+ library_size, TRUE)) != KERN_SUCCESS)
+ mach_fatal(r, "can't vm_allocate() buffer for output file: %s "
+- "of size %llu", output, library_size);
++ "of size %lu", output, library_size);
+
+
+ /* put in the archive magic string in the buffer */
+@@ -2581,7 +2581,7 @@
+ if((r = vm_allocate(mach_task_self(), (vm_address_t *)&library,
+ library_size, TRUE)) != KERN_SUCCESS)
+ mach_fatal(r, "can't vm_allocate() buffer for output file: %s of "
+- "size %llu", output, library_size);
++ "size %lu", output, library_size);
+
+ /*
+ * Create the output file. The unlink() is done to handle the problem
+@@ -2635,7 +2635,7 @@
+ if(cmd_flags.fat64 == FALSE && offset > UINT32_MAX)
+ error("file too large to create as a fat file because "
+ "offset field in struct fat_arch is only 32-bits and "
+- "offset (%llu) to architecture %s exceeds that",
++ "offset (%lu) to architecture %s exceeds that",
+ offset, archs[i].arch_flag.name);
+ if(archs[i].arch_flag.cputype & CPU_ARCH_ABI64){
+ if(cmd_flags.fat64 == TRUE)
+@@ -2660,7 +2660,7 @@
+ if(cmd_flags.fat64 == FALSE && archs[i].size > UINT32_MAX)
+ error("file too large to create as a fat file because "
+ "size field in struct fat_arch is only 32-bits and "
+- "size (%llu) of architecture %s exceeds that",
++ "size (%lu) of architecture %s exceeds that",
+ archs[i].size, archs[i].arch_flag.name);
+ if(cmd_flags.fat64 == TRUE)
+ fat_arch64[i].size = archs[i].size;
+@@ -3043,15 +3043,15 @@
+ return;
+
+ if(offset + size > library_size)
+- fatal("internal error: output_flush(offset = %llu, size = %llu) "
+- "out of range for library_size = %llu", offset, size,
++ fatal("internal error: output_flush(offset = %lu, size = %lu) "
++ "out of range for library_size = %lu", offset, size,
+ library_size);
+
+ #ifdef DEBUG
+ if(cmd_flags.debug & (1 << 2))
+ print_block_list();
+ if(cmd_flags.debug & (1 << 1))
+- printf("output_flush(offset = %llu, size %llu)", offset, size);
++ printf("output_flush(offset = %lu, size %lu)", offset, size);
+ #endif /* DEBUG */
+
+ if(size == 0){
+@@ -3087,9 +3087,9 @@
+ */
+ if(before != NULL){
+ if(before->offset + before->size > offset){
+- warning("internal error: output_flush(offset = %llu, size = "
+- "%llu) overlaps with flushed block(offset = %llu, "
+- "size = %llu)", offset, size, before->offset,
++ warning("internal error: output_flush(offset = %lu, size = "
++ "%lu) overlaps with flushed block(offset = %lu, "
++ "size = %lu)", offset, size, before->offset,
+ before->size);
+ printf("calling abort()\n");
+ abort();
+@@ -3097,9 +3097,9 @@
+ }
+ if(after != NULL){
+ if(offset + size > after->offset){
+- warning("internal error: output_flush(offset = %llu, size = "
+- "%llu) overlaps with flushed block(offset = %llu, "
+- "size = %llu)", offset, size, after->offset,
++ warning("internal error: output_flush(offset = %lu, size = "
++ "%lu) overlaps with flushed block(offset = %lu, "
++ "size = %lu)", offset, size, after->offset,
+ after->size);
+ printf("calling abort()\n");
+ abort();
diff --git a/nix/nixcrpkgs/macos/cctools-ld64-registers.patch b/nix/nixcrpkgs/macos/cctools-ld64-registers.patch
new file mode 100644
index 000000000..70963e253
--- /dev/null
+++ b/nix/nixcrpkgs/macos/cctools-ld64-registers.patch
@@ -0,0 +1,299 @@
+diff -ur cctools-port-c1cc758/cctools/ld64/src/ld/parsers/libunwind/Registers.hpp cctools-port-patched/cctools/ld64/src/ld/parsers/libunwind/Registers.hpp
+--- cctools-port-c1cc758/cctools/ld64/src/ld/parsers/libunwind/Registers.hpp 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-patched/cctools/ld64/src/ld/parsers/libunwind/Registers.hpp 2017-10-29 10:12:23.150301208 -0700
+@@ -72,22 +72,22 @@
+ const char* getRegisterName(int num);
+ void jumpto();
+
+- uint32_t getSP() const { return fRegisters.__esp; }
+- void setSP(uint32_t value) { fRegisters.__esp = value; }
+- uint32_t getIP() const { return fRegisters.__eip; }
+- void setIP(uint32_t value) { fRegisters.__eip = value; }
+- uint32_t getEBP() const { return fRegisters.__ebp; }
+- void setEBP(uint32_t value) { fRegisters.__ebp = value; }
+- uint32_t getEBX() const { return fRegisters.__ebx; }
+- void setEBX(uint32_t value) { fRegisters.__ebx = value; }
+- uint32_t getECX() const { return fRegisters.__ecx; }
+- void setECX(uint32_t value) { fRegisters.__ecx = value; }
+- uint32_t getEDX() const { return fRegisters.__edx; }
+- void setEDX(uint32_t value) { fRegisters.__edx = value; }
+- uint32_t getESI() const { return fRegisters.__esi; }
+- void setESI(uint32_t value) { fRegisters.__esi = value; }
+- uint32_t getEDI() const { return fRegisters.__edi; }
+- void setEDI(uint32_t value) { fRegisters.__edi = value; }
++ uint32_t getSP() const { return fRegisters.esp; }
++ void setSP(uint32_t value) { fRegisters.esp = value; }
++ uint32_t getIP() const { return fRegisters.eip; }
++ void setIP(uint32_t value) { fRegisters.eip = value; }
++ uint32_t getEBP() const { return fRegisters.ebp; }
++ void setEBP(uint32_t value) { fRegisters.ebp = value; }
++ uint32_t getEBX() const { return fRegisters.ebx; }
++ void setEBX(uint32_t value) { fRegisters.ebx = value; }
++ uint32_t getECX() const { return fRegisters.ecx; }
++ void setECX(uint32_t value) { fRegisters.ecx = value; }
++ uint32_t getEDX() const { return fRegisters.edx; }
++ void setEDX(uint32_t value) { fRegisters.edx = value; }
++ uint32_t getESI() const { return fRegisters.esi; }
++ void setESI(uint32_t value) { fRegisters.esi = value; }
++ uint32_t getEDI() const { return fRegisters.edi; }
++ void setEDI(uint32_t value) { fRegisters.edi = value; }
+
+ private:
+ i386_thread_state_t fRegisters;
+@@ -122,25 +122,25 @@
+ {
+ switch ( regNum ) {
+ case UNW_REG_IP:
+- return fRegisters.__eip;
++ return fRegisters.eip;
+ case UNW_REG_SP:
+- return fRegisters.__esp;
++ return fRegisters.esp;
+ case UNW_X86_EAX:
+- return fRegisters.__eax;
++ return fRegisters.eax;
+ case UNW_X86_ECX:
+- return fRegisters.__ecx;
++ return fRegisters.ecx;
+ case UNW_X86_EDX:
+- return fRegisters.__edx;
++ return fRegisters.edx;
+ case UNW_X86_EBX:
+- return fRegisters.__ebx;
++ return fRegisters.ebx;
+ case UNW_X86_EBP:
+- return fRegisters.__ebp;
++ return fRegisters.ebp;
+ case UNW_X86_ESP:
+- return fRegisters.__esp;
++ return fRegisters.esp;
+ case UNW_X86_ESI:
+- return fRegisters.__esi;
++ return fRegisters.esi;
+ case UNW_X86_EDI:
+- return fRegisters.__edi;
++ return fRegisters.edi;
+ }
+ ABORT("unsupported x86 register");
+ }
+@@ -149,34 +149,34 @@
+ {
+ switch ( regNum ) {
+ case UNW_REG_IP:
+- fRegisters.__eip = value;
++ fRegisters.eip = value;
+ return;
+ case UNW_REG_SP:
+- fRegisters.__esp = value;
++ fRegisters.esp = value;
+ return;
+ case UNW_X86_EAX:
+- fRegisters.__eax = value;
++ fRegisters.eax = value;
+ return;
+ case UNW_X86_ECX:
+- fRegisters.__ecx = value;
++ fRegisters.ecx = value;
+ return;
+ case UNW_X86_EDX:
+- fRegisters.__edx = value;
++ fRegisters.edx = value;
+ return;
+ case UNW_X86_EBX:
+- fRegisters.__ebx = value;
++ fRegisters.ebx = value;
+ return;
+ case UNW_X86_EBP:
+- fRegisters.__ebp = value;
++ fRegisters.ebp = value;
+ return;
+ case UNW_X86_ESP:
+- fRegisters.__esp = value;
++ fRegisters.esp = value;
+ return;
+ case UNW_X86_ESI:
+- fRegisters.__esi = value;
++ fRegisters.esi = value;
+ return;
+ case UNW_X86_EDI:
+- fRegisters.__edi = value;
++ fRegisters.edi = value;
+ return;
+ }
+ ABORT("unsupported x86 register");
+@@ -253,22 +253,22 @@
+ void setVectorRegister(int num, v128 value);
+ const char* getRegisterName(int num);
+ void jumpto();
+- uint64_t getSP() const { return fRegisters.__rsp; }
+- void setSP(uint64_t value) { fRegisters.__rsp = value; }
+- uint64_t getIP() const { return fRegisters.__rip; }
+- void setIP(uint64_t value) { fRegisters.__rip = value; }
+- uint64_t getRBP() const { return fRegisters.__rbp; }
+- void setRBP(uint64_t value) { fRegisters.__rbp = value; }
+- uint64_t getRBX() const { return fRegisters.__rbx; }
+- void setRBX(uint64_t value) { fRegisters.__rbx = value; }
+- uint64_t getR12() const { return fRegisters.__r12; }
+- void setR12(uint64_t value) { fRegisters.__r12 = value; }
+- uint64_t getR13() const { return fRegisters.__r13; }
+- void setR13(uint64_t value) { fRegisters.__r13 = value; }
+- uint64_t getR14() const { return fRegisters.__r14; }
+- void setR14(uint64_t value) { fRegisters.__r14 = value; }
+- uint64_t getR15() const { return fRegisters.__r15; }
+- void setR15(uint64_t value) { fRegisters.__r15 = value; }
++ uint64_t getSP() const { return fRegisters.rsp; }
++ void setSP(uint64_t value) { fRegisters.rsp = value; }
++ uint64_t getIP() const { return fRegisters.rip; }
++ void setIP(uint64_t value) { fRegisters.rip = value; }
++ uint64_t getRBP() const { return fRegisters.rbp; }
++ void setRBP(uint64_t value) { fRegisters.rbp = value; }
++ uint64_t getRBX() const { return fRegisters.rbx; }
++ void setRBX(uint64_t value) { fRegisters.rbx = value; }
++ uint64_t getR12() const { return fRegisters.r12; }
++ void setR12(uint64_t value) { fRegisters.r12 = value; }
++ uint64_t getR13() const { return fRegisters.r13; }
++ void setR13(uint64_t value) { fRegisters.r13 = value; }
++ uint64_t getR14() const { return fRegisters.r14; }
++ void setR14(uint64_t value) { fRegisters.r14 = value; }
++ uint64_t getR15() const { return fRegisters.r15; }
++ void setR15(uint64_t value) { fRegisters.r15 = value; }
+ private:
+ x86_thread_state64_t fRegisters;
+ };
+@@ -302,41 +302,41 @@
+ {
+ switch ( regNum ) {
+ case UNW_REG_IP:
+- return fRegisters.__rip;
++ return fRegisters.rip;
+ case UNW_REG_SP:
+- return fRegisters.__rsp;
++ return fRegisters.rsp;
+ case UNW_X86_64_RAX:
+- return fRegisters.__rax;
++ return fRegisters.rax;
+ case UNW_X86_64_RDX:
+- return fRegisters.__rdx;
++ return fRegisters.rdx;
+ case UNW_X86_64_RCX:
+- return fRegisters.__rcx;
++ return fRegisters.rcx;
+ case UNW_X86_64_RBX:
+- return fRegisters.__rbx;
++ return fRegisters.rbx;
+ case UNW_X86_64_RSI:
+- return fRegisters.__rsi;
++ return fRegisters.rsi;
+ case UNW_X86_64_RDI:
+- return fRegisters.__rdi;
++ return fRegisters.rdi;
+ case UNW_X86_64_RBP:
+- return fRegisters.__rbp;
++ return fRegisters.rbp;
+ case UNW_X86_64_RSP:
+- return fRegisters.__rsp;
++ return fRegisters.rsp;
+ case UNW_X86_64_R8:
+- return fRegisters.__r8;
++ return fRegisters.r8;
+ case UNW_X86_64_R9:
+- return fRegisters.__r9;
++ return fRegisters.r9;
+ case UNW_X86_64_R10:
+- return fRegisters.__r10;
++ return fRegisters.r10;
+ case UNW_X86_64_R11:
+- return fRegisters.__r11;
++ return fRegisters.r11;
+ case UNW_X86_64_R12:
+- return fRegisters.__r12;
++ return fRegisters.r12;
+ case UNW_X86_64_R13:
+- return fRegisters.__r13;
++ return fRegisters.r13;
+ case UNW_X86_64_R14:
+- return fRegisters.__r14;
++ return fRegisters.r14;
+ case UNW_X86_64_R15:
+- return fRegisters.__r15;
++ return fRegisters.r15;
+ }
+ ABORT("unsupported x86_64 register");
+ }
+@@ -345,58 +345,58 @@
+ {
+ switch ( regNum ) {
+ case UNW_REG_IP:
+- fRegisters.__rip = value;
++ fRegisters.rip = value;
+ return;
+ case UNW_REG_SP:
+- fRegisters.__rsp = value;
++ fRegisters.rsp = value;
+ return;
+ case UNW_X86_64_RAX:
+- fRegisters.__rax = value;
++ fRegisters.rax = value;
+ return;
+ case UNW_X86_64_RDX:
+- fRegisters.__rdx = value;
++ fRegisters.rdx = value;
+ return;
+ case UNW_X86_64_RCX:
+- fRegisters.__rcx = value;
++ fRegisters.rcx = value;
+ return;
+ case UNW_X86_64_RBX:
+- fRegisters.__rbx = value;
++ fRegisters.rbx = value;
+ return;
+ case UNW_X86_64_RSI:
+- fRegisters.__rsi = value;
++ fRegisters.rsi = value;
+ return;
+ case UNW_X86_64_RDI:
+- fRegisters.__rdi = value;
++ fRegisters.rdi = value;
+ return;
+ case UNW_X86_64_RBP:
+- fRegisters.__rbp = value;
++ fRegisters.rbp = value;
+ return;
+ case UNW_X86_64_RSP:
+- fRegisters.__rsp = value;
++ fRegisters.rsp = value;
+ return;
+ case UNW_X86_64_R8:
+- fRegisters.__r8 = value;
++ fRegisters.r8 = value;
+ return;
+ case UNW_X86_64_R9:
+- fRegisters.__r9 = value;
++ fRegisters.r9 = value;
+ return;
+ case UNW_X86_64_R10:
+- fRegisters.__r10 = value;
++ fRegisters.r10 = value;
+ return;
+ case UNW_X86_64_R11:
+- fRegisters.__r11 = value;
++ fRegisters.r11 = value;
+ return;
+ case UNW_X86_64_R12:
+- fRegisters.__r12 = value;
++ fRegisters.r12 = value;
+ return;
+ case UNW_X86_64_R13:
+- fRegisters.__r13 = value;
++ fRegisters.r13 = value;
+ return;
+ case UNW_X86_64_R14:
+- fRegisters.__r14 = value;
++ fRegisters.r14 = value;
+ return;
+ case UNW_X86_64_R15:
+- fRegisters.__r15 = value;
++ fRegisters.r15 = value;
+ return;
+ }
+ ABORT("unsupported x86_64 register");
diff --git a/nix/nixcrpkgs/macos/cctools-libstuff-no-error.patch b/nix/nixcrpkgs/macos/cctools-libstuff-no-error.patch
new file mode 100644
index 000000000..6be415388
--- /dev/null
+++ b/nix/nixcrpkgs/macos/cctools-libstuff-no-error.patch
@@ -0,0 +1,93 @@
+diff -ur cctools-port-c1cc758/cctools/include/stuff/errors.h cctools-port-libstuff-no-error/cctools/include/stuff/errors.h
+--- cctools-port-c1cc758/cctools/include/stuff/errors.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/include/stuff/errors.h 2017-11-10 21:52:54.172522281 -0800
+@@ -40,7 +40,7 @@
+ __attribute__ ((format (printf, 1, 2)))
+ #endif
+ __attribute__((visibility("hidden")));
+-extern void error(
++extern void errorf(
+ const char *format, ...)
+ #ifdef __GNUC__
+ __attribute__ ((format (printf, 1, 2)))
+diff -ur cctools-port-c1cc758/cctools/libstuff/errors.c cctools-port-libstuff-no-error/cctools/libstuff/errors.c
+--- cctools-port-c1cc758/cctools/libstuff/errors.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/errors.c 2017-11-10 21:52:42.795730237 -0800
+@@ -57,7 +57,7 @@
+ */
+ __private_extern__
+ void
+-error(
++errorf(
+ const char *format,
+ ...)
+ {
+diff -ur cctools-port-c1cc758/cctools/libstuff/ofile.c cctools-port-libstuff-no-error/cctools/libstuff/ofile.c
+--- cctools-port-c1cc758/cctools/libstuff/ofile.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/ofile.c 2017-11-10 21:54:20.156803208 -0800
+@@ -115,6 +115,8 @@
+ };
+ #endif /* !defined(OTOOL) */
+
++#define error errorf
++
+ static enum bool ofile_specific_arch(
+ struct ofile *ofile,
+ uint32_t narch);
+diff -ur cctools-port-c1cc758/cctools/libstuff/swap_headers.c cctools-port-libstuff-no-error/cctools/libstuff/swap_headers.c
+--- cctools-port-c1cc758/cctools/libstuff/swap_headers.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/swap_headers.c 2017-11-10 21:54:49.873797374 -0800
+@@ -50,6 +50,8 @@
+ #include "stuff/bytesex.h"
+ #include "stuff/errors.h"
+
++#define error errorf
++
+ /*
+ * swap_object_headers() swaps the object file headers from the host byte sex
+ * into the non-host byte sex. It returns TRUE if it can and did swap the
+diff -ur cctools-port-c1cc758/cctools/libstuff/SymLoc.c cctools-port-libstuff-no-error/cctools/libstuff/SymLoc.c
+--- cctools-port-c1cc758/cctools/libstuff/SymLoc.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/SymLoc.c 2017-11-10 21:53:06.199321490 -0800
+@@ -118,7 +118,7 @@
+ if(fclose(file) != 0)
+ system_error("fclose() failed");
+ if (!*viewPath) {
+- error("symLocForDylib(): Can't locate view path for release %s",
++ errorf("symLocForDylib(): Can't locate view path for release %s",
+ releaseName);
+ return NULL;
+ }
+@@ -252,7 +252,7 @@
+ // process return value
+ if (!c) {
+ if(no_error_if_missing == FALSE)
+- error("Can't find project that builds %s", installName);
++ errorf("Can't find project that builds %s", installName);
+ return NULL;
+ } else {
+ *found_project = TRUE;
+diff -ur cctools-port-c1cc758/cctools/libstuff/version_number.c cctools-port-libstuff-no-error/cctools/libstuff/version_number.c
+--- cctools-port-c1cc758/cctools/libstuff/version_number.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/version_number.c 2017-11-10 21:55:18.674114769 -0800
+@@ -27,6 +27,8 @@
+ #include "stuff/allocate.h"
+ #include "stuff/errors.h"
+
++#define error errorf
++
+ /*
+ * get_version_number() converts an ascii version number string of the form:
+ * X[.Y[.Z]]
+diff -ur cctools-port-c1cc758/cctools/libstuff/writeout.c cctools-port-libstuff-no-error/cctools/libstuff/writeout.c
+--- cctools-port-c1cc758/cctools/libstuff/writeout.c 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-libstuff-no-error/cctools/libstuff/writeout.c 2017-11-10 21:55:43.537722114 -0800
+@@ -37,6 +37,8 @@
+ #include "stuff/lto.h"
+ #endif /* LTO_SUPPORT */
+
++#define error errorf
++
+ static void copy_new_symbol_info(
+ char *p,
+ uint32_t *size,
diff --git a/nix/nixcrpkgs/macos/cctools-private-extern.patch b/nix/nixcrpkgs/macos/cctools-private-extern.patch
new file mode 100644
index 000000000..ce0f099fd
--- /dev/null
+++ b/nix/nixcrpkgs/macos/cctools-private-extern.patch
@@ -0,0 +1,271 @@
+diff -ur cctools-port-c1cc758/cctools/include/foreign/extern.h cctools-port-private-extern/cctools/include/foreign/extern.h
+--- cctools-port-c1cc758/cctools/include/foreign/extern.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/foreign/extern.h 2017-11-10 18:32:37.035890924 -0800
+@@ -1 +1,2 @@
++#pragma once
+ #define __private_extern__ __attribute__((visibility("hidden")))
+diff -ur cctools-port-c1cc758/cctools/include/mach-o/dyld.h cctools-port-private-extern/cctools/include/mach-o/dyld.h
+--- cctools-port-c1cc758/cctools/include/mach-o/dyld.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/mach-o/dyld.h 2017-11-10 18:32:37.035890924 -0800
+@@ -27,9 +27,7 @@
+ extern "C" {
+ #endif /* __cplusplus */
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++#include
+
+ #include
+ #include
+diff -ur cctools-port-c1cc758/cctools/include/stuff/allocate.h cctools-port-private-extern/cctools/include/stuff/allocate.h
+--- cctools-port-c1cc758/cctools/include/stuff/allocate.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/allocate.h 2017-11-10 18:33:52.006780029 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ /* defined in allocate.c */
+
+diff -ur cctools-port-c1cc758/cctools/include/stuff/arch.h cctools-port-private-extern/cctools/include/stuff/arch.h
+--- cctools-port-c1cc758/cctools/include/stuff/arch.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/arch.h 2017-11-10 18:34:36.487305108 -0800
+@@ -23,9 +23,8 @@
+ #ifndef _STUFF_ARCH_H_
+ #define _STUFF_ARCH_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++#include
++
+ /*
+ * This file contains the current known set of flags and constants for the
+ * known architectures.
+diff -ur cctools-port-c1cc758/cctools/include/stuff/best_arch.h cctools-port-private-extern/cctools/include/stuff/best_arch.h
+--- cctools-port-c1cc758/cctools/include/stuff/best_arch.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/best_arch.h 2017-11-10 18:34:48.764116432 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ #include
+ #include
+diff -ur cctools-port-c1cc758/cctools/include/stuff/breakout.h cctools-port-private-extern/cctools/include/stuff/breakout.h
+--- cctools-port-c1cc758/cctools/include/stuff/breakout.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/breakout.h 2017-11-10 18:35:04.334299743 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ #import "stuff/ofile.h"
+
+diff -ur cctools-port-c1cc758/cctools/include/stuff/bytesex.h cctools-port-private-extern/cctools/include/stuff/bytesex.h
+--- cctools-port-c1cc758/cctools/include/stuff/bytesex.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/bytesex.h 2017-11-10 18:35:12.637730768 -0800
+@@ -29,9 +29,7 @@
+ #ifndef _STUFF_BYTESEX_H_
+ #define _STUFF_BYTESEX_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++#include
+
+ #include
+ #include
+diff -ur cctools-port-c1cc758/cctools/include/stuff/execute.h cctools-port-private-extern/cctools/include/stuff/execute.h
+--- cctools-port-c1cc758/cctools/include/stuff/execute.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/execute.h 2017-11-10 18:35:34.417986815 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ /*
+ * execute() does an execvp using the argv passed to it. If the parameter
+diff -ur cctools-port-c1cc758/cctools/include/stuff/guess_short_name.h cctools-port-private-extern/cctools/include/stuff/guess_short_name.h
+--- cctools-port-c1cc758/cctools/include/stuff/guess_short_name.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/guess_short_name.h 2017-11-10 18:40:11.801171715 -0800
+@@ -22,6 +22,8 @@
+ */
+ #include "stuff/bool.h"
+
++#include
++
+ __private_extern__ char * guess_short_name(
+ char *name,
+ enum bool *is_framework,
+diff -ur cctools-port-c1cc758/cctools/include/stuff/hash_string.h cctools-port-private-extern/cctools/include/stuff/hash_string.h
+--- cctools-port-c1cc758/cctools/include/stuff/hash_string.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/hash_string.h 2017-11-10 18:35:43.698095826 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ __private_extern__ int32_t hash_string(
+ char *key);
+diff -ur cctools-port-c1cc758/cctools/include/stuff/hppa.h cctools-port-private-extern/cctools/include/stuff/hppa.h
+--- cctools-port-c1cc758/cctools/include/stuff/hppa.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/hppa.h 2017-11-10 18:36:01.414970472 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ __private_extern__ void calc_hppa_HILO(
+ uint32_t base,
+diff -ur cctools-port-c1cc758/cctools/include/stuff/lto.h cctools-port-private-extern/cctools/include/stuff/lto.h
+--- cctools-port-c1cc758/cctools/include/stuff/lto.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/lto.h 2017-11-10 18:40:27.811342692 -0800
+@@ -3,6 +3,8 @@
+
+ #include "stuff/arch.h"
+
++#include
++
+ #ifdef LTO_SUPPORT
+
+ __private_extern__ int is_llvm_bitcode_from_memory(
+diff -ur cctools-port-c1cc758/cctools/include/stuff/macosx_deployment_target.h cctools-port-private-extern/cctools/include/stuff/macosx_deployment_target.h
+--- cctools-port-c1cc758/cctools/include/stuff/macosx_deployment_target.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/macosx_deployment_target.h 2017-11-10 18:39:47.814249693 -0800
+@@ -22,6 +22,8 @@
+ */
+ #include
+
++#include
++
+ struct macosx_deployment_target {
+ uint32_t major; /* major version */
+ uint32_t minor; /* minor version (if any or zero) */
+diff -ur cctools-port-c1cc758/cctools/include/stuff/ofile.h cctools-port-private-extern/cctools/include/stuff/ofile.h
+--- cctools-port-c1cc758/cctools/include/stuff/ofile.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/ofile.h 2017-11-10 18:36:14.268454589 -0800
+@@ -24,9 +24,7 @@
+ #ifndef _STUFF_OFILE_H_
+ #define _STUFF_OFILE_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++#include
+
+ #import
+ #ifndef AR_EFMT1
+diff -ur cctools-port-c1cc758/cctools/include/stuff/print.h cctools-port-private-extern/cctools/include/stuff/print.h
+--- cctools-port-c1cc758/cctools/include/stuff/print.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/print.h 2017-11-10 18:36:24.805244801 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ #import
+
+diff -ur cctools-port-c1cc758/cctools/include/stuff/reloc.h cctools-port-private-extern/cctools/include/stuff/reloc.h
+--- cctools-port-c1cc758/cctools/include/stuff/reloc.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/reloc.h 2017-11-10 18:36:31.878661041 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ #import
+ #import "stuff/bool.h"
+diff -ur cctools-port-c1cc758/cctools/include/stuff/rnd.h cctools-port-private-extern/cctools/include/stuff/rnd.h
+--- cctools-port-c1cc758/cctools/include/stuff/rnd.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/rnd.h 2017-11-10 18:36:39.068745293 -0800
+@@ -27,9 +27,7 @@
+ */
+ #include
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++#include
+
+ /*
+ * rnd() rounds v to a multiple of r.
+diff -ur cctools-port-c1cc758/cctools/include/stuff/symbol_list.h cctools-port-private-extern/cctools/include/stuff/symbol_list.h
+--- cctools-port-c1cc758/cctools/include/stuff/symbol_list.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/symbol_list.h 2017-11-10 18:37:11.605792928 -0800
+@@ -23,6 +23,8 @@
+ #include
+ #include
+
++#include
++
+ /*
+ * Data structures to perform selective stripping of symbol table entries.
+ */
+diff -ur cctools-port-c1cc758/cctools/include/stuff/unix_standard_mode.h cctools-port-private-extern/cctools/include/stuff/unix_standard_mode.h
+--- cctools-port-c1cc758/cctools/include/stuff/unix_standard_mode.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/unix_standard_mode.h 2017-11-10 18:37:42.596155389 -0800
+@@ -22,5 +22,7 @@
+ */
+ #include "stuff/bool.h"
+
++#include
++
+ __private_extern__ enum bool get_unix_standard_mode(
+ void);
+diff -ur cctools-port-c1cc758/cctools/include/stuff/vm_flush_cache.h cctools-port-private-extern/cctools/include/stuff/vm_flush_cache.h
+--- cctools-port-c1cc758/cctools/include/stuff/vm_flush_cache.h 2017-10-01 13:47:04.000000000 -0700
++++ cctools-port-private-extern/cctools/include/stuff/vm_flush_cache.h 2017-11-10 18:37:59.973025145 -0800
+@@ -20,9 +20,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
+-#define __private_extern__ __declspec(private_extern)
+-#endif
++
++#include
+
+ #import
+ __private_extern__ kern_return_t vm_flush_cache(
diff --git a/nix/nixcrpkgs/macos/clang_builder.sh b/nix/nixcrpkgs/macos/clang_builder.sh
new file mode 100644
index 000000000..2afa96bb9
--- /dev/null
+++ b/nix/nixcrpkgs/macos/clang_builder.sh
@@ -0,0 +1,30 @@
+source $setup
+
+tar -xf $llvm_src
+mv llvm-* llvm
+
+tar -xf $lld_src
+mv lld-* lld
+mv lld llvm/tools/
+
+tar -xf $src
+mv cfe-* clang
+cd clang
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+mv clang llvm/projects/
+
+mkdir build
+cd build
+
+cmake ../llvm -GNinja -DDEFAULT_SYSROOT=$out -DCMAKE_INSTALL_PREFIX=$out $cmake_flags
+
+ninja
+
+ninja install
+
+# clang-tblgen is supposed to be an internal tool, but tapi needs it
+cp bin/clang-tblgen $out/bin
diff --git a/nix/nixcrpkgs/macos/clang_megapatch.patch b/nix/nixcrpkgs/macos/clang_megapatch.patch
new file mode 100644
index 000000000..b5941e2c3
--- /dev/null
+++ b/nix/nixcrpkgs/macos/clang_megapatch.patch
@@ -0,0 +1,37 @@
+diff -ur cfe-5.0.0.src.orig/lib/Driver/ToolChains/Gnu.cpp cfe-5.0.0.src/lib/Driver/ToolChains/Gnu.cpp
+--- cfe-5.0.0.src.orig/lib/Driver/ToolChains/Gnu.cpp 2017-09-13 07:15:52.419093088 -0700
++++ cfe-5.0.0.src/lib/Driver/ToolChains/Gnu.cpp 2017-09-13 07:21:58.892639000 -0700
+@@ -493,10 +493,6 @@
+ CmdArgs.push_back("-export-dynamic");
+
+ if (!Args.hasArg(options::OPT_shared)) {
+- const std::string Loader =
+- D.DyldPrefix + ToolChain.getDynamicLinker(Args);
+- CmdArgs.push_back("-dynamic-linker");
+- CmdArgs.push_back(Args.MakeArgString(Loader));
+ }
+ }
+
+diff -ur cfe-5.0.0.src.orig/lib/Driver/ToolChains/Linux.cpp cfe-5.0.0.src/lib/Driver/ToolChains/Linux.cpp
+--- cfe-5.0.0.src.orig/lib/Driver/ToolChains/Linux.cpp 2017-09-13 07:15:52.419093088 -0700
++++ cfe-5.0.0.src/lib/Driver/ToolChains/Linux.cpp 2017-09-13 07:17:58.530311694 -0700
+@@ -195,18 +195,7 @@
+ llvm::Triple::ArchType Arch = Triple.getArch();
+ std::string SysRoot = computeSysRoot();
+
+- // Cross-compiling binutils and GCC installations (vanilla and openSUSE at
+- // least) put various tools in a triple-prefixed directory off of the parent
+- // of the GCC installation. We use the GCC triple here to ensure that we end
+- // up with tools that support the same amount of cross compiling as the
+- // detected GCC installation. For example, if we find a GCC installation
+- // targeting x86_64, but it is a bi-arch GCC installation, it can also be
+- // used to target i386.
+- // FIXME: This seems unlikely to be Linux-specific.
+- ToolChain::path_list &PPaths = getProgramPaths();
+- PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
+- GCCInstallation.getTriple().str() + "/bin")
+- .str());
++ // Removed some code here that found programs like ld in "/..//bin"
+
+ Distro Distro(D.getVFS());
+
diff --git a/nix/nixcrpkgs/macos/default.nix b/nix/nixcrpkgs/macos/default.nix
new file mode 100644
index 000000000..b90556c3a
--- /dev/null
+++ b/nix/nixcrpkgs/macos/default.nix
@@ -0,0 +1,192 @@
+# Note: To reduce clutter here, it might be nice to move clang to
+# `native`, and also make `native` provide a function for building
+# binutils. So clang and binutils recipes could be shared by the
+# different platforms we targets.
+
+{ osx_sdk, native }:
+let
+ nixpkgs = native.nixpkgs;
+
+ arch = "x86_64";
+
+ # was darwin15, changed to darwin so that lld guesses flavor=Darwin correctly
+ darwin_name = "darwin15";
+
+ macos_version_min = "10.11";
+
+ host = "${arch}-apple-${darwin_name}";
+
+ os = "macos";
+
+ compiler = "clang";
+
+ exe_suffix = "";
+
+ clang = native.make_derivation rec {
+ name = "clang";
+
+ version = "5.0.0";
+
+ src = nixpkgs.fetchurl {
+ url = "https://llvm.org/releases/${version}/cfe-${version}.src.tar.xz";
+ sha256 = "0w09s8fn3lkn6i04nj0cisgp821r815fk5b5fjn97xrd371277q1";
+ };
+
+ llvm_src = nixpkgs.fetchurl {
+ url = "https://llvm.org/releases/${version}/llvm-${version}.src.tar.xz";
+ sha256 = "1nin64vz21hyng6jr19knxipvggaqlkl2l9jpd5czbc4c2pcnpg3";
+ };
+
+ # Note: We aren't actually using lld for anything yet.
+ lld_src = nixpkgs.fetchurl {
+ url = "http://releases.llvm.org/${version}/lld-${version}.src.tar.xz";
+ sha256 = "15rqsmfw0jlsri7hszbs8l0j7v1030cy9xvvdb245397llh7k6ir";
+ };
+
+ patches = [ ./clang_megapatch.patch ];
+
+ builder = ./clang_builder.sh;
+
+ native_inputs = [ nixpkgs.python2 ];
+
+ cmake_flags =
+ "-DCMAKE_BUILD_TYPE=Release " +
+ # "-DCMAKE_BUILD_TYPE=Debug " +
+ "-DLLVM_TARGETS_TO_BUILD=X86\;ARM " +
+ "-DLLVM_ENABLE_RTTI=ON " + # ld64 uses dynamic_cast, requiring rtti
+ "-DLLVM_ENABLE_ASSERTIONS=OFF";
+ };
+
+ # Note: There is an alternative version we could use, but it
+ # has a copy of LLVM in it: https://github.com/tpoechtrager/apple-libtapi
+ tapi = native.make_derivation rec {
+ name = "tapi";
+ version = "${version0}.${version1}.${version2}";
+ version0 = "2";
+ version1 = "0";
+ version2 = "0";
+ src = nixpkgs.fetchurl {
+ url = "https://github.com/DavidEGrayson/tapi/archive/f98d0c3.tar.gz";
+ sha256 = "0jibz0fsyh47q8y3w6f0qspjh6fhs164rkhjg7x6k7qhlawcdy6g";
+ };
+ builder = ./tapi_builder.sh;
+ native_inputs = [ clang ];
+ inherit clang;
+ };
+
+ cctools_commit = "c1cc758";
+ cctools_apple_version = "274.2"; # from README.md
+ cctools_port_src = nixpkgs.fetchurl {
+ url = "https://github.com/tpoechtrager/cctools-port/archive/${cctools_commit}.tar.gz";
+ sha256= "11bfcndzbdmjp2piabyqs34da617fh5fhirqvb9w87anfan15ffa";
+ };
+
+ ld = native.make_derivation rec {
+ name = "cctools-ld64";
+ apple_version = cctools_apple_version;
+ src = cctools_port_src;
+ patches = [
+ ./cctools-format.patch
+ ./cctools-ld64-registers.patch
+ ];
+ builder = ./ld_builder.sh;
+ native_inputs = [ tapi ];
+ inherit host;
+ };
+
+ ranlib = native.make_derivation rec {
+ name = "cctools-ranlib";
+ apple_version = cctools_apple_version;
+ src = ld.src;
+ builder = ./ranlib_builder.sh;
+ patches = [
+ ./cctools-format.patch
+ ./cctools-bytesex.patch
+ ];
+ inherit host;
+ };
+
+ ar = native.make_derivation rec {
+ name = "cctools-ar";
+ apple_version = cctools_apple_version;
+ src = cctools_port_src;
+ builder = ./ar_builder.sh;
+ patches = [
+ ./cctools-format.patch
+ ./cctools-libstuff-no-error.patch
+ ];
+ inherit host ranlib;
+ };
+
+ strip = native.make_derivation rec {
+ name = "cctools-strip";
+ apple_version = cctools_apple_version;
+ src = cctools_port_src;
+ builder = ./strip_builder.sh;
+ patches = [
+ ./cctools-format.patch
+ ];
+ inherit host;
+ };
+
+ # TODO: add instructions for building the SDK tarball, probably want a copy of
+ # the script from osxcross.
+ sdk = native.make_derivation rec {
+ name = "macos-sdk";
+ builder = ./sdk_builder.sh;
+ src = osx_sdk;
+ };
+
+ toolchain = native.make_derivation rec {
+ name = "macos-toolchain";
+ builder = ./toolchain_builder.sh;
+ src_file = ./wrapper.cpp;
+ inherit host clang ld ranlib ar strip sdk;
+
+ CXXFLAGS =
+ "-std=c++11 " +
+ "-Wall " +
+ "-I. " +
+ "-O2 -g " +
+ "-DWRAPPER_OS_VERSION_MIN=\\\"${macos_version_min}\\\" " +
+ "-DWRAPPER_HOST=\\\"${host}\\\" " +
+ "-DWRAPPER_ARCH=\\\"${arch}\\\" " +
+ "-DWRAPPER_SDK_PATH=\\\"${sdk}\\\" " +
+ "-DWRAPPER_LINKER_VERSION=\\\"${ld.apple_version}\\\"";
+ };
+
+ cmake_toolchain = import ../cmake_toolchain {
+ cmake_system_name = "Darwin";
+ inherit nixpkgs host;
+ };
+
+ crossenv = {
+ is_cross = true;
+
+ # Build tools available on the PATH for every derivation.
+ default_native_inputs = native.default_native_inputs
+ ++ [ clang toolchain native.wrappers ];
+
+ # Target info environment variables.
+ inherit host arch os compiler exe_suffix macos_version_min;
+
+ # CMake toolchain file.
+ inherit cmake_toolchain;
+
+ # A wide variety of programs and build tools.
+ inherit nixpkgs;
+
+ # Some native build tools made by nixcrpkgs.
+ inherit native;
+
+ # License information that should be shipped with any software
+ # compiled by this environment.
+ global_license_set = { };
+
+ # Make it easy to build or refer to the build tools.
+ inherit clang tapi ld ranlib ar sdk toolchain;
+
+ make_derivation = import ../make_derivation.nix crossenv;
+ };
+in
+ crossenv
diff --git a/nix/nixcrpkgs/macos/gen_sdk_package.sh b/nix/nixcrpkgs/macos/gen_sdk_package.sh
new file mode 100755
index 000000000..843171ba6
--- /dev/null
+++ b/nix/nixcrpkgs/macos/gen_sdk_package.sh
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+#
+# Package the OS X SDKs into a tar file to be used by `build.sh`.
+#
+
+# This file comes from the osxcross project and is licensed under the GNU GPLv2.
+# For more information, see the `COPYING` file from:
+# https://github.com/tpoechtrager/osxcross/tree/1a1733a773fe26e7b6c93b16fbf9341f22fac831
+
+export LC_ALL=C
+
+function set_xcode_dir()
+{
+ local tmp=$(ls $1 2>/dev/null | grep "^Xcode.*.app" | grep -v "beta" | head -n1)
+
+ if [ -z "$tmp" ]; then
+ tmp=$(ls $1 2>/dev/null | grep "^Xcode.*.app" | head -n1)
+ fi
+
+ if [ -n "$tmp" ]; then
+ XCODEDIR="$1/$tmp"
+ fi
+}
+
+if [ $(uname -s) != "Darwin" ]; then
+ if [ -z "$XCODEDIR" ]; then
+ echo "This script must be run on OS X" 1>&2
+ echo "... Or with XCODEDIR=... on Linux" 1>&2
+ exit 1
+ else
+ case $XCODEDIR in
+ /*) ;;
+ *) XCODEDIR="$PWD/$XCODEDIR" ;;
+ esac
+ set_xcode_dir $XCODEDIR
+ fi
+else
+ set_xcode_dir $(echo /Volumes/Xcode* | tr ' ' '\n' | grep -v "beta" | head -n1)
+
+ if [ -z "$XCODEDIR" ]; then
+ set_xcode_dir /Applications
+
+ if [ -z "$XCODEDIR" ]; then
+ set_xcode_dir $(echo /Volumes/Xcode* | tr ' ' '\n' | head -n1)
+
+ if [ -z "$XCODEDIR" ]; then
+ echo "please mount Xcode.dmg" 1>&2
+ exit 1
+ fi
+ fi
+ fi
+fi
+
+if [ ! -d $XCODEDIR ]; then
+ echo "cannot find Xcode (XCODEDIR=$XCODEDIR)" 1>&2
+ exit 1
+fi
+
+echo -e "found Xcode: $XCODEDIR"
+
+WDIR=$(pwd)
+
+which gnutar &>/dev/null
+
+if [ $? -eq 0 ]; then
+ TAR=gnutar
+else
+ TAR=tar
+fi
+
+which xz &>/dev/null
+
+if [ $? -eq 0 ]; then
+ COMPRESSOR=xz
+ PKGEXT="tar.xz"
+else
+ COMPRESSOR=bzip2
+ PKGEXT="tar.bz2"
+fi
+
+set -e
+
+pushd $XCODEDIR &>/dev/null
+
+if [ -d "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" ]; then
+ pushd "Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" &>/dev/null
+else
+ if [ -d "../Packages" ]; then
+ pushd "../Packages" &>/dev/null
+ elif [ -d "Packages" ]; then
+ pushd "Packages" &>/dev/null
+ else
+ if [ $? -ne 0 ]; then
+ echo "Xcode (or this script) is out of date" 1>&2
+ echo "trying some magic to find the SDKs anyway ..." 1>&2
+
+ SDKDIR=$(find . -name SDKs -type d | grep MacOSX | head -n1)
+
+ if [ -z "$SDKDIR" ]; then
+ echo "cannot find SDKs!" 1>&2
+ exit 1
+ fi
+
+ pushd $SDKDIR &>/dev/null
+ fi
+ fi
+fi
+
+SDKS=$(ls | grep "^MacOSX10.*" | grep -v "Patch")
+
+if [ -z "$SDKS" ]; then
+ echo "No SDK found" 1>&2
+ exit 1
+fi
+
+# Xcode 5
+LIBCXXDIR1="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1"
+
+# Xcode 6
+LIBCXXDIR2="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1"
+
+# Manual directory
+MANDIR="Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/share/man"
+
+for SDK in $SDKS; do
+ echo -n "packaging $(echo "$SDK" | sed -E "s/(.sdk|.pkg)//g") SDK "
+ echo "(this may take several minutes) ..."
+
+ if [[ $SDK == *.pkg ]]; then
+ cp $SDK $WDIR
+ continue
+ fi
+
+ TMP=$(mktemp -d /tmp/XXXXXXXXXXX)
+ cp -r $SDK $TMP &>/dev/null || true
+
+ pushd $XCODEDIR &>/dev/null
+
+ # libc++ headers for C++11/C++14
+ if [ -d $LIBCXXDIR1 ]; then
+ cp -rf $LIBCXXDIR1 "$TMP/$SDK/usr/include/c++"
+ elif [ -d $LIBCXXDIR2 ]; then
+ cp -rf $LIBCXXDIR2 "$TMP/$SDK/usr/include/c++"
+ fi
+
+ if [ -d $MANDIR ]; then
+ mkdir -p $TMP/$SDK/usr/share/man
+ cp -rf $MANDIR/* $TMP/$SDK/usr/share/man
+ fi
+
+ popd &>/dev/null
+
+ pushd $TMP &>/dev/null
+ $TAR -cf - * | $COMPRESSOR -9 -c - > "$WDIR/$SDK.$PKGEXT"
+ popd &>/dev/null
+
+ rm -rf $TMP
+done
+
+popd &>/dev/null
+popd &>/dev/null
+
+echo ""
+ls -lh | grep MacOSX
diff --git a/nix/nixcrpkgs/macos/ld_builder.sh b/nix/nixcrpkgs/macos/ld_builder.sh
new file mode 100644
index 000000000..29453d31c
--- /dev/null
+++ b/nix/nixcrpkgs/macos/ld_builder.sh
@@ -0,0 +1,45 @@
+source $setup
+
+tar -xf $src
+mv cctools-port-* cctools-port
+
+cd cctools-port
+
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+
+# Similar to but not the same as the other _structs.h.
+rm cctools/include/foreign/mach/i386/_structs.h
+
+cd ..
+
+mv cctools-port/cctools/ld64 ld64
+mv cctools-port/cctools/include include
+rm -r cctools-port
+rm -r ld64/src/other
+
+mkdir build
+cd build
+
+CFLAGS="-Wno-deprecated -Wno-deprecated-declarations -Wno-unused-result -Werror -Wfatal-errors -O2 -g -I../ld64/src -I../ld64/src/ld -I../ld64/src/ld/parsers -I../ld64/src/abstraction -I../ld64/src/3rd -I../ld64/src/3rd/include -I../ld64/src/3rd/BlocksRuntime -I../include -I../include/foreign -DTAPI_SUPPORT -DPROGRAM_PREFIX=\\\"$host-\\\" -D__LITTLE_ENDIAN__ -D__private_extern__= $(pkg-config --cflags libtapi)"
+
+CXXFLAGS="-std=gnu++11 $CFLAGS"
+
+LDFLAGS="$(pkg-config --libs libtapi) -ldl -lpthread"
+
+for f in ../ld64/src/ld/*.c ../ld64/src/3rd/*.c; do
+ echo "compiling $f"
+ eval "gcc -c $CFLAGS $f -o $(basename $f).o"
+done
+
+for f in $(find ../ld64/src -name \*.cpp); do
+ echo "compiling $f"
+ eval "g++ -c $CXXFLAGS $f -o $(basename $f).o"
+done
+
+g++ *.o $LDFLAGS -o $host-ld
+
+mkdir -p $out/bin
+cp $host-ld $out/bin
diff --git a/nix/nixcrpkgs/macos/ranlib_builder.sh b/nix/nixcrpkgs/macos/ranlib_builder.sh
new file mode 100644
index 000000000..15c0bd206
--- /dev/null
+++ b/nix/nixcrpkgs/macos/ranlib_builder.sh
@@ -0,0 +1,45 @@
+source $setup
+
+tar -xf $src
+mv cctools-port-* cctools-port
+
+cd cctools-port
+
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+
+# Similar to but not the same as the other _structs.h.
+rm cctools/include/foreign/mach/i386/_structs.h
+
+# Causes a troublesome undefined reference.
+rm cctools/libstuff/vm_flush_cache.c
+
+cd ..
+
+mv cctools-port/cctools/misc .
+mv cctools-port/cctools/include .
+mv cctools-port/cctools/libstuff .
+rm -r cctools-port
+
+mkdir build
+cd build
+
+CFLAGS="-Wno-deprecated -Wno-deprecated-declarations -Wno-unused-result -Wno-format-overflow -Werror -Wfatal-errors -O2 -g -I../include -I../include/foreign -DPROGRAM_PREFIX=\\\"$host-\\\" -D__LITTLE_ENDIAN__ -D__private_extern__= -D__DARWIN_UNIX03 -DPACKAGE_NAME=\\\"cctools\\\" -DPACKAGE_VERSION=\\\"$apple_version\\\" -DEMULATED_HOST_CPU_TYPE=16777223 -DEMULATED_HOST_CPU_SUBTYPE=3"
+
+CXXFLAGS="-std=gnu++11 $CFLAGS"
+
+LDFLAGS="-ldl"
+
+for f in ../libstuff/*.c ; do
+ echo "compiling $f"
+ eval "gcc -c $CFLAGS $f -o $(basename $f).o"
+done
+
+eval "gcc $CFLAGS ../misc/libtool.c *.o $LDFLAGS -o $host-libtool"
+eval "gcc $CFLAGS -DRANLIB ../misc/libtool.c *.o $LDFLAGS -o $host-ranlib"
+
+mkdir -p $out/bin
+cp $host-libtool $host-ranlib $out/bin/
+
diff --git a/nix/nixcrpkgs/macos/sdk_builder.sh b/nix/nixcrpkgs/macos/sdk_builder.sh
new file mode 100644
index 000000000..8a0f872e0
--- /dev/null
+++ b/nix/nixcrpkgs/macos/sdk_builder.sh
@@ -0,0 +1,4 @@
+source $setup
+
+tar -xf $src
+mv MacOSX*.sdk $out
diff --git a/nix/nixcrpkgs/macos/strip_builder.sh b/nix/nixcrpkgs/macos/strip_builder.sh
new file mode 100644
index 000000000..e69a12949
--- /dev/null
+++ b/nix/nixcrpkgs/macos/strip_builder.sh
@@ -0,0 +1,43 @@
+source $setup
+
+tar -xf $src
+mv cctools-port-* cctools-port
+
+cd cctools-port
+
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+
+# Similar to but not the same as the other _structs.h.
+rm cctools/include/foreign/mach/i386/_structs.h
+
+# Causes a troublesome undefined reference.
+rm cctools/libstuff/vm_flush_cache.c
+
+cd ..
+
+mv cctools-port/cctools/misc .
+mv cctools-port/cctools/include .
+mv cctools-port/cctools/libstuff .
+rm -r cctools-port
+
+mkdir build
+cd build
+
+CFLAGS="-Wno-deprecated -Wno-deprecated-declarations -Wno-unused-result -Werror -Wfatal-errors -O2 -g -I../include -I../include/foreign -DPROGRAM_PREFIX=\\\"$host-\\\" -D__LITTLE_ENDIAN__ -D__private_extern__= -D__DARWIN_UNIX03 -DPACKAGE_NAME=\\\"cctools\\\" -DPACKAGE_VERSION=\\\"$apple_version\\\" -DEMULATED_HOST_CPU_TYPE=16777223 -DEMULATED_HOST_CPU_SUBTYPE=3"
+
+CXXFLAGS="-std=gnu++11 $CFLAGS"
+
+LDFLAGS="-ldl -lpthread"
+
+for f in ../misc/strip.c ../libstuff/*.c; do
+ echo "compiling $f"
+ eval "gcc -c $CFLAGS $f -o $(basename $f).o"
+done
+
+gcc *.o $LDFLAGS -o $host-strip
+
+mkdir -p $out/bin
+cp $host-strip $out/bin/
diff --git a/nix/nixcrpkgs/macos/tapi_builder.sh b/nix/nixcrpkgs/macos/tapi_builder.sh
new file mode 100644
index 000000000..d8c15a6a1
--- /dev/null
+++ b/nix/nixcrpkgs/macos/tapi_builder.sh
@@ -0,0 +1,80 @@
+source $setup
+
+tar -xf $src
+mv tapi-* tapi
+
+mkdir build
+cd build
+
+mkdir -p include/tapi/{Core,Driver}
+cat > include/tapi/Core/ArchitectureConfig.h < include/tapi/Version.inc < $out/lib/pkgconfig/libtapi.pc <
+#include
+#include
+#include
+#include
+#include
+
+int do_exec(const std::string & compiler_name,
+ const std::vector & args)
+{
+ char ** exec_args = new char *[args.size() + 1];
+ size_t i = 0;
+ for (const std::string & arg : args)
+ {
+ exec_args[i++] = (char *)arg.c_str();
+ }
+ exec_args[i] = nullptr;
+
+ execvp(compiler_name.c_str(), exec_args);
+
+ int result = errno;
+ std::cerr << "execvp failed: " << compiler_name << ": "
+ << strerror(result) << std::endl;
+ return 1;
+}
+
+int compiler_main(int argc, char ** argv,
+ const std::string & compiler_name)
+{
+ std::vector args;
+
+ args.push_back(compiler_name);
+
+ args.push_back("-target");
+ args.push_back(WRAPPER_HOST);
+
+ args.push_back("-mmacosx-version-min=" WRAPPER_OS_VERSION_MIN);
+
+ // The ld64 linker will just assume sdk_version is the same as
+ // macosx-version-min if we don't supply it. That probably will not
+ // do any harm.
+ // args.push_back("-Wl,-sdk_version," WRAPPER_SDK_VERSION);
+
+ // Suppress warnings about the -Wl arguments not being used when we're just
+ // compiling and not linking.
+ args.push_back("-Wno-unused-command-line-argument");
+
+ args.push_back("--sysroot");
+ args.push_back(WRAPPER_SDK_PATH);
+
+ // Causes clang to pass -demangle, -lto_library, -no_deduplicate, and other
+ // options that could be useful. Version 274.2 is the version number used here:
+ // https://github.com/tpoechtrager/osxcross/blob/474f359/build.sh#L140
+ if (WRAPPER_LINKER_VERSION[0])
+ {
+ args.push_back("-mlinker-version=" WRAPPER_LINKER_VERSION);
+ }
+
+ if (compiler_name == "clang++")
+ {
+ args.push_back("-stdlib=libc++");
+ args.push_back("-cxx-isystem");
+ args.push_back(WRAPPER_SDK_PATH "/usr/include/c++/v1");
+ }
+
+ for (int i = 1; i < argc; ++i)
+ {
+ args.push_back(argv[i]);
+ }
+
+ return do_exec(compiler_name, args);
+}
+
+int c_compiler_main(int argc, char ** argv)
+{
+ return compiler_main(argc, argv, "clang");
+}
+
+int cxx_compiler_main(int argc, char ** argv)
+{
+ return compiler_main(argc, argv, "clang++");
+}
+
+int wrapper_main(int argc, char ** argv)
+{
+ std::cout <<
+ "host: " WRAPPER_HOST "\n"
+ "path: " WRAPPER_PATH "\n"
+ "sdk_path: " WRAPPER_SDK_PATH "\n";
+ return 0;
+}
+
+struct {
+ const char * name;
+ int (*main_func)(int argc, char ** argv);
+} prgms[] = {
+ { WRAPPER_HOST "-gcc", c_compiler_main },
+ { WRAPPER_HOST "-cc", c_compiler_main },
+ { WRAPPER_HOST "-clang", c_compiler_main },
+ { WRAPPER_HOST "-g++", cxx_compiler_main },
+ { WRAPPER_HOST "-c++", cxx_compiler_main },
+ { WRAPPER_HOST "-clang++", cxx_compiler_main },
+ { WRAPPER_HOST "-wrapper", wrapper_main },
+ { nullptr, nullptr },
+};
+
+const char * get_program_name(const char * path)
+{
+ const char * p = strrchr(path, '/');
+ if (p) { path = p + 1; }
+ return path;
+}
+
+int main(int argc, char ** argv)
+{
+ // We only want this wrapper and the compiler it invokes to access a certain
+ // set of tools that are determined at build time. Ignore whatever is on the
+ // user's path and use the path specified by our Nix expression instead.
+ int result = setenv("PATH", WRAPPER_PATH, 1);
+ if (result)
+ {
+ std::cerr << "wrapper failed to set PATH" << std::endl;
+ return 1;
+ }
+
+ std::string program_name = get_program_name(argv[0]);
+
+ for (auto * p = prgms; p->name; p++)
+ {
+ if (program_name == p->name)
+ {
+ return p->main_func(argc, argv);
+ }
+ }
+
+ std::cerr << "compiler wrapper invoked with unknown program name: "
+ << argv[0] << std::endl;
+ return 1;
+}
diff --git a/nix/nixcrpkgs/make_derivation.nix b/nix/nixcrpkgs/make_derivation.nix
new file mode 100644
index 000000000..af74ee91f
--- /dev/null
+++ b/nix/nixcrpkgs/make_derivation.nix
@@ -0,0 +1,91 @@
+env: attrs:
+
+let
+ nixpkgs = env.nixpkgs;
+
+ native_inputs =
+ (attrs.native_inputs or [])
+ ++ env.default_native_inputs;
+
+ cross_inputs = (attrs.cross_inputs or []);
+
+ path_join = builtins.concatStringsSep ":";
+
+ path_map = dir: inputs: (map (i: "${i}" + dir) inputs);
+
+ # We can't just set PATH in our derivation because nix-shell will make the
+ # derivation's PATH override the system PATH, meaning we can't use utilities
+ # like "git" or "which" form the host system. So we set _PATH instead, and we
+ # use a setup script ($setup) that copies _PATH to PATH. And we provide
+ # $stdenv/setup so that nix-shell can find our setup script.
+ #
+ # nixcrpkgs does not expose its users to this mess. The user can specify a
+ # PATH if they want, and it will be automatically moved to _PATH in the
+ # derivation.
+ filtered_attrs = nixpkgs.lib.filterAttrs (n: v: n != "PATH") attrs;
+
+ path_attrs = {
+ _PATH = path_join (
+ (if attrs ? PATH then [attrs.PATH] else []) ++
+ (path_map "/bin" native_inputs)
+ );
+ };
+
+ default_attrs = {
+ system = builtins.currentSystem;
+
+ SHELL = "${nixpkgs.bashInteractive}/bin/bash";
+
+ setup = ./pretend_stdenv/setup;
+
+ # This allows nix-shell to find our setup script.
+ stdenv = ./pretend_stdenv;
+
+ PKG_CONFIG_PATH = path_join (
+ (if attrs ? PKG_CONFIG_PATH then [attrs.PKG_CONFIG_PATH] else []) ++
+ (path_map "/lib/pkgconfig" native_inputs)
+ );
+ };
+
+ cross_attrs = if !env.is_cross then {} else {
+ NIXCRPKGS = true;
+
+ inherit (env) host arch os exe_suffix;
+ inherit (env) cmake_toolchain;
+
+ PKG_CONFIG_CROSS_PATH = path_join (
+ (if attrs ? PKG_CONFIG_CROSS_PATH then [attrs.PKG_CONFIG_CROSS_PATH] else []) ++
+ (path_map "/lib/pkgconfig" cross_inputs)
+ );
+
+ CMAKE_CROSS_PREFIX_PATH = path_join (
+ (if attrs ? CMAKE_CROSS_PREFIX_PATH then [attrs.CMAKE_CROSS_PREFIX_PATH] else []) ++
+ cross_inputs
+ );
+ };
+
+ name_attrs = {
+ name = (attrs.name or "package")
+ + (if env.is_cross then "-${env.host}" else "");
+ };
+
+ builder_attrs =
+ if builtins.isAttrs attrs.builder then
+ if attrs.builder ? ruby then
+ {
+ builder = "${nixpkgs.ruby}/bin/ruby";
+ args = [attrs.builder.ruby];
+ }
+ else
+ attrs.builder
+ else
+ rec {
+ builder = "${nixpkgs.bashInteractive}/bin/bash";
+ args = ["-ue" attrs.builder];
+ };
+
+ drv_attrs = default_attrs // cross_attrs
+ // filtered_attrs // name_attrs // builder_attrs // path_attrs;
+
+in
+ derivation drv_attrs
diff --git a/nix/nixcrpkgs/mingw-w64/binutils/builder.sh b/nix/nixcrpkgs/mingw-w64/binutils/builder.sh
new file mode 100644
index 000000000..8795ea0ce
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/binutils/builder.sh
@@ -0,0 +1,26 @@
+source $stdenv/setup
+
+unset CC CXX CFLAGS LDFLAGS LD AR AS RANLIB SIZE STRINGS NM STRIP OBJCOPY
+
+tar -xf $src
+
+cd binutils-$version
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+
+# Clear the default library search path (noSysDirs)
+echo 'NATIVE_LIB_DIRS=' >> ld/configure.tgt
+
+cd ..
+
+mkdir build
+cd build
+
+../binutils-$version/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
diff --git a/nix/nixcrpkgs/mingw-w64/binutils/default.nix b/nix/nixcrpkgs/mingw-w64/binutils/default.nix
new file mode 100644
index 000000000..1a52fd226
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/binutils/default.nix
@@ -0,0 +1,26 @@
+{ native, host }:
+
+native.make_derivation rec {
+ name = "binutils-${version}-${host}";
+
+ version = "2.27";
+
+ src = native.nixpkgs.fetchurl {
+ url = "mirror://gnu/binutils/binutils-${version}.tar.bz2";
+ sha256 = "125clslv17xh1sab74343fg6v31msavpmaa1c1394zsqa773g5rn";
+ };
+
+ patches = [
+ ./deterministic.patch
+ ];
+
+ build_inputs = [ native.nixpkgs.bison native.nixpkgs.zlib ];
+
+ configure_flags =
+ "--target=${host} " +
+ "--enable-shared " +
+ "--enable-deterministic-archives " +
+ "--disable-werror ";
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/mingw-w64/binutils/deterministic.patch b/nix/nixcrpkgs/mingw-w64/binutils/deterministic.patch
new file mode 100644
index 000000000..0a264b35c
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/binutils/deterministic.patch
@@ -0,0 +1,12 @@
+Make binutils output deterministic by default.
+--- orig/ld/ldlang.c
++++ new/ld/ldlang.c
+@@ -3095,6 +3095,8 @@
+ ldfile_output_machine))
+ einfo (_("%P%F:%s: can not set architecture: %E\n"), name);
+
++ link_info.output_bfd->flags |= BFD_DETERMINISTIC_OUTPUT;
++
+ link_info.hash = bfd_link_hash_table_create (link_info.output_bfd);
+ if (link_info.hash == NULL)
+ einfo (_("%P%F: can not create hash table: %E\n"));
diff --git a/nix/nixcrpkgs/mingw-w64/builder.sh b/nix/nixcrpkgs/mingw-w64/builder.sh
new file mode 100644
index 000000000..65c9e68e3
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/builder.sh
@@ -0,0 +1,35 @@
+source $setup
+
+cp -r $src mingw-w64
+chmod -R u+w mingw-w64
+
+cd mingw-w64
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+if [ -n "$just_headers" ]; then
+ mkdir build_headers
+ cd build_headers
+ ../mingw-w64/mingw-w64-headers/configure --prefix=$out $configure_flags
+ make
+ make install
+ cd ..
+else
+ mkdir build_crt_and_headers
+ cd build_crt_and_headers
+ ../mingw-w64/configure --prefix=$out $configure_flags
+ make
+ make install
+ cd ..
+
+ mkdir build_winpthreads
+ cd build_winpthreads
+ LDFLAGS="-L${out}/lib" ../mingw-w64/mingw-w64-libraries/winpthreads/configure \
+ --host=$host --prefix=$out --disable-shared --enable-static
+ make
+ make install
+ cd ..
+fi
diff --git a/nix/nixcrpkgs/mingw-w64/default.nix b/nix/nixcrpkgs/mingw-w64/default.nix
new file mode 100644
index 000000000..691c27154
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/default.nix
@@ -0,0 +1,106 @@
+{ native, arch }:
+
+let
+ nixpkgs = native.nixpkgs;
+
+ host = "${arch}-w64-mingw32";
+
+ binutils = import ./binutils { inherit native host; };
+
+ mingw-w64_info = rec {
+ name = "mingw-w64-${version}";
+ version = "2017-08-03";
+ src = nixpkgs.fetchgit {
+ url = "git://git.code.sf.net/p/mingw-w64/mingw-w64";
+ rev = "6de0055f99ed447ec63c1a650a3830f266a808bd";
+ sha256 = "1830rcd0vsbvpr5m1lrabcqh12qrw1flq333b8xrs5b3n542xy2i";
+ };
+ patches = [
+ ./usb.patch
+ ./guid-selectany.patch
+ ];
+ configure_flags = "--enable-secure-api --enable-idl";
+ };
+
+ mingw-w64_headers = native.make_derivation {
+ name = "${mingw-w64_info.name}-headers";
+ inherit host;
+ inherit (mingw-w64_info) src patches configure_flags;
+ builder = ./builder.sh;
+ just_headers = true;
+ };
+
+ gcc_stage_1 = import ./gcc {
+ stage = 1;
+ libc = mingw-w64_headers;
+ inherit native arch binutils;
+ };
+
+ mingw-w64_full = native.make_derivation {
+ name = "${mingw-w64_info.name}-${host}";
+ inherit host;
+ inherit (mingw-w64_info) version src patches;
+ configure_flags =
+ "--host=${host} " +
+ "--disable-shared --enable-static " +
+ mingw-w64_info.configure_flags;
+ native_inputs = [ binutils gcc_stage_1 ];
+ builder = ./builder.sh;
+ just_headers = false;
+ };
+
+ gcc = import ./gcc {
+ libc = mingw-w64_full;
+ inherit native arch binutils;
+ };
+
+ license = native.make_derivation {
+ name = "${mingw-w64_info.name}-license";
+ inherit (mingw-w64_info) version src;
+ gcc_src = gcc.src;
+ builder = ./license_builder.sh;
+ };
+
+ global_license_set = { _global = license; };
+
+ cmake_toolchain = import ../cmake_toolchain {
+ cmake_system_name = "Windows";
+ inherit nixpkgs host;
+ };
+
+ os = "windows";
+
+ compiler = "gcc";
+
+ exe_suffix = ".exe";
+
+ crossenv = {
+ is_cross = true;
+
+ default_native_inputs = native.default_native_inputs
+ ++ [ gcc binutils native.pkgconf native.wrappers ];
+
+ # Target info variables.
+ inherit host arch os compiler exe_suffix;
+
+ # CMake toolchain file.
+ inherit cmake_toolchain;
+
+ # A wide variety of programs and build tools.
+ inherit nixpkgs;
+
+ # Some native build tools made by nixcrpkgs.
+ inherit native;
+
+ # License information that should be shipped with any software compiled by
+ # this environment.
+ inherit global_license_set;
+
+ # Make it easy to build or refer to the build tools.
+ inherit gcc binutils mingw-w64_full mingw-w64_info mingw-w64_headers gcc_stage_1;
+ mingw-w64 = mingw-w64_full;
+
+ make_derivation = import ../make_derivation.nix crossenv;
+ };
+in
+ crossenv
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/builder.sh b/nix/nixcrpkgs/mingw-w64/gcc/builder.sh
new file mode 100644
index 000000000..ae8462f8d
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/builder.sh
@@ -0,0 +1,63 @@
+source $setup
+
+tar -xf $src
+
+cd gcc-$version
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+
+# Prevents a name collision with mingw-w64 headers.
+# See: https://gcc.gnu.org/ml/gcc-help/2017-05/msg00121.html
+cd libstdc++-v3
+sed -i 's/\b__in\b/___in/g' \
+ include/ext/random.tcc \
+ include/ext/vstring.tcc \
+ include/std/utility \
+ include/std/tuple \
+ include/std/istream \
+ include/tr2/bool_set.tcc \
+ include/tr2/bool_set \
+ include/bits/basic_string.h \
+ include/bits/basic_string.tcc \
+ include/bits/locale_facets.h \
+ include/bits/istream.tcc \
+ include/tr1/utility \
+ include/tr1/tuple
+sed -i 's/\b__out\b/___out/g' \
+ include/ext/random.tcc \
+ include/ext/algorithm \
+ include/ext/pb_ds/detail/debug_map_base.hpp \
+ include/std/ostream \
+ include/std/thread \
+ include/tr2/bool_set \
+ include/bits/ostream.tcc \
+ include/bits/regex.tcc \
+ include/bits/stl_algo.h \
+ include/bits/locale_conv.h \
+ include/bits/regex.h \
+ include/bits/ostream_insert.h \
+ include/tr1/regex \
+ include/parallel/algo.h \
+ include/parallel/set_operations.h \
+ include/parallel/multiway_merge.h \
+ include/parallel/unique_copy.h \
+ include/experimental/algorithm \
+ config/locale/dragonfly/c_locale.h \
+ config/locale/generic/c_locale.h \
+ config/locale/gnu/c_locale.h
+
+cd ../..
+
+mkdir build
+cd build
+
+../gcc-$version/configure --prefix=$out $configure_flags
+
+make $make_flags
+
+make $install_targets
+
+# Remove "install-tools" so we don't have a reference to bash.
+rm -r "$out/libexec/gcc/$target/$version/install-tools/"
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/cppdefault.patch b/nix/nixcrpkgs/mingw-w64/gcc/cppdefault.patch
new file mode 100644
index 000000000..adc979e68
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/cppdefault.patch
@@ -0,0 +1,35 @@
+cppdefault.c If CROSS_DIRECTORY_STRUCTURE is defined, don't use the native
+system header dir; use CROSS_INCLUDE_DIR instead if it is defined.
+
+This just makes GCC's behavior match the documentation for the
+"--with-sysroot" configure option, which corresponds to
+TARGET_SYSTEM_ROOT. The documentation says that if you specify
+directories with --with-sysroot and --with-native-system-header-dir,
+then the compilter will concatenate the the two together (with the
+sysroot coming first) and search that directory instead of the default
+/usr/include.
+
+The concatenation is done with this line in configure.ac:
+
+ CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$${sysroot_headers_suffix}$(NATIVE_SYSTEM_HEADER_DIR)'
+
+Then Makefile.in sets the preprocessor macro CROSS_INCLUDE_DIR equal to
+CROSS_SYSTEM_HEADER_DIR.
+
+This patch reverts one of the changes from Daniel Jacobowitz on 2013-02-13.
+https://github.com/gcc-mirror/gcc/commit/17acc97af91fbd116659301b0b7d4965ecc1631d
+
+--- gcc-5.4.0/gcc/cppdefault.c
++++ gcc-5.4.0/gcc/cppdefault.c
+@@ -28,9 +28,9 @@
+ #define NATIVE_SYSTEM_HEADER_COMPONENT 0
+ #endif
+
+-#if defined (CROSS_DIRECTORY_STRUCTURE) && !defined (TARGET_SYSTEM_ROOT)
++#if defined (CROSS_DIRECTORY_STRUCTURE)
+ # undef LOCAL_INCLUDE_DIR
+ # undef NATIVE_SYSTEM_HEADER_DIR
+ #else
+ # undef CROSS_INCLUDE_DIR
+ #endif
+
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/default.nix b/nix/nixcrpkgs/mingw-w64/gcc/default.nix
new file mode 100644
index 000000000..8a5a46b7b
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/default.nix
@@ -0,0 +1,103 @@
+{ native, arch, stage ? 2, binutils, libc }:
+
+let
+ nixpkgs = native.nixpkgs;
+ isl = nixpkgs.isl_0_14;
+ inherit (nixpkgs) stdenv lib fetchurl;
+ inherit (nixpkgs) gettext gmp libmpc libelf mpfr texinfo which zlib;
+
+ stageName = if stage == 1 then "-stage1"
+ else assert stage == 2; "";
+in
+
+native.make_derivation rec {
+ name = "gcc-${version}-${target}${stageName}";
+
+ target = "${arch}-w64-mingw32";
+
+ version = "6.3.0";
+
+ src = fetchurl {
+ url = "mirror://gnu/gcc/gcc-${version}/gcc-${version}.tar.bz2";
+ sha256 = "17xjz30jb65hcf714vn9gcxvrrji8j20xm7n33qg1ywhyzryfsph";
+ };
+
+ builder = ./builder.sh;
+
+ patches = [
+ # TODO: combine three of these patches into one called search-dirs.patch
+ ./mingw-search-paths.patch
+ ./use-source-date-epoch.patch
+ ./libstdc++-target.patch
+ ./no-sys-dirs.patch
+ ./cppdefault.patch
+
+ # Fix a compiler error in GCC's ubsan.c: ISO C++ forbids comparison
+ # between pointer and integer.
+ ./ubsan.patch
+ ];
+
+ # TODO: can probably remove libelf here, and might as well remove
+ # the libraries that are given to GCC as configure flags
+ # TODO: just let GCC use its own gettext (intl)
+ native_inputs = [
+ binutils gettext libelf texinfo which zlib
+ ];
+
+ configure_flags =
+ "--target=${arch}-w64-mingw32 " +
+ "--with-sysroot=${libc} " +
+ "--with-native-system-header-dir=/include " +
+ "--with-gnu-as " +
+ "--with-gnu-ld " +
+ "--with-as=${binutils}/bin/${arch}-w64-mingw32-as " +
+ "--with-ld=${binutils}/bin/${arch}-w64-mingw32-ld " +
+ "--with-isl=${isl} " +
+ "--with-gmp-include=${gmp.dev}/include " +
+ "--with-gmp-lib=${gmp.out}/lib " +
+ "--with-mpfr-include=${mpfr.dev}/include " +
+ "--with-mpfr-lib=${mpfr.out}/lib " +
+ "--with-mpc=${libmpc} " +
+ "--with-zlib-include=${zlib.dev}/include " +
+ "--with-zlib-lib=${zlib.out}/lib " +
+ "--enable-lto " +
+ "--enable-plugin " +
+ "--enable-static " +
+ "--enable-sjlj-exceptions " +
+ "--enable-__cxa_atexit " +
+ "--enable-long-long " +
+ "--with-dwarf2 " +
+ "--enable-fully-dynamic-string " +
+ (if stage == 1 then
+ "--enable-languages=c " +
+ "--enable-threads=win32 "
+ else
+ "--enable-languages=c,c++ " +
+ "--enable-threads=posix "
+ ) +
+ "--without-included-gettext " +
+ "--disable-libstdcxx-pch " +
+ "--disable-nls " +
+ "--disable-shared " +
+ "--disable-multilib " +
+ "--disable-libssp " +
+ "--disable-win32-registry " +
+ "--disable-bootstrap"; # TODO: not needed, --disable-bootstrap
+ # only applies to native builds
+
+ make_flags =
+ if stage == 1 then
+ ["all-gcc" "all-target-libgcc"]
+ else
+ [];
+
+ install_targets =
+ if stage == 1 then
+ ["install-gcc install-target-libgcc"]
+ else
+ ["install-strip"];
+
+ hardeningDisable = [ "format" ];
+}
+
+# TODO: why is GCC providing a fixed limits.h?
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/libstdc++-target.patch b/nix/nixcrpkgs/mingw-w64/gcc/libstdc++-target.patch
new file mode 100644
index 000000000..fb622b395
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/libstdc++-target.patch
@@ -0,0 +1,32 @@
+Patch to make the target libraries 'configure' scripts find the proper CPP.
+I noticed that building the mingw32 cross compiler.
+Looking at the build script for mingw in archlinux, I think that only nixos
+needs this patch. I don't know why.
+diff --git a/Makefile.in b/Makefile.in
+index 93f66b6..d691917 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -266,6 +266,7 @@ BASE_TARGET_EXPORTS = \
+ AR="$(AR_FOR_TARGET)"; export AR; \
+ AS="$(COMPILER_AS_FOR_TARGET)"; export AS; \
+ CC="$(CC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CC; \
++ CPP="$(CC_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CC; \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CONFIG_SHELL="$(SHELL)"; export CONFIG_SHELL; \
+ CPPFLAGS="$(CPPFLAGS_FOR_TARGET)"; export CPPFLAGS; \
+@@ -291,11 +292,13 @@ BASE_TARGET_EXPORTS = \
+ RAW_CXX_TARGET_EXPORTS = \
+ $(BASE_TARGET_EXPORTS) \
+ CXX_FOR_TARGET="$(RAW_CXX_FOR_TARGET)"; export CXX_FOR_TARGET; \
+- CXX="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX;
++ CXX="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX; \
++ CXXCPP="$(RAW_CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CXX;
+
+ NORMAL_TARGET_EXPORTS = \
+ $(BASE_TARGET_EXPORTS) \
+- CXX="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX;
++ CXX="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS"; export CXX; \
++ CXXCPP="$(CXX_FOR_TARGET) $(XGCC_FLAGS_FOR_TARGET) $$TFLAGS -E"; export CXX;
+
+ # Where to find GMP
+ HOST_GMPLIBS = @gmplibs@
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/mingw-search-paths.patch b/nix/nixcrpkgs/mingw-w64/gcc/mingw-search-paths.patch
new file mode 100644
index 000000000..c79730e10
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/mingw-search-paths.patch
@@ -0,0 +1,14 @@
+Make it so GCC does not force us to have a "mingw" symlink.
+
+--- gcc-6.3.0-orig/gcc/config/i386/mingw32.h
++++ gcc-6.3.0/gcc/config/i386/mingw32.h
+@@ -163,3 +163,3 @@
+ #ifndef STANDARD_STARTFILE_PREFIX_1
+-#define STANDARD_STARTFILE_PREFIX_1 "/mingw/lib/"
++#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
+ #endif
+@@ -172,3 +172,3 @@
+ #undef NATIVE_SYSTEM_HEADER_DIR
+-#define NATIVE_SYSTEM_HEADER_DIR "/mingw/include"
++#define NATIVE_SYSTEM_HEADER_DIR "/include"
+
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/no-sys-dirs.patch b/nix/nixcrpkgs/mingw-w64/gcc/no-sys-dirs.patch
new file mode 100644
index 000000000..36df51904
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/no-sys-dirs.patch
@@ -0,0 +1,28 @@
+diff -ru -x '*~' gcc-4.8.3-orig/gcc/cppdefault.c gcc-4.8.3/gcc/cppdefault.c
+--- gcc-4.8.3-orig/gcc/cppdefault.c 2013-01-10 21:38:27.000000000 +0100
++++ gcc-4.8.3/gcc/cppdefault.c 2014-08-18 16:20:32.893944536 +0200
+@@ -35,6 +35,8 @@
+ # undef CROSS_INCLUDE_DIR
+ #endif
+
++#undef LOCAL_INCLUDE_DIR
++
+ const struct default_include cpp_include_defaults[]
+ #ifdef INCLUDE_DEFAULTS
+ = INCLUDE_DEFAULTS;
+diff -ru -x '*~' gcc-4.8.3-orig/gcc/gcc.c gcc-4.8.3/gcc/gcc.c
+--- gcc-4.8.3-orig/gcc/gcc.c 2014-03-23 12:30:57.000000000 +0100
++++ gcc-4.8.3/gcc/gcc.c 2014-08-18 13:19:32.689201690 +0200
+@@ -1162,10 +1162,10 @@
+ /* Default prefixes to attach to command names. */
+
+ #ifndef STANDARD_STARTFILE_PREFIX_1
+-#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
++#define STANDARD_STARTFILE_PREFIX_1 ""
+ #endif
+ #ifndef STANDARD_STARTFILE_PREFIX_2
+-#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
++#define STANDARD_STARTFILE_PREFIX_2 ""
+ #endif
+
+ #ifdef CROSS_DIRECTORY_STRUCTURE /* Don't use these prefixes for a cross compiler. */
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/ubsan.patch b/nix/nixcrpkgs/mingw-w64/gcc/ubsan.patch
new file mode 100644
index 000000000..0ad3b7991
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/ubsan.patch
@@ -0,0 +1,10 @@
+--- gcc-6.3.0-orig/gcc/ubsan.c
++++ gcc-6.3.0/gcc/ubsan.c
+@@ -1471,7 +1471,7 @@
+
+ expanded_location xloc = expand_location (loc);
+ if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0
+- || xloc.file == '\0' || xloc.file[0] == '\xff'
++ || xloc.file == NULL || xloc.file[0] == '\xff'
+ || xloc.file[1] == '\xff')
+ return false;
diff --git a/nix/nixcrpkgs/mingw-w64/gcc/use-source-date-epoch.patch b/nix/nixcrpkgs/mingw-w64/gcc/use-source-date-epoch.patch
new file mode 100644
index 000000000..65a5ab028
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/gcc/use-source-date-epoch.patch
@@ -0,0 +1,52 @@
+https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02210.html
+
+diff --git a/libcpp/macro.c b/libcpp/macro.c
+index 1e0a0b5..a52e3cb 100644
+--- a/libcpp/macro.c
++++ b/libcpp/macro.c
+@@ -349,14 +349,38 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
+ slow on some systems. */
+ time_t tt;
+ struct tm *tb = NULL;
++ char *source_date_epoch;
+
+- /* (time_t) -1 is a legitimate value for "number of seconds
+- since the Epoch", so we have to do a little dance to
+- distinguish that from a genuine error. */
+- errno = 0;
+- tt = time(NULL);
+- if (tt != (time_t)-1 || errno == 0)
+- tb = localtime (&tt);
++ /* Allow the date and time to be set externally by an exported
++ environment variable to enable reproducible builds. */
++ source_date_epoch = getenv ("SOURCE_DATE_EPOCH");
++ if (source_date_epoch)
++ {
++ errno = 0;
++ tt = (time_t) strtol (source_date_epoch, NULL, 10);
++ if (errno == 0)
++ {
++ tb = gmtime (&tt);
++ if (tb == NULL)
++ cpp_error (pfile, CPP_DL_ERROR,
++ "SOURCE_DATE_EPOCH=\"%s\" is not a valid date",
++ source_date_epoch);
++ }
++ else
++ cpp_error (pfile, CPP_DL_ERROR,
++ "SOURCE_DATE_EPOCH=\"%s\" is not a valid number",
++ source_date_epoch);
++ }
++ else
++ {
++ /* (time_t) -1 is a legitimate value for "number of seconds
++ since the Epoch", so we have to do a little dance to
++ distinguish that from a genuine error. */
++ errno = 0;
++ tt = time(NULL);
++ if (tt != (time_t)-1 || errno == 0)
++ tb = localtime (&tt);
++ }
+
+ if (tb)
+ {
diff --git a/nix/nixcrpkgs/mingw-w64/guid-selectany.patch b/nix/nixcrpkgs/mingw-w64/guid-selectany.patch
new file mode 100644
index 000000000..b495a67b5
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/guid-selectany.patch
@@ -0,0 +1,38 @@
+From 339371eafd2fb2bcbf8b0a08e5328fc7c16b892f Mon Sep 17 00:00:00 2001
+From: David Grayson
+Date: Thu, 4 May 2017 06:41:28 -0700
+Subject: [PATCH] guiddef.h: Use __declspec(selectany) on GUID declarations.
+
+If __declspec(selectany) is not used on the prototype but later used
+on a definition, GCC 6+ seems to ignore it, and you can get
+multiple-definition errors at link time.
+
+That situation can arise in code like Microsoft's usbview utility that
+has multiple translation units including the following headers in this
+order: windows.h, initguid.h, winioctl.h.
+
+However, this patch cannot be upstreamed to mingw-w64 because it
+breaks older versions of GCC, and MSDN says that putting selectany on
+a declaration is "incorrect". Once GCC is fixed, we can remove this
+patch.
+---
+ mingw-w64-headers/include/guiddef.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/mingw-w64-headers/include/guiddef.h b/mingw-w64-headers/include/guiddef.h
+index 9ecea3e2..6c9444cf 100644
+--- a/mingw-w64-headers/include/guiddef.h
++++ b/mingw-w64-headers/include/guiddef.h
+@@ -58,8 +58,7 @@ __extension__ template const GUID &__mingw_uuidof();
+ #define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID DECLSPEC_SELECTANY name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+ #endif
+ #else
+-/* __declspec(selectany) must be applied to initialized objects on GCC 5 hence must not be used here. */
+-#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID name
++#define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) EXTERN_C const GUID DECLSPEC_SELECTANY name
+ #endif
+
+ #define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID (name, l, w1, w2, 0xc0, 0, 0, 0, 0, 0, 0, 0x46)
+--
+2.12.1
+
diff --git a/nix/nixcrpkgs/mingw-w64/license_builder.sh b/nix/nixcrpkgs/mingw-w64/license_builder.sh
new file mode 100644
index 000000000..beb53ee27
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/license_builder.sh
@@ -0,0 +1,42 @@
+source $setup
+
+tar -xf $gcc_src
+mv gcc-* gcc
+
+license_gcc=$(cat gcc/COPYING3.LIB)
+cd $src
+license_runtime=$(cat COPYING.MinGW-w64-runtime/COPYING.MinGW-w64-runtime.txt)
+license_winpthread=$(cat mingw-w64-libraries/winpthreads/COPYING)
+
+cat > $out <
+ The third-party software included with this software may
+ have been patched or otherwise modified.
+
+
+GCC run-time libraries
+
+
+ The GCC run-time libraries libgcc and libstdc++ are licensed under the GNU
+ General Public License Version 3 (GPLv3) as shown below.
+
+
+
+$license_gcc
+
+
+MinGW-w64 runtime components
+
+
+$license_runtime
+
+
+
+ libwinpthread also comes from the mingw-w64 project and its license is below.
+
+
+
+$license_winpthread
+
+
+EOF
diff --git a/nix/nixcrpkgs/mingw-w64/usb.patch b/nix/nixcrpkgs/mingw-w64/usb.patch
new file mode 100644
index 000000000..768c4a979
--- /dev/null
+++ b/nix/nixcrpkgs/mingw-w64/usb.patch
@@ -0,0 +1,73 @@
+diff --git a/mingw-w64-headers/include/usbspec.h b/mingw-w64-headers/include/usbspec.h
+index 86557d8d..97ab5f3b 100644
+--- a/mingw-w64-headers/include/usbspec.h
++++ b/mingw-w64-headers/include/usbspec.h
+@@ -213,6 +213,13 @@ typedef struct _USB_BOS_DESCRIPTOR {
+ #define USB_DEVICE_CAPABILITY_USB20_EXTENSION 0x02
+ #define USB_DEVICE_CAPABILITY_SUPERSPEED_USB 0x03
+ #define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04
++#define USB_DEVICE_CAPABILITY_PLATFORM 0x05
++#define USB_DEVICE_CAPABILITY_POWER_DELIVERY 0x06
++#define USB_DEVICE_CAPABILITY_BATTERY_INFO 0x07
++#define USB_DEVICE_CAPABILITY_PD_CONSUMER_PORT 0x08
++#define USB_DEVICE_CAPABILITY_PD_PROVIDER_PORT 0x09
++#define USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB 0x0A
++#define USB_DEVICE_CAPABILITY_PRECISION_TIME_MEASUREMENT 0x0B
+ #define USB_DEVICE_CAPABILITY_BILLBOARD 0x0D
+
+ typedef struct _USB_DEVICE_CAPABILITY_USB20_EXTENSION_DESCRIPTOR {
+@@ -666,6 +673,54 @@ typedef struct _USB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR {
+ ULONG dwBytesPerInterval;
+ } USB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR,*PUSB_SUPERSPEEDPLUS_ISOCH_ENDPOINT_COMPANION_DESCRIPTOR;
+
++typedef union _USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED {
++ ULONG AsUlong32;
++ struct {
++ ULONG SublinkSpeedAttrID:4;
++ ULONG LaneSpeedExponent:2;
++ ULONG SublinkTypeMode:1;
++ ULONG SublinkTypeDir:1;
++ ULONG Reserved:6;
++ ULONG LinkProtocol:2;
++ ULONG LaneSpeedMantissa:16;
++ };
++} USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED, *PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED;
++
++typedef struct _USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR {
++ UCHAR bLength;
++ UCHAR bDescriptorType;
++ UCHAR bDevCapabilityType;
++ UCHAR bReserved;
++ union {
++ ULONG AsUlong;
++ struct {
++ ULONG SublinkSpeedAttrCount:5;
++ ULONG SublinkSpeedIDCount:4;
++ ULONG Reserved:23;
++ };
++ } bmAttributes;
++ union {
++ USHORT AsUshort;
++ struct {
++ USHORT SublinkSpeedAttrID:4;
++ USHORT Reserved:4;
++ USHORT MinRxLaneCount:4;
++ USHORT MinTxLaneCount:4;
++ };
++ } wFunctionalitySupport;
++ USHORT wReserved;
++ USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_SPEED bmSublinkSpeedAttr[1];
++} USB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR,*PUSB_DEVICE_CAPABILITY_SUPERSPEEDPLUS_USB_DESCRIPTOR;
++
++typedef struct _USB_DEVICE_CAPABILITY_PLATFORM_DESCRIPTOR {
++ UCHAR bLength;
++ UCHAR bDescriptorType;
++ UCHAR bDevCapabilityType;
++ UCHAR bReserved;
++ GUID PlatformCapabilityUuid;
++ UCHAR CapabililityData[1];
++} USB_DEVICE_CAPABILITY_PLATFORM_DESCRIPTOR,*PUSB_DEVICE_CAPABILITY_PLATFORM_DESCRIPTOR;
++
+ #include
+
+ #endif
diff --git a/nix/nixcrpkgs/native/default.nix b/nix/nixcrpkgs/native/default.nix
new file mode 100644
index 000000000..e56c5ce5c
--- /dev/null
+++ b/nix/nixcrpkgs/native/default.nix
@@ -0,0 +1,54 @@
+{ nixpkgs }:
+
+let
+ native_base = {
+ inherit nixpkgs;
+
+ is_cross = false;
+
+ default_native_inputs = [
+ nixpkgs.bashInteractive
+ nixpkgs.binutils
+ (nixpkgs.binutils-unwrapped or nixpkgs.binutils)
+ nixpkgs.bzip2
+ nixpkgs.cmake
+ nixpkgs.coreutils
+ nixpkgs.diffutils
+ nixpkgs.findutils
+ nixpkgs.gcc
+ nixpkgs.gawk
+ nixpkgs.gnumake
+ nixpkgs.gnugrep
+ nixpkgs.gnused
+ nixpkgs.gnutar
+ nixpkgs.gzip
+ nixpkgs.ninja
+ nixpkgs.patch
+ nixpkgs.which
+ nixpkgs.xz
+ ];
+
+ make_derivation = import ../make_derivation.nix native_base;
+ };
+
+ pkgconf = import ./pkgconf { env = native_base; };
+
+ wrappers = import ./wrappers { env = native_base; };
+
+ gnu_config = nixpkgs.fetchgit {
+ url = "https://git.savannah.gnu.org/git/config.git";
+ rev = "81497f5aaf50a12a9fe0cba30ef18bda46b62959";
+ sha256 = "1fq0nki2118zwbc8rdkqx5i04lbfw7gqbsyf5bscg5im6sfphq1d";
+ };
+
+ native = native_base // {
+ default_native_inputs = native_base.default_native_inputs ++ [
+ pkgconf
+ ];
+
+ inherit pkgconf wrappers gnu_config;
+
+ make_derivation = import ../make_derivation.nix native;
+ };
+
+in native
diff --git a/nix/nixcrpkgs/native/pkgconf/builder.sh b/nix/nixcrpkgs/native/pkgconf/builder.sh
new file mode 100644
index 000000000..e58ccf98a
--- /dev/null
+++ b/nix/nixcrpkgs/native/pkgconf/builder.sh
@@ -0,0 +1,21 @@
+source $setup
+
+tar -xf $src
+
+mkdir build
+
+cd build
+
+../pkgconf-$version/configure \
+ --prefix=$out \
+ --with-system-libdir=/no-system-libdir/ \
+ --with-system-includedir=/no-system-includedir/
+
+make
+
+make install
+
+ln -s $out/bin/pkgconf $out/bin/pkg-config
+
+mkdir $out/license
+cp ../pkgconf-$version/COPYING $out/license/LICENSE
diff --git a/nix/nixcrpkgs/native/pkgconf/default.nix b/nix/nixcrpkgs/native/pkgconf/default.nix
new file mode 100644
index 000000000..cd7eea7bd
--- /dev/null
+++ b/nix/nixcrpkgs/native/pkgconf/default.nix
@@ -0,0 +1,14 @@
+{ env }:
+
+env.make_derivation rec {
+ name = "pkgconf-${version}";
+
+ version = "1.0.1";
+
+ src = env.nixpkgs.fetchurl {
+ url = "https://github.com/pkgconf/pkgconf/releases/download/pkgconf-${version}/pkgconf-${version}.tar.gz";
+ sha256 = "1w9wb2z7zz6s4mifbllvhx0401bwsynhp02v312i6i9jn1m2zkj5";
+ };
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/native/wrappers/builder.sh b/nix/nixcrpkgs/native/wrappers/builder.sh
new file mode 100644
index 000000000..64d149cef
--- /dev/null
+++ b/nix/nixcrpkgs/native/wrappers/builder.sh
@@ -0,0 +1,17 @@
+source $setup
+
+mkdir -p $out/bin
+
+cat > $out/bin/pkg-config-cross < $out/bin/cmake-cross < $out/gdbcmd.txt
+set substitute-path ../samples src/angle/samples
+set substitute-path ../util src/angle/util
+EOF
diff --git a/nix/nixcrpkgs/pkgs/angle/default.nix b/nix/nixcrpkgs/pkgs/angle/default.nix
new file mode 100644
index 000000000..da5a76c37
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/default.nix
@@ -0,0 +1,23 @@
+{ crossenv, gdb, debug ? false }:
+
+if crossenv.os != "windows" then "" else
+
+let
+ angle = import ./lib.nix {
+ inherit crossenv debug;
+ };
+
+ util = import ./util.nix {
+ inherit crossenv angle;
+ };
+
+ examples = import ./examples.nix {
+ inherit crossenv angle;
+ angle_util = util;
+ };
+
+ debug_bundle = import ./debug_bundle.nix {
+ inherit crossenv gdb angle examples;
+ };
+
+in angle // { inherit util examples debug_bundle; }
diff --git a/nix/nixcrpkgs/pkgs/angle/examples.nix b/nix/nixcrpkgs/pkgs/angle/examples.nix
new file mode 100644
index 000000000..6ccb47f05
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/examples.nix
@@ -0,0 +1,11 @@
+{ crossenv, angle, angle_util }:
+
+crossenv.make_derivation rec {
+ name = "angle-samples-${angle.version}";
+
+ src = angle.src;
+
+ inherit angle angle_util;
+
+ builder = ./samples_builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/angle/lib.nix b/nix/nixcrpkgs/pkgs/angle/lib.nix
new file mode 100644
index 000000000..7357d905f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/lib.nix
@@ -0,0 +1,43 @@
+{ crossenv, debug ? false }:
+
+if crossenv.os != "windows" then "windows only" else
+
+crossenv.make_derivation rec {
+ name = "angle-${version}";
+
+ version = "2017-03-09";
+
+ src = crossenv.nixpkgs.fetchgit {
+ url = "https://chromium.googlesource.com/angle/angle";
+ rev = "fe9306a8e5bb6a8d52368e8e7b8e92f3bc7e77d4";
+ sha256 = "0m2pbkl9x9kybcxzhai0s3bk9k0r8nb531gzlxcvb3gb2za388bn";
+ };
+
+ patches = [ ./megapatch.patch ];
+
+ builder = ./builder.sh;
+
+ native_inputs = [
+ crossenv.nixpkgs.pythonPackages.gyp
+ ];
+
+ GYP_GENERATORS = "ninja";
+
+ gyp_flags =
+ "-D OS=win " +
+ "-D TARGET=win32 " +
+ "-D use_ozone=0 " +
+ "-D angle_enable_vulkan=0 " + # Vulkan support is in progress
+ "-D angle_gl_library_type=static_library " +
+ "-I ../src/gyp/common.gypi " +
+ "--depth .";
+
+ CC_target = "${crossenv.host}-gcc";
+ CXX_target = "${crossenv.host}-g++";
+ AR = "${crossenv.host}-ar";
+ RANLIB = "${crossenv.host}-ranlib";
+
+ CXXFLAGS = "-msse2 -Wno-conversion-null";
+
+ inherit debug;
+}
diff --git a/nix/nixcrpkgs/pkgs/angle/megapatch.patch b/nix/nixcrpkgs/pkgs/angle/megapatch.patch
new file mode 100644
index 000000000..319b192a7
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/megapatch.patch
@@ -0,0 +1,24 @@
+diff -ur angle-src-orig/src/angle.gyp angle-src/src/angle.gyp
+--- angle-src-orig/src/angle.gyp 2017-02-07 07:42:35.090343332 -0800
++++ angle-src/src/angle.gyp 2017-02-09 08:44:52.752006998 -0800
+@@ -286,7 +286,7 @@
+ }
+ ]
+ }],
+- ['OS=="win"',
++ ['OS=="win" and 0',
+ {
+ 'targets':
+ [
+diff -ur angle-src-orig/src/libGLESv2.gypi angle-src/src/libGLESv2.gypi
+--- angle-src-orig/src/libGLESv2.gypi 2017-02-07 07:42:35.113676666 -0800
++++ angle-src/src/libGLESv2.gypi 2017-02-09 09:19:37.985340331 -0800
+@@ -1078,7 +1078,7 @@
+ '<@(libangle_null_sources)',
+ ],
+ }],
+- ['angle_build_winrt==0 and OS=="win"',
++ ['angle_build_winrt==0 and OS=="win" and 0',
+ {
+ 'dependencies':
+ [
diff --git a/nix/nixcrpkgs/pkgs/angle/samples_builder.sh b/nix/nixcrpkgs/pkgs/angle/samples_builder.sh
new file mode 100644
index 000000000..3b89c9c0b
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/samples_builder.sh
@@ -0,0 +1,54 @@
+source $setup
+
+cp -r $src/samples .
+cp -r $src/util .
+
+mkdir include
+cp -r $src/samples/sample_util/* include/
+
+mkdir build
+cd build
+mkdir bin
+
+CFLAGS="-mwindows -g -O2 -I../include -I$angle_util/include -I$angle/include"
+CFLAGS="$CFLAGS -DGL_APICALL= -DANGLE_EXPORT= -DGL_GLEXT_PROTOTYPES"
+LDFLAGS="-L$angle_util/lib -L$angle/lib"
+LIBS="-langle_util -lEGL_static -lGLESv2_static -lANGLE -ltranslator
+-lpreprocessor -langle_image_util -langle_common -ld3d9 -lgdi32"
+
+echo "compiling texture_wrap"
+$host-g++ $CFLAGS $LDFLAGS \
+ ../samples/texture_wrap/TextureWrap.cpp \
+ ../samples/sample_util/texture_utils.cpp \
+ ../samples/sample_util/SampleApplication.cpp \
+ $LIBS -o bin/texture_wrap${exe_suffix}
+
+echo "compiling simple_texture_2d"
+$host-g++ $CFLAGS $LDFLAGS \
+ ../samples/simple_texture_2d/SimpleTexture2D.cpp \
+ ../samples/sample_util/texture_utils.cpp \
+ ../samples/sample_util/SampleApplication.cpp \
+ $LIBS -o bin/simple_texture_2d${exe_suffix}
+
+echo "compiling particle_system"
+$host-g++ $CFLAGS $LDFLAGS \
+ ../samples/particle_system/ParticleSystem.cpp \
+ ../samples/sample_util/tga_utils.cpp \
+ ../samples/sample_util/SampleApplication.cpp \
+ $LIBS -o bin/particle_system${exe_suffix}
+cp ../samples/particle_system/smoke.tga bin/
+
+echo "compiling hello_triangle"
+$host-g++ $CFLAGS $LDFLAGS \
+ ../samples/hello_triangle/HelloTriangle.cpp \
+ ../samples/sample_util/SampleApplication.cpp \
+ $LIBS -o bin/hello_triangle${exe_suffix}
+
+echo "compiling window_test"
+$host-g++ $CFLAGS $LDFLAGS \
+ ../samples/WindowTest/WindowTest.cpp \
+ -langle_util -lgdi32 -o bin/window_test${exe_suffix}
+
+mkdir -p $out/license
+cp $src/LICENSE $out/license/
+cp -r bin $out/
diff --git a/nix/nixcrpkgs/pkgs/angle/util.nix b/nix/nixcrpkgs/pkgs/angle/util.nix
new file mode 100644
index 000000000..83d703882
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/util.nix
@@ -0,0 +1,15 @@
+# libangle_util is a helper library for programs like tests
+# and samples that surround ANGLE but that are not the ANGLE libraries
+# themselves
+
+{ crossenv, angle }:
+
+crossenv.make_derivation rec {
+ name = "angle_util-${angle.version}";
+
+ src = angle.src;
+
+ inherit angle;
+
+ builder = ./util_builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/angle/util_builder.sh b/nix/nixcrpkgs/pkgs/angle/util_builder.sh
new file mode 100644
index 000000000..7929083b6
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/angle/util_builder.sh
@@ -0,0 +1,38 @@
+source $setup
+
+cp -r $src/util .
+
+mkdir include
+cp -r $src/util/*.h include/
+cp -r $src/include/export.h include/
+mkdir include/common
+cp -r $src/src/common/*.h include/common/
+mkdir -p include/windows/win32
+cp -r $src/util/windows/*.h include/windows/
+cp -r $src/util/windows/win32/*.h include/windows/win32/
+
+mkdir -p build/{obj,lib}
+cd build
+
+source_files=../util/*.cpp
+
+if [ "$os" == "windows" ]; then
+ source_files="$source_files ../util/windows/*.cpp ../util/windows/win32/*.cpp"
+fi
+
+for c in $source_files; do
+ echo "compiling $(basename $c)"
+ $host-g++ -c -g -O2 -fpermissive \
+ -I../include -I"$angle/include" -L"$angle/lib" \
+ -DGL_APICALL= -DANGLE_EXPORT= -DEGLAPI= \
+ -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -DLIBANGLE_UTIL_IMPLEMENTATION \
+ $c -lGLESv2 -lEGL \
+ -o obj/$(basename $c).o
+done
+
+$host-ar r lib/libangle_util.a obj/*.o
+
+mkdir -p $out/{license,lib}
+cp $src/LICENSE $out/license/
+cp lib/libangle_util.a $out/lib/
+cp -r ../include $out/
diff --git a/nix/nixcrpkgs/pkgs/at-spi2-headers/builder.sh b/nix/nixcrpkgs/pkgs/at-spi2-headers/builder.sh
new file mode 100644
index 000000000..04ac14fda
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/at-spi2-headers/builder.sh
@@ -0,0 +1,12 @@
+source $setup
+
+mkdir -p $out/include/atspi $out/lib/pkgconfig
+
+cp $src/atspi/*.h $out/include/atspi/
+
+cat > $out/lib/pkgconfig/atspi-2.pc < $out <at-spi2-headers
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/avrdude/builder.sh b/nix/nixcrpkgs/pkgs/avrdude/builder.sh
new file mode 100644
index 000000000..8c7f2c078
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/avrdude/builder.sh
@@ -0,0 +1,23 @@
+source $setup
+
+tar -xf $src
+mv avrdude-* avrdude
+
+ls -lad avrdude
+cd avrdude
+chmod -R u+w .
+cp $config_dot_sub config.sub
+cat $extra_conf >> avrdude.conf.in
+cd ..
+
+mkdir build
+cd build
+
+../avrdude/configure --host=$host --prefix=$out \
+ --enable-static \
+ --disable-shared \
+ --disable-dependency-tracking
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/avrdude/config.sub b/nix/nixcrpkgs/pkgs/avrdude/config.sub
new file mode 100644
index 000000000..1d8e98bce
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/avrdude/config.sub
@@ -0,0 +1,1801 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2018 Free Software Foundation, Inc.
+
+timestamp='2018-02-22'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see .
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to .
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+Canonicalize a configuration name.
+
+Options:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to ."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2018 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo "$1"
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | cloudabi*-eabi* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
+ if [ "$basic_machine" != "$1" ]
+ then os=`echo "$1" | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia16 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pru \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | wasm32 \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pru-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | wasm32-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-pc
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2*)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ e500v[12])
+ basic_machine=powerpc-unknown
+ os=$os"spe"
+ ;;
+ e500v[12]-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=$os"spe"
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next)
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ nsv-tandem)
+ basic_machine=nsv-tandem
+ ;;
+ nsx-tandem)
+ basic_machine=nsx-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ x64)
+ basic_machine=x86_64-pc
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases that might get confused
+ # with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # es1800 is here to avoid being matched by es* (a different OS)
+ -es1800*)
+ os=-ose
+ ;;
+ # Now accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST end in a * to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
+ | -midnightbsd*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -xray | -os68k* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo "$os" | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2)
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -pikeos*)
+ # Until real need of OS specific support for
+ # particular features comes up, bare metal
+ # configurations are quite functional.
+ case $basic_machine in
+ arm*)
+ os=-eabi
+ ;;
+ *)
+ os=-elf
+ ;;
+ esac
+ ;;
+ -nacl*)
+ ;;
+ -ios)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ pru-*)
+ os=-elf
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next)
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo "$basic_machine$os"
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-functions 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/nix/nixcrpkgs/pkgs/avrdude/default.nix b/nix/nixcrpkgs/pkgs/avrdude/default.nix
new file mode 100644
index 000000000..d5442cc90
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/avrdude/default.nix
@@ -0,0 +1,35 @@
+# TODO: remove giveio.sys and any other sketchy drivers or binaries from the source
+
+# Note: There are no patches to help AVRDUDE find its configuration
+# file, so it will expect that file to be at
+# /nix/store/...-avrdude/etc/avrdude.conf
+
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "avrdude-${version}";
+
+ version = "6.3"; # February 2016
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "http://download.savannah.gnu.org/releases/avrdude/avrdude-${version}.tar.gz";
+ sha256 = "15m1w1qad3dj7r8n5ng1qqcaiyx1gyd6hnc3p2apgjllccdp77qg";
+ };
+
+ native_inputs = [
+ crossenv.nixpkgs.yacc
+ crossenv.nixpkgs.flex
+ ];
+
+ cross_inputs = [
+ # TODO: libusb
+ # TODO: libftdi
+ # TODO: libelf
+ # TODO: libhid
+ ];
+
+ config_dot_sub = ./config.sub;
+ extra_conf = ./extra.conf;
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/avrdude/extra.conf b/nix/nixcrpkgs/pkgs/avrdude/extra.conf
new file mode 100644
index 000000000..539cd65f4
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/avrdude/extra.conf
@@ -0,0 +1,6 @@
+part parent "m328p"
+ id = "m328pb";
+ desc = "ATmega328PB";
+ signature = 0x1e 0x95 0x16;
+ ocdrev = 1;
+;
\ No newline at end of file
diff --git a/nix/nixcrpkgs/pkgs/curl/builder.sh b/nix/nixcrpkgs/pkgs/curl/builder.sh
new file mode 100644
index 000000000..303f6278e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/curl/builder.sh
@@ -0,0 +1,15 @@
+source $setup
+
+tar -xf $src
+cd *
+
+export CFLAGS=-fPIC
+
+case $host in
+ *darwin*) CFLAGS="$CFLAGS -mmacosx-version-min=10.11";;
+esac
+
+./configure --prefix=$out --host=$host $configureFlags
+
+make
+make install
diff --git a/nix/nixcrpkgs/pkgs/curl/default.nix b/nix/nixcrpkgs/pkgs/curl/default.nix
new file mode 100644
index 000000000..7000fe6ba
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/curl/default.nix
@@ -0,0 +1,21 @@
+{ crossenv, openssl, zlib }:
+
+crossenv.make_derivation rec {
+ name = "curl-${version}";
+ version = "7.62.0";
+
+ cross_inputs = [ crossenv.nixpkgs.perl ];
+ native_inputs = [ zlib openssl ];
+ builder = ./builder.sh;
+
+ configureFlags = [
+ "--disable-shared"
+ "--disable-manual"
+ "--disable-ldap"
+ ];
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://curl.haxx.se/download/${name}.tar.bz2";
+ sha256 = "084niy7cin13ba65p8x38w2xcyc54n3fgzbin40fa2shfr0ca0kq";
+ };
+}
diff --git a/nix/nixcrpkgs/pkgs/dejavu-fonts/builder.sh b/nix/nixcrpkgs/pkgs/dejavu-fonts/builder.sh
new file mode 100644
index 000000000..1161ce85a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/dejavu-fonts/builder.sh
@@ -0,0 +1,6 @@
+source $setup
+
+tar -xf $src
+cd dejavu-*
+mkdir $out
+cp -r * $out/
diff --git a/nix/nixcrpkgs/pkgs/dejavu-fonts/default.nix b/nix/nixcrpkgs/pkgs/dejavu-fonts/default.nix
new file mode 100644
index 000000000..bd8a9d743
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/dejavu-fonts/default.nix
@@ -0,0 +1,29 @@
+{ crossenv }:
+
+let
+ version = "2.37";
+
+ name = "dejavu-fonts-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ # Sourceforge went down. The original URL was:
+ # http://sourceforge.net/projects/dejavu/files/dejavu/${version}/dejavu-fonts-ttf-${version}.tar.bz2";
+ url = "https://files.tmphax.com/repo1/dejavu-fonts-ttf-${version}.tar.bz2";
+ sha256 = "1mqpds24wfs5cmfhj57fsfs07mji2z8812i5c4pi5pbi738s977s";
+ };
+
+ fonts = crossenv.native.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ fonts // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/dejavu-fonts/license_builder.sh b/nix/nixcrpkgs/pkgs/dejavu-fonts/license_builder.sh
new file mode 100644
index 000000000..4ba33030b
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/dejavu-fonts/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv dejavu-* dejavu
+
+license=$(cat dejavu/LICENSE)
+
+cat > $out <DejaVu Fonts
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/devcon/builder.sh b/nix/nixcrpkgs/pkgs/devcon/builder.sh
new file mode 100644
index 000000000..166abe2ad
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/devcon/builder.sh
@@ -0,0 +1,26 @@
+source $setup
+
+cp --no-preserve=mode -r $src/setup/devcon .
+
+cd devcon
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+$host-windmc msg.mc
+cd ..
+
+mkdir build
+cd build
+
+$host-windres ../devcon/devcon.rc rc.o
+
+$host-g++ -municode -O2 \
+ -DUNICODE -D_UNICODE \
+ ../devcon/*.cpp rc.o \
+ -lsetupapi -lole32 \
+ -o devcon.exe
+
+mkdir -p $out/bin $out/license
+cp devcon.exe $out/bin
+cp $src/LICENSE $out/license
diff --git a/nix/nixcrpkgs/pkgs/devcon/default.nix b/nix/nixcrpkgs/pkgs/devcon/default.nix
new file mode 100644
index 000000000..e9410aee8
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/devcon/default.nix
@@ -0,0 +1,20 @@
+{ crossenv }:
+
+if crossenv.os != "windows" then "windows only" else
+
+crossenv.make_derivation rec {
+ name = "devcon-${version}";
+
+ version = "2017-05-01";
+
+ src = crossenv.nixpkgs.fetchFromGitHub {
+ owner = "Microsoft";
+ repo = "Windows-driver-samples";
+ rev = "4c5c5e0297c7a61e151f92af702cdac650a14489";
+ sha256 = "1drq26bnad98xqn805qx0b6g4y65lmrdj7v40b3jhhzdsp8993pf";
+ };
+
+ patches = [];
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/devcon/my_xmlhelper.c b/nix/nixcrpkgs/pkgs/devcon/my_xmlhelper.c
new file mode 100644
index 000000000..0cdf29140
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/devcon/my_xmlhelper.c
@@ -0,0 +1,47 @@
+#include "xmlhelper.h"
+
+EXTERN_C HRESULT InitXmlHelper()
+{
+ return 0;
+}
+
+EXTERN_C HRESULT ReleaseXmlWriter()
+{
+ return 0;
+}
+
+EXTERN_C HRESULT SaveXml(LPTSTR szfileName, DWORD dwCreationDisposition)
+{
+ MessageBox(NULL,
+ "Sorry, XML saving is not supported in this build.",
+ "XML not supported",
+ MB_OK | MB_ICONEXCLAMATION);
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddHostController(
+ PSTR hcName,
+ PUSBHOSTCONTROLLERINFO hcInfo
+ )
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddRootHub(PSTR rhName, PUSBROOTHUBINFO rhInfo)
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddExternalHub(PSTR ehName, PUSBEXTERNALHUBINFO ehInfo)
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddUsbDevice(PSTR devName, PUSBDEVICEINFO deviceInfo)
+{
+ return 0;
+}
+
+EXTERN_C VOID XmlNotifyEndOfNodeList(PVOID pContext)
+{
+}
diff --git a/nix/nixcrpkgs/pkgs/expat/builder.sh b/nix/nixcrpkgs/pkgs/expat/builder.sh
new file mode 100644
index 000000000..3a8bfb731
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/expat/builder.sh
@@ -0,0 +1,26 @@
+source $setup
+
+tar -xf $src
+
+cd expat-$version
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+mkdir build
+cd build
+
+../expat-$version/configure \
+ --prefix=$out --host=$host \
+ --enable-static --disable-shared
+
+make
+
+make install
+
+mv $out/bin/xmlwf $out/bin/xmlwf.exe
+
+mkdir $out/license
+cp ../expat-$version/COPYING $out/license/LICENSE
diff --git a/nix/nixcrpkgs/pkgs/expat/cve-2016-0718.patch b/nix/nixcrpkgs/pkgs/expat/cve-2016-0718.patch
new file mode 100644
index 000000000..6d66fec0c
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/expat/cve-2016-0718.patch
@@ -0,0 +1,26 @@
+From 3e6190e433479e56f8c1e5adc1198b3c86b15577 Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping
+Date: Sun, 17 Jul 2016 20:22:29 +0200
+Subject: [PATCH] Fix regression introduced by patch to CVE-2016-0718 (bug
+ #539)
+
+Tag names were cut off in some cases; reported by Andy Wang
+---
+ expat/lib/xmlparse.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
+index 13e080d..2630310 100644
+--- expat/lib/xmlparse.c
++++ expat-fixed/lib/xmlparse.c
+@@ -2430,7 +2430,7 @@ doContent(XML_Parser parser,
+ &fromPtr, rawNameEnd,
+ (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+ convLen = (int)(toPtr - (XML_Char *)tag->buf);
+- if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
++ if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
+ tag->name.strLen = convLen;
+ break;
+ }
+--
+2.9.2
diff --git a/nix/nixcrpkgs/pkgs/expat/default.nix b/nix/nixcrpkgs/pkgs/expat/default.nix
new file mode 100644
index 000000000..860f54004
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/expat/default.nix
@@ -0,0 +1,20 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "expat-${version}";
+
+ version = "2.2.0";
+
+ src = crossenv.nixpkgs.fetchurl {
+ # Sourceforge went down. The original URL we used was:
+ # mirror://sourceforge/expat/expat-${version}.tar.bz2
+ url = "https://files.tmphax.com/repo1/expat-${version}.tar.bz2";
+ sha256 = "1zq4lnwjlw8s9mmachwfvfjf2x3lk24jm41746ykhdcvs7r0zrfr";
+ };
+
+ patches = [
+ ./cve-2016-0718.patch
+ ];
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/fixesproto/builder.sh b/nix/nixcrpkgs/pkgs/fixesproto/builder.sh
new file mode 100644
index 000000000..4d91d6e9f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/fixesproto/builder.sh
@@ -0,0 +1,16 @@
+source $setup
+
+cp -r $src src
+chmod -R u+w src
+cd src
+autoreconf -v --install
+cd ..
+
+mkdir build
+cd build
+
+../src/configure --prefix=$out
+make
+make install
+
+ln -sf $xextproto/lib/pkgconfig/*.pc $out/lib/pkgconfig
diff --git a/nix/nixcrpkgs/pkgs/fixesproto/default.nix b/nix/nixcrpkgs/pkgs/fixesproto/default.nix
new file mode 100644
index 000000000..49936287e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/fixesproto/default.nix
@@ -0,0 +1,41 @@
+{ crossenv, xorg-macros, xextproto }:
+
+let
+ version = "2017-01-26";
+
+ name = "fixesproto-${version}";
+
+ src = crossenv.nixpkgs.fetchgit {
+ url = "https://anongit.freedesktop.org/git/xorg/proto/fixesproto";
+ rev = "4292ec1c63180c5f4e7c0e606fa68c51913f172b";
+ sha256 = "0mmx4cmkbrsmbq1j58g8gcx4h3qz9y4xbjpz7jcl7crki7zrz3kx";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ native_inputs = [
+ crossenv.nixpkgs.autoconf
+ crossenv.nixpkgs.automake
+ ];
+
+ ACLOCAL_PATH = "${xorg-macros}/lib/aclocal";
+
+ inherit xextproto;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xorg-macros.license_set //
+ xextproto.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/fixesproto/license_builder.sh b/nix/nixcrpkgs/pkgs/fixesproto/license_builder.sh
new file mode 100644
index 000000000..8e347c361
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/fixesproto/license_builder.sh
@@ -0,0 +1,11 @@
+source $setup
+
+license=$(cat $src/COPYING)
+
+cat > $out <fixesproto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/gdb/builder.sh b/nix/nixcrpkgs/pkgs/gdb/builder.sh
new file mode 100644
index 000000000..8133f5199
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/gdb/builder.sh
@@ -0,0 +1,31 @@
+source $setup
+
+tar -xf $src
+
+cd gdb-$version
+for patch in $patches
+do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+mkdir build
+cd build
+
+export LDFLAGS="-L$curses/lib"
+export CFLAGS="-I$curses/include"
+export CXXFLAGS="-I$curses/include"
+
+../gdb-$version/configure \
+ --prefix=$out \
+ --host=$host \
+ --target=$host \
+ --with-expat=yes --with-libexpat-prefix=$expat \
+ --enable-tui \
+ --disable-win32-registry \
+ --disable-rpath
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/gdb/default.nix b/nix/nixcrpkgs/pkgs/gdb/default.nix
new file mode 100644
index 000000000..43378cb68
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/gdb/default.nix
@@ -0,0 +1,38 @@
+# Note: This package has only been tested on Windows, and the pdcurses library
+# it uses does not support Linux in console mode or mac OS X.
+
+# Note: GDB has a bundled copy of readline that it uses.
+# There is a --with-system-readline option we could try to use.
+
+# Note: consider providing a mingw-w64 isl to gdb because its configure script looks for it
+
+{ crossenv, expat, curses }:
+
+crossenv.make_derivation rec {
+ name = "gdb-${version}";
+
+ version = "7.12.1";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://ftp.gnu.org/gnu/gdb/gdb-${version}.tar.xz";
+ sha256 = "11ii260h1sd7v0bs3cz6d5l8gqxxgldry0md60ncjgixjw5nh1s6";
+ };
+
+ patches = [
+ # Make GCC better at finding source files.
+ # https://sourceware.org/ml/gdb-patches/2017-02/msg00693.html
+ ./substitute-path-all-filenames.patch
+ ];
+
+ native_inputs = [
+ crossenv.nixpkgs.texinfo
+ crossenv.nixpkgs.bison
+ crossenv.nixpkgs.yacc
+ crossenv.nixpkgs.m4
+ crossenv.nixpkgs.flex
+ ];
+
+ inherit expat curses;
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/gdb/substitute-path-all-filenames.patch b/nix/nixcrpkgs/pkgs/gdb/substitute-path-all-filenames.patch
new file mode 100644
index 000000000..f1821a772
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/gdb/substitute-path-all-filenames.patch
@@ -0,0 +1,14 @@
+diff -ur gdb-7.12.1-orig/gdb/source.c gdb-7.12.1/gdb/source.c
+--- gdb-7.12.1-orig/gdb/source.c 2017-02-24 19:33:13.340349333 -0800
++++ gdb-7.12.1/gdb/source.c 2017-02-24 19:34:40.660349333 -0800
+@@ -1103,10 +1103,7 @@
+ }
+ }
+
+- if (IS_ABSOLUTE_PATH (filename))
+ {
+- /* If filename is absolute path, try the source path
+- substitution on it. */
+ char *rewritten_filename = rewrite_source_path (filename);
+
+ if (rewritten_filename != NULL)
diff --git a/nix/nixcrpkgs/pkgs/hello/builder.sh b/nix/nixcrpkgs/pkgs/hello/builder.sh
new file mode 100644
index 000000000..36c57adc7
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello/builder.sh
@@ -0,0 +1,7 @@
+source $setup
+
+$host-gcc $src_file -o hello$exe_suffix
+
+mkdir -p $out/bin
+
+cp hello$exe_suffix $out/bin/
diff --git a/nix/nixcrpkgs/pkgs/hello/default.nix b/nix/nixcrpkgs/pkgs/hello/default.nix
new file mode 100644
index 000000000..c8e4d5208
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello/default.nix
@@ -0,0 +1,7 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "hello";
+ src_file = ./hello.c;
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/hello/hello.c b/nix/nixcrpkgs/pkgs/hello/hello.c
new file mode 100644
index 000000000..98e2277bc
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello/hello.c
@@ -0,0 +1,15 @@
+#include
+
+#ifdef _WIN32
+#include
+#endif
+
+int main(int argc, char ** argv)
+{
+ printf("Hello, World!\n");
+
+#ifdef _WIN32
+ MessageBoxA(NULL, "Hello, World!", "Hello", MB_OK);
+#endif
+ return 0;
+}
diff --git a/nix/nixcrpkgs/pkgs/hello_cpp/builder.sh b/nix/nixcrpkgs/pkgs/hello_cpp/builder.sh
new file mode 100644
index 000000000..dae159775
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello_cpp/builder.sh
@@ -0,0 +1,8 @@
+. $setup
+
+$host-g++ $src_file -o hello$exe_suffix
+
+mkdir -p $out/bin/
+
+cp hello$exe_suffix $out/bin/
+
diff --git a/nix/nixcrpkgs/pkgs/hello_cpp/default.nix b/nix/nixcrpkgs/pkgs/hello_cpp/default.nix
new file mode 100644
index 000000000..8f35d0b6f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello_cpp/default.nix
@@ -0,0 +1,7 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "hello_cpp";
+ src_file = ./hello.cpp;
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/hello_cpp/hello.cpp b/nix/nixcrpkgs/pkgs/hello_cpp/hello.cpp
new file mode 100644
index 000000000..d081ace70
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/hello_cpp/hello.cpp
@@ -0,0 +1,15 @@
+#include
+
+#ifdef _WIN32
+#include
+#endif
+
+int main(int argc, char ** argv)
+{
+ std::cout << "hello world" << std::endl;
+
+#ifdef _WIN32
+ MessageBoxA(NULL, "Hello world", "Hello Box", MB_OK);
+#endif
+ return 0;
+}
diff --git a/nix/nixcrpkgs/pkgs/inputproto/builder.sh b/nix/nixcrpkgs/pkgs/inputproto/builder.sh
new file mode 100644
index 000000000..ff349bbcd
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/inputproto/builder.sh
@@ -0,0 +1,13 @@
+source $setup
+
+tar -xf $src
+mv inputproto-* proto
+
+mkdir build
+cd build
+
+../proto/configure --prefix=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/inputproto/default.nix b/nix/nixcrpkgs/pkgs/inputproto/default.nix
new file mode 100644
index 000000000..7c384049d
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/inputproto/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+let
+ version = "2.3.2";
+
+ name = "inputproto-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xorg.freedesktop.org/releases/individual/proto/inputproto-${version}.tar.bz2";
+ sha256 = "07gk7v006zqn3dcfh16l06gnccy7xnqywf3vl9c209ikazsnlfl9";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/inputproto/license_builder.sh b/nix/nixcrpkgs/pkgs/inputproto/license_builder.sh
new file mode 100644
index 000000000..aad143efb
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/inputproto/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv inputproto-* inputproto
+
+license=$(cat inputproto/COPYING)
+
+cat > $out <inputproto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/ion/builder.sh b/nix/nixcrpkgs/pkgs/ion/builder.sh
new file mode 100644
index 000000000..6ac7950a2
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/ion/builder.sh
@@ -0,0 +1,20 @@
+source $setup
+
+tar -xf $src
+mv bitwise-* bitwise
+
+mkdir build
+cd build
+
+$host-gcc -O2 ../bitwise/ion/main.c -o ion$exe_suffix \
+ -DIONHOME=\"$out/ionhome\"
+
+# TODO: make -DIONHOME actually work
+
+mkdir $out
+
+mkdir $out/bin
+mv ion$exe_suffix $out/bin/
+
+mkdir $out/ionhome
+mv ../bitwise/ion/system_packages $out/ionhome/
diff --git a/nix/nixcrpkgs/pkgs/ion/default.nix b/nix/nixcrpkgs/pkgs/ion/default.nix
new file mode 100644
index 000000000..222f6c885
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/ion/default.nix
@@ -0,0 +1,21 @@
+{ crossenv }:
+
+# TODO: SDL integration would be nice, so we can use noir.ion
+
+let
+ version = "7524dc7"; # 2018-04-30
+
+ name = "ion-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/DavidEGrayson/bitwise/archive/${version}.tar.gz";
+ sha256 = "169j7yhphvcyfbqgi5p1i4lhd9n5a31n99fv2kxyrh7djmr8g2s9";
+ };
+
+ ion = crossenv.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+in
+ ion
diff --git a/nix/nixcrpkgs/pkgs/kbproto/builder.sh b/nix/nixcrpkgs/pkgs/kbproto/builder.sh
new file mode 100644
index 000000000..3f21643e8
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/kbproto/builder.sh
@@ -0,0 +1,13 @@
+source $setup
+
+tar -xf $src
+mv kbproto-* proto
+
+mkdir build
+cd build
+
+../proto/configure --prefix=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/kbproto/default.nix b/nix/nixcrpkgs/pkgs/kbproto/default.nix
new file mode 100644
index 000000000..6af2fcf90
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/kbproto/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+let
+ version = "1.0.7";
+
+ name = "kbproto-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xorg.freedesktop.org/releases/individual/proto/kbproto-${version}.tar.bz2";
+ sha256 = "0mxqj1pzhjpz9495vrjnpi10kv2n1s4vs7di0sh3yvipfq5j30pq";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/kbproto/license_builder.sh b/nix/nixcrpkgs/pkgs/kbproto/license_builder.sh
new file mode 100644
index 000000000..65776595a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/kbproto/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv kbproto-* kbproto
+
+license=$(cat kbproto/COPYING)
+
+cat > $out <kbproto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libgmp/builder.sh b/nix/nixcrpkgs/pkgs/libgmp/builder.sh
new file mode 100644
index 000000000..c284c9a5f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libgmp/builder.sh
@@ -0,0 +1,9 @@
+source $setup
+
+tar -xf $src
+
+mkdir build
+cd build
+../gmp-$version/configure --host=$host --prefix=$out --disable-shared
+make
+make install
diff --git a/nix/nixcrpkgs/pkgs/libgmp/default.nix b/nix/nixcrpkgs/pkgs/libgmp/default.nix
new file mode 100644
index 000000000..52af7aefb
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libgmp/default.nix
@@ -0,0 +1,16 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "gmp-${version}";
+ version = "6.1.2";
+ builder = ./builder.sh;
+ native_inputs = [ crossenv.nixpkgs.m4 ];
+
+ src = crossenv.nixpkgs.fetchurl {
+ urls = [ "mirror://gnu/gmp/${name}.tar.bz2"
+ "ftp://ftp.gmplib.org/pub/${name}/${name}.tar.bz2"
+ ];
+ sha256 = "1clg7pbpk6qwxj5b2mw0pghzawp2qlm3jf9gdd8i6fl6yh2bnxaj";
+ };
+
+}
diff --git a/nix/nixcrpkgs/pkgs/libsigsegv/builder.sh b/nix/nixcrpkgs/pkgs/libsigsegv/builder.sh
new file mode 100644
index 000000000..78d3fb9de
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libsigsegv/builder.sh
@@ -0,0 +1,15 @@
+source $setup
+
+tar -xf $src
+
+mkdir build
+cd build
+
+../libsigsegv-$version/configure \
+ --host=$host \
+ --prefix=$out \
+ --enable-static=yes \
+ --enable-shared=no
+
+make
+make install
diff --git a/nix/nixcrpkgs/pkgs/libsigsegv/default.nix b/nix/nixcrpkgs/pkgs/libsigsegv/default.nix
new file mode 100644
index 000000000..60e8c7b6a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libsigsegv/default.nix
@@ -0,0 +1,13 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "libsigsegv-${version}";
+ version = "2.12";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "mirror://gnu/libsigsegv/${name}.tar.gz";
+ sha256 = "1dlhqf4igzpqayms25lkhycjq1ccavisx8cnb3y4zapbkqsszq9s";
+ };
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/libudev/builder.sh b/nix/nixcrpkgs/pkgs/libudev/builder.sh
new file mode 100644
index 000000000..aad209a22
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libudev/builder.sh
@@ -0,0 +1,71 @@
+source $setup
+
+tar -xf $src
+mv systemd-* systemd
+
+cd systemd
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+$host-g++ -x c++ -c $size_flags - -o test.o <
+#include
+#include
+static_assert(sizeof(pid_t) == SIZEOF_PID_T);
+static_assert(sizeof(uid_t) == SIZEOF_UID_T);
+static_assert(sizeof(gid_t) == SIZEOF_GID_T);
+static_assert(sizeof(time_t) == SIZEOF_TIME_T);
+static_assert(sizeof(rlim_t) == SIZEOF_RLIM_T);
+static_assert(sizeof(dev_t) == SIZEOF_DEV_T);
+static_assert(sizeof(ino_t) == SIZEOF_INO_T);
+EOF
+
+rm test.o
+
+mkdir build
+cd build
+
+# -DHAVE_SECURE_GETENV: We don't have secure_getenv but we want to avoid a header error,
+# and hopefully secure_getenv isn't actually needed by libudev.
+
+$host-gcc -c -Werror -I$fill $fill/*.c
+$host-gcc -c $CFLAGS \
+ -I../systemd/src/libudev \
+ -I../systemd/src/basic \
+ -I../systemd/src/libsystemd/sd-device \
+ -I../systemd/src/libsystemd/sd-hwdb \
+ -I../systemd/src/systemd \
+ ../systemd/src/libudev/*.c
+$host-gcc -c $CFLAGS \
+ -I../systemd/src/libsystemd/sd-device \
+ -I../systemd/src/basic \
+ -I../systemd/src/systemd \
+ ../systemd/src/libsystemd/sd-device/{device-enumerator,device-private,sd-device}.c
+$host-gcc -c $CFLAGS \
+ -DPACKAGE_STRING="\"libudev $version\"" \
+ -DFALLBACK_HOSTNAME="\"localhost\"" \
+ -DDEFAULT_HIERARCHY_NAME="\"hybrid\"" \
+ -DDEFAULT_HIERARCHY=CGROUP_UNIFIED_SYSTEMD \
+ -I../systemd/src/basic \
+ -I../systemd/src/systemd \
+ -I$fill \
+ ../systemd/src/basic/{alloc-util,architecture,bus-label,cgroup-util,device-nodes,dirent-util,env-util,escape,extract-word,fd-util,fileio,fs-util,gunicode,glob-util,hashmap,hash-funcs,hexdecoct,hostname-util,io-util,log,login-util,mempool,mkdir,path-util,proc-cmdline,parse-util,prioq,process-util,random-util,signal-util,siphash24,socket-util,stat-util,string-table,string-util,strv,strxcpyx,syslog-util,terminal-util,time-util,unit-name,user-util,utf8,util,virt,MurmurHash2}.c
+$host-ar cr libudev.a *.o
+
+mkdir -p $out/lib/pkgconfig $out/include
+cp libudev.a $out/lib/
+cp ../systemd/src/libudev/libudev.h $out/include/
+
+cat > $out/lib/pkgconfig/libudev.pc <
+
+ With parts from the musl C library
+ Copyright 2005-2014 Rich Felker, et al.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see .
+***/
+
+#include
+#include
+#include
+
+static const char *consume_nonarg(const char *fmt)
+{
+ do {
+ if (*fmt == '\0')
+ return fmt;
+ } while (*fmt++ != '%');
+ return fmt;
+}
+
+static const char *consume_num(const char *fmt)
+{
+ for (;*fmt >= '0' && *fmt <= '9'; fmt++)
+ /* do nothing */;
+ return fmt;
+}
+
+static const char *consume_argn(const char *fmt, size_t *arg)
+{
+ const char *p = fmt;
+ size_t val = 0;
+
+ if (*p < '1' || *p > '9')
+ return fmt;
+ do {
+ val = 10*val + (*p++ - '0');
+ } while (*p >= '0' && *p <= '9');
+
+ if (*p != '$')
+ return fmt;
+ *arg = val;
+ return p+1;
+}
+
+static const char *consume_flags(const char *fmt)
+{
+ while (1) {
+ switch (*fmt) {
+ case '#':
+ case '0':
+ case '-':
+ case ' ':
+ case '+':
+ case '\'':
+ case 'I':
+ fmt++;
+ continue;
+ }
+ return fmt;
+ }
+}
+
+enum state {
+ BARE,
+ LPRE,
+ LLPRE,
+ HPRE,
+ HHPRE,
+ BIGLPRE,
+ ZTPRE,
+ JPRE,
+ STOP
+};
+
+enum type {
+ NONE,
+ PTR,
+ INT,
+ UINT,
+ ULLONG,
+ LONG,
+ ULONG,
+ SHORT,
+ USHORT,
+ CHAR,
+ UCHAR,
+ LLONG,
+ SIZET,
+ IMAX,
+ UMAX,
+ PDIFF,
+ UIPTR,
+ DBL,
+ LDBL,
+ MAXTYPE
+};
+
+static const short pa_types[MAXTYPE] = {
+ [NONE] = PA_INT,
+ [PTR] = PA_POINTER,
+ [INT] = PA_INT,
+ [UINT] = PA_INT,
+ [ULLONG] = PA_INT | PA_FLAG_LONG_LONG,
+ [LONG] = PA_INT | PA_FLAG_LONG,
+ [ULONG] = PA_INT | PA_FLAG_LONG,
+ [SHORT] = PA_INT | PA_FLAG_SHORT,
+ [USHORT] = PA_INT | PA_FLAG_SHORT,
+ [CHAR] = PA_CHAR,
+ [UCHAR] = PA_CHAR,
+ [LLONG] = PA_INT | PA_FLAG_LONG_LONG,
+ [SIZET] = PA_INT | PA_FLAG_LONG,
+ [IMAX] = PA_INT | PA_FLAG_LONG_LONG,
+ [UMAX] = PA_INT | PA_FLAG_LONG_LONG,
+ [PDIFF] = PA_INT | PA_FLAG_LONG_LONG,
+ [UIPTR] = PA_INT | PA_FLAG_LONG,
+ [DBL] = PA_DOUBLE,
+ [LDBL] = PA_DOUBLE | PA_FLAG_LONG_DOUBLE
+};
+
+#define S(x) [(x)-'A']
+#define E(x) (STOP + (x))
+
+static const unsigned char states[]['z'-'A'+1] = {
+ { /* 0: bare types */
+ S('d') = E(INT), S('i') = E(INT),
+ S('o') = E(UINT),S('u') = E(UINT),S('x') = E(UINT), S('X') = E(UINT),
+ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
+ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
+ S('c') = E(CHAR),S('C') = E(INT),
+ S('s') = E(PTR), S('S') = E(PTR), S('p') = E(UIPTR),S('n') = E(PTR),
+ S('m') = E(NONE),
+ S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
+ S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE
+ }, { /* 1: l-prefixed */
+ S('d') = E(LONG), S('i') = E(LONG),
+ S('o') = E(ULONG),S('u') = E(ULONG),S('x') = E(ULONG),S('X') = E(ULONG),
+ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
+ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
+ S('c') = E(INT), S('s') = E(PTR), S('n') = E(PTR),
+ S('l') = LLPRE
+ }, { /* 2: ll-prefixed */
+ S('d') = E(LLONG), S('i') = E(LLONG),
+ S('o') = E(ULLONG),S('u') = E(ULLONG),
+ S('x') = E(ULLONG),S('X') = E(ULLONG),
+ S('n') = E(PTR)
+ }, { /* 3: h-prefixed */
+ S('d') = E(SHORT), S('i') = E(SHORT),
+ S('o') = E(USHORT),S('u') = E(USHORT),
+ S('x') = E(USHORT),S('X') = E(USHORT),
+ S('n') = E(PTR),
+ S('h') = HHPRE
+ }, { /* 4: hh-prefixed */
+ S('d') = E(CHAR), S('i') = E(CHAR),
+ S('o') = E(UCHAR),S('u') = E(UCHAR),
+ S('x') = E(UCHAR),S('X') = E(UCHAR),
+ S('n') = E(PTR)
+ }, { /* 5: L-prefixed */
+ S('e') = E(LDBL),S('f') = E(LDBL),S('g') = E(LDBL), S('a') = E(LDBL),
+ S('E') = E(LDBL),S('F') = E(LDBL),S('G') = E(LDBL), S('A') = E(LDBL),
+ S('n') = E(PTR)
+ }, { /* 6: z- or t-prefixed (assumed to be same size) */
+ S('d') = E(PDIFF),S('i') = E(PDIFF),
+ S('o') = E(SIZET),S('u') = E(SIZET),
+ S('x') = E(SIZET),S('X') = E(SIZET),
+ S('n') = E(PTR)
+ }, { /* 7: j-prefixed */
+ S('d') = E(IMAX), S('i') = E(IMAX),
+ S('o') = E(UMAX), S('u') = E(UMAX),
+ S('x') = E(UMAX), S('X') = E(UMAX),
+ S('n') = E(PTR)
+ }
+};
+
+size_t parse_printf_format(const char *fmt, size_t n, int *types)
+{
+ size_t i = 0;
+ size_t last = 0;
+
+ memset(types, 0, n);
+
+ while (1) {
+ size_t arg;
+ unsigned int state;
+
+ fmt = consume_nonarg(fmt);
+ if (*fmt == '\0')
+ break;
+ if (*fmt == '%') {
+ fmt++;
+ continue;
+ }
+ arg = 0;
+ fmt = consume_argn(fmt, &arg);
+ /* flags */
+ fmt = consume_flags(fmt);
+ /* width */
+ if (*fmt == '*') {
+ size_t warg = 0;
+ fmt = consume_argn(fmt+1, &warg);
+ if (warg == 0)
+ warg = ++i;
+ if (warg > last)
+ last = warg;
+ if (warg <= n && types[warg-1] == NONE)
+ types[warg-1] = INT;
+ } else
+ fmt = consume_num(fmt);
+ /* precision */
+ if (*fmt == '.') {
+ fmt++;
+ if (*fmt == '*') {
+ size_t parg = 0;
+ fmt = consume_argn(fmt+1, &parg);
+ if (parg == 0)
+ parg = ++i;
+ if (parg > last)
+ last = parg;
+ if (parg <= n && types[parg-1] == NONE)
+ types[parg-1] = INT;
+ } else {
+ if (*fmt == '-')
+ fmt++;
+ fmt = consume_num(fmt);
+ }
+ }
+ /* length modifier and conversion specifier */
+ state = BARE;
+ do {
+ unsigned char c = *fmt++;
+
+ if (c < 'A' || c > 'z')
+ continue;
+ state = states[state]S(c);
+ if (state == 0)
+ continue;
+ } while (state < STOP);
+
+ if (state == E(NONE))
+ continue;
+
+ if (arg == 0)
+ arg = ++i;
+ if (arg > last)
+ last = arg;
+ if (arg <= n)
+ types[arg-1] = state - STOP;
+ }
+
+ if (last > n)
+ last = n;
+ for (i = 0; i < last; i++)
+ types[i] = pa_types[types[i]];
+
+ return last;
+}
diff --git a/nix/nixcrpkgs/pkgs/libudev/fill/printf.h b/nix/nixcrpkgs/pkgs/libudev/fill/printf.h
new file mode 100644
index 000000000..ee64bdca4
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libudev/fill/printf.h
@@ -0,0 +1,50 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Emil Renner Berthing
+
+ With parts from the GNU C Library
+ Copyright 1991-2014 Free Software Foundation, Inc.
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see .
+***/
+
+#pragma once
+
+#include
+
+enum { /* C type: */
+ PA_INT, /* int */
+ PA_CHAR, /* int, cast to char */
+ PA_WCHAR, /* wide char */
+ PA_STRING, /* const char *, a '\0'-terminated string */
+ PA_WSTRING, /* const wchar_t *, wide character string */
+ PA_POINTER, /* void * */
+ PA_FLOAT, /* float */
+ PA_DOUBLE, /* double */
+ PA_LAST
+};
+
+/* Flag bits that can be set in a type returned by `parse_printf_format'. */
+#define PA_FLAG_MASK 0xff00
+#define PA_FLAG_LONG_LONG (1 << 8)
+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
+#define PA_FLAG_LONG (1 << 9)
+#define PA_FLAG_SHORT (1 << 10)
+#define PA_FLAG_PTR (1 << 11)
+
+size_t parse_printf_format(const char *fmt, size_t n, int *types);
+
diff --git a/nix/nixcrpkgs/pkgs/libudev/license_builder.sh b/nix/nixcrpkgs/pkgs/libudev/license_builder.sh
new file mode 100644
index 000000000..9b612b976
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libudev/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv systemd-* systemd
+
+license=$(cat systemd/LICENSE.LGPL2.1)
+
+cat > $out <libudev (part of systemd)
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libudev/megapatch.patch b/nix/nixcrpkgs/pkgs/libudev/megapatch.patch
new file mode 100644
index 000000000..a22af551f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libudev/megapatch.patch
@@ -0,0 +1,102 @@
+diff -ur systemd-234-orig/src/basic/glob-util.c systemd-234/src/basic/glob-util.c
+--- systemd-234-orig/src/basic/glob-util.c 2017-07-17 19:46:03.031674662 -0700
++++ systemd-234/src/basic/glob-util.c 2017-07-22 20:11:56.931514364 -0700
+@@ -31,22 +31,8 @@
+ int safe_glob(const char *path, int flags, glob_t *pglob) {
+ int k;
+
+- /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
+- assert(!(flags & GLOB_ALTDIRFUNC));
+-
+- if (!pglob->gl_closedir)
+- pglob->gl_closedir = (void (*)(void *)) closedir;
+- if (!pglob->gl_readdir)
+- pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
+- if (!pglob->gl_opendir)
+- pglob->gl_opendir = (void *(*)(const char *)) opendir;
+- if (!pglob->gl_lstat)
+- pglob->gl_lstat = lstat;
+- if (!pglob->gl_stat)
+- pglob->gl_stat = stat;
+-
+ errno = 0;
+- k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
++ k = glob(path, flags, NULL, pglob);
+
+ if (k == GLOB_NOMATCH)
+ return -ENOENT;
+@@ -66,7 +52,7 @@
+
+ assert(path);
+
+- k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
++ k = safe_glob(path, GLOB_NOSORT, &g);
+ if (k == -ENOENT)
+ return false;
+ if (k < 0)
+@@ -78,7 +64,7 @@
+ _cleanup_globfree_ glob_t g = {};
+ int k;
+
+- k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
++ k = safe_glob(path, GLOB_NOSORT, &g);
+ if (k < 0)
+ return k;
+
+diff -ur systemd-234-orig/src/basic/missing.h systemd-234/src/basic/missing.h
+--- systemd-234-orig/src/basic/missing.h 2017-07-17 19:46:03.031674662 -0700
++++ systemd-234/src/basic/missing.h 2017-07-21 08:02:12.349505168 -0700
+@@ -40,6 +40,22 @@
+ #include
+ #include
+
++static __inline__ char * canonicalize_file_name(const char * path)
++{
++ return realpath(path, NULL);
++}
++
++static __inline__ char * strndupa(const char * s, size_t n)
++{
++ size_t length = strnlen(s, n);
++ char * new_string = (char *)__builtin_alloca(length + 1);
++ new_string[length] = 0;
++ memcpy(new_string, s, length);
++ return new_string;
++}
++
++typedef int comparison_fn_t(const void *, const void *);
++
+ #ifdef HAVE_AUDIT
+ #include
+ #endif
+@@ -550,7 +566,7 @@
+ # ifdef HAVE___SECURE_GETENV
+ # define secure_getenv __secure_getenv
+ # else
+-# error "neither secure_getenv nor __secure_getenv are available"
++# define secure_getenv getenv
+ # endif
+ #endif
+
+diff -ur systemd-234-orig/src/basic/mkdir.c systemd-234/src/basic/mkdir.c
+--- systemd-234-orig/src/basic/mkdir.c 2017-07-17 19:46:03.031674662 -0700
++++ systemd-234/src/basic/mkdir.c 2017-07-22 21:09:51.065274838 -0700
+@@ -28,6 +28,7 @@
+ #include "path-util.h"
+ #include "stat-util.h"
+ #include "user-util.h"
++#include "missing.h"
+
+ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkdir_func_t _mkdir) {
+ struct stat st;
+diff -ur systemd-234-orig/src/basic/parse-util.c systemd-234/src/basic/parse-util.c
+--- systemd-234-orig/src/basic/parse-util.c 2017-07-17 19:46:03.031674662 -0700
++++ systemd-234/src/basic/parse-util.c 2017-07-21 07:59:05.337491775 -0700
+@@ -30,6 +30,7 @@
+ #include "parse-util.h"
+ #include "process-util.h"
+ #include "string-util.h"
++#include "missing.h"
+
+ int parse_boolean(const char *v) {
+ assert(v);
diff --git a/nix/nixcrpkgs/pkgs/libusb/builder.sh b/nix/nixcrpkgs/pkgs/libusb/builder.sh
new file mode 100644
index 000000000..211ee465a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusb/builder.sh
@@ -0,0 +1,27 @@
+source $setup
+
+tar -xf $src
+mv libusb-* libusb
+
+mkdir build
+cd build
+
+if [ -n "$libudev" ]; then
+ export CFLAGS="${CFLAGS:=} -isystem $libudev/include"
+ export LDFLAGS="${LDFLAGS:=} -L$libudev/lib"
+fi
+
+../libusb/configure \
+ --prefix=$out \
+ --host=$host \
+ --enable-static \
+ --disable-shared
+
+make
+
+make install
+
+if [ -n "$libudev" ]; then
+ ln -s $libudev/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ echo "Requires: libudev" >> $out/lib/pkgconfig/libusb-1.0.pc
+fi
diff --git a/nix/nixcrpkgs/pkgs/libusb/default.nix b/nix/nixcrpkgs/pkgs/libusb/default.nix
new file mode 100644
index 000000000..3edc45f0b
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusb/default.nix
@@ -0,0 +1,20 @@
+{ crossenv, libudev }:
+
+let
+ version = "1.0.22";
+
+ name = "libusbp-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.tar.bz2";
+ sha256 = "0mw1a5ss4alg37m6bd4k44v35xwrcwp5qm4s686q1nsgkbavkbkm";
+ };
+
+ lib = crossenv.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+ libudev = if crossenv.os == "linux" then libudev else null;
+ };
+
+in
+ lib
diff --git a/nix/nixcrpkgs/pkgs/libusbp/builder.sh b/nix/nixcrpkgs/pkgs/libusbp/builder.sh
new file mode 100644
index 000000000..f117fa578
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusbp/builder.sh
@@ -0,0 +1,23 @@
+source $setup
+
+tar -xf $src
+mv libusbp-* libusbp
+
+mkdir build
+cd build
+
+cmake-cross ../libusbp \
+ -DCMAKE_INSTALL_PREFIX=$out \
+ -DBUILD_SHARED_LIBS=false
+
+make
+
+make install
+
+if [ -d $out/bin ]; then
+ find $out/bin -type f -exec $host-strip {} +
+fi
+
+if [ -n "$libudev" ]; then
+ ln -s $libudev/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+fi
diff --git a/nix/nixcrpkgs/pkgs/libusbp/default.nix b/nix/nixcrpkgs/pkgs/libusbp/default.nix
new file mode 100644
index 000000000..75c58a241
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusbp/default.nix
@@ -0,0 +1,43 @@
+{ crossenv, libudev }:
+
+let
+ version = "1.1.0";
+
+ name = "libusbp-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/pololu/libusbp/archive/${version}.tar.gz";
+ sha256 = "18l34580ci1pq8p3133dnp8nzlz17qw2796xsz1gn0aca6978izc";
+ };
+
+ lib = crossenv.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+
+ cross_inputs =
+ if crossenv.os == "linux" then
+ [ libudev ]
+ else
+ [];
+
+ libudev = if crossenv.os == "linux" then libudev else null;
+ };
+
+ examples = crossenv.make_derivation {
+ name = "${name}-examples";
+ inherit src version;
+ builder = ./examples_builder.sh;
+ cross_inputs = [ lib ];
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ (if crossenv.os == "linux" then libudev.license_set else {}) //
+ { "${name}" = license; };
+in
+ lib // { inherit examples license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libusbp/examples_builder.sh b/nix/nixcrpkgs/pkgs/libusbp/examples_builder.sh
new file mode 100644
index 000000000..563608be0
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusbp/examples_builder.sh
@@ -0,0 +1,15 @@
+source $setup
+
+tar -xf $src
+mv libusbp-* libusbp
+
+mkdir build
+cd build
+
+FLAGS="-std=gnu++11 $(pkg-config-cross --cflags --libs libusbp-1)"
+
+$host-g++ ../libusbp/examples/lsusb/*.cpp -o lsusb$exe_suffix $FLAGS
+$host-g++ ../libusbp/examples/lsport/*.cpp -o lsport$exe_suffix $FLAGS
+
+mkdir -p $out/bin
+cp * $out/bin/
diff --git a/nix/nixcrpkgs/pkgs/libusbp/license_builder.sh b/nix/nixcrpkgs/pkgs/libusbp/license_builder.sh
new file mode 100644
index 000000000..93111231a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libusbp/license_builder.sh
@@ -0,0 +1,20 @@
+source $setup
+
+tar -xf $src
+mv libusbp-* libusbp
+
+license=$(cat libusbp/LICENSE.txt)
+
+{
+ cat > $out <Pololu USB library (libusbp)
+
+
+ The Pololu USB Library (libusbp) is licensed under the following license:
+
+
+
+$license
+
+EOF
+} > $out
diff --git a/nix/nixcrpkgs/pkgs/libx11/builder.sh b/nix/nixcrpkgs/pkgs/libx11/builder.sh
new file mode 100644
index 000000000..9f46ef8ac
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libx11/builder.sh
@@ -0,0 +1,24 @@
+source $setup
+
+tar -xf $src
+mv libX11-* libx11
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../libx11/configure --prefix $out $configure_flags
+
+make
+
+make install
+
+# Make static linking work.
+sed -i 's/Requires.private/Requires/' $out/lib/pkgconfig/*.pc
+
+ln -s x11-xcb.pc $out/lib/pkgconfig/X11-xcb.pc
+ln -s x11.pc $out/lib/pkgconfig/X11.pc
+
+ln -sf $xproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $kbproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libxcb/lib/pkgconfig/*.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/libx11/default.nix b/nix/nixcrpkgs/pkgs/libx11/default.nix
new file mode 100644
index 000000000..a20b63f75
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libx11/default.nix
@@ -0,0 +1,55 @@
+{ crossenv, xorg-macros, xproto, libxcb, xtrans,
+ xextproto, inputproto, kbproto }:
+
+let
+ version = "1.6.5";
+
+ name = "libx11-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xorg.freedesktop.org/releases/individual/libX11-${version}.tar.bz2";
+ sha256 = "0pa3cfp6h9rl2vxmkph65250gfqyki0ccqyaan6bl9d25gdr0f2d";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--disable-malloc0returnsnull " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [
+ xorg-macros
+ xproto
+ libxcb
+ xtrans
+ xextproto
+ inputproto
+ kbproto
+ ];
+
+ inherit kbproto xproto libxcb;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xorg-macros.license_set //
+ xproto.license_set //
+ libxcb.license_set //
+ xtrans.license_set //
+ xextproto.license_set //
+ inputproto.license_set //
+ kbproto.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libx11/license_builder.sh b/nix/nixcrpkgs/pkgs/libx11/license_builder.sh
new file mode 100644
index 000000000..030bafd88
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libx11/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libX11-* libx11
+
+license=$(cat libx11/COPYING)
+
+cat > $out <libx11
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libxall/builder.rb b/nix/nixcrpkgs/pkgs/libxall/builder.rb
new file mode 100644
index 000000000..f7937666a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxall/builder.rb
@@ -0,0 +1,40 @@
+require 'pathname'
+require 'fileutils'
+include FileUtils
+
+OutDir = Pathname(ENV.fetch('out'))
+LibDirs = ENV.fetch('libs').split(' ').map { |s| Pathname(s) }
+
+def symlink_file(target, dest)
+ real_target = target.realpath
+
+ if dest.exist?
+ if !dest.symlink?
+ raise "Want to link #{dest} (to #{target}) " \
+ "but it already exists and is not a symlink."
+ end
+
+ current_target = dest.readlink
+ if current_target != real_target
+ raise "Conflict: #{dest} links to #{current_target} " \
+ "but we want to link it to #{real_target}."
+ end
+ else
+ dest.make_symlink(real_target)
+ end
+end
+
+def recursive_symlink(target, dest)
+ if target.directory?
+ dest.mkdir if !dest.directory?
+ target.children(false).each do |c|
+ recursive_symlink(target + c, dest + c)
+ end
+ else
+ symlink_file(target, dest)
+ end
+end
+
+LibDirs.each do |libdir|
+ recursive_symlink(libdir, OutDir)
+end
diff --git a/nix/nixcrpkgs/pkgs/libxall/default.nix b/nix/nixcrpkgs/pkgs/libxall/default.nix
new file mode 100644
index 000000000..f570802ea
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxall/default.nix
@@ -0,0 +1,15 @@
+# Amalgamates all of our X libraries into one derivation to make it easier to
+# build projects like Qt that expect them all to be installed in one place.
+
+{ crossenv, libs }:
+
+let
+ lib = crossenv.make_derivation {
+ name = "libxall";
+ builder.ruby = ./builder.rb;
+ inherit libs;
+ };
+
+ license_set = builtins.foldl' (x: y: x // y) {} (map (x: x.license_set) libs);
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libxau/builder.sh b/nix/nixcrpkgs/pkgs/libxau/builder.sh
new file mode 100644
index 000000000..b1dd74899
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxau/builder.sh
@@ -0,0 +1,16 @@
+source $setup
+
+tar -xf $src
+mv libXau-* libxau
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../libxau/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+ln -s $xproto/lib/pkgconfig/xproto.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/libxau/default.nix b/nix/nixcrpkgs/pkgs/libxau/default.nix
new file mode 100644
index 000000000..fcfabbb0c
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxau/default.nix
@@ -0,0 +1,40 @@
+{ crossenv, xorg-macros, xproto }:
+
+let
+ version = "1.0.8";
+
+ name = "libxau-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/archive/individual/lib/libXau-${version}.tar.bz2";
+ sha256 = "1wm4pv12f36cwzhldpp7vy3lhm3xdcnp4f184xkxsp7b18r7gm7x";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ xorg-macros xproto ];
+
+ inherit xproto;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xorg-macros.license_set //
+ xproto.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libxau/license_builder.sh b/nix/nixcrpkgs/pkgs/libxau/license_builder.sh
new file mode 100644
index 000000000..fb3825f7a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxau/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libXau-* libxau
+
+license=$(cat libxau/COPYING)
+
+cat > $out <libxau
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libxcb/builder.sh b/nix/nixcrpkgs/pkgs/libxcb/builder.sh
new file mode 100644
index 000000000..19162ca98
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/builder.sh
@@ -0,0 +1,28 @@
+source $setup
+
+tar -xf $src
+mv libxcb-* libxcb
+
+cd libxcb
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../libxcb/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+# Make static linking work.
+sed -i 's/Requires.private/Requires/' $out/lib/pkgconfig/*.pc
+sed -i 's/Libs.private/Libs/' $out/lib/pkgconfig/*.pc
+
+ln -sf $libxau/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+
diff --git a/nix/nixcrpkgs/pkgs/libxcb/default.nix b/nix/nixcrpkgs/pkgs/libxcb/default.nix
new file mode 100644
index 000000000..d927f1555
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/default.nix
@@ -0,0 +1,56 @@
+{ crossenv, xcb-proto, libxau }:
+
+let
+ version = "1.12";
+
+ name = "libxcb-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/libxcb-${version}.tar.bz2";
+ sha256 = "0nvv0la91cf8p5qqlb3r5xnmg1jn2wphn4fb5jfbr6byqsvv3psa";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ patches = [ ./no-pthread-stubs.patch ];
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared " +
+ "--enable-xinput " +
+ "--enable-xkb";
+
+ cross_inputs = [ xcb-proto libxau ];
+
+ inherit libxau;
+
+ native_inputs = [ crossenv.nixpkgs.python2 ];
+ };
+
+ examples = crossenv.make_derivation rec {
+ name = "libxcb-examples";
+
+ builder = ./examples_builder.sh;
+
+ cross_inputs = [ lib ];
+
+ example1 = ./example1.c;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xcb-proto.license_set //
+ libxau.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit examples license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libxcb/example1.c b/nix/nixcrpkgs/pkgs/libxcb/example1.c
new file mode 100644
index 000000000..48c284636
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/example1.c
@@ -0,0 +1,68 @@
+// Source: https://en.wikipedia.org/wiki/XCB#Example
+
+#include
+#include
+#include
+
+int main(void)
+{
+ xcb_connection_t *c;
+ xcb_screen_t *s;
+ xcb_window_t w;
+ xcb_gcontext_t g;
+ xcb_generic_event_t *e;
+ uint32_t mask;
+ uint32_t values[2];
+ int done = 0;
+ xcb_rectangle_t r = { 20, 20, 60, 60 };
+
+ /* open connection with the server */
+ c = xcb_connect(NULL,NULL);
+ if (xcb_connection_has_error(c)) {
+ printf("Cannot open display\n");
+ exit(1);
+ }
+ /* get the first screen */
+ s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;
+
+ /* create black graphics context */
+ g = xcb_generate_id(c);
+ w = s->root;
+ mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
+ values[0] = s->black_pixel;
+ values[1] = 0;
+ xcb_create_gc(c, g, w, mask, values);
+
+ /* create window */
+ w = xcb_generate_id(c);
+ mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+ values[0] = s->white_pixel;
+ values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
+ xcb_create_window(c, s->root_depth, w, s->root,
+ 10, 10, 100, 100, 1,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
+ mask, values);
+
+ /* map (show) the window */
+ xcb_map_window(c, w);
+
+ xcb_flush(c);
+
+ /* event loop */
+ while (!done && (e = xcb_wait_for_event(c))) {
+ switch (e->response_type & ~0x80) {
+ case XCB_EXPOSE: /* draw or redraw the window */
+ xcb_poly_fill_rectangle(c, w, g, 1, &r);
+ xcb_flush(c);
+ break;
+ case XCB_KEY_PRESS: /* exit on key press */
+ done = 1;
+ break;
+ }
+ free(e);
+ }
+ /* close connection to server */
+ xcb_disconnect(c);
+
+ return 0;
+}
diff --git a/nix/nixcrpkgs/pkgs/libxcb/examples_builder.sh b/nix/nixcrpkgs/pkgs/libxcb/examples_builder.sh
new file mode 100644
index 000000000..1a936f734
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/examples_builder.sh
@@ -0,0 +1,10 @@
+source $setup
+
+pkg-config-cross xcb --cflags --libs
+
+$host-gcc -Wall $example1 \
+ $(pkg-config-cross xcb --cflags --libs) \
+ -o example1$exe_suffix
+
+mkdir -p $out/bin
+cp example1$exe_suffix $out/bin/
diff --git a/nix/nixcrpkgs/pkgs/libxcb/license_builder.sh b/nix/nixcrpkgs/pkgs/libxcb/license_builder.sh
new file mode 100644
index 000000000..31dd9f821
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libxcb-* libxcb
+
+license=$(cat libxcb/COPYING)
+
+cat > $out <libxcb
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libxcb/no-pthread-stubs.patch b/nix/nixcrpkgs/pkgs/libxcb/no-pthread-stubs.patch
new file mode 100644
index 000000000..53c66b74e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxcb/no-pthread-stubs.patch
@@ -0,0 +1,12 @@
+diff -ur libxcb-1.12-orig/configure libxcb-1.12/configure
+--- libxcb-1.12-orig/configure 2017-07-29 22:28:37.986987240 -0700
++++ libxcb-1.12/configure 2017-07-29 22:51:26.410210675 -0700
+@@ -19666,7 +19666,7 @@
+ $as_echo "yes" >&6; }
+
+ fi
+-NEEDED="pthread-stubs xau >= 0.99.2"
++NEEDED="xau >= 0.99.2"
+
+ pkg_failed=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NEEDED" >&5
diff --git a/nix/nixcrpkgs/pkgs/libxext/builder.sh b/nix/nixcrpkgs/pkgs/libxext/builder.sh
new file mode 100644
index 000000000..53bec1552
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxext/builder.sh
@@ -0,0 +1,19 @@
+source $setup
+
+tar -xf $src
+mv libXext-* xext
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../xext/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+sed -i 's/Requires.private/Requires/' $out/lib/pkgconfig/*.pc
+
+ln -sf $xextproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libx11/lib/pkgconfig/*.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/libxext/default.nix b/nix/nixcrpkgs/pkgs/libxext/default.nix
new file mode 100644
index 000000000..7cb0295ba
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxext/default.nix
@@ -0,0 +1,43 @@
+{ crossenv, xproto, libx11, xextproto }:
+
+let
+ version = "1.3.3";
+
+ name = "libxext-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/releases/individual/lib/libXext-${version}.tar.bz2";
+ sha256 = "0dbfn5bznnrhqzvkrcmw4c44yvvpwdcsrvzxf4rk27r36b9x865m";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--disable-malloc0returnsnull " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ xproto libx11 xextproto ];
+
+ inherit xextproto libx11;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xproto.license_set //
+ libx11.license_set //
+ xextproto.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
+
diff --git a/nix/nixcrpkgs/pkgs/libxext/license_builder.sh b/nix/nixcrpkgs/pkgs/libxext/license_builder.sh
new file mode 100644
index 000000000..991196310
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxext/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libXext-* libxext
+
+license=$(cat libxext/COPYING)
+
+cat > $out <libxext
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libxfixes/builder.sh b/nix/nixcrpkgs/pkgs/libxfixes/builder.sh
new file mode 100644
index 000000000..0217ce743
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxfixes/builder.sh
@@ -0,0 +1,20 @@
+source $setup
+
+tar -xf $src
+mv libXfixes-* xfixes
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../xfixes/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+sed -i 's/Requires.private/Requires/' $out/lib/pkgconfig/*.pc
+
+ln -sf $xproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $fixesproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libx11/lib/pkgconfig/*.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/libxfixes/default.nix b/nix/nixcrpkgs/pkgs/libxfixes/default.nix
new file mode 100644
index 000000000..fb98228ec
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxfixes/default.nix
@@ -0,0 +1,42 @@
+{ crossenv, xproto, xextproto, libx11, fixesproto }:
+
+let
+ version = "5.0.3";
+
+ name = "libxfixes-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/releases/individual/lib/libXfixes-${version}.tar.bz2";
+ sha256 = "1miana3y4hwdqdparsccmygqr3ic3hs5jrqfzp70hvi2zwxd676y";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ xproto xextproto libx11 fixesproto ];
+
+ inherit xproto libx11 fixesproto;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xproto.license_set //
+ xextproto.license_set //
+ libx11.license_set //
+ fixesproto.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libxfixes/license_builder.sh b/nix/nixcrpkgs/pkgs/libxfixes/license_builder.sh
new file mode 100644
index 000000000..72bd5a222
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxfixes/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libXfixes-* libxfixes
+
+license=$(cat libxfixes/COPYING)
+
+cat > $out <libxfixes
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/libxi/builder.sh b/nix/nixcrpkgs/pkgs/libxi/builder.sh
new file mode 100644
index 000000000..8c07f9da2
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxi/builder.sh
@@ -0,0 +1,21 @@
+source $setup
+
+tar -xf $src
+mv libXi-* libxi
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../libxi/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+sed -i 's/Requires.private/Requires/' $out/lib/pkgconfig/*.pc
+
+ln -sf $inputproto/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libx11/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libxext/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libxfixes/lib/pkgconfig/*.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/libxi/default.nix b/nix/nixcrpkgs/pkgs/libxi/default.nix
new file mode 100644
index 000000000..ab41d41d8
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxi/default.nix
@@ -0,0 +1,45 @@
+{ crossenv, xproto, xextproto, inputproto, libx11, libxext, libxfixes }:
+
+let
+ version = "1.7.9";
+
+ name = "libxi-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/releases/individual/lib/libXi-${version}.tar.bz2";
+ sha256 = "0idg1wc01hndvaa820fvfs7phvd1ymf0lldmq6386i7rhkzvirn2";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--disable-malloc0returnsnull " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ xproto xextproto inputproto libx11 libxext libxfixes ];
+
+ inherit inputproto libx11 libxext libxfixes;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ xproto.license_set //
+ xextproto.license_set //
+ inputproto.license_set //
+ libx11.license_set //
+ libxext.license_set //
+ libxfixes.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/libxi/license_builder.sh b/nix/nixcrpkgs/pkgs/libxi/license_builder.sh
new file mode 100644
index 000000000..966f93096
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/libxi/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv libXi-* libxi
+
+license=$(cat libxi/COPYING)
+
+cat > $out <libxi
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/ncurses/builder.sh b/nix/nixcrpkgs/pkgs/ncurses/builder.sh
new file mode 100644
index 000000000..d7740f353
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/ncurses/builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+cd *
+
+./configure --host=$host --prefix=$out $configureFlags
+
+make
+
+make install.{libs,includes,data}
+
+# TODO Why do I need to do this?
+mkdir -p $out/lib/pkgconfig
+cp misc/*.pc $out/lib/pkgconfig
diff --git a/nix/nixcrpkgs/pkgs/ncurses/default.nix b/nix/nixcrpkgs/pkgs/ncurses/default.nix
new file mode 100644
index 000000000..e602b2ec6
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/ncurses/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "ncurses-${version}";
+ version = "6.1-20181027";
+ builder = ./builder.sh;
+
+ # Needs to be the same version.
+ native_inputs = [ crossenv.nixpkgs.ncurses ];
+
+ configureFlags = [
+ "--without-debug"
+ "--enable-pc-files"
+ "--enable-symlinks"
+ # "--with-manpage-format=normal"
+ "--without-cxx"
+ # "--enable-widec"
+ ];
+
+ src = crossenv.nixpkgs.fetchurl {
+ urls = [
+ "https://invisible-mirror.net/archives/ncurses/current/ncurses-${version}.tgz"
+ "ftp://ftp.invisible-island.net/ncurses/current/ncurses-${version}.tgz"
+ ];
+ sha256 = "1xn6wpi22jc61158w4ifq6s1fvilhmsy1in2srn3plk8pm0d4902";
+ };
+}
diff --git a/nix/nixcrpkgs/pkgs/openocd/builder.sh b/nix/nixcrpkgs/pkgs/openocd/builder.sh
new file mode 100644
index 000000000..c1c388d88
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/openocd/builder.sh
@@ -0,0 +1,24 @@
+source $setup
+
+cp -r $src openocd
+chmod -R u+w openocd
+
+cd openocd
+SKIP_SUBMODULE=1 ./bootstrap
+cd ..
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross ../openocd/configure \
+ --prefix=$out \
+ --host=$host \
+ --disable-dependency-tracking \
+ --enable-static \
+ --disable-shared
+
+make
+
+make install
+
+$host-strip $out/bin/openocd
diff --git a/nix/nixcrpkgs/pkgs/openocd/default.nix b/nix/nixcrpkgs/pkgs/openocd/default.nix
new file mode 100644
index 000000000..756ce9989
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/openocd/default.nix
@@ -0,0 +1,39 @@
+{ crossenv, libusb }:
+
+let
+ version = "2018-08-16";
+
+ name = "openocd-${version}";
+
+ nixpkgs = crossenv.nixpkgs;
+
+ src = nixpkgs.fetchgit {
+ url = "git://repo.or.cz/openocd"; # official mirror
+ rev = "b2d259f67cc3ee4b689e704228d97943bae94064";
+ sha256 = "0c5zpjplwp0ivl4mpiix628j0iad9gkmg9f7lidgqjr5a80cr6hg";
+ deepClone = true;
+ };
+
+ drv = crossenv.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+
+ native_inputs = [
+ nixpkgs.autoconf
+ nixpkgs.automake
+ nixpkgs.libtool
+ nixpkgs.m4
+ ];
+
+ ACLOCAL_PATH =
+ "${nixpkgs.libtool}/share/aclocal:" +
+ "${crossenv.native.pkgconf}/share/aclocal";
+
+ # Avoid a name conflict: get_home_dir is also defined in libudev.
+ CFLAGS = "-Dget_home_dir=openocd_get_home_dir";
+
+ cross_inputs = [ libusb ];
+ };
+
+in
+ drv
diff --git a/nix/nixcrpkgs/pkgs/openssl/builder.sh b/nix/nixcrpkgs/pkgs/openssl/builder.sh
new file mode 100644
index 000000000..e47e43ab1
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/openssl/builder.sh
@@ -0,0 +1,46 @@
+source $setup
+
+tar -xf $src
+
+mkdir build
+cd build
+
+err () { echo ERR "$@" >&2; }
+
+case $host in
+ i686-linux-musleabi)
+ confighost=linux-x86;;
+ x86_64-linux-musleabi)
+ confighost=linux-x86_64;;
+ x86_64-apple-darwin*)
+ confighost=darwin64-x86_64-cc;;
+ *)
+ err openssl builder.sh needs to excplicitly translate
+ err "'host=$host'" to something openssl understands.
+ confighost=$host;;
+esac
+
+# TODO The `no-async` option seems weird, but
+# https://github.com/openssl/openssl/issues/1607
+
+# TODO I stole the no-dso option from the here[1], but is it
+# needed? I seems to be related to shared libraries, which we aren't using
+# anyways, but I don't like not understanding.
+#
+# [1]: https://github.com/rust-embedded/cross/blob/master/docker/openssl.sh
+
+# TODO Why `-fPIC`? I stole it from [2]
+#
+# [2]: https://github.com/rust-embedded/cross/pull/218/files
+
+../openssl-$version/Configure \
+ --prefix=$out \
+ --cross-compile-prefix=$host- \
+ no-shared \
+ no-dso \
+ no-async \
+ $confighost \
+ -fPIC
+
+make
+make install
diff --git a/nix/nixcrpkgs/pkgs/openssl/default.nix b/nix/nixcrpkgs/pkgs/openssl/default.nix
new file mode 100644
index 000000000..de9b876f9
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/openssl/default.nix
@@ -0,0 +1,83 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "openssl-${version}";
+ version = "1.1.1";
+
+ native_inputs = [ crossenv.nixpkgs.perl ];
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.openssl.org/source/${name}.tar.gz";
+ sha256 = "0gbab2fjgms1kx5xjvqx8bxhr98k4r8l2fa8vw7kvh491xd8fdi8";
+ };
+
+ builder = ./builder.sh;
+}
+
+# let
+#
+# coreutils = crossenv.nixpkgs.coreutils;
+#
+# # with stdenv.lib;
+#
+# in
+#
+# {
+#
+# patches = [ ./nix-ssl-cert-file.patch ];
+#
+# native_inputs = [ crossenv.nixpkgs.perl ];
+#
+# postPatch = ''
+# patchShebangs Configure
+# '' + optionalString (versionAtLeast version "1.1.1") ''
+# substituteInPlace config --replace '/usr/bin/env' '${coreutils}/bin/env'
+# '' + optionalString (versionAtLeast version "1.1.0" && stdenv.hostPlatform.isMusl) ''
+# substituteInPlace crypto/async/arch/async_posix.h \
+# --replace '!defined(__ANDROID__) && !defined(__OpenBSD__)' \
+# '!defined(__ANDROID__) && !defined(__OpenBSD__) && 0'
+# '';
+#
+# configureScript = {
+# "x86_64-darwin" = "./Configure darwin64-x86_64-cc";
+# "x86_64-solaris" = "./Configure solaris64-x86_64-gcc";
+# "armv6l-linux" = "./Configure linux-armv4 -march=armv6";
+# "armv7l-linux" = "./Configure linux-armv4 -march=armv7-a";
+# }.${stdenv.hostPlatform.system} or (
+# if stdenv.hostPlatform == stdenv.buildPlatform
+# then "./config"
+# else if stdenv.hostPlatform.isMinGW
+# then "./Configure mingw${optionalString
+# (stdenv.hostPlatform.parsed.cpu.bits != 32)
+# (toString stdenv.hostPlatform.parsed.cpu.bits)}"
+# else if stdenv.hostPlatform.isLinux
+# then "./Configure linux-generic${toString stdenv.hostPlatform.parsed.cpu.bits}"
+# else if stdenv.hostPlatform.isiOS
+# then "./Configure ios${toString stdenv.hostPlatform.parsed.cpu.bits}-cross"
+# else
+# throw "Not sure what configuration to use for ${stdenv.hostPlatform.config}"
+# );
+#
+# configureFlags = [
+# "shared" # "shared" builds both shared and static libraries
+# "--libdir=lib"
+# "--openssldir=etc/ssl"
+# ] ++ stdenv.lib.optionals withCryptodev [
+# "-DHAVE_CRYPTODEV"
+# "-DUSE_CRYPTODEV_DIGESTS"
+# ]
+# ++ stdenv.lib.optional (versionAtLeast version "1.1.0" && stdenv.hostPlatform.isAarch64) "no-afalgeng";
+#
+# postInstall = ''
+# mkdir -p $bin
+# mv $out/bin $bin/
+#
+# mkdir $dev
+# mv $out/include $dev/
+#
+# # remove dependency on Perl at runtime
+# rm -r $out/etc/ssl/misc
+#
+# rmdir $out/etc/ssl/{certs,private}
+# '';
+# };
diff --git a/nix/nixcrpkgs/pkgs/p-load/builder.sh b/nix/nixcrpkgs/pkgs/p-load/builder.sh
new file mode 100644
index 000000000..7ebc2e6ac
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/p-load/builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv p-load-* p-load
+
+mkdir build
+cd build
+
+cmake-cross ../p-load \
+ -DCMAKE_INSTALL_PREFIX=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/p-load/default.nix b/nix/nixcrpkgs/pkgs/p-load/default.nix
new file mode 100644
index 000000000..6ce88528b
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/p-load/default.nix
@@ -0,0 +1,16 @@
+{ crossenv, libusbp }:
+
+crossenv.make_derivation rec {
+ name = "p-load-${version}";
+
+ version = "2041b02"; # 2.1.0ish
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/pololu/p-load/archive/${version}.tar.gz";
+ sha256 = "07xn0k96pkvirsh45zn9976lwliiqkfx76vy1yrbx6kp55ssp2zp";
+ };
+
+ builder = ./builder.sh;
+
+ cross_inputs = [ libusbp ];
+}
diff --git a/nix/nixcrpkgs/pkgs/pavr2/builder.sh b/nix/nixcrpkgs/pkgs/pavr2/builder.sh
new file mode 100644
index 000000000..b516b6926
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pavr2/builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv pololu-usb-avr-programmer-v2-* pavr2
+
+mkdir build
+cd build
+
+cmake-cross ../pavr2 \
+ -DCMAKE_INSTALL_PREFIX=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/pavr2/default.nix b/nix/nixcrpkgs/pkgs/pavr2/default.nix
new file mode 100644
index 000000000..379e61b51
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pavr2/default.nix
@@ -0,0 +1,16 @@
+{ crossenv, qt, libusbp }:
+
+crossenv.make_derivation rec {
+ name = "pavr2-${version}";
+
+ version = "a113a3b"; # 1.0.2ish
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/pololu/pololu-usb-avr-programmer-v2/archive/${version}.tar.gz";
+ sha256 = "1mg467jx7mpcn01vh8rq80w7p8mbj7l69dmpyni0nik44ggsj7ij";
+ };
+
+ builder = ./builder.sh;
+
+ cross_inputs = [ libusbp qt ];
+}
diff --git a/nix/nixcrpkgs/pkgs/pdcurses/builder.sh b/nix/nixcrpkgs/pkgs/pdcurses/builder.sh
new file mode 100644
index 000000000..e9dc46205
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pdcurses/builder.sh
@@ -0,0 +1,37 @@
+source $setup
+
+tar -xf $src
+mv PDCurses-* pdcurses
+
+mkdir build
+cd build
+
+source_files=../pdcurses/pdcurses/*.c
+
+if [ "$os" == "windows" ]; then
+ os_files=../pdcurses/win32/*.c
+fi
+
+if [ "$os" == "linux" ]; then
+ os_files=
+fi
+
+source_files="$source_files $os_files"
+
+for s in $source_files; do
+ echo "compiling $s"
+ $host-gcc -g -O2 -I../pdcurses \
+ -DPDC_WIDE -DPDC_FORCE_UTF8 -c "$s" -o "$(basename $s).o"
+done
+
+$host-ar r libpdcurses.a *.o
+$host-ranlib libpdcurses.a
+
+mkdir -p $out/{lib,include}
+cp libpdcurses.a $out/lib/libpdcurses.a
+
+# Make libcurses.a so programs like GDB can find pdcurses.
+ln -s $out/lib/libpdcurses.a $out/lib/libcurses.a
+
+cd ../pdcurses
+cp curses.h panel.h term.h $out/include/
diff --git a/nix/nixcrpkgs/pkgs/pdcurses/default.nix b/nix/nixcrpkgs/pkgs/pdcurses/default.nix
new file mode 100644
index 000000000..0a47f6564
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pdcurses/default.nix
@@ -0,0 +1,16 @@
+# Note: This only seems to work on Windows.
+
+{ crossenv }:
+
+let
+
+ pdcurses = import ./lib.nix {
+ inherit crossenv;
+ };
+
+ examples = import ./examples.nix {
+ inherit crossenv pdcurses;
+ };
+
+in
+ pdcurses // { inherit examples; }
diff --git a/nix/nixcrpkgs/pkgs/pdcurses/demos_builder.sh b/nix/nixcrpkgs/pkgs/pdcurses/demos_builder.sh
new file mode 100644
index 000000000..eea6a6737
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pdcurses/demos_builder.sh
@@ -0,0 +1,25 @@
+source $setup
+
+tar -xf $src
+mv PDCurses-$version/demos .
+rm -r PDCurses-$version
+
+mkdir build
+cd build
+
+CFLAGS="-g -O2 -I$pdcurses/include -DPDC_WIDE"
+
+$host-gcc $CFLAGS -c ../demos/tui.c -o tui.o
+$host-ar r tui.a tui.o
+
+demos="firework newdemo ptest rain testcurs worm xmas tuidemo"
+
+for name in $demos; do
+ src=../demos/$name.c
+ echo "compiling $name"
+ $host-gcc $CFLAGS -L"$pdcurses/lib" \
+ "$src" tui.a -lpdcurses -o "$name.exe"
+done
+
+mkdir -p $out/bin
+mv *.exe $out/bin/
diff --git a/nix/nixcrpkgs/pkgs/pdcurses/examples.nix b/nix/nixcrpkgs/pkgs/pdcurses/examples.nix
new file mode 100644
index 000000000..8b3dbee38
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pdcurses/examples.nix
@@ -0,0 +1,11 @@
+{ crossenv, pdcurses }:
+
+crossenv.make_derivation rec {
+ name = "pdcurses_demos-${version}";
+
+ inherit pdcurses;
+ inherit (pdcurses) src version;
+
+ builder = ./demos_builder.sh;
+}
+
diff --git a/nix/nixcrpkgs/pkgs/pdcurses/lib.nix b/nix/nixcrpkgs/pkgs/pdcurses/lib.nix
new file mode 100644
index 000000000..ef4293502
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/pdcurses/lib.nix
@@ -0,0 +1,16 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "pdcurses-${version}";
+
+ version = "3.4";
+
+ src = crossenv.nixpkgs.fetchurl {
+ # Sourceforge went down. The original URL was:
+ # url = "mirror://sourceforge/pdcurses/PDCurses-${version}.tar.gz";
+ url = "https://files.tmphax.com/repo1/pdcurses-${version}.tar.gz";
+ sha256 = "0jz6l8552fnf1j542yhzifgknrdzrisxg158ks0l87g777a8zba6";
+ };
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/qt/absolute-paths.patch b/nix/nixcrpkgs/pkgs/qt/absolute-paths.patch
new file mode 100644
index 000000000..93ab1e1fc
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/absolute-paths.patch
@@ -0,0 +1,63 @@
+diff -ur qtbase-opensource-src-5.9.2-orig/configure qtbase-opensource-src-5.9.2/configure
+--- qtbase-opensource-src-5.9.2-orig/configure 2017-10-26 08:10:12.932646805 -0700
++++ qtbase-opensource-src-5.9.2/configure 2017-11-01 08:48:44.973917507 -0700
+@@ -36,9 +36,9 @@
+ relconf=`basename $0`
+ # the directory of this script is the "source tree"
+ relpath=`dirname $0`
+-relpath=`(cd "$relpath"; /bin/pwd)`
++relpath=`(cd "$relpath"; pwd)`
+ # the current directory is the "build tree" or "object tree"
+-outpath=`/bin/pwd`
++outpath=`pwd`
+
+ WHICH="which"
+
+@@ -232,7 +232,7 @@
+
+ sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1")
+ if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi
+- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null)
++ sysroot=$(xcrun --sdk $sdk --show-sdk-path 2>/dev/null)
+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi
+
+ case "$sdk" in
+@@ -267,7 +267,7 @@
+ # Prefix tool with toolchain path
+ var=$(echo "$line" | cut -d '=' -f 1)
+ val=$(echo "$line" | cut -d '=' -f 2-)
+- sdk_val=$(/usr/bin/xcrun -sdk $sdk -find $(echo $val | cut -d ' ' -f 1))
++ sdk_val=$(xcrun -sdk $sdk -find $(echo $val | cut -d ' ' -f 1))
+ val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
+ echo "$var=$val"
+ ;;
+@@ -305,9 +305,6 @@
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+
+ BUILD_ON_MAC=no
+-if [ -d /System/Library/Frameworks/Carbon.framework ]; then
+- BUILD_ON_MAC=yes
+-fi
+ if [ "$OSTYPE" = "msys" ]; then
+ relpath=`(cd "$relpath"; pwd -W)`
+ outpath=`pwd -W`
+@@ -318,7 +315,7 @@
+ #-------------------------------------------------------------------------------
+
+ if [ "$BUILD_ON_MAC" = "yes" ]; then
+- if ! /usr/bin/xcode-select --print-path >/dev/null 2>&1; then
++ if ! xcode-select --print-path >/dev/null 2>&1; then
+ echo >&2
+ echo " No Xcode selected. Please install Xcode via the App Store, " >&2
+ echo " or the command line developer tools via xcode-select --install, " >&2
+@@ -329,8 +326,8 @@
+ fi
+
+ # In the else case we are probably using a Command Line Tools installation
+- if /usr/bin/xcrun -find xcodebuild >/dev/null 2>&1; then
+- if ! /usr/bin/xcrun xcodebuild -license check 2>/dev/null; then
++ if xcrun -find xcodebuild >/dev/null 2>&1; then
++ if ! xcrun xcodebuild -license check 2>/dev/null; then
+ echo >&2
+ echo " Xcode setup not complete. You need to confirm the license" >&2
+ echo " agreement by running 'sudo xcrun xcodebuild -license accept'." >&2
diff --git a/nix/nixcrpkgs/pkgs/qt/builder.sh b/nix/nixcrpkgs/pkgs/qt/builder.sh
new file mode 100644
index 000000000..1668ce280
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/builder.sh
@@ -0,0 +1,23 @@
+source $setup
+
+mkdir -p $out
+pushd $out
+tar -xf $src
+mv qtbase-opensource-src-* src
+cd src
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+popd
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+$out/src/configure -prefix $out $configure_flags
+
+make
+
+make install
+
diff --git a/nix/nixcrpkgs/pkgs/qt/core_macros.cmake b/nix/nixcrpkgs/pkgs/qt/core_macros.cmake
new file mode 100644
index 000000000..f3ef672fd
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/core_macros.cmake
@@ -0,0 +1,106 @@
+# These macros come from src/corelib/Qt5CoreMacros.cmake originally.
+
+#=============================================================================
+# Copyright 2005-2011 Kitware, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Kitware, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#=============================================================================
+
+macro(QT5_MAKE_OUTPUT_FILE infile prefix ext outfile )
+ string(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength)
+ string(LENGTH ${infile} _infileLength)
+ set(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR})
+ if(_infileLength GREATER _binlength)
+ string(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile)
+ if(_checkinfile STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ file(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile})
+ else()
+ file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
+ endif()
+ else()
+ file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile})
+ endif()
+ if(WIN32 AND rel MATCHES "^([a-zA-Z]):(.*)$") # absolute path
+ set(rel "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}")
+ endif()
+ set(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}")
+ string(REPLACE ".." "__" _outfile ${_outfile})
+ get_filename_component(outpath ${_outfile} PATH)
+ get_filename_component(_outfile ${_outfile} NAME_WE)
+ file(MAKE_DIRECTORY ${outpath})
+ set(${outfile} ${outpath}/${prefix}${_outfile}.${ext})
+endmacro()
+
+function(_QT5_PARSE_QRC_FILE infile _out_depends _rc_depends)
+ get_filename_component(rc_path ${infile} PATH)
+ if(EXISTS "${infile}")
+ file(READ "${infile}" RC_FILE_CONTENTS)
+ string(REGEX MATCHALL "]*>" "" RC_FILE "${RC_FILE}")
+ if(NOT IS_ABSOLUTE "${RC_FILE}")
+ set(RC_FILE "${rc_path}/${RC_FILE}")
+ endif()
+ set(RC_DEPENDS ${RC_DEPENDS} "${RC_FILE}")
+ endforeach()
+ qt5_make_output_file("${infile}" "" "qrc.depends" out_depends)
+ configure_file("${infile}" "${out_depends}" COPYONLY)
+ else()
+ set(out_depends)
+ endif()
+ set(${_out_depends} ${out_depends} PARENT_SCOPE)
+ set(${_rc_depends} ${RC_DEPENDS} PARENT_SCOPE)
+endfunction()
+
+function(QT5_ADD_RESOURCES outfiles )
+ set(options)
+ set(oneValueArgs)
+ set(multiValueArgs OPTIONS)
+ cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ set(rcc_files ${_RCC_UNPARSED_ARGUMENTS})
+ set(rcc_options ${_RCC_OPTIONS})
+
+ if("${rcc_options}" MATCHES "-binary")
+ message(WARNING "Use qt5_add_binary_resources for binary option")
+ endif()
+
+ foreach(it ${rcc_files})
+ get_filename_component(outfilename ${it} NAME_WE)
+ get_filename_component(infile ${it} ABSOLUTE)
+ set(outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${outfilename}.cpp)
+ _QT5_PARSE_QRC_FILE(${infile} _out_depends _rc_depends)
+ add_custom_command(OUTPUT ${outfile}
+ COMMAND ${Qt5Core_RCC_EXECUTABLE}
+ ARGS ${rcc_options} --name ${outfilename} --output ${outfile} ${infile}
+ MAIN_DEPENDENCY ${infile}
+ DEPENDS ${_rc_depends} "${out_depends}" VERBATIM)
+ list(APPEND ${outfiles} ${outfile})
+ endforeach()
+ set(${outfiles} ${${outfiles}} PARENT_SCOPE)
+endfunction()
diff --git a/nix/nixcrpkgs/pkgs/qt/dbus-null-pointer.patch b/nix/nixcrpkgs/pkgs/qt/dbus-null-pointer.patch
new file mode 100644
index 000000000..8e8543c62
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/dbus-null-pointer.patch
@@ -0,0 +1,12 @@
+diff -ur qtbase-opensource-src-5.9.6-orig/src/platformsupport/linuxaccessibility/dbusconnection.cpp qtbase-opensource-src-5.9.6/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+--- qtbase-opensource-src-5.9.6-orig/src/platformsupport/linuxaccessibility/dbusconnection.cpp 2018-06-19 12:42:00.533895696 -0700
++++ qtbase-opensource-src-5.9.6/src/platformsupport/linuxaccessibility/dbusconnection.cpp 2018-06-19 12:45:03.308744607 -0700
+@@ -75,7 +75,7 @@
+ connect(dbusWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered()));
+
+ // If it is registered already, setup a11y right away
+- if (c.interface()->isServiceRegistered(A11Y_SERVICE))
++ if (c.interface() && c.interface()->isServiceRegistered(A11Y_SERVICE))
+ serviceRegistered();
+
+ // In addition try if there is an xatom exposing the bus address, this allows applications run as root to work
diff --git a/nix/nixcrpkgs/pkgs/qt/default.nix b/nix/nixcrpkgs/pkgs/qt/default.nix
new file mode 100644
index 000000000..5a9f4d675
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/default.nix
@@ -0,0 +1,165 @@
+# TODO: look into why were compiling with this impure option on Linux:
+# -DDFLT_XKB_CONFIG_ROOT=\"/usr/share/X11/xkb\"
+
+# TODO: patch qt to not use /bin/pwd, test building it in a sandbox
+
+{ crossenv, libudev, libxall, at-spi2-headers, dejavu-fonts }:
+
+let
+ version = "5.9.6";
+
+ name = "qtbase-${version}";
+
+ platform =
+ let
+ os_code =
+ if crossenv.os == "windows" then "win32"
+ else if crossenv.os == "macos" then "macx"
+ else if crossenv.os == "linux" then "devices/linux-generic"
+ else crossenv.os;
+ compiler_code =
+ if crossenv.compiler == "gcc" then "g++"
+ else crossenv.compiler;
+ in "${os_code}-${compiler_code}";
+
+ base_src = crossenv.nixpkgs.fetchurl {
+ url = "https://download.qt.io/official_releases/qt/5.9/${version}/submodules/qtbase-opensource-src-${version}.tar.xz";
+ sha256 = "0vz3rgx7bk50jzy78lxv5pff2l8xqmqs9iiz7gc9n6cb4v5j1mpf";
+ };
+
+ base_raw = crossenv.make_derivation {
+ name = "qtbase-raw-${version}";
+ inherit version;
+ src = base_src;
+ builder = ./builder.sh;
+
+ patches = [
+ # Purity issue: Don't look at the build system using absolute paths.
+ ./absolute-paths.patch
+
+ # macOS configuration: Don't run tools from /usr/bin, use the right
+ # compiler, and don't pass redundant options to it (-arch, -isysroot,
+ # -mmacosx-version-min).
+ ./macos-config.patch
+
+ # libX11.a depends on libxcb.a. This makes tests.xlib in
+ # src/gui/configure.json pass, enabling lots of X functionality in Qt.
+ ./find-x-libs.patch
+
+ # Fix the build error caused by https://bugreports.qt.io/browse/QTBUG-63637
+ ./win32-link-object-max.patch
+
+ # The .pc files have incorrect library names without this (e.g. Qt5Cored)
+ ./pc-debug-name.patch
+
+ # uxtheme.h test is broken, always returns false, and results in QtWidgets
+ # apps looking bad on Windows. https://stackoverflow.com/q/44784414/28128
+ ./dont-test-uxtheme.patch
+
+ # When cross-compiling, Qt uses some heuristics about whether to trust the
+ # pkg-config executable supplied by the PKG_CONFIG environment variable.
+ # These heuristics are wrong for us, so disable them, making qt use
+ # pkg-config-cross.
+ ./pkg-config-cross.patch
+
+ # When the DBus session bus is not available, Qt tries to dereference a
+ # null pointer, so Linux applications can't start up.
+ ./dbus-null-pointer.patch
+
+ # Look for fonts in the same directory as the application by default if
+ # the QT_QPA_FONTDIR environment variable is not present. Without this
+ # patch, Qt tries to look for a font directory in the nix store that does
+ # not exists, and prints warnings.
+ # You must ship a .ttf, .ttc, .pfa, .pfb, or .otf font file
+ # with your application (e.g. https://dejavu-fonts.github.io/ ).
+ # That list of extensions comes from qbasicfontdatabase.cpp.
+ ./font-dir.patch
+ ];
+
+ configure_flags =
+ "-opensource -confirm-license " +
+ "-xplatform ${platform} " +
+ "-device-option CROSS_COMPILE=${crossenv.host}- " +
+ "-release " + # change to -debug if you want debugging symbols
+ "-static " +
+ "-pkg-config " +
+ "-nomake examples " +
+ "-no-icu " +
+ "-no-fontconfig " +
+ "-no-reduce-relocations " +
+ ( if crossenv.os == "windows" then
+ "-opengl desktop"
+ else if crossenv.os == "linux" then
+ "-qpa xcb " +
+ "-system-xcb " +
+ "-no-opengl " +
+ "-device-option QMAKE_INCDIR_X11=${libxall}/include " +
+ "-device-option QMAKE_LIBDIR_X11=${libxall}/lib"
+ else if crossenv.os == "macos" then
+ "-device-option QMAKE_MAC_SDK.macosx.--show-sdk-path=" +
+ "${crossenv.sdk} " +
+ "-device-option QMAKE_MAC_SDK.macosx.--show-sdk-platform-path=" +
+ "${crossenv.sdk}/does-not-exist " +
+ "-device-option QMAKE_MAC_SDK.macosx.--show-sdk-version=" +
+ "${crossenv.macos_version_min} " +
+ "-device-option QMAKE_XCODE_VERSION=7.0"
+ else "" );
+
+ cross_inputs =
+ if crossenv.os == "linux" then [
+ libudev # not sure if this helps, but Qt does look for it
+ libxall
+ at-spi2-headers # for accessibility
+ ]
+ else [];
+ };
+
+ # This wrapper aims to make Qt easier to use by generating CMake package files
+ # for it. The existing support for CMake in Qt does not handle static
+ # linking; other projects maintian large, messy patches to fix it, but we
+ # prefer to generate the CMake files in a clean way from scratch.
+ base = crossenv.make_derivation {
+ inherit version name;
+ os = crossenv.os;
+ qtbase = base_raw;
+ cross_inputs = base_raw.cross_inputs;
+ builder.ruby = ./wrapper_builder.rb;
+ core_macros = ./core_macros.cmake;
+ };
+
+ examples = crossenv.make_derivation {
+ name = "qtbase-examples-${version}";
+ inherit version;
+ os = crossenv.os;
+ qtbase = base;
+ cross_inputs = [ base ];
+ dejavu = dejavu-fonts;
+ builder = ./examples_builder.sh;
+ };
+
+ license_fragment = crossenv.native.make_derivation {
+ name = "qtbase-${version}-license-fragment";
+ inherit version;
+ src = base_src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ (
+ if crossenv.os == "linux" then
+ libudev.license_set //
+ libxall.license_set //
+ at-spi2-headers.license_set
+ else
+ {}
+ ) //
+ { "${name}" = license_fragment; };
+in
+ base // {
+ recurseForDerivations = true;
+ inherit base_src;
+ inherit base_raw;
+ inherit base;
+ inherit examples;
+ inherit license_set;
+ }
diff --git a/nix/nixcrpkgs/pkgs/qt/dont-test-uxtheme.patch b/nix/nixcrpkgs/pkgs/qt/dont-test-uxtheme.patch
new file mode 100644
index 000000000..c41620138
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/dont-test-uxtheme.patch
@@ -0,0 +1,24 @@
+diff -ur qtbase-opensource-src-5.9.2-orig/src/widgets/configure.json qtbase-opensource-src-5.9.2/src/widgets/configure.json
+--- qtbase-opensource-src-5.9.2-orig/src/widgets/configure.json 2017-10-25 13:52:49.173421900 -0700
++++ qtbase-opensource-src-5.9.2/src/widgets/configure.json 2017-10-25 13:53:42.891341214 -0700
+@@ -28,11 +28,6 @@
+ },
+
+ "tests": {
+- "uxtheme": {
+- "label": "uxtheme.h",
+- "type": "files",
+- "files": [ "uxtheme.h" ]
+- }
+ },
+
+ "features": {
+@@ -57,7 +52,7 @@
+ },
+ "style-windowsxp": {
+ "label": "WindowsXP",
+- "condition": "features.style-windows && config.win32 && !config.winrt && tests.uxtheme",
++ "condition": "features.style-windows && config.win32 && !config.winrt",
+ "output": [ "privateFeature", "styles" ]
+ },
+ "style-windowsvista": {
diff --git a/nix/nixcrpkgs/pkgs/qt/examples_builder.sh b/nix/nixcrpkgs/pkgs/qt/examples_builder.sh
new file mode 100644
index 000000000..d5d56e11c
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/examples_builder.sh
@@ -0,0 +1,88 @@
+source $setup
+
+examples=$qtbase/src/examples
+
+mkdir build
+cd build
+mkdir bin moc obj
+
+cat > obj/plugins.cpp <
+#ifdef _WIN32
+Q_IMPORT_PLUGIN (QWindowsIntegrationPlugin);
+#endif
+#ifdef __linux__
+Q_IMPORT_PLUGIN (QLinuxFbIntegrationPlugin);
+Q_IMPORT_PLUGIN (QXcbIntegrationPlugin);
+#endif
+EOF
+
+CFLAGS="-std=gnu++11"
+
+echo "compiling reference to plugins"
+$host-g++ $CFLAGS \
+ $(pkg-config-cross --cflags Qt5Core) \
+ -c obj/plugins.cpp \
+ -o obj/plugins.o
+
+CFLAGS="$CFLAGS -g -I. $(pkg-config-cross --cflags Qt5Widgets)"
+LIBS="$(pkg-config-cross --libs Qt5Widgets)"
+LDFLAGS=""
+
+if [ $os = "windows" ]; then
+ CFLAGS="-mwindows $CFLAGS"
+fi
+
+echo "compiling dynamiclayouts"
+$qtbase/bin/moc $examples/widgets/layouts/dynamiclayouts/dialog.h > moc/dynamiclayouts.cpp
+$host-g++ $CFLAGS $LDFLAGS \
+ $examples/widgets/layouts/dynamiclayouts/dialog.cpp \
+ $examples/widgets/layouts/dynamiclayouts/main.cpp \
+ moc/dynamiclayouts.cpp \
+ obj/plugins.o \
+ $LIBS -o bin/dynamiclayouts$exe_suffix
+
+echo "compiling rasterwindow"
+$qtbase/bin/moc $examples/gui/rasterwindow/rasterwindow.h > moc/rasterwindow.cpp
+$host-g++ $CFLAGS $LDFLAGS \
+ $examples/gui/rasterwindow/rasterwindow.cpp \
+ $examples/gui/rasterwindow/main.cpp \
+ moc/rasterwindow.cpp \
+ obj/plugins.o \
+ $LIBS -o bin/rasterwindow$exe_suffix
+
+echo "compiling analogclock"
+$host-g++ $CFLAGS $LDFLAGS \
+ -I$examples/gui/rasterwindow/ \
+ $examples/gui/analogclock/main.cpp \
+ $examples/gui/rasterwindow/rasterwindow.cpp \
+ moc/rasterwindow.cpp \
+ obj/plugins.o \
+ $LIBS -o bin/analogclock$exe_suffix
+
+# We haven't gotten OpenGL support to work on Linux yet (TODO)
+if [ $os != "linux" ]; then
+ echo "compiling openglwindow"
+ $qtbase/bin/moc $examples/gui/openglwindow/openglwindow.h > moc/openglwindow.cpp
+ $host-g++ $CFLAGS $LDFLAGS \
+ $examples/gui/openglwindow/main.cpp \
+ $examples/gui/openglwindow/openglwindow.cpp \
+ moc/openglwindow.cpp \
+ obj/plugins.o \
+ $LIBS -o bin/openglwindow$exe_suffix
+fi
+
+# TODO: try to compile some stuff with $qtbase/bin/qmake too, make sure that works
+
+mkdir -p $out/bin
+
+for prog in analogclock dynamiclayouts openglwindow rasterwindow; do
+ if [ -f bin/$prog ]; then
+ $host-strip bin/$prog
+ cp bin/$prog $out/bin/
+ fi
+done
+
+if [ $os = "linux" ]; then
+ cp $dejavu/ttf/DejaVuSans.ttf $out/bin/
+fi
diff --git a/nix/nixcrpkgs/pkgs/qt/find-x-libs.patch b/nix/nixcrpkgs/pkgs/qt/find-x-libs.patch
new file mode 100644
index 000000000..73bd77005
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/find-x-libs.patch
@@ -0,0 +1,12 @@
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/common/linux.conf qtbase-opensource-src-5.9.2/mkspecs/common/linux.conf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/common/linux.conf 2017-10-26 08:10:12.922646692 -0700
++++ qtbase-opensource-src-5.9.2/mkspecs/common/linux.conf 2017-10-26 21:44:37.695088447 -0700
+@@ -28,7 +28,7 @@
+
+ QMAKE_LIBS =
+ QMAKE_LIBS_DYNLOAD = -ldl
+-QMAKE_LIBS_X11 = -lXext -lX11 -lm
++QMAKE_LIBS_X11 = -lXext -lX11 -lxcb -lXau
+ QMAKE_LIBS_EGL = -lEGL
+ QMAKE_LIBS_OPENGL = -lGL
+ QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
diff --git a/nix/nixcrpkgs/pkgs/qt/font-dir.patch b/nix/nixcrpkgs/pkgs/qt/font-dir.patch
new file mode 100644
index 000000000..ab8384764
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/font-dir.patch
@@ -0,0 +1,11 @@
+--- qt-5.8.0-orig/src/gui/text/qplatformfontdatabase.cpp
++++ qt-5.8.0/src/gui/text/qplatformfontdatabase.cpp
+@@ -396,7 +396,7 @@
+ {
+ QString fontpath = QString::fromLocal8Bit(qgetenv("QT_QPA_FONTDIR"));
+ if (fontpath.isEmpty())
+- fontpath = QLibraryInfo::location(QLibraryInfo::LibrariesPath) + QLatin1String("/fonts");
++ fontpath = QCoreApplication::applicationDirPath();
+
+ return fontpath;
+ }
diff --git a/nix/nixcrpkgs/pkgs/qt/license_builder.sh b/nix/nixcrpkgs/pkgs/qt/license_builder.sh
new file mode 100644
index 000000000..f0fec2354
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/license_builder.sh
@@ -0,0 +1,151 @@
+# Last updated for qtbase-opensource-src-5.8.0.tar.xz
+
+source $setup
+
+if [ "$version" != "5.9.6" ]; then
+ echo "You need to update the license fragment builder for Qt $version."
+ exit 1
+fi
+
+tar -xf $src
+mv qtbase-* qtbase
+
+# Read the license files here instead of in the big string so it is a fatal
+# error if any of them are missing.
+license_qt=$(cat qtbase/LICENSE.LGPLv3)
+cd qtbase/src/3rdparty
+license_android=$(cat android/LICENSE)
+license_angle1=$(cat angle/LICENSE)
+license_angle2=$(cat angle/TRACEEVENT_LICENSE)
+license_angle3=$(cat angle/SYSTEMINFO_LICENSE)
+license_dc=$(cat double-conversion/LICENSE)
+license_easing=$(cat easing/LICENSE)
+license_forkfd=$(cat forkfd/LICENSE)
+license_freebsd=$(cat freebsd/LICENSE)
+license_freetype=$(cat freetype/docs/GPLv2.TXT)
+license_gradle=$(cat gradle/LICENSE-GRADLEW.txt)
+license_harfbuzz=$(cat harfbuzz/COPYING)
+license_harfbuzz_ng=$(cat harfbuzz-ng/COPYING)
+license_ia2=$(cat iaccessible2/LICENSE)
+license_libjpeg=$(cat libjpeg/LICENSE)
+license_libpng=$(cat libpng/LICENSE)
+license_pcre2=$(cat pcre2/LICENCE)
+license_pixman=$(cat pixman/LICENSE)
+license_rfc6234=$(cat rfc6234/LICENSE)
+license_sha3_1=$(cat sha3/BRG_ENDIAN_LICENSE)
+license_sha3_2=$(cat sha3/CC0_LICENSE)
+license_xcb=$(cat xcb/LICENSE)
+license_xkbcommon=$(cat xkbcommon/COPYING)
+license_zlib=$(cat zlib/LICENSE)
+
+cat > $out <Qt
+
+
+ The Qt Toolkit is licensed under the
+ GNU Lesser General Public License Version 3 (LGPLv3) as shown below.
+
+
+
+$license_qt
+
+
+Third-party components bundled with Qt
+
+
+ This software might include code from third-party comoponents bundled with Qt.
+ The copyright notices of those components are reproduced below.
+
+
+
+$license_android
+
+
+
+$license_angle1
+
+
+
+$license_angle2
+
+
+
+$license_angle3
+
+
+
+$license_dc
+
+
+
+$license_easing
+
+
+
+$license_forkfd
+
+
+
+$license_freebsd
+
+
+
+$license_freetype
+
+
+
+$license_gradle
+
+
+
+$license_harfbuzz
+
+
+
+$license_harfbuzz_ng
+
+
+
+$license_ia2
+
+
+
+$license_libjpeg
+
+
+
+$license_libpng
+
+
+
+$license_pcre2
+
+
+
+$license_pixman
+
+
+
+$license_rfc6234
+
+
+
+$license_sha3_1
+
+
+
+$license_sha3_2
+
+
+
+$license_xcb
+
+
+
+$license_xkbcommon
+
+
+
+$license_zlib
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/qt/macos-config.patch b/nix/nixcrpkgs/pkgs/qt/macos-config.patch
new file mode 100644
index 000000000..de8c3a282
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/macos-config.patch
@@ -0,0 +1,167 @@
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/common/clang.conf qtbase-opensource-src-5.9.2-mac/mkspecs/common/clang.conf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/common/clang.conf 2017-11-03 20:37:01.001539490 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/common/clang.conf 2017-11-03 20:46:20.159382848 -0700
+@@ -4,8 +4,8 @@
+
+ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc
+
+-QMAKE_CC = clang
+-QMAKE_CXX = clang++
++QMAKE_CC = $${CROSS_COMPILE}clang
++QMAKE_CXX = $${CROSS_COMPILE}clang++
+
+ QMAKE_LINK_C = $$QMAKE_CC
+ QMAKE_LINK_C_SHLIB = $$QMAKE_CC
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/common/clang-mac.conf qtbase-opensource-src-5.9.2-mac/mkspecs/common/clang-mac.conf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/common/clang-mac.conf 2017-11-03 20:37:01.001539490 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/common/clang-mac.conf 2017-11-03 20:55:13.878575754 -0700
+@@ -6,8 +6,6 @@
+
+ QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvm.clang.1_0
+
+-QMAKE_CXXFLAGS += -stdlib=libc++
+-QMAKE_LFLAGS += -stdlib=libc++
+ QMAKE_AR_LTCG = libtool -static -o
+
+ QMAKE_CFLAGS_APPLICATION_EXTENSION = -fapplication-extension
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/common/mac.conf qtbase-opensource-src-5.9.2-mac/mkspecs/common/mac.conf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/common/mac.conf 2017-11-03 20:37:01.001539490 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/common/mac.conf 2017-11-03 22:03:30.960602142 -0700
+@@ -35,10 +35,10 @@
+
+ QMAKE_ACTOOL = actool
+
+-QMAKE_DSYMUTIL = dsymutil
+-QMAKE_STRIP = strip
++QMAKE_DSYMUTIL = $${CROSS_COMPILE}dsymutil
++QMAKE_STRIP = $${CROSS_COMPILE}strip
+ QMAKE_STRIPFLAGS_LIB += -S -x
+
+-QMAKE_AR = ar cq
+-QMAKE_RANLIB = ranlib -s
+-QMAKE_NM = nm -P
++QMAKE_AR = $${CROSS_COMPILE}ar cq
++QMAKE_RANLIB = $${CROSS_COMPILE}ranlib -s
++QMAKE_NM = $${CROSS_COMPILE}nm -P
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/default_post.prf qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/default_post.prf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/default_post.prf 2017-11-03 20:37:01.008206202 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/default_post.prf 2017-11-03 21:06:25.247871399 -0700
+@@ -2,29 +2,6 @@
+
+ !no_objective_c:CONFIG += objective_c
+
+-qt {
+- qtConfig(static) {
+- # C++11 support means using libc++ instead of libstd++. As the
+- # two libraries are incompatible we need to ensure the end user
+- # project is built using the same C++11 support/no support as Qt.
+- qtConfig(c++11) {
+- CONFIG += c++11
+- } else: c++11 {
+- warning("Qt was not built with C++11 enabled, disabling feature")
+- CONFIG -= c++11
+- }
+-
+- !c++11 {
+- # Explicitly use libstdc++ if C++11 support is not enabled,
+- # as otherwise the compiler will choose the standard library
+- # based on the deployment target, which for iOS 7 and OS X 10.9
+- # is libc++, and we can't mix and match the two.
+- QMAKE_CXXFLAGS += -stdlib=libstdc++
+- QMAKE_LFLAGS += -stdlib=libstdc++
+- }
+- }
+-}
+-
+ # Add the same default rpaths as Xcode does for new projects.
+ # This is especially important for iOS/tvOS/watchOS where no other option is possible.
+ !no_default_rpath {
+@@ -89,10 +66,6 @@
+
+ arch_flags = $(EXPORT_ARCH_ARGS)
+
+- QMAKE_CFLAGS += $$arch_flags
+- QMAKE_CXXFLAGS += $$arch_flags
+- QMAKE_LFLAGS += $$arch_flags
+-
+ QMAKE_PCH_ARCHS = $$VALID_ARCHS
+
+ macos: deployment_target = $$QMAKE_MACOSX_DEPLOYMENT_TARGET
+@@ -149,9 +122,6 @@
+ else: \
+ version_identifier = $$device.deployment_identifier
+ version_min_flag = -m$${version_identifier}-version-min=$$deployment_target
+- QMAKE_CFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
+- QMAKE_CXXFLAGS += -isysroot $$QMAKE_MAC_SDK_PATH $$version_min_flag
+- QMAKE_LFLAGS += -Wl,-syslibroot,$$QMAKE_MAC_SDK_PATH $$version_min_flag
+ }
+
+ # Enable precompiled headers for multiple architectures
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/default_pre.prf qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/default_pre.prf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/default_pre.prf 2017-11-03 20:37:01.008206202 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/default_pre.prf 2017-11-03 20:46:20.159382848 -0700
+@@ -1,43 +1,6 @@
+ CONFIG = asset_catalogs rez $$CONFIG
+ load(default_pre)
+
+-isEmpty(QMAKE_XCODE_DEVELOPER_PATH) {
+- # Get path of Xcode's Developer directory
+- QMAKE_XCODE_DEVELOPER_PATH = $$system("/usr/bin/xcode-select --print-path 2>/dev/null")
+- isEmpty(QMAKE_XCODE_DEVELOPER_PATH): \
+- error("Xcode path is not set. Please use xcode-select to choose Xcode installation path.")
+-
+- # Make sure Xcode path is valid
+- !exists($$QMAKE_XCODE_DEVELOPER_PATH): \
+- error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.")
+-}
+-
+-isEmpty(QMAKE_XCODEBUILD_PATH): \
+- QMAKE_XCODEBUILD_PATH = $$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null")
+-
+-!isEmpty(QMAKE_XCODEBUILD_PATH) {
+- # Make sure Xcode is set up properly
+- !system("/usr/bin/xcrun xcodebuild -license check 2>/dev/null"): \
+- error("Xcode not set up properly. You need to confirm the license agreement by running 'sudo xcrun xcodebuild -license accept'.")
+-
+- isEmpty(QMAKE_XCODE_VERSION) {
+- # Extract Xcode version using xcodebuild
+- xcode_version = $$system("/usr/bin/xcrun xcodebuild -version")
+- QMAKE_XCODE_VERSION = $$member(xcode_version, 1)
+- isEmpty(QMAKE_XCODE_VERSION): error("Could not resolve Xcode version.")
+- unset(xcode_version)
+- }
+-}
+-
+-isEmpty(QMAKE_TARGET_BUNDLE_PREFIX) {
+- QMAKE_XCODE_PREFERENCES_FILE = $$(HOME)/Library/Preferences/com.apple.dt.Xcode.plist
+- exists($$QMAKE_XCODE_PREFERENCES_FILE): \
+- QMAKE_TARGET_BUNDLE_PREFIX = $$system("/usr/libexec/PlistBuddy -c 'print IDETemplateOptions:bundleIdentifierPrefix' $$QMAKE_XCODE_PREFERENCES_FILE 2>/dev/null")
+-
+- !isEmpty(_QMAKE_CACHE_):!isEmpty(QMAKE_TARGET_BUNDLE_PREFIX): \
+- cache(QMAKE_TARGET_BUNDLE_PREFIX)
+-}
+-
+ QMAKE_ASSET_CATALOGS_APP_ICON = AppIcon
+
+ # Make the default debug info format for static debug builds
+diff -ur qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/sdk.prf qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/sdk.prf
+--- qtbase-opensource-src-5.9.2-orig/mkspecs/features/mac/sdk.prf 2017-11-03 20:37:01.008206202 -0700
++++ qtbase-opensource-src-5.9.2-mac/mkspecs/features/mac/sdk.prf 2017-11-03 20:46:20.159382848 -0700
+@@ -18,7 +18,7 @@
+ sdk = $$QMAKE_MAC_SDK
+
+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) {
+- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null")
++ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("xcrun --sdk $$sdk $$info 2>/dev/null")
+ # --show-sdk-platform-path won't work for Command Line Tools; this is fine
+ # only used by the XCTest backend to testlib
+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \
+@@ -50,7 +50,7 @@
+ value = $$eval($$tool)
+ isEmpty(value): next()
+
+- sysrooted = $$system("/usr/bin/xcrun -sdk $$QMAKE_MAC_SDK -find $$first(value) 2>/dev/null")
++ sysrooted = $$system("xcrun -sdk $$QMAKE_MAC_SDK -find $$first(value) 2>/dev/null")
+ isEmpty(sysrooted): next()
+
+ $$tool = $$sysrooted $$member(value, 1, -1)
diff --git a/nix/nixcrpkgs/pkgs/qt/pc-debug-name.patch b/nix/nixcrpkgs/pkgs/qt/pc-debug-name.patch
new file mode 100644
index 000000000..690e8bea7
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/pc-debug-name.patch
@@ -0,0 +1,33 @@
+From 995313e0795df5500fd84350e80a3f88202b473d Mon Sep 17 00:00:00 2001
+From: Martchus
+Date: Sun, 18 Sep 2016 14:01:14 +0200
+Subject: [PATCH 07/30] Prevent debug library names in pkg-config files
+
+qmake generates the pkgconfig .pc files two times, once for the
+release build and once for the debug build (which we're not actually
+building in this package). For both generations the exact same
+pkgconfig file name is used. This causes references to the debug
+build ending up in the .pc files which are unwanted
+Prevent this from happening by giving the pkgconfig .pc
+files for the debug build an unique file name.
+---
+ qmake/generators/makefile.cpp | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
+index 182fe79238..a762443fe2 100644
+--- a/qmake/generators/makefile.cpp
++++ b/qmake/generators/makefile.cpp
+@@ -3164,6 +3164,9 @@ MakefileGenerator::pkgConfigFileName(bool fixify, bool onlyPrependDestdir)
+ if (dot != -1)
+ ret = ret.left(dot);
+ }
++ if (project->isActiveConfig("debug")) {
++ ret += "d";
++ }
+ ret += Option::pkgcfg_ext;
+ QString subdir = project->first("QMAKE_PKGCONFIG_DESTDIR").toQString();
+ if(!subdir.isEmpty()) {
+--
+2.11.1
+
diff --git a/nix/nixcrpkgs/pkgs/qt/pkg-config-cross.patch b/nix/nixcrpkgs/pkgs/qt/pkg-config-cross.patch
new file mode 100644
index 000000000..506df0ff8
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/pkg-config-cross.patch
@@ -0,0 +1,13 @@
+diff -ur qt-orig/configure.pri qt/configure.pri
+--- qt-orig/configure.pri 2017-07-27 18:16:48.205591390 -0700
++++ qt/configure.pri 2017-07-29 13:11:08.957085166 -0700
+@@ -139,7 +139,8 @@
+ }
+ }
+
+- $$qtConfEvaluate("features.cross_compile") {
++ qtLog("Blindly trusting this pkg-config to be valid.");
++ false {
+ # cross compiling, check that pkg-config is set up sanely
+ sysroot = $$config.input.sysroot
+
diff --git a/nix/nixcrpkgs/pkgs/qt/win32-link-object-max.patch b/nix/nixcrpkgs/pkgs/qt/win32-link-object-max.patch
new file mode 100644
index 000000000..c47279b2e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/win32-link-object-max.patch
@@ -0,0 +1,16 @@
+diff -ur qtbase-opensource-src-5.9.6-orig/mkspecs/win32-g++/qmake.conf qtbase-opensource-src-5.9.6/mkspecs/win32-g++/qmake.conf
+--- qtbase-opensource-src-5.9.6-orig/mkspecs/win32-g++/qmake.conf 2018-06-19 12:41:49.061465695 -0700
++++ qtbase-opensource-src-5.9.6/mkspecs/win32-g++/qmake.conf 2018-06-19 12:42:15.406453120 -0700
+@@ -54,10 +54,8 @@
+ QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
+ QMAKE_LFLAGS_DLL = -shared
+ QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections
+-equals(QMAKE_HOST.os, Windows) {
+- QMAKE_LINK_OBJECT_MAX = 10
+- QMAKE_LINK_OBJECT_SCRIPT = object_script
+-}
++QMAKE_LINK_OBJECT_MAX = 10
++QMAKE_LINK_OBJECT_SCRIPT = object_script
+ QMAKE_EXT_OBJ = .o
+ QMAKE_EXT_RES = _res.o
+ QMAKE_PREFIX_SHLIB =
diff --git a/nix/nixcrpkgs/pkgs/qt/wrapper_builder.rb b/nix/nixcrpkgs/pkgs/qt/wrapper_builder.rb
new file mode 100644
index 000000000..49b3efd8a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/qt/wrapper_builder.rb
@@ -0,0 +1,499 @@
+require 'pathname'
+require 'fileutils'
+include FileUtils
+
+STDOUT.sync = true
+
+ENV['PATH'] = ENV.fetch('_PATH')
+
+Os = ENV.fetch('os')
+QtVersionString = ENV.fetch('version')
+QtVersionMajor = QtVersionString.split('.').first.to_i
+
+QtBaseDir = Pathname(ENV.fetch('qtbase'))
+
+OutDir = Pathname(ENV.fetch('out'))
+OutPcDir = OutDir + 'lib' + 'pkgconfig'
+CMakeDir = OutDir + 'lib' + 'cmake'
+OutIncDir = OutDir + 'include'
+MocExe = OutDir + 'bin' + 'moc'
+RccExe = OutDir + 'bin' + 'rcc'
+
+DepGraph = {}
+DepGraphBack = {}
+
+DepInfo = {}
+DepInfo.default_proc = proc do |hash, name|
+ hash[name] = find_dep_info(name)
+end
+
+case Os
+when "windows"
+ PrlPrefix = ''
+else
+ PrlPrefix = 'lib'
+end
+
+# Note: These dependencies just came from me fixing errors for specific
+# programs. There are likely misisng dependencies in this graph, and there
+# might be a few dependencies that could be safely removed because they are
+# purely transitive.
+def make_dep_graph
+ # High-level dependencies.
+ add_dep 'Qt5Widgets.x', 'libQt5Widgets.a'
+ add_dep 'Qt5Widgets.x', 'Qt5Gui.x'
+ add_dep 'Qt5Gui.x', 'Qt5GuiNoPlugins.x'
+ add_dep 'Qt5GuiNoPlugins.x', 'libQt5Gui.a'
+ add_dep 'Qt5GuiNoPlugins.x', 'Qt5Core.x'
+ add_dep 'Qt5Core.x', 'libQt5Core.a'
+
+ # Include directories.
+ add_dep 'Qt5Core.x', '-I' + OutIncDir.to_s
+ add_dep 'Qt5Core.x', '-I' + (OutIncDir + 'QtCore').to_s
+ add_dep 'Qt5Gui.x', '-I' + (OutIncDir + 'QtGui').to_s
+ add_dep 'Qt5Widgets.x', '-I' + (OutIncDir + 'QtWidgets').to_s
+
+ # Libraries that Qt depends on.
+ add_dep 'libQt5Widgets.a', 'libQt5Gui.a'
+ add_dep 'libQt5FontDatabaseSupport.a', 'libqtfreetype.a'
+ add_dep 'libQt5Gui.a', 'libQt5Core.a'
+ add_dep 'libQt5Gui.a', 'libqtlibpng.a'
+ add_dep 'libQt5Gui.a', 'libqtharfbuzz.a'
+ add_dep 'libQt5Core.a', 'libqtpcre2.a'
+
+ if Os == 'windows'
+ add_dep 'Qt5Gui.x', 'qwindows.x'
+ add_dep 'qwindows.x', 'libqwindows.a'
+
+ add_dep 'libqwindows.a', '-ldwmapi'
+ add_dep 'libqwindows.a', '-limm32'
+ add_dep 'libqwindows.a', '-loleaut32'
+ add_dep 'libqwindows.a', 'libQt5Gui.a'
+ add_dep 'libqwindows.a', 'libQt5EventDispatcherSupport.a'
+ add_dep 'libqwindows.a', 'libQt5FontDatabaseSupport.a'
+ add_dep 'libqwindows.a', 'libQt5ThemeSupport.a'
+
+ add_dep 'libQt5Core.a', '-lole32'
+ add_dep 'libQt5Core.a', '-luuid'
+ add_dep 'libQt5Core.a', '-lversion'
+ add_dep 'libQt5Core.a', '-lwinmm'
+ add_dep 'libQt5Core.a', '-lws2_32'
+
+ add_dep 'libQt5Gui.a', '-lopengl32'
+
+ add_dep 'libQt5Widgets.a', '-luxtheme'
+ end
+
+ if Os == 'linux'
+ add_dep 'Qt5Gui.x', 'qlinuxfb.x'
+ add_dep 'Qt5Gui.x', 'qxcb.x'
+ add_dep 'qlinuxfb.x', 'libqlinuxfb.a'
+ add_dep 'qxcb.x', 'libqxcb.a'
+
+ add_dep 'libqlinuxfb.a', 'libQt5FbSupport.a'
+ add_dep 'libqlinuxfb.a', 'libQt5InputSupport.a'
+
+ add_dep 'libqxcb.a', 'libQt5XcbQpa.a'
+
+ add_dep 'libQt5DBus.a', 'libQt5Core.a'
+ add_dep 'libQt5DBus.a', 'libQt5Gui.a'
+ add_dep 'libQt5DeviceDiscoverySupport.a', 'libudev.pc'
+ add_dep 'libQt5InputSupport.a', 'libQt5DeviceDiscoverySupport.a'
+ add_dep 'libQt5LinuxAccessibilitySupport.a', 'libQt5AccessibilitySupport.a'
+ add_dep 'libQt5LinuxAccessibilitySupport.a', 'libQt5DBus.a'
+ add_dep 'libQt5LinuxAccessibilitySupport.a', 'xcb-aux.pc'
+ add_dep 'libQt5ThemeSupport.a', 'libQt5DBus.a'
+
+ add_dep 'libQt5XcbQpa.a', 'libQt5EventDispatcherSupport.a'
+ add_dep 'libQt5XcbQpa.a', 'libQt5FontDatabaseSupport.a'
+ add_dep 'libQt5XcbQpa.a', 'libQt5Gui.a'
+ add_dep 'libQt5XcbQpa.a', 'libQt5LinuxAccessibilitySupport.a'
+ add_dep 'libQt5XcbQpa.a', 'libQt5ServiceSupport.a'
+ add_dep 'libQt5XcbQpa.a', 'libQt5ThemeSupport.a'
+ add_dep 'libQt5XcbQpa.a', 'x11.pc'
+ add_dep 'libQt5XcbQpa.a', 'x11-xcb.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-icccm.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-image.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-keysyms.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-randr.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-renderutil.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-shape.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-shm.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-sync.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-xfixes.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-xinerama.pc'
+ add_dep 'libQt5XcbQpa.a', 'xcb-xkb.pc'
+ add_dep 'libQt5XcbQpa.a', 'xi.pc'
+ end
+
+ if Os == 'macos'
+ add_dep 'Qt5Gui.x', 'qcocoa.x'
+ add_dep 'qcocoa.x', 'libqcocoa.a'
+
+ add_dep 'libqcocoa.a', 'libcocoaprintersupport.a'
+ add_dep 'libqcocoa.a', '-lcups' # Also available: -lcups.2
+ add_dep 'libqcocoa.a', 'libQt5AccessibilitySupport.a'
+ add_dep 'libqcocoa.a', 'libQt5ClipboardSupport.a'
+ add_dep 'libqcocoa.a', 'libQt5CglSupport.a'
+ add_dep 'libqcocoa.a', 'libQt5GraphicsSupport.a'
+ add_dep 'libqcocoa.a', 'libQt5FontDatabaseSupport.a'
+ add_dep 'libqcocoa.a', 'libQt5ThemeSupport.a'
+ add_dep 'libqcocoa.a', 'libQt5PrintSupport.a'
+
+ add_dep 'libqtlibpng.a', '-lz'
+
+ add_dep 'libQt5Core.a', '-lobjc'
+ add_dep 'libQt5Core.a', '-framework CoreServices'
+ add_dep 'libQt5Core.a', '-framework CoreText'
+ add_dep 'libQt5Gui.a', '-framework CoreGraphics'
+ add_dep 'libQt5Gui.a', '-framework OpenGL'
+ add_dep 'libQt5Widgets.a', '-framework Carbon'
+ add_dep 'libQt5Widgets.a', '-framework AppKit'
+ end
+
+ add_deps_of_pc_files
+end
+
+# Qt depends on some system libraries with .pc files. It tends to only depend
+# on these things at link time, not compile time. So use pkg-config with --libs
+# to get those dependencies, for use in .cmake files.
+def add_deps_of_pc_files
+ DepGraph.keys.each do |dep|
+ next if determine_dep_type(dep) != :pc
+ name = dep.chomp('.pc')
+ new_deps = `pkg-config-cross --libs #{name}`.split(' ')
+ raise "Failed to #{dep} libs" if $?.exitstatus != 0
+ new_deps.each do |new_dep|
+ add_dep dep, new_dep
+ end
+ end
+end
+
+def add_dep(library, *deps)
+ a = DepGraph[library] ||= []
+ DepGraphBack[library] ||= []
+ deps.each do |dep|
+ DepGraph[dep] ||= []
+ a << dep unless a.include? dep
+ (DepGraphBack[dep] ||= []) << library
+ end
+end
+
+# Given a name of a dep in the graph, figure out what kind of dep
+# it use.
+def determine_dep_type(name)
+ extension = Pathname(name).extname
+ case
+ when extension == '.a' then :a
+ when extension == '.pc' then :pc
+ when extension == '.x' then :x
+ when name.start_with?('-I') then :incdirflag
+ when name.start_with?('-L') then :libdirflag
+ when name.start_with?('-l') then :ldflag
+ when name.start_with?('-framework') then :ldflag
+ end
+end
+
+def find_pkg_config_file(name)
+ ENV.fetch('PKG_CONFIG_CROSS_PATH').split(':').each do |dir|
+ path = Pathname(dir) + name
+ return path if path.exist?
+ end
+ nil
+end
+
+def find_qt_library(name)
+ debug_name = Pathname(name).sub_ext("d.a").to_s
+
+ search_dirs = [ OutDir + 'lib' ] +
+ (OutDir + 'plugins').children
+
+ search_dirs.each do |dir|
+ lib = dir + name
+ return lib if lib.exist?
+ end
+
+ search_dirs.each do |dir|
+ lib = dir + debug_name
+ return lib if lib.exist?
+ end
+
+ nil
+end
+
+def find_dep_info(name)
+ case determine_dep_type(name)
+ when :a then find_qt_library(name)
+ when :pc then find_pkg_config_file(name)
+ end
+end
+
+# Given an array of dependencies and a block for retrieving dependencies of an
+# dependency, returns an array of dependencies with three guarantees:
+#
+# 1) Contains all the listed dependencies.
+# 2) Has no duplicates.
+# 3) For any dependency in the list, all of its dependencies are before it.
+#
+# Guarantee 3 only holds if the underlying graph has no circul dependencies. If
+# there is a circular dependency, it will not be detected, but it will not cause
+# an infinite loop either.
+def flatten_deps(deps)
+ work = [].concat(deps)
+ expanded = {}
+ output = {}
+ while !work.empty?
+ dep = work.last
+ if expanded[dep]
+ output[dep] = true
+ work.pop
+ else
+ expanded[dep] = true
+ deps = yield dep
+ work.concat(deps)
+ end
+ end
+ output.keys # relies on Ruby's ordered hashes
+end
+
+def canonical_x_file(dep)
+ return nil if determine_dep_type(dep) != :a
+ x_files = DepGraphBack.fetch(dep).select do |name|
+ determine_dep_type(name) == :x
+ end
+ if x_files.size > 2
+ raise "There is more than one .x file #{dep}."
+ end
+ x_files.first
+end
+
+# Note: It would be nice to find some solution so that Qt5Widgets.pc does not
+# require Qt5GuiNoPlugins, since it already requires Qt5Gui.
+def flatten_deps_for_pc_file(pc_file)
+ flatten_deps(DepGraph[pc_file]) do |dep|
+ deps = case determine_dep_type(dep)
+ when :x, :pc then
+ # Don't expand dependencies for a .pc file because we can just
+ # refer to them with the Requires line in our .pc file.
+ []
+ else DepGraph.fetch(dep)
+ end
+
+ # Replace .a files with a canonical .x file if there is one.
+ deps.map do |name|
+ substitute = canonical_x_file(name)
+ substitute = nil if substitute == pc_file
+ substitute || name
+ end
+ end
+end
+
+def flatten_deps_for_cmake_file(cmake_file)
+ flatten_deps(DepGraph[cmake_file]) do |dep|
+ DepGraph.fetch(dep)
+ end
+end
+
+def create_pc_file(name)
+ requires = []
+ libdirs = []
+ ldflags = []
+ cflags = []
+
+ deps = flatten_deps_for_pc_file(name)
+
+ deps.each do |dep|
+ dep = dep.dup
+ case determine_dep_type(dep)
+ when :a then
+ full_path = DepInfo[dep]
+ raise "Could not find library: #{dep}" if !full_path
+ libdir = full_path.dirname.to_s
+ libdir.sub!((OutDir + 'lib').to_s, '${libdir}')
+ libdir.sub!(OutDir.to_s, '${prefix}')
+ libname = full_path.basename.to_s
+ libname.sub!(/\Alib/, '')
+ libname.sub!(/.a\Z/, '')
+ libdirs << "-L#{libdir}"
+ ldflags << "-l#{libname}"
+ when :x then
+ dep.chomp!('.x')
+ requires << dep
+ when :pc then
+ dep.chomp!('.pc')
+ requires << dep
+ when :ldflag then
+ ldflags << dep
+ when :libdirflag then
+ libdirs << dep
+ when :incdirflag then
+ dep.sub!(OutIncDir.to_s, '${includedir}')
+ cflags << dep
+ end
+ end
+
+ r = ""
+ r << "prefix=#{OutDir}\n"
+ r << "libdir=${prefix}/lib\n"
+ r << "includedir=${prefix}/include\n"
+ r << "Version: #{QtVersionString}\n"
+ if !libdirs.empty? || !ldflags.empty?
+ r << "Libs: #{libdirs.reverse.uniq.join(' ')} #{ldflags.reverse.join(' ')}\n"
+ end
+ if !cflags.empty?
+ r << "Cflags: #{cflags.join(' ')}\n"
+ end
+ if !requires.empty?
+ r << "Requires: #{requires.sort.join(' ')}\n"
+ end
+
+ path = OutPcDir + Pathname(name).sub_ext(".pc")
+ File.open(path.to_s, 'w') do |f|
+ f.write r
+ end
+end
+
+# For .pc files we depend on, add symlinks to the .pc file and any other .pc
+# files in the same directory which might be transitive dependencies.
+def symlink_pc_file_closure(name)
+ dep_pc_dir = DepInfo[name].dirname
+ dep_pc_dir.each_child do |target|
+ link = OutPcDir + target.basename
+
+ # Skip it if we already made this link.
+ next if link.symlink?
+
+ # Link directly to the real PC file.
+ target = target.realpath
+
+ ln_s target, link
+ end
+end
+
+def create_pc_files
+ mkdir OutPcDir
+ DepGraph.each_key do |name|
+ case determine_dep_type(name)
+ when :x then create_pc_file(name)
+ when :pc then symlink_pc_file_closure(name)
+ end
+ end
+end
+
+def set_property(f, target_name, property_name, value)
+ if value.is_a?(Array)
+ value = value.map do |entry|
+ if entry.to_s.include?(' ')
+ "\"#{entry}\""
+ else
+ entry
+ end
+ end.join(' ')
+ end
+
+ f.puts "set_property(TARGET #{target_name} " \
+ "PROPERTY #{property_name} #{value})"
+end
+
+def set_properties(f, target_name, properties)
+ properties.each do |property_name, value|
+ set_property(f, target_name, property_name, value)
+ end
+end
+
+def import_static_lib(f, target_name, properties)
+ f.puts "add_library(#{target_name} STATIC IMPORTED)"
+ set_properties(f, target_name, properties)
+end
+
+def create_cmake_core_files
+ File.open(CMakeDir + 'core.cmake', 'w') do |f|
+ f.puts "set(QT_VERSION_MAJOR #{QtVersionMajor})"
+ f.puts
+
+ f.puts "set(QT_MOC_EXECUTABLE #{MocExe})"
+ f.puts "add_executable(Qt5::moc IMPORTED)"
+ f.puts "set_target_properties(Qt5::moc PROPERTIES " \
+ "IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})"
+ f.puts
+
+ f.puts "add_executable(Qt5::rcc IMPORTED)"
+ f.puts "set_target_properties(Qt5::rcc PROPERTIES " \
+ "IMPORTED_LOCATION #{RccExe})"
+ f.puts "set(Qt5Core_RCC_EXECUTABLE Qt5::rcc)"
+ f.puts
+
+ f.write File.read(ENV.fetch('core_macros'))
+ end
+end
+
+def create_cmake_qt5widgets
+ mkdir CMakeDir + 'Qt5Widgets'
+
+ widgets_a = find_qt_library('libQt5Widgets.a') || raise
+
+ deps = flatten_deps_for_cmake_file('Qt5Widgets.x')
+
+ incdirs = []
+ libdirflags = []
+ ldflags = []
+ deps.each do |dep|
+ dep = dep.dup
+ case determine_dep_type(dep)
+ when :a then
+ full_path = DepInfo[dep]
+ raise "Could not find library: #{dep}" if !full_path
+ libdir = full_path.dirname.to_s
+ libname = full_path.basename.to_s
+ libname.sub!(/\Alib/, '')
+ libname.sub!(/.a\Z/, '')
+ libdirflags << "-L#{libdir}"
+ ldflags << "-l#{libname}"
+ when :ldflag then
+ ldflags << dep
+ when :libdirflag then
+ libdirflags << dep
+ when :incdirflag then
+ incdir = dep.sub(/\A-I/, '')
+ incdirs << incdir
+ end
+ end
+
+ File.open(CMakeDir + 'Qt5Widgets' + 'Qt5WidgetsConfig.cmake', 'w') do |f|
+ import_static_lib f, 'Qt5::Widgets',
+ IMPORTED_LOCATION: widgets_a,
+ IMPORTED_LINK_INTERFACE_LANGUAGES: 'CXX',
+ INTERFACE_LINK_LIBRARIES: libdirflags.reverse.uniq + ldflags.reverse,
+ INTERFACE_INCLUDE_DIRECTORIES: incdirs,
+ INTERFACE_COMPILE_DEFINITIONS: 'QT_STATIC'
+
+ f.puts "include(#{CMakeDir + 'core.cmake'})"
+ end
+end
+
+def main
+ # Symlink the include, bin, and plugins directories into $out.
+ mkdir OutDir
+ ln_s QtBaseDir + 'include', OutDir + 'include'
+ ln_s QtBaseDir + 'bin', OutDir + 'bin'
+ ln_s QtBaseDir + 'plugins', OutDir + 'plugins'
+ ln_s QtBaseDir + 'src', OutDir + 'src'
+
+ # Symlink the .a files and copy the .prl files into $out/lib.
+ mkdir OutDir + 'lib'
+ (QtBaseDir + 'lib').each_child do |c|
+ ln_s c, OutDir + 'lib' if c.extname == '.a'
+ cp c, OutDir + 'lib' if c.extname == '.prl'
+ end
+
+ make_dep_graph
+
+ create_pc_files
+
+ mkdir CMakeDir
+ create_cmake_core_files
+ create_cmake_qt5widgets
+end
+
+main
diff --git a/nix/nixcrpkgs/pkgs/readline/builder.sh b/nix/nixcrpkgs/pkgs/readline/builder.sh
new file mode 100644
index 000000000..defaa8b7d
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/readline/builder.sh
@@ -0,0 +1,32 @@
+source $setup
+
+# This is from the mingw-w64-readline AUR arch package.
+export bash_cv_wcwidth_broken=no
+
+tar -xf $src
+
+cd readline-$version
+for patch in $patches_p2; do
+ echo applying patch $patch
+ patch -p2 -i $patch
+done
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cd ..
+
+mkdir build
+cd build
+
+../readline-$version/configure \
+ --prefix=$out --host=$host \
+ --enable-static --disable-shared \
+ --with-curses=$curses
+
+make
+
+make install
+
+mkdir $out/license
+cp ../readline-$version/COPYING $out/license/LICENSE
diff --git a/nix/nixcrpkgs/pkgs/readline/default.nix b/nix/nixcrpkgs/pkgs/readline/default.nix
new file mode 100644
index 000000000..b1369e70f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/readline/default.nix
@@ -0,0 +1,41 @@
+# Note: This has only been tested on Windows, and is using pdcurses
+# which only seems to work on Windows.
+
+{ crossenv, curses }:
+
+let
+ fetchurl = crossenv.nixpkgs.fetchurl;
+in
+crossenv.make_derivation rec {
+ name = "readline-${version}";
+
+ version = "7.0";
+
+ src = fetchurl {
+ url = "mirror://gnu/readline/readline-${version}.tar.gz";
+ sha256 = "0d13sg9ksf982rrrmv5mb6a2p4ys9rvg9r71d6il0vr8hmql63bm";
+ };
+
+ patches_p2 = [
+ (fetchurl {
+ url = "mirror://gnu/readline/readline-7.0-patches/readline70-001";
+ sha256 = "0xm3sxvwmss7ddyfb11n6pgcqd1aglnpy15g143vzcf75snb7hcs";
+ })
+ (fetchurl {
+ url = "mirror://gnu/readline/readline-7.0-patches/readline70-002";
+ sha256 = "0n1dxmqsbjgrfxb1hgk5c6lsraw4ncbnzxlsx7m35nym6lncjiw7";
+ })
+ (fetchurl {
+ url = "mirror://gnu/readline/readline-7.0-patches/readline70-003";
+ sha256 = "1027kmymniizcy0zbdlrczxfx3clxcdln5yq05q9yzlc6y9slhwy";
+ })
+ ];
+
+ patches = [
+ ./readline-1.patch
+ ];
+
+ builder = ./builder.sh;
+
+ inherit curses;
+}
diff --git a/nix/nixcrpkgs/pkgs/readline/readline-1.patch b/nix/nixcrpkgs/pkgs/readline/readline-1.patch
new file mode 100644
index 000000000..52938b804
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/readline/readline-1.patch
@@ -0,0 +1,171 @@
+We got this patch from the mingw-w64-readline AUR Arch package.
+
+This patch originall comes from MXE, and is licensed under the MIT license.
+
+https://github.com/mxe/mxe/blob/master/src/readline-1.patch
+
+Copyright (c) 2007-2016
+
+Volker Diels-Grabsch
+Mark Brand
+Tony Theodore
+Martin Gerhardy
+Tiancheng "Timothy" Gu
+Boris Nagaev
+... and many other contributors
+(contact via the project mailing list or issue tracker)
+
+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.
+
+From 6896ffa4fc85bf0dfae58e69a860d2076c1d9fd2 Mon Sep 17 00:00:00 2001
+From: Timothy Gu
+Date: Tue, 30 Sep 2014 17:16:32 -0700
+Subject: [PATCH 2/2] Handle missing S_IS* macros more gracefully
+
+diff --git a/colors.c b/colors.c
+index 89d9035..ec19844 100644
+--- a/colors.c
++++ b/colors.c
+@@ -152,14 +152,22 @@ _rl_print_color_indicator (char *f)
+ {
+ colored_filetype = C_FILE;
+
++#if defined (S_ISUID)
+ if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
+ colored_filetype = C_SETUID;
+- else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
++ else
++#endif
++#if defined (S_ISGID)
++ if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
+ colored_filetype = C_SETGID;
+- else if (is_colored (C_CAP) && 0) //f->has_capability)
++ else
++#endif
++ if (is_colored (C_CAP) && 0) //f->has_capability)
+ colored_filetype = C_CAP;
++#if defined(S_IXUGO)
+ else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
+ colored_filetype = C_EXEC;
++#endif
+ else if ((1 < astat.st_nlink) && is_colored (C_MULTIHARDLINK))
+ colored_filetype = C_MULTIHARDLINK;
+ }
+@@ -173,8 +181,10 @@ _rl_print_color_indicator (char *f)
+ colored_filetype = C_STICKY_OTHER_WRITABLE;
+ else
+ #endif
++#if defined (S_IWOTH)
+ if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
+ colored_filetype = C_OTHER_WRITABLE;
++#endif
+ #if defined (S_ISVTX)
+ else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
+ colored_filetype = C_STICKY;
+diff --git a/colors.h b/colors.h
+index fc926e5..e62edd0 100644
+--- a/colors.h
++++ b/colors.h
+@@ -96,7 +96,7 @@ enum indicator_no
+ };
+
+
+-#if !S_IXUGO
++#if !S_IXUGO && defined(S_IXUSR) && defined(S_IXGRP) && defined(S_IXOTH)
+ # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
+ #endif
+
+diff --git a/posixstat.h b/posixstat.h
+index 3eb7f29..854a2c9 100644
+--- a/posixstat.h
++++ b/posixstat.h
+@@ -78,30 +78,44 @@
+
+ #if defined (S_IFBLK) && !defined (S_ISBLK)
+ #define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */
++#elif !defined (S_IFBLK)
++#define S_ISBLK(m) 0
+ #endif
+
+ #if defined (S_IFCHR) && !defined (S_ISCHR)
+ #define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */
++#elif !defined (S_IFCHR)
++#define S_ISCHR(m) 0
+ #endif
+
+ #if defined (S_IFDIR) && !defined (S_ISDIR)
+ #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */
++#elif !defined (S_IFDIR)
++#define S_ISDIR(m) 0
+ #endif
+
+ #if defined (S_IFREG) && !defined (S_ISREG)
+ #define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */
++#elif !defined (S_IFREG)
++#define S_ISREG(m) 0
+ #endif
+
+ #if defined (S_IFIFO) && !defined (S_ISFIFO)
+ #define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */
++#elif !defined (S_IFIFO)
++#define S_ISFIFO(m) 0
+ #endif
+
+ #if defined (S_IFLNK) && !defined (S_ISLNK)
+ #define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */
++#elif !defined (S_IFLNK)
++#define S_ISLNK(m) 0
+ #endif
+
+ #if defined (S_IFSOCK) && !defined (S_ISSOCK)
+ #define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */
++#elif !defined (S_IFSOCK)
++#define S_ISSOCK(m) 0
+ #endif
+
+ /*
+@@ -137,6 +151,8 @@
+ /* These are non-standard, but are used in builtins.c$symbolic_umask() */
+ #define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
+ #define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
++#if defined(S_IXUSR) && defined(S_IXGRP) && defined(S_IXOTH)
+ #define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
++#endif
+
+ #endif /* _POSIXSTAT_H_ */
+--
+1.8.3.2
+
+diff --git a/histfile.c b/histfile.c
+--- a/histfile.c
++++ b/histfile.c
+@@ -610,8 +610,6 @@
+ user is running this, it's a no-op. If the shell is running after sudo
+ with a shared history file, we don't want to leave the history file
+ owned by root. */
+- if (rv == 0 && exists)
+- r = chown (filename, finfo.st_uid, finfo.st_gid);
+
+ xfree (filename);
+ FREE (tempname);
+@@ -757,8 +755,6 @@
+ user is running this, it's a no-op. If the shell is running after sudo
+ with a shared history file, we don't want to leave the history file
+ owned by root. */
+- if (rv == 0 && exists)
+- mode = chown (histname, finfo.st_uid, finfo.st_gid);
+
+ FREE (histname);
+ FREE (tempname);
diff --git a/nix/nixcrpkgs/pkgs/tic/builder.sh b/nix/nixcrpkgs/pkgs/tic/builder.sh
new file mode 100644
index 000000000..5052b2583
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/tic/builder.sh
@@ -0,0 +1,15 @@
+source $setup
+
+tar -xf $src
+mv pololu-tic-software-* tic
+
+mkdir build
+cd build
+
+cmake-cross ../tic \
+ -DCMAKE_INSTALL_PREFIX=$out \
+ -DBUILD_SHARED_LIBS=false
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/tic/default.nix b/nix/nixcrpkgs/pkgs/tic/default.nix
new file mode 100644
index 000000000..6f870d911
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/tic/default.nix
@@ -0,0 +1,16 @@
+{ crossenv, qt, libusbp }:
+
+crossenv.make_derivation rec {
+ name = "tic-${version}";
+
+ version = "e1693cd"; # 1.5.0ish
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://github.com/pololu/pololu-tic-software/archive/${version}.tar.gz";
+ sha256 = "07m75w0walr61yqki7h1ipzbfz7x417g7qnx0p1l6qdz89fyc7i8";
+ };
+
+ builder = ./builder.sh;
+
+ cross_inputs = [ libusbp qt ];
+}
diff --git a/nix/nixcrpkgs/pkgs/usbview/builder.sh b/nix/nixcrpkgs/pkgs/usbview/builder.sh
new file mode 100644
index 000000000..3aa4cb901
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/usbview/builder.sh
@@ -0,0 +1,31 @@
+source $setup
+
+cp --no-preserve=mode -r $src/usb/usbview .
+
+cd usbview
+rm usbschema.hpp xmlhelper.cpp
+for patch in $patches; do
+ echo applying patch $patch
+ patch -p1 -i $patch
+done
+cp $my_xmlhelper_c .
+cd ..
+
+mkdir build
+cd build
+
+$host-windres ../usbview/uvcview.rc rc.o
+
+# TODO: after fixing bug with selectany in GCC, remove -DINITGUID
+
+$host-gcc -mwindows -std=gnu99 -O2 \
+ -Iinclude \
+ -DNTDDI_VERSION=0x06020000 -D_WIN32_WINNT=0x0602 \
+ -DSTRSAFE_NO_DEPRECATE -Doffsetof=__builtin_offsetof \
+ ../usbview/*.c rc.o \
+ -lcomctl32 -lcomdlg32 -lsetupapi -lshell32 -lshlwapi -lole32 -lgdi32 \
+ -o usbview.exe
+
+mkdir -p $out/bin $out/license
+cp usbview.exe $out/bin
+cp $src/LICENSE $out/license
diff --git a/nix/nixcrpkgs/pkgs/usbview/default.nix b/nix/nixcrpkgs/pkgs/usbview/default.nix
new file mode 100644
index 000000000..7d5260859
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/usbview/default.nix
@@ -0,0 +1,22 @@
+{ crossenv }:
+
+if crossenv.os != "windows" then "windows only" else
+
+crossenv.make_derivation rec {
+ name = "usbview-${version}";
+
+ version = "2017-05-01";
+
+ src = crossenv.nixpkgs.fetchFromGitHub {
+ owner = "Microsoft";
+ repo = "Windows-driver-samples";
+ rev = "4c5c5e0297c7a61e151f92af702cdac650a14489";
+ sha256 = "1drq26bnad98xqn805qx0b6g4y65lmrdj7v40b3jhhzdsp8993pf";
+ };
+
+ patches = [ ./megapatch.patch ];
+
+ my_xmlhelper_c = ./my_xmlhelper.c;
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pkgs/usbview/megapatch.patch b/nix/nixcrpkgs/pkgs/usbview/megapatch.patch
new file mode 100644
index 000000000..fe3227aee
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/usbview/megapatch.patch
@@ -0,0 +1,107 @@
+diff -ur usbview-orig/usbdesc.h usbview/usbdesc.h
+--- usbview-orig/usbdesc.h 2017-04-01 16:00:09.314007997 -0700
++++ usbview/usbdesc.h 2017-04-01 16:10:23.667341332 -0700
+@@ -81,7 +81,7 @@
+ #define USB_OTHER_SPEED_CONFIGURATION_DESCRIPTOR_TYPE 0x07
+ #define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08
+ #define USB_OTG_DESCRIPTOR_TYPE 0x09
+-#define USB_DEBUG_DESCRIPTOR_TYPE 0x0A
++//#define USB_DEBUG_DESCRIPTOR_TYPE 0x0A
+ #define USB_IAD_DESCRIPTOR_TYPE 0x0B
+
+ //
+diff -ur usbview-orig/uvcdesc.h usbview/uvcdesc.h
+--- usbview-orig/uvcdesc.h 2017-04-01 16:00:09.314007997 -0700
++++ usbview/uvcdesc.h 2017-04-01 17:43:09.134007999 -0700
+@@ -15,7 +15,7 @@
+
+
+ // USB Video Device Class Code
+-#define USB_DEVICE_CLASS_VIDEO 0x0E
++//#define USB_DEVICE_CLASS_VIDEO 0x0E
+
+ // Video sub-classes
+ #define SUBCLASS_UNDEFINED 0x00
+diff -ur usbview-orig/uvcview.h usbview/uvcview.h
+--- usbview-orig/uvcview.h 2017-04-01 16:00:09.314007997 -0700
++++ usbview/uvcview.h 2017-04-03 20:25:08.145676664 -0700
+@@ -34,10 +33,10 @@
+ #include
+ #include
+ #include
+-#include
+ #include
+ #include
+ #include
++#include
+ #include
+ #include
+ #include
+@@ -50,6 +49,8 @@
+ #include
+ #include
+ #include
++#include
++#include
+
+ // This is mostly a private USB Audio descriptor header
+ #include "usbdesc.h"
+@@ -381,7 +382,7 @@
+ // ENUM.C
+ //
+
+-PCHAR ConnectionStatuses[];
++extern PCHAR ConnectionStatuses[];
+
+ //
+ // DISPVID.C
+Only in usbview: uvcview.h.orig
+diff -ur usbview-orig/uvcview.rc usbview/uvcview.rc
+--- usbview-orig/uvcview.rc 2017-04-01 16:00:09.314007997 -0700
++++ usbview/uvcview.rc 2017-04-01 16:04:07.210674665 -0700
+@@ -22,19 +22,19 @@
+ //
+ // ICON
+ //
+-IDI_ICON ICON DISCARDABLE "USB.ICO"
+-IDI_BADICON ICON DISCARDABLE "BANG.ICO"
+-IDI_COMPUTER ICON DISCARDABLE "MONITOR.ICO"
+-IDI_HUB ICON DISCARDABLE "HUB.ICO"
+-IDI_NODEVICE ICON DISCARDABLE "PORT.ICO"
+-IDI_NOSSDEVICE ICON DISCARDABLE "SSPORT.ICO"
+-IDI_SSICON ICON DISCARDABLE "SSUSB.ICO"
++IDI_ICON ICON DISCARDABLE "usb.ico"
++IDI_BADICON ICON DISCARDABLE "bang.ico"
++IDI_COMPUTER ICON DISCARDABLE "monitor.ico"
++IDI_HUB ICON DISCARDABLE "hub.ico"
++IDI_NODEVICE ICON DISCARDABLE "port.ico"
++IDI_NOSSDEVICE ICON DISCARDABLE "ssport.ico"
++IDI_SSICON ICON DISCARDABLE "ssusb.ico"
+
+ //////////////////////////////////////////////////////////////////////////////
+ //
+ // Cursor
+ //
+-IDC_SPLIT CURSOR DISCARDABLE "SPLIT.CUR"
++IDC_SPLIT CURSOR DISCARDABLE "split.cur"
+
+ /////////////////////////////////////////////////////////////////////////////
+ //
+@@ -84,7 +84,7 @@
+ BEGIN
+ MENUITEM "&Refresh\tF5", ID_REFRESH
+ MENUITEM SEPARATOR
+- MENUITEM "Save Current &View ..." ID_SAVE
++ MENUITEM "Save Current &View ...", ID_SAVE
+ MENUITEM "Save As (&txt) ...", ID_SAVEALL
+ MENUITEM "Save As (&xml) ...\tF2", ID_SAVEXML
+ MENUITEM SEPARATOR
+@@ -130,7 +130,7 @@
+ BEGIN
+ IDS_STANDARD_FONT "Courier"
+ IDS_STANDARD_FONT_HEIGHT "\13"
+- IDS_STANDARD_FONT_WIDTH "\8"
++ IDS_STANDARD_FONT_WIDTH "\08"
+ END
+
+ STRINGTABLE DISCARDABLE
diff --git a/nix/nixcrpkgs/pkgs/usbview/my_xmlhelper.c b/nix/nixcrpkgs/pkgs/usbview/my_xmlhelper.c
new file mode 100644
index 000000000..0cdf29140
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/usbview/my_xmlhelper.c
@@ -0,0 +1,47 @@
+#include "xmlhelper.h"
+
+EXTERN_C HRESULT InitXmlHelper()
+{
+ return 0;
+}
+
+EXTERN_C HRESULT ReleaseXmlWriter()
+{
+ return 0;
+}
+
+EXTERN_C HRESULT SaveXml(LPTSTR szfileName, DWORD dwCreationDisposition)
+{
+ MessageBox(NULL,
+ "Sorry, XML saving is not supported in this build.",
+ "XML not supported",
+ MB_OK | MB_ICONEXCLAMATION);
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddHostController(
+ PSTR hcName,
+ PUSBHOSTCONTROLLERINFO hcInfo
+ )
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddRootHub(PSTR rhName, PUSBROOTHUBINFO rhInfo)
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddExternalHub(PSTR ehName, PUSBEXTERNALHUBINFO ehInfo)
+{
+ return 0;
+}
+
+EXTERN_C HRESULT XmlAddUsbDevice(PSTR devName, PUSBDEVICEINFO deviceInfo)
+{
+ return 0;
+}
+
+EXTERN_C VOID XmlNotifyEndOfNodeList(PVOID pContext)
+{
+}
diff --git a/nix/nixcrpkgs/pkgs/xcb-proto/builder.sh b/nix/nixcrpkgs/pkgs/xcb-proto/builder.sh
new file mode 100644
index 000000000..e83c5bbb3
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-proto/builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+ls
+mv xcb-proto-* xcb-proto
+
+mkdir build
+cd build
+
+../xcb-proto/configure --prefix=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xcb-proto/default.nix b/nix/nixcrpkgs/pkgs/xcb-proto/default.nix
new file mode 100644
index 000000000..b9cdc0b1f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-proto/default.nix
@@ -0,0 +1,28 @@
+{ crossenv }:
+
+let
+ version = "1.12";
+
+ name = "xcb-proto-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-proto-${version}.tar.bz2";
+ sha256 = "01j91946q8f34l1mbvmmgvyc393sm28ym4lxlacpiav4qsjan8jr";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+ builder = ./builder.sh;
+ native_inputs = [ crossenv.nixpkgs.python2 ];
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-proto/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-proto/license_builder.sh
new file mode 100644
index 000000000..2ea711435
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-proto/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-proto-* xcb-proto
+
+license=$(cat xcb-proto/COPYING)
+
+cat > $out <xcb-proto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-image/default.nix b/nix/nixcrpkgs/pkgs/xcb-util-image/default.nix
new file mode 100644
index 000000000..14a5b5458
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-image/default.nix
@@ -0,0 +1,40 @@
+{ crossenv, libxcb, xcb-util }:
+
+let
+ version = "0.4.0";
+
+ name = "xcb-util-image-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-util-image-${version}.tar.bz2";
+ sha256 = "1z1gxacg7q4cw6jrd26gvi5y04npsyavblcdad1xccc8swvnmf9d";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+ builder = ./util_image_builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ libxcb xcb-util ];
+
+ inherit libxcb;
+ libxcb_util = xcb-util;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ libxcb.license_set //
+ xcb-util.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-image/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-image/license_builder.sh
new file mode 100644
index 000000000..9cc75651e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-image/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-image-* xcb-util-image
+
+license=$(cat xcb-util-image/COPYING)
+
+cat > $out <xcb-util-image
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-image/util_image_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-image/util_image_builder.sh
new file mode 100644
index 000000000..3b5d1e6cf
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-image/util_image_builder.sh
@@ -0,0 +1,20 @@
+source $setup
+
+tar -xf $src
+mv xcb-* util
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../util/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+# xcb-util-image-0.4.0/image/xcb_image.c includes
+echo "Requires: xcb-aux" >> $out/lib/pkgconfig/xcb-image.pc
+ln -sf $libxcb/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+ln -sf $libxcb_util/lib/pkgconfig/*.pc $out/lib/pkgconfig/
+
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-keysyms/default.nix b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/default.nix
new file mode 100644
index 000000000..6d5b8298f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/default.nix
@@ -0,0 +1,37 @@
+{ crossenv, libxcb }:
+
+let
+ version = "0.4.0";
+
+ name = "xcb-util-keysyms";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-util-keysyms-${version}.tar.bz2";
+ sha256 = "1nbd45pzc1wm6v5drr5338j4nicbgxa5hcakvsvm5pnyy47lky0f";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./util_keysyms_builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ libxcb ];
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ libxcb.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-keysyms/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/license_builder.sh
new file mode 100644
index 000000000..66175097f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-keysyms-* xcb-util-keysyms
+
+license=$(head -n31 xcb-util-keysyms/keysyms/keysyms.c)
+
+cat > $out <xcb-util-keysyms
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-keysyms/util_keysyms_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/util_keysyms_builder.sh
new file mode 100644
index 000000000..eaa898225
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-keysyms/util_keysyms_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-* util
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../util/configure --prefix=$out $configure_flags
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-renderutil/default.nix b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/default.nix
new file mode 100644
index 000000000..f20b271e3
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/default.nix
@@ -0,0 +1,40 @@
+{ crossenv, libxcb }:
+
+let
+ version = "0.3.9";
+
+ name = "xcb-util-renderutil"; # TODO: add -${version} (mass rebuild)
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-util-renderutil-${version}.tar.bz2";
+ sha256 = "0nza1csdvvxbmk8vgv8vpmq7q8h05xrw3cfx9lwxd1hjzd47xsf6";
+ };
+
+ lib = crossenv.make_derivation {
+ inherit version name src;
+
+ # TODO: rename all xcb-util builders to builder.sh (mass rebuild)
+ builder = ./util_renderutil_builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ libxcb ];
+
+ xcb = libxcb;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ libxcb.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-renderutil/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/license_builder.sh
new file mode 100644
index 000000000..96f60bcf9
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-renderutil-* xcb-util-renderutil
+
+license=$(cat xcb-util-renderutil/COPYING)
+
+cat > $out <xcb-util-renderutil
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-renderutil/util_renderutil_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/util_renderutil_builder.sh
new file mode 100644
index 000000000..4540eae4c
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-renderutil/util_renderutil_builder.sh
@@ -0,0 +1,16 @@
+source $setup
+
+tar -xf $src
+mv xcb-* util
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../util/configure --prefix=$out $configure_flags
+
+make
+
+make install
+
+ln -s $xcb/lib/pkgconfig/{xcb,xcb-render}.pc $out/lib/pkgconfig/
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-wm/default.nix b/nix/nixcrpkgs/pkgs/xcb-util-wm/default.nix
new file mode 100644
index 000000000..1390a4abd
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-wm/default.nix
@@ -0,0 +1,39 @@
+{ crossenv, libxcb }:
+
+let
+ version = "0.4.1";
+
+ name = "xcb-util-wm-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-util-wm-${version}.tar.bz2";
+ sha256 = "0gra7hfyxajic4mjd63cpqvd20si53j1q3rbdlkqkahfciwq3gr8";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./util_wm_builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ libxcb ];
+
+ native_inputs = [ crossenv.nixpkgs.m4 ];
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ libxcb.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-wm/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-wm/license_builder.sh
new file mode 100644
index 000000000..adbaa5ed5
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-wm/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-wm-* xcb-util-wm
+
+license=$(cat xcb-util-wm/COPYING)
+
+cat > $out <xcb-util-wm
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util-wm/util_wm_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util-wm/util_wm_builder.sh
new file mode 100644
index 000000000..eaa898225
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util-wm/util_wm_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-* util
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../util/configure --prefix=$out $configure_flags
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xcb-util/default.nix b/nix/nixcrpkgs/pkgs/xcb-util/default.nix
new file mode 100644
index 000000000..48cadb58d
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util/default.nix
@@ -0,0 +1,37 @@
+{ crossenv, libxcb }:
+
+let
+ version = "0.4.0";
+
+ name = "xcb-util-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xcb.freedesktop.org/dist/xcb-util-${version}.tar.bz2";
+ sha256 = "1sahmrgbpyki4bb72hxym0zvxwnycmswsxiisgqlln9vrdlr9r26";
+ };
+
+ lib = crossenv.make_derivation rec {
+ inherit version name src;
+
+ builder = ./util_builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ libxcb ];
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set =
+ libxcb.license_set //
+ { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xcb-util/license_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util/license_builder.sh
new file mode 100644
index 000000000..7d65ade3b
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-* xcb-util
+
+license=$(cat xcb-util/COPYING)
+
+cat > $out <xcb-util
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xcb-util/util_builder.sh b/nix/nixcrpkgs/pkgs/xcb-util/util_builder.sh
new file mode 100644
index 000000000..6264407a6
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xcb-util/util_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xcb-util-* util
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../util/configure --prefix=$out $configure_flags
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xextproto/builder.sh b/nix/nixcrpkgs/pkgs/xextproto/builder.sh
new file mode 100644
index 000000000..6bf1c02c5
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xextproto/builder.sh
@@ -0,0 +1,13 @@
+source $setup
+
+tar -xf $src
+mv xextproto-* xextproto
+
+mkdir build
+cd build
+
+../xextproto/configure --prefix=$out
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xextproto/default.nix b/nix/nixcrpkgs/pkgs/xextproto/default.nix
new file mode 100644
index 000000000..82b0a626e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xextproto/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+let
+ version = "7.3.0";
+
+ name = "xextproto-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xorg.freedesktop.org/releases/individual/proto/xextproto-${version}.tar.bz2";
+ sha256 = "1c2vma9gqgc2v06rfxdiqgwhxmzk2cbmknwf1ng3m76vr0xb5x7k";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xextproto/license_builder.sh b/nix/nixcrpkgs/pkgs/xextproto/license_builder.sh
new file mode 100644
index 000000000..9fbf3543d
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xextproto/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xextproto-* xextproto
+
+license=$(cat xextproto/COPYING)
+
+cat > $out <xextproto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xorg-macros/builder.sh b/nix/nixcrpkgs/pkgs/xorg-macros/builder.sh
new file mode 100644
index 000000000..f940d965f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xorg-macros/builder.sh
@@ -0,0 +1,18 @@
+source $setup
+
+tar -xf $src
+ls
+mv util-macros-* macros
+
+mkdir build
+cd build
+
+../macros/configure --prefix=$out
+
+make
+
+make install
+
+# The .pc files gets installed to /share/pkgconfig, but we want to see it in
+# /lib/pkgconfig.
+ln -s share $out/lib
diff --git a/nix/nixcrpkgs/pkgs/xorg-macros/default.nix b/nix/nixcrpkgs/pkgs/xorg-macros/default.nix
new file mode 100644
index 000000000..2f5c8508f
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xorg-macros/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+let
+ version = "1.19.1";
+
+ name = "xorg-macros-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/releases/individual/util/util-macros-1.19.1.tar.gz";
+ sha256 = "1f27cmbxq0kdyvqsplxpsi9pxm5qy45lcagxr9gby2hy3pjd0aj7";
+ };
+
+ lib = crossenv.native.make_derivation {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xorg-macros/license_builder.sh b/nix/nixcrpkgs/pkgs/xorg-macros/license_builder.sh
new file mode 100644
index 000000000..fb723a09d
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xorg-macros/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv util-macros-* xorg-macros
+
+license=$(cat xorg-macros/COPYING)
+
+cat > $out <xorg-macros
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xproto/builder.sh b/nix/nixcrpkgs/pkgs/xproto/builder.sh
new file mode 100644
index 000000000..7f6b13edb
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xproto/builder.sh
@@ -0,0 +1,16 @@
+source $setup
+
+tar -xf $src
+mv xproto-* xproto
+
+cp $gnu_config/{config.guess,config.sub} xproto
+
+mkdir build
+cd build
+
+PKG_CONFIG=pkg-config-cross \
+../xproto/configure --prefix=$out $configure_flags
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/xproto/default.nix b/nix/nixcrpkgs/pkgs/xproto/default.nix
new file mode 100644
index 000000000..6b16b0b4e
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xproto/default.nix
@@ -0,0 +1,38 @@
+{ crossenv, xorg-macros }:
+
+let
+ version = "7.0.31";
+
+ name = "xproto-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://www.x.org/releases/individual/proto/xproto-${version}.tar.gz";
+ sha256 = "1is3xl0zjk4l0d8d0zinkfbfapgdby2i56jjfp6caibvwam5wxbd";
+ };
+
+ lib = crossenv.make_derivation {
+ inherit version name src;
+
+ builder = ./builder.sh;
+
+ configure_flags =
+ "--host=${crossenv.host} " +
+ "--enable-static " +
+ "--disable-shared";
+
+ cross_inputs = [ xorg-macros ];
+
+ # Need the latest version of config.sub so we can support musl.
+ gnu_config = crossenv.native.gnu_config;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = xorg-macros.license_set // { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xproto/license_builder.sh b/nix/nixcrpkgs/pkgs/xproto/license_builder.sh
new file mode 100644
index 000000000..4ed0509f1
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xproto/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xproto-* xproto
+
+license=$(cat xproto/COPYING)
+
+cat > $out <xproto
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/xtrans/builder.sh b/nix/nixcrpkgs/pkgs/xtrans/builder.sh
new file mode 100644
index 000000000..354670cb0
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xtrans/builder.sh
@@ -0,0 +1,16 @@
+source $setup
+
+tar -xf $src
+mv xtrans-* xtrans
+
+mkdir build
+cd build
+
+../xtrans/configure --prefix $out
+
+make
+
+make install
+
+# So we can find the pkgconfig files in lib/pkgconfig
+ln -s share $out/lib
diff --git a/nix/nixcrpkgs/pkgs/xtrans/default.nix b/nix/nixcrpkgs/pkgs/xtrans/default.nix
new file mode 100644
index 000000000..44daf818a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xtrans/default.nix
@@ -0,0 +1,27 @@
+{ crossenv }:
+
+let
+ version = "1.3.5";
+
+ name = "xtrans-${version}";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://xorg.freedesktop.org/releases/individual/lib/xtrans-${version}.tar.bz2";
+ sha256 = "00c3ph17acnsch3gbdmx33b9ifjnl5w7vx8hrmic1r1cjcv3pgdd";
+ };
+
+ lib = crossenv.native.make_derivation rec {
+ inherit version name src;
+ builder = ./builder.sh;
+ };
+
+ license = crossenv.native.make_derivation {
+ name = "${name}-license";
+ inherit src;
+ builder = ./license_builder.sh;
+ };
+
+ license_set = { "${name}" = license; };
+
+in
+ lib // { inherit license_set; }
diff --git a/nix/nixcrpkgs/pkgs/xtrans/license_builder.sh b/nix/nixcrpkgs/pkgs/xtrans/license_builder.sh
new file mode 100644
index 000000000..0b43e8b78
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/xtrans/license_builder.sh
@@ -0,0 +1,14 @@
+source $setup
+
+tar -xf $src
+mv xtrans-* xtrans
+
+license=$(cat xtrans/COPYING)
+
+cat > $out <xtrans
+
+
+$license
+
+EOF
diff --git a/nix/nixcrpkgs/pkgs/zlib/builder.sh b/nix/nixcrpkgs/pkgs/zlib/builder.sh
new file mode 100644
index 000000000..b7906b5a2
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/zlib/builder.sh
@@ -0,0 +1,15 @@
+source $setup
+
+tar -xf $src
+
+mkdir build
+cd build
+
+sed -i 's$Darwin. | darwin.$Ignore* | ignore*$' ../zlib-$version/configure
+
+CHOST=$host \
+../zlib-$version/configure --prefix=$out --static
+
+make
+
+make install
diff --git a/nix/nixcrpkgs/pkgs/zlib/default.nix b/nix/nixcrpkgs/pkgs/zlib/default.nix
new file mode 100644
index 000000000..11242407a
--- /dev/null
+++ b/nix/nixcrpkgs/pkgs/zlib/default.nix
@@ -0,0 +1,14 @@
+{ crossenv }:
+
+crossenv.make_derivation rec {
+ name = "zlib-${version}";
+
+ version = "1.2.11";
+
+ src = crossenv.nixpkgs.fetchurl {
+ url = "https://zlib.net/zlib-${version}.tar.gz";
+ sha256 = "18dighcs333gsvajvvgqp8l4cx7h1x7yx9gd5xacnk80spyykrf3";
+ };
+
+ builder = ./builder.sh;
+}
diff --git a/nix/nixcrpkgs/pretend_stdenv/setup b/nix/nixcrpkgs/pretend_stdenv/setup
new file mode 100644
index 000000000..a0f3af700
--- /dev/null
+++ b/nix/nixcrpkgs/pretend_stdenv/setup
@@ -0,0 +1 @@
+export PATH=$_PATH
diff --git a/nix/nixcrpkgs/support/derivations.txt b/nix/nixcrpkgs/support/derivations.txt
new file mode 100644
index 000000000..d5d9f09af
--- /dev/null
+++ b/nix/nixcrpkgs/support/derivations.txt
@@ -0,0 +1,58 @@
+define all = win32,win64,linux32,linux64,linux-rpi,mac
+define windows = win32,win64
+define linux = linux32,linux64,linux-rpi
+
+# Cross-compiler toolchains
+{$windows,$linux}.gcc slow=1
+mac.toolchain slow=1
+
+# Packages
+{$windows}.angle{,.examples} slow=1
+{$windows}.angle.examples
+omni.at-spi2-headers
+{$all}.avrdude
+omni.dejavu-fonts
+{$windows}.devcon
+{$all}.expat
+omni.fixesproto
+{$windows}.gdb
+{$all}.hello
+{$all}.hello_cpp
+omni.inputproto
+{$all}.ion
+omni.kbproto
+{$linux}.libudev
+{$all}.libusb
+{$all}.libusbp{,.examples}
+{$linux}.libx11
+{$linux}.libxall
+{$all}.libxau
+{$all}.libxcb{,.examples}
+{$linux}.libxext
+{$linux}.libxfixes
+{$linux}.libxi
+{$all}.openocd
+{$all}.pavr2
+{$windows}.pdcurses{,.examples}
+{$all}.p-load
+{$all}.qt slow=1
+{$all}.qt.examples
+{$windows}.readline
+{$all}.tic
+{$windows}.usbview
+omni.xcb-proto
+{$all}.xcb-util
+{$all}.xcb-util-image
+{$all}.xcb-util-keysyms
+{$all}.xcb-util-renderutil
+{$all}.xcb-util-wm
+omni.xextproto
+omni.xorg-macros
+{$all}.xproto
+omni.xtrans
+{$all}.zlib
+
+# Derivations we care about at Pololu
+{win32,linux32,linux-rpi,mac}.{p-load,pavr2,tic} priority=1
+
+# TODO: Test building the license_sets somehow too.
diff --git a/nix/nixcrpkgs/support/expand_brackets.rb b/nix/nixcrpkgs/support/expand_brackets.rb
new file mode 100644
index 000000000..fccee4510
--- /dev/null
+++ b/nix/nixcrpkgs/support/expand_brackets.rb
@@ -0,0 +1,43 @@
+def expand_brackets_core(str, depth)
+ finished_parts = []
+ active_parts = [+'']
+ while true
+ if str.empty?
+ raise AnticipatedError, "Unmatched opening brace" if depth > 0
+ break
+ elsif str.start_with?('}')
+ str.slice!(0)
+ raise AnticipatedError, "Unmatched closing brace" if depth == 0
+ break
+ elsif str.start_with?('{')
+ # Recurse, which removes everything up to and
+ # including the matching closing brace.
+ str.slice!(0)
+ options = expand_brackets_core(str, depth + 1)
+ raise if options.empty?
+ active_parts = active_parts.flat_map { |p1|
+ options.map { |p2| p1 + p2 }
+ }
+ elsif str.start_with?(',')
+ raise AnticipatedError, "Comma at top level" if depth == 0
+ # Remove the comma, mark the parts we are working
+ # on as finished, and start a new part.
+ str.slice!(0)
+ finished_parts += active_parts
+ active_parts = ['']
+ else
+ part_length = str.index(/[{},]|$/)
+ raise if part_length < 1
+ part = str.slice!(0, part_length)
+ active_parts.each do |s|
+ s.insert(-1, part)
+ end
+ end
+ end
+ finished_parts + active_parts
+end
+
+# Expands something like "{a,b}{,.x}" to ["a", "a.x", "b", "b.x"]
+def expand_brackets(str)
+ expand_brackets_core(str.dup, 0)
+end
diff --git a/nix/nixcrpkgs/support/graph.rb b/nix/nixcrpkgs/support/graph.rb
new file mode 100644
index 000000000..b1db81137
--- /dev/null
+++ b/nix/nixcrpkgs/support/graph.rb
@@ -0,0 +1,74 @@
+def print_graph(graph)
+ graph.each do |parent, children|
+ puts "#{parent} ->"
+ children.each do |child|
+ puts " #{child}"
+ end
+ end
+end
+
+def check_graph!(graph)
+ graph.each do |parent, children|
+ children.each do |child|
+ if !graph.key?(child)
+ raise "Graph is missing an entry for #{child}"
+ end
+ end
+ end
+end
+
+def depth_first_search_exclude_start(graph, start)
+ stack = [graph.fetch(start).to_a.reverse]
+ visited = Set.new
+ until stack.empty?
+ node = stack.last.pop
+ if node.nil?
+ stack.pop
+ next
+ end
+ next if visited.include?(node)
+ visited << node
+ stack << graph.fetch(node).to_a.reverse
+ yield node
+ end
+end
+
+def transitive_closure(graph)
+ tc = {}
+ graph.each_key do |node|
+ tc[node] = enum_for(:depth_first_search_exclude_start, graph, node).to_a
+ end
+ tc
+end
+
+def restricted_transitive_closure(graph, allowed)
+ rtc = {}
+ graph.each_key do |node|
+ next if !allowed.include?(node)
+ reached_nodes = []
+ depth_first_search_exclude_start(graph, node) do |reached_node|
+ next if !allowed.include?(reached_node)
+ reached_nodes << reached_node
+ end
+ rtc[node] = reached_nodes
+ end
+ rtc
+end
+
+def transitive_reduction(graph)
+ tr = {}
+ graph.each do |start_node, nodes|
+ nodes_with_max_distance_1 = Set.new(nodes)
+ distance = 1
+ until nodes.empty?
+ nodes = Set.new nodes.flat_map &graph.method(:fetch)
+ nodes_with_max_distance_1 -= nodes
+ distance += 1
+ if distance > graph.size
+ raise "Cycle detected: this algorithm only works with DAGs."
+ end
+ end
+ tr[start_node] = nodes_with_max_distance_1.to_a
+ end
+ tr
+end
diff --git a/nix/nixcrpkgs/support/manage b/nix/nixcrpkgs/support/manage
new file mode 100755
index 000000000..a21f3ec9f
--- /dev/null
+++ b/nix/nixcrpkgs/support/manage
@@ -0,0 +1,541 @@
+#!/usr/bin/env ruby
+
+# This part of hte code is under construction. It will eventually be a script that
+# helps us check that the derivations we care about are all building,
+# and prints the status of those builds.
+
+
+# This requires Ruby 2.5.0 or later because it uses a new syntax for rescuing
+# exceptions in a block with needing to make an extra begin/end pair.
+
+require 'open3'
+require 'pathname'
+require 'set'
+require 'sqlite3' # gem install sqlite3
+require_relative 'graph'
+require_relative 'expand_brackets'
+
+ResultsDir = Pathname('support/results')
+
+class AnticipatedError < RuntimeError
+end
+
+# Don't automatically change directory because maybe people want to test one
+# nixcrpkgs repository using the test script from another one. But do give an
+# early, friendly warning if they are running in the wrong directory.
+def check_directory!
+ return if File.directory?('pretend_stdenv')
+ $stderr.puts "You should run this script from the nixcrpkgs directory."
+ dir = Pathname(__FILE__).parent.parent
+ $stderr.puts "Try running these commands:\n cd #{dir}\n test/test.rb"
+ exit 1
+end
+
+def substitute_definitions(defs, str)
+ str.gsub(/\$([\w-]+)/) do |x|
+ defs.fetch($1)
+ end
+end
+
+def parse_derivation_list(filename)
+ defs = {}
+ all_paths = Set.new
+ all_attrs = {}
+ File.foreach(filename).with_index do |line, line_index|
+ line.strip!
+
+ # Handle empty lines and comments.
+ next if line.empty? || line.start_with?('#')
+
+ # Handle variable definitions (e.g. "define windows = win32,win64").
+ if line.start_with?('define')
+ md = line.match(/^define\s+([\w-]+)\s*=\s*(.*)$/)
+ if !md
+ raise AnticipatedError, "Invalid definition syntax."
+ end
+ name, value = md[1], md[2]
+ defs[name] = value
+ next
+ end
+
+ # Expand variable definitions (e.g. $windows expands to "win32,win64").
+ line = substitute_definitions(defs, line)
+
+ # Figure out which parts of the line are attribute paths with brackets and
+ # which are attributes.
+ items = line.split(' ')
+ attr_defs, path_items = items.partition { |p| p.include?('=') }
+
+ # Expand any brackets in the attribute paths to get the complete list of
+ # paths specified on this line.
+ paths = path_items.flat_map { |p| expand_brackets(p) }.map(&:to_sym)
+
+ # Process attribute definitions on the line, like "priority=1".
+ attrs = {}
+ attr_defs.each do |attr_def|
+ md = attr_def.match(/^(\w+)=(\d+)$/)
+ if !md
+ raise AnticipatedError, "Invalid attribute definition: #{attr_def.inspect}."
+ end
+ name, value = md[1], md[2]
+ case name
+ when 'priority', 'slow'
+ attrs[name.to_sym] = value.to_i
+ else
+ raise AnticipatedError, "Unrecognized attribute: #{name.inspect}."
+ end
+ end
+
+ # Record the paths for this line and the attributes for those paths,
+ # overriding previous attributes values if necessary.
+ all_paths += paths
+ if !attrs.empty?
+ paths.each do |path|
+ (all_attrs[path] ||= {}).merge!(attrs)
+ end
+ end
+ rescue AnticipatedError => e
+ raise AnticipatedError, "#{filename}:#{line_index + 1}: error: #{e}"
+ end
+
+ if all_paths.empty?
+ raise AnticipatedError, "#{filename} specifies no paths"
+ end
+
+ all_paths.each do |path|
+ if !path.match?(/^[\w.-]+$/)
+ raise "Invalid characters in path name: #{path}"
+ end
+ end
+
+ { defs: defs, paths: all_paths.to_a, attrs: all_attrs }
+end
+
+# Make a hash holding the priority of each Nix attribute path we want to build.
+# This routine determines the default priority.
+def make_path_priority_map(settings)
+ attrs = settings.fetch(:attrs)
+ m = {}
+ settings.fetch(:paths).each do |path|
+ m[path] = attrs.fetch(path, {}).fetch(:priority, 0)
+ end
+ m
+end
+
+# Make a hash holding the relative build time of each Nix attribute path we want
+# to build. This routine detrmines the default time, and what "slow" means.
+def make_path_time_map(settings)
+ attrs = settings.fetch(:attrs)
+ m = {}
+ settings.fetch(:paths).each do |path|
+ m[path] = attrs.fetch(path, {})[:slow] ? 100 : 1
+ end
+ m
+end
+
+def instantiate_drvs(paths)
+ cmd = 'nix-instantiate ' + paths.map { |p| "-A #{p}" }.join(' ')
+ stdout_str, stderr_str, status = Open3.capture3(cmd)
+ if !status.success?
+ $stderr.puts stderr_str
+ raise AnticipatedError, "Failed to instantiate derivations."
+ end
+ paths.zip(stdout_str.split.map(&:to_sym)).to_h
+end
+
+# We want there to be a one-to-one mapping between paths in the derivations.txt
+# list and derivations, so we can make a graph of dependencies of the
+# derivations and each derivation in the graph will have a unique path in the
+# derivations.txt list.
+def check_paths_are_unique!(path_drv_map)
+ set = Set.new
+ path_drv_map.each do |key, drv|
+ if set.include?(drv)
+ raise AnticipatedError, "The derivation #{key} is the same as " \
+ "other derivations in the list. Maybe use the 'omni' namespace."
+ end
+ set << drv
+ end
+end
+
+# Makes a new map that has the same keys as map1, and the values
+# have all been mapped by map2.
+#
+# Requires map2 to have a key for every value in map1.
+def map_compose(map1, map2)
+ map1.transform_values &map2.method(:fetch)
+end
+
+# Like map_compose, but excludes keys from map1 where the corresponding map1
+# value is not a key of map2.
+def map_join(map1, map2)
+ r = {}
+ map1.each do |key, value|
+ if map2.key?(value)
+ r[key] = map2.fetch(value)
+ end
+ end
+ r
+end
+
+def nix_db
+ return $db if $db
+ $db = SQLite3::Database.new '/nix/var/nix/db/db.sqlite', readonly: true
+end
+
+# Given an array of derivations (paths to .drv files in /nix), this function
+# queries the Nix database and returns hash table mapping derivations to
+# a boolean that is true if they have already been built.
+def get_build_status(drvs)
+ drv_list_str = drvs.map { |d| "\"#{d}\"" }.join(", ")
+ query = < 0
+ more_attrs << " penwidth=3"
+ end
+
+ # Draw slow nodes as a double octagon.
+ if path_time_map.fetch(path) > 10
+ more_attrs << " shape=doubleoctagon"
+ end
+ f.puts "\"#{path}\" [label=\"#{component}\"#{more_attrs}]"
+ end
+ f.puts "}"
+ end
+
+ # Output dependencies between nodes.
+ visible_paths.each do |path|
+ path_graph.fetch(path).each do |dep|
+ next if decompose.(dep).first == 'omni'
+ f.puts "\"#{path}\" -> \"#{dep}\""
+ end
+ end
+ f.puts "}"
+ end
+end
+
+def make_build_plan(path_state)
+ path_graph = path_state.fetch(:graph)
+ path_priority_map = path_state.fetch(:priority_map)
+ path_time_map = path_state.fetch(:time_map)
+ path_built_map = path_state.fetch(:built_map)
+
+ # It's handy to be able to get all the dependencies of a node in one step, and
+ # we will use that frequently to calculate how expensive it is to build a
+ # node and to make the toplogical sort.
+ path_graph = transitive_closure(path_graph).freeze
+
+ # The paths we need to build. In the future we could filter this by priority.
+ required_paths = Set.new(path_graph.keys).freeze
+
+ # built_paths: The set of paths that are already built. We will mutate this
+ # as we simulate our build plan.
+ built_paths = Set.new
+ path_built_map.each do |path, built|
+ built_paths << path if built
+ end
+
+ # List of paths to build. Each path should only be built once all the paths it
+ # depends on are built. I know nix-build can take care of that for us, but it's
+ # nice to see the precise order of what is going to be built so we can tell when
+ # slow things will get built.
+ build_plan = []
+
+ # Computes the time to build a path, taking into account what has already been
+ # built.
+ calculate_time = lambda do |path|
+ deps = path_graph.fetch(path) + [path]
+ deps.reject! &built_paths.method(:include?)
+ deps.map(&path_time_map.method(:fetch)).sum
+ end
+
+ # Adds plans to build this path and all of its unbuilt depedencies.
+ add_to_build_plan = lambda do |path|
+ deps = path_graph.fetch(path) + [path]
+
+ # Remove dependencies that are already built.
+ deps.reject! &built_paths.method(:include?)
+
+ # Topological sort
+ deps.sort! do |p1, p2|
+ case
+ when path_graph.fetch(p1).include?(p2) then 1
+ when path_graph.fetch(p2).include?(p1) then -1
+ else 0
+ end
+ end
+
+ deps.each do |path|
+ build_plan << path
+ built_paths << path
+ end
+ end
+
+ while true
+ unbuilt_required_paths = required_paths - built_paths
+ break if unbuilt_required_paths.empty?
+
+ # Find the maximum priority of the unbuilt required paths.
+ max_priority = nil
+ unbuilt_required_paths.each do |path|
+ priority = path_priority_map.fetch(path)
+ if !max_priority || priority > max_priority
+ max_priority = priority
+ end
+ end
+
+ top_priority_paths = unbuilt_required_paths.select do |path|
+ path_priority_map.fetch(path) == max_priority
+ end
+
+ target = top_priority_paths.min_by(&calculate_time)
+
+ add_to_build_plan.(target)
+ end
+
+ build_plan
+end
+
+# Updates the 'support/results' directory, which holds
+# symbolic links to all the derivations defined by nixcrpkgs and
+# listed in support/derivations.txt which have already been built.
+#
+# Intended use:
+# ln -s $PWD/support/results /nix/var/nix/gcroots/nixcrpkgs-results
+# support/manage results
+# nix-collect-garbage
+def update_results_dir(path_valid_results_map)
+ ResultsDir.mkdir if !ResultsDir.directory?
+ ResultsDir.children.each do |p|
+ p.unlink
+ end
+ modern_links = Set.new
+ path_valid_results_map.each do |path, results_map|
+ results_map.each do |id, result|
+ suffix = id == :out ? '' : ".#{id}"
+ link_name = "#{path}#{suffix}"
+ (ResultsDir + link_name).make_symlink(result)
+ modern_links << link_name
+ end
+ end
+end
+
+def build_paths(path_graph, path_built_map, build_plan, keep_going: true)
+ path_built_map = path_built_map.dup
+ path_graph = transitive_closure(path_graph)
+ build_plan.each do |path|
+ if !path_graph.fetch(path).all?(&path_built_map.method(:fetch))
+ # One of the dependencies of this path has not been built, presumably
+ # because there was an error.
+ puts "# skipping #{path}"
+ next
+ end
+
+ print "nix-build -A #{path}"
+ system("nix-build -A #{path} > /dev/null 2> /dev/null")
+
+ if $?.success?
+ path_built_map[path] = true
+ puts
+ else
+ puts " # failed"
+ return false if !keep_going
+ end
+ end
+ true
+end
+
+def parse_args(argv)
+ action = case argv.first
+ when 'graph' then :graph
+ when 'results' then :results
+ when 'build' then :build
+ when 'plan' then :plan
+ when 'stats', nil then :stats
+ else raise AnticipatedError, "Invalid action: #{argv.first.inspect}"
+ end
+
+ { action: action }
+end
+
+begin
+ check_directory!
+ args = parse_args(ARGV)
+ action = args.fetch(:action)
+
+ settings = parse_derivation_list('support/derivations.txt')
+
+ path_drv_map = instantiate_drvs(settings.fetch(:paths))
+ check_paths_are_unique!(path_drv_map)
+
+ drvs = path_drv_map.values.uniq
+ drv_built_map = get_build_status(drvs)
+
+ if [:graph, :build, :plan].include?(action)
+ global_drv_graph = get_drv_graph
+ drv_graph = graph_restrict_nodes(global_drv_graph, drvs)
+ path_state = {
+ graph: graph_unmap(drv_graph, path_drv_map).freeze,
+ priority_map: make_path_priority_map(settings).freeze,
+ time_map: make_path_time_map(settings).freeze,
+ built_map: map_compose(path_drv_map, drv_built_map).freeze,
+ }.freeze
+ end
+
+ if action == :graph
+ output_graphviz(path_state)
+ end
+
+ if [:build, :plan].include?(action)
+ build_plan = make_build_plan(path_state)
+ end
+
+ if action == :plan
+ puts "Build plan:"
+ build_plan.each do |path|
+ puts "nix-build -A #{path}"
+ end
+ end
+
+ if action == :build
+ success = build_paths(path_state[:graph], path_state[:built_map], build_plan)
+ exit(1) if !success
+ end
+
+ if action == :results || action == :build
+ drv_valid_results_map = get_valid_results(drvs)
+ path_valid_results_map = map_join(path_drv_map, drv_valid_results_map).freeze
+ update_results_dir(path_valid_results_map)
+ end
+
+ if action == :stats
+ print_stats(drv_built_map)
+ end
+rescue AnticipatedError => e
+ $stderr.puts e
+end
diff --git a/nix/nixcrpkgs/top.nix b/nix/nixcrpkgs/top.nix
new file mode 100644
index 000000000..5e1aa63a6
--- /dev/null
+++ b/nix/nixcrpkgs/top.nix
@@ -0,0 +1,72 @@
+{ osx_sdk, nixpkgs }:
+
+rec {
+ inherit nixpkgs;
+
+ # Some native build tools.
+ native = import ./native { inherit nixpkgs; };
+
+ # Cross-compiling environments for each target system.
+ crossenvs = {
+ i686-w64-mingw32 = import ./mingw-w64 { inherit native; arch = "i686"; };
+ x86_64-w64-mingw32 = import ./mingw-w64 { inherit native; arch = "x86_64"; };
+ i686-linux-musl = import ./linux { inherit native; arch = "i686"; };
+ x86_64-linux-musl = import ./linux { inherit native; arch = "x86_64"; };
+ armv6-linux-musl = import ./linux {
+ inherit native;
+ arch = "armv6";
+ gcc_options = "--with-fpu=vfp --with-float=hard ";
+ };
+ macos = import ./macos { inherit osx_sdk native; };
+ };
+
+ pkgFun = crossenv: import ./pkgs.nix { inherit crossenv; } // crossenv;
+
+ # Sets of packages for each target system.
+ i686-w64-mingw32 = pkgFun crossenvs.i686-w64-mingw32;
+ x86_64-w64-mingw32 = pkgFun crossenvs.x86_64-w64-mingw32;
+ i686-linux-musl = pkgFun crossenvs.i686-linux-musl;
+ x86_64-linux-musl = pkgFun crossenvs.x86_64-linux-musl;
+ armv6-linux-musl = pkgFun crossenvs.armv6-linux-musl;
+ macos = pkgFun crossenvs.macos;
+
+ # omni is convenient name for packages that are used for cross-compiling but
+ # are actually the same on all platforms. You can just refer to it by
+ # 'omni.package_name' instead of 'some_platform.package_name'.
+ omni = pkgFun { inherit native nixpkgs; };
+
+ # Handy aliases.
+ win32 = i686-w64-mingw32;
+ win64 = x86_64-w64-mingw32;
+ linux32 = i686-linux-musl;
+ linux-x86 = i686-linux-musl;
+ linux-i686 = i686-linux-musl;
+ linux64 = x86_64-linux-musl;
+ linux-x86_64 = x86_64-linux-musl;
+ linux-rpi = armv6-linux-musl;
+ rpi = armv6-linux-musl;
+ mac = macos;
+
+ # filter is a function that can be applied to a local directory to filter out
+ # files that are likely to change frequently without affecting the build,
+ # causing unneeded rebuilds.
+ filter_func = name: type: let bn = baseNameOf (toString name); in !(
+ (type == "directory" && bn == ".git") ||
+ (type == "symlink" && nixpkgs.lib.hasPrefix "result" bn) ||
+ (type == "directory" && bn == "nix") ||
+ (type == "directory" && bn == "build") ||
+ nixpkgs.lib.hasSuffix ".nix" bn ||
+ nixpkgs.lib.hasSuffix "~" bn
+ );
+ filter = builtins.filterSource filter_func;
+
+ # bundle is a function that takes a set of derivations and makes a
+ # derivation for a bundle that has symbolic links in it to each of
+ # the input derivations.
+ bundle = drvs: native.make_derivation rec {
+ name = "bundle";
+ builder = ./bundle_builder.sh;
+ names = builtins.attrNames drvs;
+ dirs = builtins.attrValues drvs;
+ };
+}
diff --git a/nix/ops/brass/builder.sh b/nix/ops/brass/builder.sh
index 8c8677a5f..408dc99bb 100755
--- a/nix/ops/brass/builder.sh
+++ b/nix/ops/brass/builder.sh
@@ -15,13 +15,13 @@ cleanup () {
trap cleanup EXIT
-urb ./zod -p hood -d '+hood/autoload |'
-urb ./zod -p hood -d "+hood/mount %"
+herb ./zod -p hood -d '+hood/autoload |'
+herb ./zod -p hood -d "+hood/mount %"
rm -r ./zod/home
cp -r $ARVO ./zod/home
-urb ./zod -p hood -d "+hood/commit %home"
-urb ./zod -P brass.pill -d '+brass'
+herb ./zod -p hood -d "+hood/commit %home"
+herb ./zod -P brass.pill -d '+brass'
mv brass.pill $out
diff --git a/nix/ops/brass/default.nix b/nix/ops/brass/default.nix
index 45253b9b6..50b8e98ce 100644
--- a/nix/ops/brass/default.nix
+++ b/nix/ops/brass/default.nix
@@ -3,7 +3,7 @@
pkgs.stdenv.mkDerivation rec {
name = "brass";
builder = ./builder.sh;
- buildInputs = [ urbit tlon.urb pkgs.coreutils ];
+ buildInputs = [ urbit tlon.herb pkgs.coreutils ];
FAKEZOD = fakezod;
ARVO = arvo;
diff --git a/nix/ops/fakeship/builder.sh b/nix/ops/fakeship/builder.sh
index 8a00b164a..1a5c42231 100755
--- a/nix/ops/fakeship/builder.sh
+++ b/nix/ops/fakeship/builder.sh
@@ -5,13 +5,13 @@ set -ex
urbit -d -F $SHIP -B "$PILL" $out
check () {
- [ 3 -eq "$(urb $out -d 3)" ]
+ [ 3 -eq "$(herb $out -d 3)" ]
}
if check
then
echo "Boot success." >&2
- urb $out -p hood -d '+hood/exit' || true
+ herb $out -p hood -d '+hood/exit' || true
else
echo "Boot failure." >&2
kill $(< $out/.vere.lock) || true
diff --git a/nix/ops/fakeship/default.nix b/nix/ops/fakeship/default.nix
index 133a1ba3b..7d534fd20 100644
--- a/nix/ops/fakeship/default.nix
+++ b/nix/ops/fakeship/default.nix
@@ -3,7 +3,7 @@
pkgs.stdenv.mkDerivation rec {
name = "fake" + ship;
builder = ./builder.sh;
- buildInputs = [ urbit tlon.urb ];
+ buildInputs = [ urbit tlon.herb ];
PILL = brass;
SHIP = ship;
}
diff --git a/nix/ops/solid/builder.sh b/nix/ops/solid/builder.sh
index 0c94c14a5..345c92d18 100755
--- a/nix/ops/solid/builder.sh
+++ b/nix/ops/solid/builder.sh
@@ -15,8 +15,8 @@ cleanup () {
trap cleanup EXIT
-urb ./zod -p hood -d '+hood/autoload |'
-urb ./zod -p hood -d "+hood/mount %"
+herb ./zod -p hood -d '+hood/autoload |'
+herb ./zod -p hood -d "+hood/mount %"
rm -r ./zod/home
cp -r $ARVO ./zod/home
@@ -25,7 +25,7 @@ cp -r $ARVO ./zod/home
# cp $ARVO/gen/solid.hoon ./zod/home/gen/
# cp $ARVO/lib/pill.hoon ./zod/home/lib/
-urb ./zod -p hood -d "+hood/commit %home"
-urb ./zod -P urbit.pill -d '+solid, =dub &'
+herb ./zod -p hood -d "+hood/commit %home"
+herb ./zod -P urbit.pill -d '+solid, =dub &'
mv urbit.pill $out
diff --git a/nix/ops/solid/default.nix b/nix/ops/solid/default.nix
index 983456891..370aaf4a3 100644
--- a/nix/ops/solid/default.nix
+++ b/nix/ops/solid/default.nix
@@ -3,7 +3,7 @@
pkgs.stdenv.mkDerivation rec {
name = "solid";
builder = ./builder.sh;
- buildInputs = [ urbit tlon.urb pkgs.coreutils ];
+ buildInputs = [ urbit tlon.herb pkgs.coreutils ];
FAKEZOD = fakezod;
ARVO = arvo;
diff --git a/nix/ops/test/builder.sh b/nix/ops/test/builder.sh
index 45cda7d3e..8034ea55e 100644
--- a/nix/ops/test/builder.sh
+++ b/nix/ops/test/builder.sh
@@ -20,29 +20,29 @@ shutdown () {
trap shutdown EXIT
-urb ./ship -p hood -d '+hood/autoload |'
-urb ./ship -p hood -d '+hood/mount %'
+herb ./ship -p hood -d '+hood/autoload |'
+herb ./ship -p hood -d '+hood/mount %'
rm -r ./ship/home
cp -r $ARVO ./ship/home
-urb ./ship -p hood -d '+hood/commit %home'
+herb ./ship -p hood -d '+hood/commit %home'
# Start the test app
-urb ./ship -p hood -d '+hood/start %test'
+herb ./ship -p hood -d '+hood/start %test'
# Run the %cores tests
-urb ./ship -d '~& ~ ~& %start-test-cores ~'
-urb ./ship -p test -d ':- %cores /'
-urb ./ship -d '~& %finish-test-cores ~'
+herb ./ship -d '~& ~ ~& %start-test-cores ~'
+herb ./ship -p test -d ':- %cores /'
+herb ./ship -d '~& %finish-test-cores ~'
# Run the %renders tests
-urb ./ship -d '~& ~ ~& %start-test-renders ~'
-urb ./ship -p test -d ':- %renders /'
-urb ./ship -d '~& %finish-test-renders ~'
+herb ./ship -d '~& ~ ~& %start-test-renders ~'
+herb ./ship -p test -d ':- %renders /'
+herb ./ship -d '~& %finish-test-renders ~'
# Run the test generator
-urb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' |
+herb ./ship -d '+test, =seed `@uvI`(shaz %reproducible)' |
tee test-generator-output
shutdown
diff --git a/nix/ops/test/default.nix b/nix/ops/test/default.nix
index 3a1841495..b6f4c26d8 100644
--- a/nix/ops/test/default.nix
+++ b/nix/ops/test/default.nix
@@ -3,7 +3,7 @@
pkgs.stdenv.mkDerivation rec {
name = "test";
builder = ./builder.sh;
- buildInputs = [ urbit tlon.urb pkgs.coreutils ];
+ buildInputs = [ urbit tlon.herb pkgs.coreutils ];
SHIP = ship;
ARVO = arvo;
diff --git a/nix/pkgs/default.nix b/nix/pkgs/default.nix
index ee384fcc9..1f7fa7fbf 100644
--- a/nix/pkgs/default.nix
+++ b/nix/pkgs/default.nix
@@ -4,26 +4,20 @@ let
deps = import ../deps { inherit pkgs; };
+ ent = import ./ent { inherit pkgs; };
+ arvo = import ./arvo { inherit pkgs; };
+ herb = import ../../pkg/herb { inherit pkgs; };
+
+ mkUrbit = { debug }:
+ import ./urbit {
+ inherit pkgs ent debug;
+ inherit (deps) argon2 murmur3 uv ed25519 sni scrypt softfloat3;
+ inherit (deps) secp256k1 h2o;
+ };
+
+ urbit = mkUrbit { debug=false; };
+ urbit-debug = mkUrbit { debug=true; };
+
in
-rec {
- arvo = import ./arvo { inherit pkgs; };
- ent = import ./ent { inherit pkgs; };
- urb = import ../../pkg/urb { inherit pkgs; };
-
- urbit = import ./urbit {
- inherit pkgs ent;
- inherit (deps) argon2 murmur3 uv ed25519 sni scrypt softfloat3;
- inherit (deps) secp256k1 h2o;
- name = "urbit";
- debug = false;
- };
-
- urbit-debug = import ./urbit {
- inherit pkgs ent;
- inherit (deps) argon2 murmur3 uv ed25519 sni scrypt softfloat3;
- inherit (deps) secp256k1 h2o;
- name = "urbit-debug";
- debug = true;
- };
-}
+{ inherit ent arvo herb urbit urbit-debug; }
diff --git a/nix/pkgs/urbit/builder.sh b/nix/pkgs/urbit/builder.sh
index 3b9ee115e..bb04e4df5 100644
--- a/nix/pkgs/urbit/builder.sh
+++ b/nix/pkgs/urbit/builder.sh
@@ -6,7 +6,9 @@ cd src
bash ./configure
+make clean
make urbit urbit-worker -j8
+make test
mkdir -p $out/bin
cp urbit $out/bin/$exename
diff --git a/nix/pkgs/urbit/default.nix b/nix/pkgs/urbit/default.nix
index b536eef94..8c80427d4 100644
--- a/nix/pkgs/urbit/default.nix
+++ b/nix/pkgs/urbit/default.nix
@@ -1,12 +1,14 @@
{
pkgs,
- name ? "urbit",
- debug ? false,
+ debug,
argon2, ed25519, ent, h2o, murmur3, scrypt, secp256k1, sni, softfloat3, uv
}:
let
+ name =
+ if debug then "urbit-debug" else "urbit";
+
deps =
with pkgs;
[ curl gmp libsigsegv ncurses openssl zlib ];
@@ -14,16 +16,6 @@ let
vendor =
[ argon2 softfloat3 ed25519 ent h2o scrypt uv murmur3 secp256k1 sni ];
- # osx =
- # with pkgs;
- # lib.optionals stdenv.isDarwin (
- # with darwin.apple_sdk.frameworks;
- # [ Cocoa CoreServices ]);
-
- # NIX_LDFLAGS =
- # pkgs.lib.optionalString pkgs.stdenv.isDarwin
- # "-framework CoreServices -framework CoreFoundation";
-
in
pkgs.stdenv.mkDerivation {
diff --git a/nix/pkgs/urbit/release.nix b/nix/pkgs/urbit/release.nix
index 2d6c93ff0..615344c0f 100644
--- a/nix/pkgs/urbit/release.nix
+++ b/nix/pkgs/urbit/release.nix
@@ -20,6 +20,7 @@ env.make_derivation {
MEMORY_DEBUG = debug;
CPU_DEBUG = debug;
EVENT_TIME_DEBUG = false;
+ NCURSES = env.ncurses;
name = "${name}-${env_name}";
exename = name;
diff --git a/nix/pkgs/urbit/release.sh b/nix/pkgs/urbit/release.sh
index 9983c2831..e21dd63a7 100644
--- a/nix/pkgs/urbit/release.sh
+++ b/nix/pkgs/urbit/release.sh
@@ -17,5 +17,6 @@ bash ./configure
make urbit urbit-worker -j8
mkdir -p $out/bin
-cp urbit $out/bin/$exename
-cp urbit-worker $out/bin/$exename-worker
+cp -r $NCURSES/share/terminfo $out/bin/$exename-terminfo
+cp urbit $out/bin/$exename
+cp urbit-worker $out/bin/$exename-worker
diff --git a/nix/pkgs/urbit/shell.nix b/nix/pkgs/urbit/shell.nix
index 310b3eba1..4a6ea350e 100644
--- a/nix/pkgs/urbit/shell.nix
+++ b/nix/pkgs/urbit/shell.nix
@@ -8,6 +8,7 @@ in
import ./default.nix {
inherit pkgs;
+ debug = false;
inherit (tlon) ent;
inherit (deps)
argon2 ed25519 h2o murmur3 scrypt secp256k1 sni softfloat3 uv;
diff --git a/pkg/arvo b/pkg/arvo
index 59dd85392..46c924734 160000
--- a/pkg/arvo
+++ b/pkg/arvo
@@ -1 +1 @@
-Subproject commit 59dd8539262e93c46221f02db5098803504e4af0
+Subproject commit 46c92473477ba8f4d14a6e2bb22319c8bf5970a4
diff --git a/pkg/urb/.gitignore b/pkg/herb/.gitignore
similarity index 100%
rename from pkg/urb/.gitignore
rename to pkg/herb/.gitignore
diff --git a/pkg/urb/LICENSE b/pkg/herb/LICENSE
similarity index 100%
rename from pkg/urb/LICENSE
rename to pkg/herb/LICENSE
diff --git a/pkg/urb/README.md b/pkg/herb/README.md
similarity index 60%
rename from pkg/urb/README.md
rename to pkg/herb/README.md
index 097d8b843..d0f2eab8f 100644
--- a/pkg/urb/README.md
+++ b/pkg/herb/README.md
@@ -1,4 +1,4 @@
-# urb
+# Herb
Unix control of Urbit
@@ -7,10 +7,10 @@ Unix control of Urbit
To run without installing anything:
```bash
-nix-shell --pure --command 'python ./urb -d "(add 3 4)"'
+nix-shell --pure --command 'python ./herb -d "(add 3 4)"'
```
-To install `urb`:
+To install `herb`:
```bash
nix-env -if .
diff --git a/pkg/urb/default.nix b/pkg/herb/default.nix
similarity index 79%
rename from pkg/urb/default.nix
rename to pkg/herb/default.nix
index 2aff0056b..b1dd819a6 100644
--- a/pkg/urb/default.nix
+++ b/pkg/herb/default.nix
@@ -21,19 +21,19 @@ let
in
pkgs.stdenv.mkDerivation rec {
- name = "urb";
+ name = "herb";
buildInputs = [ pyenv ];
unpackPhase = "true";
installPhase = ''
mkdir -p $out/bin
- cp ${./urb} $out/bin/urb.py
+ cp ${./herb} $out/bin/herb.py
- cat > $out/bin/urb < $out/bin/herb <config.mk <
#include
#include
+#include
#include
#include
#include
@@ -232,12 +233,19 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.nuu = c3y;
}
- // make -c optional
+ // make -c optional, catch invalid boot of existing pier
//
- if ( c3n == u3_Host.ops_u.nuu ) {
+ {
struct stat s;
if ( 0 != stat(u3_Host.dir_c, &s) ) {
- u3_Host.ops_u.nuu = c3y;
+ if ( c3n == u3_Host.ops_u.nuu ) {
+ u3_Host.ops_u.nuu = c3y;
+ }
+ }
+ else if ( c3y == u3_Host.ops_u.nuu ) {
+ fprintf(stderr, "tried to create, but %s already exists\n", u3_Host.dir_c);
+ fprintf(stderr, "normal usage: %s %s\n", argv[0], u3_Host.dir_c);
+ exit(1);
}
}
@@ -430,82 +438,6 @@ u3_ve_sysopt()
u3_Local = strdup(u3_Host.dir_c);
}
-#if 0
-static jmp_buf Signal_buf;
-#ifndef SIGSTKSZ
-# define SIGSTKSZ 16384
-#endif
-static uint8_t Sigstk[SIGSTKSZ];
-
-volatile enum { sig_none, sig_overflow, sig_interrupt } Sigcause;
-
-static void _main_cont(void *arg1, void *arg2, void *arg3)
-{
- (void)(arg1);
- (void)(arg2);
- (void)(arg3);
- siglongjmp(Signal_buf, 1);
-}
-
-static void
-overflow_handler(int emergency, stackoverflow_context_t scp)
-{
- if ( 1 == emergency ) {
- write(2, "stack emergency\n", strlen("stack emergency" + 2));
- exit(1);
- } else {
- Sigcause = sig_overflow;
- sigsegv_leave_handler(_main_cont, NULL, NULL, NULL);
- }
-}
-
- // Install signal handlers and set buffers.
- //
- // Note that we use the sigmask-restoring variant. Essentially, when
- // we get a signal, we force the system back into the just-booted state.
- // If anything goes wrong during boot (above), it's curtains.
- {
- if ( 0 != sigsetjmp(Signal_buf, 1) ) {
- switch ( Sigcause ) {
- case sig_overflow: printf("[stack overflow]\r\n"); break;
- case sig_interrupt: printf("[interrupt]\r\n"); break;
- default: printf("[signal error!]\r\n"); break;
- }
- Sigcause = sig_none;
-
- signal(SIGINT, SIG_DFL);
- stackoverflow_deinstall_handler();
-
- // Print the trace, do a GC, etc.
- //
- // This is half-assed at present, so we exit.
- //
- u3_lo_sway(0, u3k(u3_wire_tax(u3_Wire)));
-
- u3_pier_exit(u3A);
-
- exit(1);
- }
- if ( -1 == stackoverflow_install_handler
- (overflow_handler, Sigstk, SIGSTKSZ) )
- {
- fprintf(stderr, "overflow_handler: install failed\n");
- exit(1);
- }
- signal(SIGINT, interrupt_handler);
- signal(SIGIO, SIG_IGN);
- }
-
-static void
-interrupt_handler(int x)
-{
- Sigcause = sig_interrupt;
- longjmp(Signal_buf, 1);
-}
-#endif
-
-#define GRAB
-
static void
report(void)
{
@@ -523,13 +455,13 @@ report(void)
H2O_LIBRARY_VERSION_PATCH);
}
-void
+static void
_stop_exit(c3_i int_i)
{
- fprintf(stderr, "\r\n[received keyboard stop signal, exiting]\r\n");
- // XX crashes if we haven't started a pier yet
+ // explicit fprintf to avoid allocation in u3l_log
//
- u3_pier_exit(u3_pier_stub());
+ fprintf(stderr, "\r\n[received keyboard stop signal, exiting]\r\n");
+ u3_daemon_bail();
}
/*
@@ -638,6 +570,12 @@ main(c3_i argc,
u3_Host.wrk_c = c3_malloc(worker_exe_len);
snprintf(u3_Host.wrk_c, worker_exe_len, "%s-worker", argv[0]);
+ // Set TERMINFO_DIRS environment variable
+ c3_i terminfo_len = 1 + strlen(argv[0]) + strlen("-terminfo");
+ c3_c terminfo_dir[terminfo_len];
+ snprintf(terminfo_dir, terminfo_len, "%s-terminfo", argv[0]);
+ setenv("TERMINFO_DIRS", terminfo_dir, 1);
+
if ( c3y == u3_Host.ops_u.dem ) {
_fork_into_background_process();
}
@@ -655,7 +593,9 @@ main(c3_i argc,
#endif
u3_ve_sysopt();
- // Block profiling signal, which should be delievered to exactly one thread.
+ // Block profiling signal, which should be delivered to exactly one thread.
+ //
+ // XX review, may be unnecessary due to similar in u3m_init()
//
if ( _(u3_Host.ops_u.pro) ) {
sigset_t set;
@@ -670,6 +610,8 @@ main(c3_i argc,
// Handle SIGTSTP as if it was SIGTERM.
//
+ // Configured here using signal() so as to be immediately available.
+ //
signal(SIGTSTP, _stop_exit);
printf("~\n");
@@ -719,6 +661,10 @@ main(c3_i argc,
*/
u3C.dir_c = u3_Host.dir_c;
+ /* Logging that doesn't interfere with console output.
+ */
+ u3C.stderr_log_f = u3_term_io_log;
+
/* Set GC flag.
*/
if ( _(u3_Host.ops_u.gab) ) {
@@ -786,7 +732,7 @@ main(c3_i argc,
close(rad);
}
- u3_king_commence();
+ u3_daemon_commence();
}
return 0;
}
diff --git a/pkg/urbit/debian/changelog b/pkg/urbit/debian/changelog
deleted file mode 100644
index 47cafdcfe..000000000
--- a/pkg/urbit/debian/changelog
+++ /dev/null
@@ -1,5 +0,0 @@
-urbit (0.6-0) unstable; urgency=high
-
- * Memory-allocation bug fix in _box_slot in Vere. Breaking change.
-
- -- Keaton Dunsford Fri, 8 Jun 2018 14:31:08 -0700
diff --git a/pkg/urbit/debian/compat b/pkg/urbit/debian/compat
deleted file mode 100644
index f599e28b8..000000000
--- a/pkg/urbit/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-10
diff --git a/pkg/urbit/debian/control b/pkg/urbit/debian/control
deleted file mode 100644
index 430ff65e3..000000000
--- a/pkg/urbit/debian/control
+++ /dev/null
@@ -1,12 +0,0 @@
-Source: urbit
-Section: net
-Priority: extra
-Maintainer: Ted Blackman
-Build-Depends: debhelper (>= 9), libgmp3-dev, libsigsegv-dev, openssl, libssl-dev,libtool, meson, re2c, libcurl4-gnutls-dev
-Standards-Version: 3.9.5
-Homepage: http://urbit.org
-
-Package: urbit
-Architecture: any
-Depends: libgmp3-dev, libsigsegv-dev, openssl, libcurl4-gnutls-dev
-Description: An operating function
diff --git a/pkg/urbit/debian/copyright b/pkg/urbit/debian/copyright
deleted file mode 100644
index 72fb2d7eb..000000000
--- a/pkg/urbit/debian/copyright
+++ /dev/null
@@ -1,27 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: urbit
-Source:
-
-Files: *
-License: MIT
- The MIT License (MIT)
- .
- Copyright (c) 2017 Urbit
- .
- 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/pkg/urbit/debian/debhelper-build-stamp b/pkg/urbit/debian/debhelper-build-stamp
deleted file mode 100644
index 7d4ce33b1..000000000
--- a/pkg/urbit/debian/debhelper-build-stamp
+++ /dev/null
@@ -1 +0,0 @@
-urbit
diff --git a/pkg/urbit/debian/docs b/pkg/urbit/debian/docs
deleted file mode 100644
index d99978a9b..000000000
--- a/pkg/urbit/debian/docs
+++ /dev/null
@@ -1,2 +0,0 @@
-LICENSE.txt
-README.md
diff --git a/pkg/urbit/debian/install b/pkg/urbit/debian/install
deleted file mode 100644
index 474c77259..000000000
--- a/pkg/urbit/debian/install
+++ /dev/null
@@ -1 +0,0 @@
-bin/urbit usr/bin
diff --git a/pkg/urbit/debian/rules b/pkg/urbit/debian/rules
deleted file mode 100755
index 3ee6d911c..000000000
--- a/pkg/urbit/debian/rules
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/make -f
-%:
- dh $@
-
-override_dh_auto_install:
diff --git a/pkg/urbit/debian/source/format b/pkg/urbit/debian/source/format
deleted file mode 100644
index 163aaf8d8..000000000
--- a/pkg/urbit/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/pkg/urbit/gdb-test-hash b/pkg/urbit/gdb-test-hash
deleted file mode 100644
index d2ba41a73..000000000
--- a/pkg/urbit/gdb-test-hash
+++ /dev/null
@@ -1,4 +0,0 @@
-file bin/test_hash
-handle SIGSEGV nostop noprint
-start
-
diff --git a/pkg/urbit/include/all.h b/pkg/urbit/include/all.h
index 4f77916b1..a14f2bb30 100644
--- a/pkg/urbit/include/all.h
+++ b/pkg/urbit/include/all.h
@@ -19,6 +19,7 @@
# include "noun/hashtable.h" // u3h: hashtables
# include "noun/imprison.h" // u3i: noun construction
# include "noun/jets.h" // u3j: jet control
+# include "noun/log.h" // u3l: logging
# include "noun/manage.h" // u3m: master state
# include "noun/nock.h" // u3n: nock execution
# include "noun/options.h" // u3o: config options
@@ -31,24 +32,3 @@
# include "jets/k.h" // u3k: jets (transfer, args)
# include "jets/q.h" // u3q: jets (retain, args)
# include "jets/w.h" // u3w: jets (retain, core)
-
- /** u3_term: log output dependencies.
- **/
- extern FILE*
- u3_term_io_hija(void);
-
- extern void
- u3_term_io_loja(int x);
-
- extern void
- u3_term_tape(u3_noun tep);
-
- extern void
- u3_term_wall(u3_noun wol);
-
- /* uL, uH: wrap hijack/lojack around fprintf.
- **
- ** uL(fprintf(uH, ...));
- */
-# define uH u3_term_io_hija()
-# define uL(x) u3_term_io_loja(x)
diff --git a/pkg/urbit/include/c/defs.h b/pkg/urbit/include/c/defs.h
index f4a56681d..81fde31f8 100644
--- a/pkg/urbit/include/c/defs.h
+++ b/pkg/urbit/include/c/defs.h
@@ -20,8 +20,7 @@
# define c3_assert(x) \
do { \
if (!(x)) { \
- fprintf(stderr, \
- "\rAssertion '%s' failed " \
+ u3l_log("\rAssertion '%s' failed " \
"in %s:%d\n", \
#x, __FILE__, __LINE__); \
c3_cooked(); \
@@ -84,18 +83,6 @@
| (((w) >> 8) & 0xff) << 16 \
| ( (w) & 0xff) << 24 )
- /* Logging shorthand.
- */
-# define c3_log_every(n, args...) \
- do { \
- static c3_w cnt_w = 0; \
- \
- if ( 0 == cnt_w % (n) ) { \
- uL(fprintf(uH, args)); \
- } \
- cnt_w = (cnt_w + 1) % (n); \
- } while (0)
-
/* Asserting allocators.
*/
# define c3_free(s) free(s)
diff --git a/pkg/urbit/include/c/motes.h b/pkg/urbit/include/c/motes.h
index f55602d2c..2a539c148 100644
--- a/pkg/urbit/include/c/motes.h
+++ b/pkg/urbit/include/c/motes.h
@@ -1042,6 +1042,7 @@
# define c3__spot c3_s4('s','p','o','t')
# define c3__stam c3_s4('s','t','a','m')
# define c3__star c3_s4('s','t','a','r')
+# define c3__stdr c3_s4('s','t','d','r')
# define c3__stem c3_s4('s','t','e','m')
# define c3__step c3_s4('s','t','e','p')
# define c3__stid c3_s4('s','t','i','d')
diff --git a/pkg/urbit/include/noun/jets.h b/pkg/urbit/include/noun/jets.h
index 74e9bc314..f0361d599 100644
--- a/pkg/urbit/include/noun/jets.h
+++ b/pkg/urbit/include/noun/jets.h
@@ -132,7 +132,7 @@
**/
/* u3j_boot(): initialize jet system.
*/
- void
+ c3_w
u3j_boot(c3_o nuu_o);
/* u3j_clear(): clear jet table to re-register.
diff --git a/pkg/urbit/include/noun/log.h b/pkg/urbit/include/noun/log.h
new file mode 100644
index 000000000..204cb8505
--- /dev/null
+++ b/pkg/urbit/include/noun/log.h
@@ -0,0 +1,9 @@
+/* noun/log.h
+**
+*/
+
+/* u3_log(): logs to stderr or redirects to configured function.
+*/
+ void
+ u3l_log(const char* format, ...)
+ __attribute__ ((format (printf, 1, 2)));
diff --git a/pkg/urbit/include/noun/options.h b/pkg/urbit/include/noun/options.h
index 9ac90512e..5aecc1758 100644
--- a/pkg/urbit/include/noun/options.h
+++ b/pkg/urbit/include/noun/options.h
@@ -10,6 +10,10 @@
u3_noun who; // single identity
c3_c* dir_c; // execution directory (pier)
c3_w wag_w; // flags (both ways)
+ void (*stderr_log_f)(c3_c*); // errors from c code
+ void (*slog_f)(u3_noun); // function pointer for slog
+ void (*sign_hold_f)(void); // suspend system signal regime
+ void (*sign_move_f)(void); // restore system signal regime
} u3o_config;
/* u3o_flag: process/system flags.
diff --git a/pkg/urbit/include/noun/trace.h b/pkg/urbit/include/noun/trace.h
index 75dc93b5d..555479f14 100644
--- a/pkg/urbit/include/noun/trace.h
+++ b/pkg/urbit/include/noun/trace.h
@@ -63,11 +63,6 @@
void
u3t_slog(u3_noun hod);
- /* u3t_shiv(): atom-only print.
- */
- void
- u3t_shiv(u3_noun hod);
-
/* u3t_heck(): profile point.
*/
void
diff --git a/pkg/urbit/include/vere/vere.h b/pkg/urbit/include/vere/vere.h
index f3e4b15b9..de181b5ab 100644
--- a/pkg/urbit/include/vere/vere.h
+++ b/pkg/urbit/include/vere/vere.h
@@ -619,9 +619,9 @@
struct _u3_writ* nex_u; // next in queue, or 0
} u3_writ;
- /* u3_lord: working process controller.
+ /* u3_controller: working process controller.
*/
- typedef struct _u3_lord {
+ typedef struct _u3_controller {
uv_process_t cub_u; // process handle
uv_process_options_t ops_u; // process configuration
uv_stdio_container_t cod_u[3]; // process options
@@ -634,7 +634,7 @@
c3_d rel_d; // last event released
c3_l mug_l; // mug after last completion
struct _u3_pier* pir_u; // pier backpointer
- } u3_lord;
+ } u3_controller;
/* u3_disk: manage events on disk.
**
@@ -657,7 +657,9 @@
/* u3_boot: startup controller.
*/
typedef struct _u3_boot {
-
+ u3_noun pil; // pill
+ u3_noun ven; // boot event
+ struct _u3_pier* pir_u; // pier backpointer
} u3_boot;
/* u3_psat: pier state.
@@ -676,8 +678,9 @@
c3_c* pax_c; // pier directory
c3_w wag_w; // config flags
c3_d gen_d; // last event discovered
- c3_d but_d; // boot barrier
- c3_d lif_d; // lifecycle boot barrier
+ c3_d lif_d; // lifecycle barrier
+ u3_boot* bot_u; // boot state
+ c3_d but_d; // boot/restart barrier
c3_d tic_d[1]; // ticket (unstretched)
c3_d sec_d[1]; // generator (unstretched)
c3_d key_d[4]; // secret (stretched)
@@ -685,12 +688,9 @@
c3_c* who_c; // identity as C string
c3_s por_s; // UDP port
c3_o fak_o; // yes iff fake security
- c3_o liv_o; // live
u3_psat sat_e; // pier state
- u3_noun bot; // boot event XX review
- u3_noun pil; // pill XX review
u3_disk* log_u; // event log
- u3_lord* god_u; // computer
+ u3_controller* god_u; // computer
u3_ames* sam_u; // packet interface
u3_behn* teh_u; // behn timer
u3_unix* unx_u; // sync and clay
@@ -702,25 +702,25 @@
/* u3_king: all executing piers.
*/
- typedef struct _u3_king {
+ typedef struct _u3_daemon {
c3_c* soc_c; // socket name
- c3_w len_w; // number of lords used
- c3_w all_w; // number of lords allocated
- u3_pier** tab_u; // lord table
+ c3_w len_w; // number used
+ c3_w all_w; // number allocated
+ u3_pier** tab_u; // pier table
uv_pipe_t cmd_u; // command socket
u3_moor* cli_u; // connected clients
uv_timer_t tim_u; // gc timer
- } u3_king;
+ } u3_daemon;
# define u3L u3_Host.lup_u // global event loop
# define u3Z (&(u3_Raft))
-# define u3K u3_King
+# define u3K u3_Daemon
/** Global variables.
**/
- c3_global u3_host u3_Host;
- c3_global c3_c* u3_Local;
- c3_global u3_king u3_King;
+ c3_global u3_host u3_Host;
+ c3_global c3_c* u3_Local;
+ c3_global u3_daemon u3_Daemon;
/** Functions.
**/
@@ -934,6 +934,16 @@
/** Terminal, new style.
**/
+ /* u3_term_start_spinner(): prepare spinner state. RETAIN.
+ */
+ void
+ u3_term_start_spinner(u3_noun ovo);
+
+ /* u3_term_stop_spinner(): reset spinner state and restore input line.
+ */
+ void
+ u3_term_stop_spinner(void);
+
/* u3_term_get_blew(): return window size [columns rows].
*/
u3_noun
@@ -990,18 +1000,16 @@
FILE*
u3_term_io_hija(void);
+ /* u3_term_it_log(): writes a log message
+ */
+ void
+ u3_term_io_log(c3_c* line);
+
/* u3_term_io_loja(): release console from cooked print.
*/
void
u3_term_io_loja(int x);
- /* uL, uH: wrap hijack/lojack around fprintf.
- **
- ** uL(fprintf(uH, ...));
- */
-# define uH u3_term_io_hija()
-# define uL(x) u3_term_io_loja(x)
-
/** Ames, packet networking.
**/
@@ -1235,11 +1243,6 @@
/** Pier control.
**/
- /* u3_pier_create(): create a pier, loading existing.
- */
- u3_pier*
- u3_pier_create(c3_w wag_w, c3_c* pax_c);
-
/* u3_pier_interrupt(): interrupt running process.
*/
void
@@ -1257,7 +1260,7 @@
void
u3_pier_exit(u3_pier* pir_u);
- /* u3_pier_bail(): clean up all event state.
+ /* u3_pier_bail(): immediately shutdown..
*/
void
u3_pier_bail(void);
@@ -1326,15 +1329,20 @@
u3_noun
u3_dawn_vent(u3_noun seed);
- /* u3_king_commence(): start the daemon
+ /* u3_daemon_commence(): start the daemon
*/
void
- u3_king_commence();
+ u3_daemon_commence();
- /* u3_king_grab(): gc the kingdom
+ /* u3_daemon_bail(): immediately shutdown.
*/
void
- u3_king_grab(void* vod_p);
+ u3_daemon_bail(void);
+
+ /* u3_king_grab(): gc the daemon area
+ */
+ void
+ u3_daemon_grab(void* vod_p);
c3_w
- u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
+ u3_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
diff --git a/pkg/urbit/jets/e/argon2.c b/pkg/urbit/jets/e/argon2.c
index cc439014b..0663304b7 100644
--- a/pkg/urbit/jets/e/argon2.c
+++ b/pkg/urbit/jets/e/argon2.c
@@ -72,7 +72,7 @@
int argon_res;
switch ( type ) {
default:
- fprintf(stderr, "\nunjetted argon2 variant %i\n", type);
+ u3l_log("\nunjetted argon2 variant %i\n", type);
u3m_bail(c3__exit);
break;
//
@@ -94,7 +94,7 @@
}
if ( ARGON2_OK != argon_res ) {
- fprintf(stderr, "\nargon2 error: %s\n", argon2_error_message(argon_res));
+ u3l_log("\nargon2 error: %s\n", argon2_error_message(argon_res));
u3m_bail(c3__exit);
}
diff --git a/pkg/urbit/jets/e/blake.c b/pkg/urbit/jets/e/blake.c
index 329e86d2f..eece09ab5 100644
--- a/pkg/urbit/jets/e/blake.c
+++ b/pkg/urbit/jets/e/blake.c
@@ -43,7 +43,7 @@
if ( 0 != ret )
{
- fprintf(stderr, "\rblake jet: cryto lib error\n");
+ u3l_log("\rblake jet: cryto lib error\n");
return u3m_bail(c3__exit);
}
@@ -64,7 +64,7 @@
u3r_cell(key, &wik, &dak) || u3ud(wik) || u3ud(dak) ||
u3ud(out) )
{
- fprintf(stderr, "\rblake jet: arguments error\n");
+ u3l_log("\rblake jet: arguments error\n");
return u3m_bail(c3__exit);
} else {
return u3qe_blake(wid, dat, wik, dak, out);
diff --git a/pkg/urbit/jets/e/ripe.c b/pkg/urbit/jets/e/ripe.c
index 05276a5fa..13b592151 100644
--- a/pkg/urbit/jets/e/ripe.c
+++ b/pkg/urbit/jets/e/ripe.c
@@ -37,20 +37,20 @@
ret_w = EVP_DigestInit_ex(con_u, rip_u, NULL);
if ( 1 != ret_w ) {
u3a_free(dat_y);
- fprintf(stderr, "\rripe jet: crypto library fail 1\n");
+ u3l_log("\rripe jet: crypto library fail 1\n");
return u3m_bail(c3__exit);
}
ret_w = EVP_DigestUpdate(con_u, (void*)dat_y, wid);
u3a_free(dat_y);
if (1 != ret_w) {
- fprintf(stderr, "\rripe jet: crypto library fail 2\n");
+ u3l_log("\rripe jet: crypto library fail 2\n");
return u3m_bail(c3__exit);
}
ret_w = EVP_DigestFinal_ex(con_u, sib_y, &sil_w);
if ( 1 != ret_w ) {
- fprintf(stderr, "\rripe jet: crypto library fail 3\n");
+ u3l_log("\rripe jet: crypto library fail 3\n");
return u3m_bail(c3__exit);
}
@@ -71,7 +71,7 @@
u3ud(wid) || u3ud(dat))
)
{
- fprintf(stderr, "\rripe jet: argument error\n");
+ u3l_log("\rripe jet: argument error\n");
return u3m_bail(c3__exit);
}
else {
diff --git a/pkg/urbit/jets/e/rub.c b/pkg/urbit/jets/e/rub.c
index 27380273d..716c0beb5 100644
--- a/pkg/urbit/jets/e/rub.c
+++ b/pkg/urbit/jets/e/rub.c
@@ -25,7 +25,7 @@
// Sanity check: crash if decoding more bits than available
if ( c3y == u3qa_gth(x, m)) {
- // fprintf(stderr, "[%%rub-hard %d %d %d]\r\n", a, x, m);
+ // u3l_log("[%%rub-hard %d %d %d]\r\n", a, x, m);
return u3m_bail(c3__exit);
}
diff --git a/pkg/urbit/jets/e/secp.c b/pkg/urbit/jets/e/secp.c
index 5bc651a11..746d3b255 100644
--- a/pkg/urbit/jets/e/secp.c
+++ b/pkg/urbit/jets/e/secp.c
@@ -64,7 +64,7 @@ u3we_sign(u3_noun cor)
0)) ||
(c3n == u3ud(has)) ||
(c3n == u3ud(prv))) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
} else {
return (u3qe_sign(has, prv));
@@ -100,7 +100,7 @@ u3qe_sign(u3_atom has,
(secp256k1_nonce_function) NULL, /* IN: nonce-function ptr ; NULL = default */
(const void *) NULL); /* IN: data for nonce function; not used */
if (1 != ret) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
@@ -113,7 +113,7 @@ u3qe_sign(u3_atom has,
& v, /* OUT: v */
& sig_u); /* IN: 65 byte sig */
if (1 != ret) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
@@ -149,7 +149,7 @@ u3we_reco(u3_noun cor)
(c3n == u3ud(sir)) ||
(c3n == u3ud(sis)) )
{
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
} else {
return u3qe_reco(has, siv, sir, sis);
@@ -197,7 +197,7 @@ u3qe_reco(u3_atom has,
ras_y, /* IN: r/s */
siv_ws); /* IN: v */
if (1 != ret) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
@@ -210,7 +210,7 @@ u3qe_reco(u3_atom has,
(const c3_y *) & has); /* IN: message has */
if (1 != ret) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
@@ -226,7 +226,7 @@ u3qe_reco(u3_atom has,
SECP256K1_EC_UNCOMPRESSED); /* IN: flags */
if (1 != ret) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
@@ -269,7 +269,7 @@ u3we_make(u3_noun cor)
(c3n == u3ud(has)) ||
(c3n == u3ud(prv)) )
{
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
} else {
return u3qe_make(has, prv);
@@ -303,7 +303,7 @@ u3qe_make(u3_atom has,
(void *) NULL, /* IN: arbitrary data pointer (unused) */
0); /* IN: attempt number (0 == normal) */
if (1 != ret_ws) {
- fprintf(stderr, "\rsecp jet: crypto package error\n");
+ u3l_log("\rsecp jet: crypto package error\n");
return u3m_bail(c3__exit);
}
diff --git a/pkg/urbit/jets/f/core.c b/pkg/urbit/jets/f/core.c
index 6747cfab9..753ea74de 100644
--- a/pkg/urbit/jets/f/core.c
+++ b/pkg/urbit/jets/f/core.c
@@ -22,7 +22,7 @@
(u3_nul == u3h(hr_con)) &&
(u3_nul == u3t(hr_con)) )
{
- fprintf(stderr, "old core\r\n");
+ u3l_log("old core\r\n");
abort();
}
}
diff --git a/pkg/urbit/jets/f/look.c b/pkg/urbit/jets/f/look.c
index cc1e4c32a..e54091b0b 100644
--- a/pkg/urbit/jets/f/look.c
+++ b/pkg/urbit/jets/f/look.c
@@ -20,7 +20,7 @@
u3r_trel(dab, &n_dab, &l_dab, &r_dab);
if ( c3n == u3du(n_dab) ) {
// return u3m_bail(c3__fail);
- fprintf(stderr, "bad look\r\n");
+ u3l_log("bad look\r\n");
return u3m_bail(c3__exit) ;
}
else {
diff --git a/pkg/urbit/jets/f/ut_find.c b/pkg/urbit/jets/f/ut_find.c
index 3d5fe0d61..faa50a70b 100644
--- a/pkg/urbit/jets/f/ut_find.c
+++ b/pkg/urbit/jets/f/ut_find.c
@@ -630,11 +630,11 @@
default: return u3m_bail(c3__fail);
case c3__noun: {
- // fprintf(stderr, "noun\r\n");
+ // u3l_log("noun\r\n");
return _find_buck_stop(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__void: {
- // fprintf(stderr, "void\r\n");
+ // u3l_log("void\r\n");
// return _find_buck_stop(van, sut, way, p_heg, q_heg, axe, lon, gil);
return u3_nul;
}
@@ -644,17 +644,17 @@
case c3__atom:
{
- // fprintf(stderr, "atom\r\n");
+ // u3l_log("atom\r\n");
return _find_buck_stop(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__cell:
{
- // fprintf(stderr, "cell\r\n");
+ // u3l_log("cell\r\n");
return _find_buck_cell(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__core:
{
- // fprintf(stderr, "core\r\n");
+ // u3l_log("core\r\n");
return _find_buck_core(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__hint:
@@ -666,17 +666,17 @@
}
case c3__face:
{
- // fprintf(stderr, "face\r\n");
+ // u3l_log("face\r\n");
return _find_buck_face(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__fork:
{
- // fprintf(stderr, "fork\r\n");
+ // u3l_log("fork\r\n");
return _find_buck_fork(van, sut, way, p_heg, q_heg, axe, lon, gil);
}
case c3__hold:
{
- // fprintf(stderr, "hold\r\n");
+ // u3l_log("hold\r\n");
if ( (c3y == u3qdi_has(gil, sut)) ) {
return u3_nul;
}
diff --git a/pkg/urbit/jets/f/ut_mull.c b/pkg/urbit/jets/f/ut_mull.c
index cacd936de..abd4859a9 100644
--- a/pkg/urbit/jets/f/ut_mull.c
+++ b/pkg/urbit/jets/f/ut_mull.c
@@ -88,7 +88,7 @@
u3_noun von = u3i_molt(u3k(van), u3x_sam, u3k(sut), 0);
u3_noun gat = u3j_hook(von, "mile");
- // fprintf(stderr, "mile\r\n");
+ // u3l_log("mile\r\n");
return u3n_kick_on(u3i_molt(gat,
u3x_sam_2,
u3k(dox),
diff --git a/pkg/urbit/noun/allocate.c b/pkg/urbit/noun/allocate.c
index e76f7bfd3..e6057bc5f 100644
--- a/pkg/urbit/noun/allocate.c
+++ b/pkg/urbit/noun/allocate.c
@@ -373,13 +373,13 @@ u3a_reclaim(void)
if ( (0 == u3R->cax.har_p) ||
(0 == u3to(u3h_root, u3R->cax.har_p)->use_w) )
{
- fprintf(stderr, "allocate: reclaim: memo cache: empty\r\n");
+ u3l_log("allocate: reclaim: memo cache: empty\r\n");
u3m_bail(c3__meme);
}
#if 1
- fprintf(stderr, "allocate: reclaim: half of %d entries\r\n",
- u3to(u3h_root, u3R->cax.har_p)->use_w);
+ u3l_log("allocate: reclaim: half of %d entries\r\n",
+ u3to(u3h_root, u3R->cax.har_p)->use_w);
u3h_trim_to(u3R->cax.har_p, u3to(u3h_root, u3R->cax.har_p)->use_w / 2);
#else
@@ -406,7 +406,7 @@ _ca_willoc(c3_w len_w, c3_w ald_w, c3_w alp_w)
sel_w += 1;
}
- // fprintf(stderr, "walloc %d: *pfr_p %x\n", len_w, u3R->all.fre_p[sel_w]);
+ // u3l_log("walloc %d: *pfr_p %x\n", len_w, u3R->all.fre_p[sel_w]);
while ( 1 ) {
u3p(u3a_fbox) *pfr_p = &u3R->all.fre_p[sel_w];
@@ -537,7 +537,7 @@ u3a_walloc(c3_w len_w)
u3a_botox(ptr_v) == (u3a_box*)(void *)0x200dfe3e4 ) {
static int xuc_i;
- printf("xuc_i %d\r\n", xuc_i);
+ u3l_log("xuc_i %d\r\n", xuc_i);
if ( 1 == xuc_i ) {
u3a_box* box_u = u3a_botox(ptr_v);
@@ -664,7 +664,7 @@ u3a_malloc(size_t len_i)
if ( u3a_botox(out_w) == (u3a_box*)(void *)0x3bdd1c80) {
static int xuc_i = 0;
- fprintf(stderr,"xuc_i %d\r\n", xuc_i);
+ u3l_log("xuc_i %d\r\n", xuc_i);
// if ( 1 == xuc_i ) { abort(); }
xuc_i++;
}
@@ -869,7 +869,7 @@ u3a_free(void* tox_v)
c3_w pad_w = tox_w[-1];
c3_w* org_w = tox_w - (pad_w + 1);
- // printf("free %p %p\r\n", org_w, tox_w);
+ // u3l_log("free %p %p\r\n", org_w, tox_w);
u3a_wfree(org_w);
}
@@ -995,7 +995,7 @@ _me_gain_use(u3_noun dog)
if ( u3r_mug(dog) == 0x15d47649 ) {
static c3_w bug_w = 0;
- printf("bad %x %d %d\r\n", dog, bug_w, box_u->use_w);
+ u3l_log("bad %x %d %d\r\n", dog, bug_w, box_u->use_w);
if ( bug_w == 0 ) { abort(); }
bug_w++;
}
@@ -1005,7 +1005,7 @@ _me_gain_use(u3_noun dog)
static c3_w bug_w = 0;
if ( BDA == dog ) {
- printf("BDA %d %d\r\n", bug_w, box_u->use_w);
+ u3l_log("BDA %d %d\r\n", bug_w, box_u->use_w);
// if ( bug_w == 0 ) { abort(); }
bug_w++;
}
@@ -1019,7 +1019,7 @@ _me_gain_use(u3_noun dog)
if ( FOO && u3a_botox(u3a_to_ptr(dog)) == (void *)0x200dfe3e4 ) {
u3a_box* box_u = u3a_botox(u3a_to_ptr(dog));
- printf("GAIN %d %d\r\n", bug_w, box_u->use_w);
+ u3l_log("GAIN %d %d\r\n", bug_w, box_u->use_w);
if ( bug_w == 8 ) { abort(); }
bug_w++;
}
@@ -1168,7 +1168,7 @@ _me_copy_south(u3_noun dog)
if ( dog_u->mug_w >> 31 ) {
u3_noun nov = (u3_noun) dog_u->mug_w;
- // printf("south: %p is already %p\r\n", dog_u, u3a_to_ptr(nov));
+ // u3l_log("south: %p is already %p\r\n", dog_u, u3a_to_ptr(nov));
c3_assert(_(u3a_south_is_normal(u3R, nov)));
_me_gain_use(nov);
@@ -1182,10 +1182,10 @@ _me_copy_south(u3_noun dog)
u3_noun new = u3a_de_twin(dog, new_w);
u3a_cell* new_u = (u3a_cell*)(void *)new_w;
- // printf("south: cell %p to %p\r\n", old_u, new_u);
+ // u3l_log("south: cell %p to %p\r\n", old_u, new_u);
#if 0
if ( old_u->mug_w == 0x730e66cc ) {
- fprintf(stderr, "BAD: take %p\r\n", new_u);
+ u3l_log("BAD: take %p\r\n", new_u);
}
#endif
new_u->mug_w = old_u->mug_w;
@@ -1204,7 +1204,7 @@ _me_copy_south(u3_noun dog)
u3_noun new = u3a_de_twin(dog, new_w);
u3a_atom* new_u = (u3a_atom*)(void *)new_w;
- // printf("south: atom %p to %p\r\n", old_u, new_u);
+ // u3l_log("south: atom %p to %p\r\n", old_u, new_u);
new_u->mug_w = old_u->mug_w;
// new_u->mug_w = 0;
@@ -1241,7 +1241,7 @@ _me_take_north(u3_noun dog)
*/
u3_noun mos = _me_copy_north(dog);
- // printf("north: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
+ // u3l_log("north: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
return mos;
}
else {
@@ -1267,7 +1267,7 @@ _me_take_south(u3_noun dog)
*/
u3_noun mos = _me_copy_south(dog);
- // printf("south: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
+ // u3l_log("south: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
return mos;
}
else {
@@ -1497,7 +1497,7 @@ void
u3a_luse(u3_noun som)
{
if ( 0 == u3a_use(som) ) {
- fprintf(stderr, "luse: insane %d 0x%x\r\n", som, som);
+ u3l_log("luse: insane %d 0x%x\r\n", som, som);
abort();
}
if ( _(u3du(som)) ) {
@@ -1545,7 +1545,7 @@ u3a_mark_ptr(void* ptr_v)
c3_ws use_ws = (c3_ws)box_u->use_w;
if ( use_ws == 0 ) {
- fprintf(stderr, "%p is bogus\r\n", ptr_v);
+ u3l_log("%p is bogus\r\n", ptr_v);
siz_w = 0;
}
else {
@@ -1579,7 +1579,7 @@ u3a_mark_mptr(void* ptr_v)
c3_w pad_w = ptr_w[-1];
c3_w* org_w = ptr_w - (pad_w + 1);
- // printf("free %p %p\r\n", org_w, ptr_w);
+ // u3l_log("free %p %p\r\n", org_w, ptr_w);
return u3a_mark_ptr(org_w);
}
@@ -1709,9 +1709,9 @@ _ca_print_box(u3a_box* box_u)
{
int i;
for ( i = 0; i < box_u->siz_w; i++ ) {
- printf("%08x ", (unsigned int)(((c3_w*)box_u)[i]));
+ u3l_log("%08x ", (unsigned int)(((c3_w*)box_u)[i]));
}
- printf("\r\n");
+ u3l_log("\r\n");
}
#endif
return 0;
@@ -1733,12 +1733,12 @@ _ca_print_box(u3a_box* box_u)
static void
_ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_w eus_w, c3_w use_w)
{
- fprintf(stderr, "%s: %p mug=%x (marked=%u swept=%u)\r\n",
- cap_c,
- box_u,
- ((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
- eus_w,
- use_w);
+ u3l_log("%s: %p mug=%x (marked=%u swept=%u)\r\n",
+ cap_c,
+ box_u,
+ ((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
+ eus_w,
+ use_w);
if ( box_u->cod_w ) {
u3m_p(" code", box_u->cod_w);
@@ -1748,7 +1748,7 @@ _ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_w eus_w, c3_w use_w)
{
c3_c* dat_c = _ca_print_box(box_u);
- fprintf(stderr, " data: %s\r\n", dat_c);
+ u3l_log(" data: %s\r\n", dat_c);
free(dat_c);
}
}
@@ -1758,17 +1758,17 @@ _ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_w eus_w, c3_w use_w)
static void
_ca_print_leak(c3_c* cap_c, u3a_box* box_u, c3_ws use_ws)
{
- fprintf(stderr, "%s: %p mug=%x swept=%d\r\n",
- cap_c,
- box_u,
- ((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
- use_ws);
+ u3l_log("%s: %p mug=%x swept=%d\r\n",
+ cap_c,
+ box_u,
+ ((u3a_noun *)(u3a_boxto(box_u)))->mug_w,
+ use_ws);
u3a_print_memory(stderr, " size", box_u->siz_w);
{
c3_c* dat_c = _ca_print_box(box_u);
- fprintf(stderr, " data: %s\r\n", dat_c);
+ u3l_log(" data: %s\r\n", dat_c);
free(dat_c);
}
}
@@ -1808,8 +1808,8 @@ u3a_sweep(void)
}
#ifdef U3_CPU_DEBUG
if ( fre_w != u3R->all.fre_w ) {
- fprintf(stderr, "fre discrepancy (%x): %x, %x, %x\r\n", u3R->par_p,
- fre_w, u3R->all.fre_w, (u3R->all.fre_w - fre_w));
+ u3l_log("fre discrepancy (%x): %x, %x, %x\r\n", u3R->par_p,
+ fre_w, u3R->all.fre_w, (u3R->all.fre_w - fre_w));
}
#endif
neg_w = (end_w - fre_w);
diff --git a/pkg/urbit/noun/events.c b/pkg/urbit/noun/events.c
index cbb2f8f48..39f9b0271 100644
--- a/pkg/urbit/noun/events.c
+++ b/pkg/urbit/noun/events.c
@@ -64,7 +64,7 @@ u3e_check(c3_c* cap_c)
}
sum_w += mug_w;
}
- printf("%s: sum %x (%x, %x)\r\n", cap_c, sum_w, nor_w, sou_w);
+ u3l_log("%s: sum %x (%x, %x)\r\n", cap_c, sum_w, nor_w, sou_w);
}
}
@@ -121,8 +121,8 @@ u3e_fault(void* adr_v, c3_i ser_i)
c3_w* adr_w = (c3_w*) adr_v;
if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3a_words)) ) {
- fprintf(stderr, "address %p out of loom!\r\n", adr_v);
- fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3a_words);
+ u3l_log("address %p out of loom!\r\n", adr_v);
+ u3l_log("loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3a_words);
c3_assert(0);
return 0;
}
@@ -134,7 +134,7 @@ u3e_fault(void* adr_v, c3_i ser_i)
#if 0
if ( pag_w == 131041 ) {
- printf("dirty page %d (at %p); unprotecting %p to %p\r\n",
+ u3l_log("dirty page %d (at %p); unprotecting %p to %p\r\n",
pag_w,
adr_v,
(u3_Loom + (pag_w << u3a_page)),
@@ -143,8 +143,8 @@ u3e_fault(void* adr_v, c3_i ser_i)
#endif
if ( 0 != (u3P.dit_w[blk_w] & (1 << bit_w)) ) {
- fprintf(stderr, "strange page: %d, at %p, off %x\r\n",
- pag_w, adr_w, off_w);
+ u3l_log("strange page: %d, at %p, off %x\r\n",
+ pag_w, adr_w, off_w);
abort();
}
@@ -203,7 +203,7 @@ _ce_image_open(u3e_image* img_u)
}
else {
if ( siz_d != (pgs_d << (c3_d)(u3a_page + 2)) ) {
- fprintf(stderr, "%s: corrupt size %" PRIx64 "\r\n", ful_c, siz_d);
+ u3l_log("%s: corrupt size %" PRIx64 "\r\n", ful_c, siz_d);
return c3n;
}
img_u->pgs_w = (c3_w) pgs_d;
@@ -324,14 +324,14 @@ _ce_patch_verify(u3_ce_patch* pat_u)
c3_w nug_w = u3r_mug_words(mem_w, (1 << u3a_page));
if ( mug_w != nug_w ) {
- printf("_ce_patch_verify: mug mismatch %d/%d; (%x, %x)\r\n",
+ u3l_log("_ce_patch_verify: mug mismatch %d/%d; (%x, %x)\r\n",
pag_w, i_w, mug_w, nug_w);
c3_assert(0);
return c3n;
}
#if 0
else {
- printf("verify: patch %d/%d, %x\r\n", pag_w, i_w, mug_w);
+ u3l_log("verify: patch %d/%d, %x\r\n", pag_w, i_w, mug_w);
}
#endif
}
@@ -448,7 +448,7 @@ _ce_patch_save_page(u3_ce_patch* pat_u,
(1 << u3a_page));
#if 0
- printf("protect a: page %d\r\n", pag_w);
+ u3l_log("protect a: page %d\r\n", pag_w);
#endif
_ce_patch_write_page(pat_u, pgc_w, mem_w);
@@ -474,7 +474,7 @@ _ce_patch_junk_page(u3_ce_patch* pat_u,
c3_w blk_w = (pag_w >> 5);
c3_w bit_w = (pag_w & 31);
- // printf("protect b: page %d\r\n", pag_w);
+ // u3l_log("protect b: page %d\r\n", pag_w);
if ( -1 == mprotect(u3_Loom + (pag_w << u3a_page),
(1 << (u3a_page + 2)),
PROT_READ) )
@@ -629,8 +629,8 @@ _ce_patch_apply(u3_ce_patch* pat_u)
{
c3_w i_w;
- //printf("image: nor_w %d, new %d\r\n", u3P.nor_u.pgs_w, pat_u->con_u->nor_w);
- //printf("image: sou_w %d, new %d\r\n", u3P.sou_u.pgs_w, pat_u->con_u->sou_w);
+ //u3l_log("image: nor_w %d, new %d\r\n", u3P.nor_u.pgs_w, pat_u->con_u->nor_w);
+ //u3l_log("image: sou_w %d, new %d\r\n", u3P.sou_u.pgs_w, pat_u->con_u->sou_w);
if ( u3P.nor_u.pgs_w > pat_u->con_u->nor_w ) {
c3_w ret_w;
@@ -690,7 +690,7 @@ _ce_patch_apply(u3_ce_patch* pat_u)
}
}
#if 0
- printf("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, (1 << u3a_page)));
+ u3l_log("apply: %d, %x\n", pag_w, u3r_mug_words(mem_w, (1 << u3a_page)));
#endif
}
}
@@ -715,8 +715,8 @@ _ce_image_blit(u3e_image* img_u,
c3_w off_w = (ptr_w - u3_Loom);
c3_w pag_w = (off_w >> u3a_page);
- printf("blit: page %d, mug %x\r\n", pag_w,
- u3r_mug_words(ptr_w, (1 << u3a_page)));
+ u3l_log("blit: page %d, mug %x\r\n", pag_w,
+ u3r_mug_words(ptr_w, (1 << u3a_page)));
}
#endif
ptr_w += stp_ws;
@@ -748,11 +748,11 @@ _ce_image_fine(u3e_image* img_u,
if ( mem_w != fil_w ) {
c3_w pag_w = (ptr_w - u3_Loom) >> u3a_page;
- fprintf(stderr, "mismatch: page %d, mem_w %x, fil_w %x, K %x\r\n",
- pag_w,
- mem_w,
- fil_w,
- u3K.mug_w[pag_w]);
+ u3l_log("mismatch: page %d, mem_w %x, fil_w %x, K %x\r\n",
+ pag_w,
+ mem_w,
+ fil_w,
+ u3K.mug_w[pag_w]);
abort();
}
ptr_w += stp_ws;
@@ -796,10 +796,10 @@ u3e_save(void)
// u3a_print_memory(stderr, "sync: save", 4096 * pat_u->con_u->pgs_w);
_ce_patch_sync(pat_u);
- // printf("_ce_patch_verify\r\n");
+ // u3l_log("_ce_patch_verify\r\n");
_ce_patch_verify(pat_u);
- // printf("_ce_patch_apply\r\n");
+ // u3l_log("_ce_patch_apply\r\n");
_ce_patch_apply(pat_u);
#ifdef U3_SNAPSHOT_VALIDATION
@@ -817,14 +817,14 @@ u3e_save(void)
}
#endif
- // printf("_ce_image_sync\r\n");
+ // u3l_log("_ce_image_sync\r\n");
_ce_image_sync(&u3P.nor_u);
_ce_image_sync(&u3P.sou_u);
- // printf("_ce_patch_delete\r\n");
+ // u3l_log("_ce_patch_delete\r\n");
_ce_patch_delete();
- // printf("_ce_patch_free\r\n");
+ // u3l_log("_ce_patch_free\r\n");
_ce_patch_free(pat_u);
}
@@ -848,7 +848,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
if ( (c3n == _ce_image_open(&u3P.nor_u)) ||
(c3n == _ce_image_open(&u3P.sou_u)) )
{
- printf("boot: image failed\r\n");
+ fprintf(stderr, "boot: image failed\r\n");
exit(1);
}
else {
@@ -857,16 +857,16 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
/* Load any patch files; apply them to images.
*/
if ( 0 != (pat_u = _ce_patch_open()) ) {
- printf("boot: _ce_patch_apply\r\n");
+ u3l_log("boot: _ce_patch_apply\r\n");
_ce_patch_apply(pat_u);
- printf("boot: _ce_image_sync\r\n");
+ u3l_log("boot: _ce_image_sync\r\n");
_ce_image_sync(&u3P.nor_u);
_ce_image_sync(&u3P.sou_u);
- printf("boot: _ce_patch_delete\r\n");
+ u3l_log("boot: _ce_patch_delete\r\n");
_ce_patch_delete();
- printf("boot: _ce_patch_free\r\n");
+ u3l_log("boot: _ce_patch_free\r\n");
_ce_patch_free(pat_u);
}
@@ -885,13 +885,14 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
perror("protect");
c3_assert(0);
}
- printf("boot: protected loom\r\n");
+
+ u3l_log("boot: protected loom\r\n");
}
/* If the images were empty, we are logically booting.
*/
if ( (0 == u3P.nor_u.pgs_w) && (0 == u3P.sou_u.pgs_w) ) {
- printf("live: logical boot\r\n");
+ u3l_log("live: logical boot\r\n");
nuu_o = c3y;
}
else {
diff --git a/pkg/urbit/noun/hashtable.c b/pkg/urbit/noun/hashtable.c
index 52fa7e2d2..abc769477 100644
--- a/pkg/urbit/noun/hashtable.c
+++ b/pkg/urbit/noun/hashtable.c
@@ -352,7 +352,7 @@ _ch_trim_slot(u3h_root* har_u, u3h_slot *sot_w, c3_w lef_w, c3_w rem_w)
else {
u3_noun kev = u3h_slot_to_noun(*sot_w);
*sot_w = 0;
- // uL(fprintf(uH, "trim: freeing %x, use count %d\r\n", kev, u3a_use(kev)));
+ // u3l_log("trim: freeing %x, use count %d\r\n", kev, u3a_use(kev)));
u3z(kev);
har_u->arm_u.mug_w = _ch_skip_slot(har_u->arm_u.mug_w, lef_w);
diff --git a/pkg/urbit/noun/imprison.c b/pkg/urbit/noun/imprison.c
index 4244c3ae8..58a30cb6d 100644
--- a/pkg/urbit/noun/imprison.c
+++ b/pkg/urbit/noun/imprison.c
@@ -220,7 +220,7 @@ u3i_cell(u3_noun a, u3_noun b)
if ( (0x730e66cc == u3r_mug(pro)) &&
(c3__tssg == u3h(u3t(u3t(pro)))) ) {
static c3_w xuc_w;
- fprintf(stderr, "BAD %x %p\r\n", pro, u3a_to_ptr(a));
+ u3l_log("BAD %x %p\r\n", pro, u3a_to_ptr(a));
BAD = pro;
if ( xuc_w == 1 ) u3m_bail(c3__exit);
xuc_w++;
@@ -235,7 +235,7 @@ u3i_cell(u3_noun a, u3_noun b)
u3_noun pro = u3a_to_pom(u3a_outa(nov_w));
u3m_p("leaked", pro);
- printf("pro %u, %x\r\n", pro, u3r_mug(pro));
+ u3l_log("pro %u, %x\r\n", pro, u3r_mug(pro));
abort();
}
#endif
diff --git a/pkg/urbit/noun/jets.c b/pkg/urbit/noun/jets.c
index 55b8cb052..a73acccee 100644
--- a/pkg/urbit/noun/jets.c
+++ b/pkg/urbit/noun/jets.c
@@ -80,7 +80,7 @@ _cj_hash(c3_c* has_c)
{
c3_w i_w, len_w = strlen(has_c);
if ( 64 != len_w ) {
- fprintf(stderr, "bash not 64 characters: %s\r\n", has_c);
+ u3l_log("bash not 64 characters: %s\r\n", has_c);
c3_assert(0);
}
c3_assert( 64 == len_w );
@@ -257,18 +257,18 @@ _cj_axis(u3_noun fol)
(0 != p_fol) ||
(!_(u3a_is_cat(q_fol))) )
{
- fprintf(stderr, "axis: bad a\r\n");
+ u3l_log("axis: bad a\r\n");
return 0;
}
return q_fol;
}
else {
if ( 9 != p_fol )
- { fprintf(stderr, "axis: bad b\r\n"); return 0; }
+ { u3l_log("axis: bad b\r\n"); return 0; }
if ( !_(u3a_is_cat(q_fol)) )
- { fprintf(stderr, "axis: bad c\r\n"); return 0; }
+ { u3l_log("axis: bad c\r\n"); return 0; }
if ( !_(u3du(r_fol)) || (0 != u3h(r_fol)) || (1 != u3t(r_fol)) )
- { fprintf(stderr, "axis: bad d\r\n"); return 0; }
+ { u3l_log("axis: bad d\r\n"); return 0; }
return q_fol;
}
@@ -299,7 +299,7 @@ _cj_warm_hump(c3_l jax_l, u3_noun huc)
((1 << 31) & (axe_l = (c3_w)axe_d)) ||
(axe_l < 2) )
{
- fprintf(stderr, "jets: activate: bad fcs %s\r\n", jet_u->fcs_c);
+ u3l_log("jets: activate: bad fcs %s\r\n", jet_u->fcs_c);
}
}
else {
@@ -307,7 +307,7 @@ _cj_warm_hump(c3_l jax_l, u3_noun huc)
u3_noun fol = u3kdb_get(u3k(huc), nam);
if ( u3_none == fol ) {
- fprintf(stderr, "jets: activate: bad fcs %s\r\n", jet_u->fcs_c);
+ u3l_log("jets: activate: bad fcs %s\r\n", jet_u->fcs_c);
}
else {
axe_l = _cj_axis(fol);
@@ -802,7 +802,7 @@ _cj_hot_mean(c3_l par_l, u3_noun nam)
while ( (cop_u = &dev_u[i_l])->cos_c ) {
if ( _(u3r_sing_c(cop_u->cos_c, nam)) ) {
#if 0
- fprintf(stderr, "hot: bound jet %d/%s/%s/\r\n",
+ u3l_log("hot: bound jet %d/%s/%s/\r\n",
cop_u->jax_l,
cop_u->cos_c,
par_u ? par_u->cos_c : "~");
@@ -817,10 +817,9 @@ _cj_hot_mean(c3_l par_l, u3_noun nam)
/* u3j_boot(): initialize jet system.
*/
-void
+c3_w
u3j_boot(c3_o nuu_o)
{
- c3_w jax_l;
c3_assert(u3R == &(u3H->rod_u));
u3D.len_l =_cj_count(0, u3D.dev_u);
@@ -833,8 +832,11 @@ u3j_boot(c3_o nuu_o)
u3h_free(u3R->jed.hot_p);
}
u3R->jed.hot_p = u3h_new();
- jax_l = _cj_install(u3D.ray_u, 1, (c3_l) (long long) u3D.dev_u[0].par_u, u3_nul, u3D.dev_u);
- fprintf(stderr, "boot: installed %d jets\r\n", jax_l);
+
+ return _cj_install(u3D.ray_u, 1,
+ (c3_l) (long long) u3D.dev_u[0].par_u,
+ u3_nul,
+ u3D.dev_u);
}
/* _cj_soft(): kick softly by arm axis.
@@ -912,7 +914,7 @@ _cj_kick_z(u3_noun cor, u3j_core* cop_u, u3j_harm* ham_u, u3_atom axe)
ham_u->liv = c3y;
if ( c3n == u3r_sing(ame, pro) ) {
- fprintf(stderr, "test: %s %s: mismatch: good %x, bad %x\r\n",
+ u3l_log("test: %s %s: mismatch: good %x, bad %x\r\n",
cop_u->cos_c,
(!strcmp(".2", ham_u->fcs_c)) ? "$" : ham_u->fcs_c,
u3r_mug(ame),
@@ -925,7 +927,7 @@ _cj_kick_z(u3_noun cor, u3j_core* cop_u, u3j_harm* ham_u, u3_atom axe)
else {
#if 1
- fprintf(stderr, "test: %s %s\r\n",
+ u3l_log("test: %s %s\r\n",
cop_u->cos_c,
(!strcmp(".2", ham_u->fcs_c)) ? "$" : ham_u->fcs_c);
#endif
@@ -1674,7 +1676,7 @@ u3j_gate_prep(u3j_site* sit_u, u3_noun cor)
pay = u3qc_cap(pax),
pam = u3qc_mas(pax);
if ( 3 != pay || 2 == pam || (3 != pam && 3 != u3qc_cap(pam)) ) {
- fprintf(stderr, "u3j_gate_prep(): parent axis includes sample\r\n");
+ u3l_log("u3j_gate_prep(): parent axis includes sample\r\n");
u3m_p("axis", pax);
u3_weak act = _cj_find_warm(loc);
c3_assert( u3_none != act );
@@ -1745,12 +1747,12 @@ _cj_minx(u3_noun cey, u3_noun cor)
par = u3r_at(axe, cor);
if ( u3_none == par || c3n == u3du(par) ) {
- fprintf(stderr, "fund: %s is bogus\r\n", u3r_string(nam));
+ u3l_log("fund: %s is bogus\r\n", u3r_string(nam));
return u3_none;
}
pel = _cj_spot(par, NULL);
if ( u3_none == pel ) {
- fprintf(stderr, "fund: in %s, parent %x not found at %d\r\n",
+ u3l_log("fund: in %s, parent %x not found at %d\r\n",
u3r_string(nam),
u3r_mug(u3h(par)),
axe);
@@ -1809,7 +1811,7 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas)
jax_l = _cj_hot_mean(par_l, nam);
#if 0
u3m_p("new jet", bal);
- fprintf(stderr, " bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
+ u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
#endif
if ( !(u3C.wag_w & u3o_hashless) ) {
@@ -1817,17 +1819,17 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas)
c3_y dig_y[32];
c3_w i_w;
u3_noun i = bal;
- fprintf(stderr, "hot jet: ");
+ u3l_log("hot jet: ");
while ( i != u3_nul ) {
_cj_print_tas(stderr, u3h(i));
i = u3t(i);
}
- fprintf(stderr, "\r\n axe %d, jax %d,\r\n bash ", axe, jax_l);
+ u3l_log("\r\n axe %d, jax %d,\r\n bash ", axe, jax_l);
u3r_bytes(0, 32, dig_y, bas);
for ( i_w = 32; i_w > 0; ) {
- fprintf(stderr, "%02x", dig_y[--i_w]);
+ u3l_log("%02x", dig_y[--i_w]);
}
- fprintf(stderr, "\r\n");
+ u3l_log("\r\n");
}
}
@@ -1857,7 +1859,7 @@ _cj_mine(u3_noun cey, u3_noun cor, u3_noun bas)
if ( c3n == hav_o ) {
u3m_p("unregistered battery", bal);
- fprintf(stderr, "hash: %x\r\n", bas);
+ u3l_log("hash: %x\r\n", bas);
}
u3z(bas);
}
@@ -2069,7 +2071,7 @@ _cj_ream(u3_noun all)
act = u3nq(jax_l, hap, bal, _cj_jit(jax_l, bat));
#if 0
u3m_p("old jet", bal);
- fprintf(stderr, " bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
+ u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
#endif
u3h_put(u3R->jed.war_p, loc, act);
}
@@ -2108,7 +2110,7 @@ _cj_ream(u3_noun all)
act = u3nq(jax_l, hap, bal, _cj_jit(jax_l, bat));
#if 0
u3m_p("old jet", bal);
- fprintf(stderr, " bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
+ u3l_log(" bat %x, jax %d\r\n", u3r_mug(bat), jax_l);
#endif
u3h_put(u3R->jed.war_p, loc, act);
}
diff --git a/pkg/urbit/noun/log.c b/pkg/urbit/noun/log.c
new file mode 100644
index 000000000..8d58fef29
--- /dev/null
+++ b/pkg/urbit/noun/log.c
@@ -0,0 +1,28 @@
+/* noun/log.c
+**
+*/
+#include "all.h"
+
+#include
+
+void
+u3l_log(const char* format, ...)
+{
+ va_list myargs;
+ va_start(myargs, format);
+
+ if (u3C.stderr_log_f) {
+ // the user set their own logging function. render the line and redirect
+ // to them.
+ //
+ char msg[4096];
+ vsnprintf(msg, 4096, format, myargs);
+ u3C.stderr_log_f(msg);
+ } else {
+ // this process did not set a logging function, fallback to stderr
+ //
+ vfprintf(stderr, format, myargs);
+ }
+
+ va_end(myargs);
+}
diff --git a/pkg/urbit/noun/manage.c b/pkg/urbit/noun/manage.c
index 9e05b45e0..bf3e2ae15 100644
--- a/pkg/urbit/noun/manage.c
+++ b/pkg/urbit/noun/manage.c
@@ -41,7 +41,7 @@
void
u3m_leap(c3_w pad_w);
- /* u3m_golf(): record cap length for u3_flog().
+ /* u3m_golf(): record cap length for u3m_flog().
*/
c3_w
u3m_golf(void);
@@ -80,9 +80,6 @@ static sigjmp_buf u3_Signal;
static uint8_t Sigstk[SIGSTKSZ];
#endif
-void u3_unix_ef_hold(void); // suspend system signal regime
-void u3_unix_ef_move(void); // restore system signal regime
-
#if 0
/* _cm_punt(): crudely print trace.
*/
@@ -306,7 +303,7 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg)
while ( rod_u->kid_p ) {
#if 0
- fprintf(stderr, "collecting %d frames\r\n",
+ u3l_log("collecting %d frames\r\n",
u3kb_lent((u3to(u3_road, rod_u->kid_p)->bug.tax));
#endif
tax = u3kb_weld(_cm_stack_recover(u3to(u3_road, rod_u->kid_p)), tax);
@@ -329,7 +326,11 @@ _cm_signal_recover(c3_l sig_l, u3_noun arg)
static void
_cm_signal_deep(c3_w sec_w)
{
- u3_unix_ef_hold();
+ // disable outer system signal handling
+ //
+ if ( 0 != u3C.sign_hold_f ) {
+ u3C.sign_hold_f();
+ }
#ifndef NO_OVERFLOW
stackoverflow_install_handler(_cm_signal_handle_over, Sigstk, SIGSTKSZ);
@@ -363,7 +364,7 @@ _cm_signal_deep(c3_w sec_w)
static void
_cm_signal_done()
{
- // signal(SIGINT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGVTALRM, SIG_IGN);
@@ -376,7 +377,13 @@ _cm_signal_done()
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
}
- u3_unix_ef_move();
+
+ // restore outer system signal handling
+ //
+ if ( 0 != u3C.sign_move_f ) {
+ u3C.sign_move_f();
+ }
+
u3t_boff();
}
@@ -399,7 +406,7 @@ u3m_file(c3_c* pas_c)
c3_y* pad_y;
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
- fprintf(stderr, "%s: %s\r\n", pas_c, strerror(errno));
+ u3l_log("%s: %s\r\n", pas_c, strerror(errno));
return u3m_bail(c3__fail);
}
fln_w = buf_b.st_size;
@@ -558,7 +565,7 @@ u3m_dump(void)
fre_u = fre_u->nex_u;
}
}
- fprintf(stderr, "dump: hat_w %x, fre_w %x, allocated %x\n",
+ u3l_log("dump: hat_w %x, fre_w %x, allocated %x\n",
hat_w, fre_w, (hat_w - fre_w));
if ( 0 != (hat_w - fre_w) ) {
@@ -570,14 +577,14 @@ u3m_dump(void)
if ( 0 != box_u->use_w ) {
#ifdef U3_MEMORY_DEBUG
- // printf("live %d words, code %x\n", box_u->siz_w, box_u->cod_w);
+ // u3l_log("live %d words, code %x\n", box_u->siz_w, box_u->cod_w);
#endif
mem_w += box_u->siz_w;
}
box_w += box_u->siz_w;
}
- fprintf(stderr, "second count: %x\n", mem_w);
+ u3l_log("second count: %x\n", mem_w);
}
}
#endif
@@ -623,11 +630,11 @@ u3m_bail(u3_noun how)
str_c[2] = ((how >> 16) & 0xff);
str_c[3] = ((how >> 24) & 0xff);
str_c[4] = 0;
- fprintf(stderr, "\r\nbail: %s\r\n", str_c);
+ u3l_log("\r\nbail: %s\r\n", str_c);
}
else {
c3_assert(_(u3ud(u3h(how))));
- fprintf(stderr, "\r\nbail: %d\r\n", u3h(how));
+ u3l_log("\r\nbail: %d\r\n", u3h(how));
}
}
@@ -637,7 +644,7 @@ u3m_bail(u3_noun how)
}
case c3__meme: {
- fprintf(stderr, "bailing out\r\n");
+ u3l_log("bailing out\r\n");
abort();
}
case c3__exit: {
@@ -645,7 +652,7 @@ u3m_bail(u3_noun how)
static c3_w xuc_w = 0;
{
- // fprintf(stderr, "exit %d\r\n", xuc_w);
+ // u3l_log("exit %d\r\n", xuc_w);
// if ( 49 == xuc_w ) { abort(); }
xuc_w++;
break;
@@ -653,7 +660,7 @@ u3m_bail(u3_noun how)
}
case c3__foul:
case c3__oops:
- fprintf(stderr, "bailing out\r\n");
+ u3l_log("bailing out\r\n");
assert(0);
}
@@ -738,7 +745,7 @@ u3m_leap(c3_w pad_w)
rod_u = _pave_south(u3a_into(bot_p), c3_wiseof(u3a_road), len_w);
#if 0
- fprintf(stderr, "leap: from north %p (cap %x), to south %p\r\n",
+ u3l_log("leap: from north %p (cap %x), to south %p\r\n",
u3R,
u3R->cap_p + len_p,
rod_u);
@@ -750,7 +757,7 @@ u3m_leap(c3_w pad_w)
rod_u = _pave_north(u3a_into(bot_p), c3_wiseof(u3a_road), len_w);
#if 0
- fprintf(stderr, "leap: from north %p (cap %p), to south %p\r\n",
+ u3l_log("leap: from north %p (cap %p), to south %p\r\n",
u3R,
u3R->cap_p - len_p,
rod_u);
@@ -785,7 +792,7 @@ u3m_fall()
c3_assert(0 != u3R->par_p);
#if 0
- fprintf(stderr, "fall: from %s %p, to %s %p (cap %p, was %p)\r\n",
+ u3l_log("fall: from %s %p, to %s %p (cap %p, was %p)\r\n",
_(u3a_is_north(u3R)) ? "north" : "south",
u3R,
_(u3a_is_north(u3R)) ? "north" : "south",
@@ -844,7 +851,7 @@ u3m_love(u3_noun pro)
return pro;
}
-/* u3m_golf(): record cap_p length for u3_flog().
+/* u3m_golf(): record cap_p length for u3m_flog().
*/
c3_w
u3m_golf(void)
@@ -1436,7 +1443,7 @@ u3m_p(const c3_c* cap_c, u3_noun som)
{
c3_c* pre_c = u3m_pretty(som);
- fprintf(stderr, "%s: %s\r\n", cap_c, pre_c);
+ u3l_log("%s: %s\r\n", cap_c, pre_c);
free(pre_c);
}
@@ -1530,7 +1537,7 @@ static void
_cm_signals(void)
{
if ( 0 != sigsegv_install_handler(u3e_fault) ) {
- fprintf(stderr, "sigsegv install failed\n");
+ u3l_log("sigsegv install failed\n");
exit(1);
}
// signal(SIGINT, _loom_stop);
@@ -1583,16 +1590,16 @@ u3m_init(void)
MAP_ANON | MAP_PRIVATE,
-1, 0);
- fprintf(stderr, "boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
- fprintf(stderr, "see urbit.org/docs/getting-started#swap for adding swap space\r\n");
+ u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
+ u3l_log("see urbit.org/docs/getting-started#swap for adding swap space\r\n");
if ( -1 != (c3_ps)map_v ) {
- fprintf(stderr,
- "if porting to a new platform, try U3_OS_LoomBase %p\r\n",
+ u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n",
dyn_v);
}
exit(1);
}
- printf("loom: mapped %dMB\r\n", len_w >> 20);
+
+ u3l_log("loom: mapped %dMB\r\n", len_w >> 20);
}
}
@@ -1627,16 +1634,16 @@ _cm_init_new(void)
MAP_ANON | MAP_PRIVATE,
-1, 0);
- fprintf(stderr, "boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
- fprintf(stderr, "see urbit.org/docs/using/install to add swap space\r\n");
+ u3l_log("boot: mapping %dMB failed\r\n", (len_w / (1024 * 1024)));
+ u3l_log("see urbit.org/docs/using/install to add swap space\r\n");
if ( -1 != (c3_ps)map_v ) {
- fprintf(stderr,
- "if porting to a new platform, try U3_OS_LoomBase %p\r\n",
+ u3l_log("if porting to a new platform, try U3_OS_LoomBase %p\r\n",
dyn_v);
}
exit(1);
}
- printf("loom: mapped %dMB\r\n", len_w >> 20);
+
+ u3l_log("loom: mapped %dMB\r\n", len_w >> 20);
}
}
@@ -1652,12 +1659,12 @@ _get_cmd_output(c3_c *cmd_c, c3_c *out_c, c3_w len_c)
{
FILE *fp = popen(cmd_c, "r");
if ( NULL == fp ) {
- fprintf(stderr, "'%s' failed\n", cmd_c);
+ u3l_log("'%s' failed\n", cmd_c);
exit(1);
}
if ( NULL == fgets(out_c, len_c, fp) ) {
- fprintf(stderr, "'%s' produced no output\n", cmd_c);
+ u3l_log("'%s' produced no output\n", cmd_c);
exit(1);
}
@@ -1690,7 +1697,7 @@ _git_pill_url(c3_c *out_c, c3_c *arv_c)
assert(NULL != arv_c);
if ( 0 != system("which git >> /dev/null") ) {
- fprintf(stderr, "Could not find git executable\n");
+ u3l_log("Could not find git executable\n");
exit(1);
}
@@ -1732,7 +1739,7 @@ _boot_home(c3_c *dir_c, c3_c *pil_c, c3_c *url_c, c3_c *arv_c)
snprintf(ful_c, 2048, "%s/.urb/%s", dir_c, nam_c);
if ( stat(ful_c, &s) == 0 ) {
/* we're in a "logical boot". awful hack, but bail here */
- printf("%s confirmed to exist\r\n", ful_c);
+ u3l_log("%s confirmed to exist\r\n", ful_c);
return;
}
}
@@ -1741,9 +1748,9 @@ _boot_home(c3_c *dir_c, c3_c *pil_c, c3_c *url_c, c3_c *arv_c)
if ( pil_c != 0 ) {
snprintf(ful_c, 2048, "cp %s %s/.urb/%s",
pil_c, dir_c, nam_c);
- printf("%s\r\n", ful_c);
+ u3l_log("%s\r\n", ful_c);
if ( 0 != system(ful_c) ) {
- fprintf(stderr, "could not %s\n", ful_c);
+ u3l_log("could not %s\n", ful_c);
exit(1);
}
}
@@ -1762,13 +1769,13 @@ _boot_home(c3_c *dir_c, c3_c *pil_c, c3_c *url_c, c3_c *arv_c)
}
snprintf(ful_c, 2048, "%s/.urb/urbit.pill", dir_c);
- printf("fetching %s to %s\r\n", url_c, ful_c);
+ u3l_log("fetching %s to %s\r\n", url_c, ful_c);
if ( !(curl = curl_easy_init()) ) {
- fprintf(stderr, "failed to initialize libcurl\n");
+ u3l_log("failed to initialize libcurl\n");
exit(1);
}
if ( !(file = fopen(ful_c, "w")) ) {
- fprintf(stderr, "failed to open %s\n", ful_c);
+ u3l_log("failed to open %s\n", ful_c);
exit(1);
}
curl_easy_setopt(curl, CURLOPT_URL, url_c);
@@ -1777,16 +1784,14 @@ _boot_home(c3_c *dir_c, c3_c *pil_c, c3_c *url_c, c3_c *arv_c)
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &cod_l);
fclose(file);
if ( CURLE_OK != result ) {
- fprintf(stderr, "failed to fetch %s: %s\n",
- url_c, curl_easy_strerror(result));
- fprintf(stderr,
- "please fetch it manually and specify the location with -B\n");
+ u3l_log("failed to fetch %s: %s\n",
+ url_c, curl_easy_strerror(result));
+ u3l_log("please fetch it manually and specify the location with -B\n");
exit(1);
}
if ( 300 <= cod_l ) {
- fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
- fprintf(stderr,
- "please fetch it manually and specify the location with -B\n");
+ u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l);
+ u3l_log("please fetch it manually and specify the location with -B\n");
exit(1);
}
curl_easy_cleanup(curl);
@@ -1831,7 +1836,7 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
_boot_home(dir_c, pil_c, url_c, arv_c);
snprintf(ful_c, 2048, "%s/.urb/urbit.pill", dir_c);
- printf("boot: loading %s\r\n", ful_c);
+ u3l_log("boot: loading %s\r\n", ful_c);
{
u3_noun pil = u3m_file(ful_c);
@@ -1841,7 +1846,7 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
u3_noun pro = u3m_soft(0, u3ke_cue, u3k(pil));
if ( 0 != u3h(pro) ) {
- fprintf(stderr, "boot: failed: unable to parse pill\r\n");
+ u3l_log("boot: failed: unable to parse pill\r\n");
exit(1);
}
@@ -1852,7 +1857,7 @@ u3m_boot(c3_o nuu_o, c3_o bug_o, c3_c* dir_c,
// XX confirm trel of lists?
//
if ( c3n == u3r_trel(sys, &bot, 0, 0) ) {
- fprintf(stderr, "boot: failed: obsolete pill structure\r\n");
+ u3l_log("boot: failed: obsolete pill structure\r\n");
exit(1);
}
@@ -1888,6 +1893,9 @@ u3m_boot_new(c3_c* dir_c)
/* Activate tracing.
*/
+ u3C.slog_f = 0;
+ u3C.sign_hold_f = 0;
+ u3C.sign_move_f = 0;
u3t_init();
/* Construct or activate the allocator.
@@ -1896,7 +1904,10 @@ u3m_boot_new(c3_c* dir_c)
/* Initialize the jet system.
*/
- u3j_boot(nuu_o);
+ {
+ c3_w len_w = u3j_boot(nuu_o);
+ u3l_log("boot: installed %d jets\r\n", len_w);
+ }
/* Reactivate jets on old kernel.
*/
@@ -1928,6 +1939,9 @@ u3m_boot_pier(void)
/* Activate tracing.
*/
+ u3C.slog_f = 0;
+ u3C.sign_hold_f = 0;
+ u3C.sign_move_f = 0;
u3t_init();
/* Construct or activate the allocator.
diff --git a/pkg/urbit/noun/nock.c b/pkg/urbit/noun/nock.c
index 66782033a..a08034db6 100644
--- a/pkg/urbit/noun/nock.c
+++ b/pkg/urbit/noun/nock.c
@@ -3,23 +3,6 @@
*/
#include "all.h"
- /* u3_term_io_hija(): hijack console for cooked print.
- */
- FILE*
- u3_term_io_hija(void);
-
- /* u3_term_io_loja(): release console from cooked print.
- */
- void
- u3_term_io_loja(int x);
-
- /* uL, uH: wrap hijack/lojack around fprintf.
- **
- ** uL(fprintf(uH, ...));
- */
-# define uH u3_term_io_hija()
-# define uL(x) u3_term_io_loja(x)
-
// define to have each opcode printed as it executes,
// along with some other debugging info
# undef VERBOSE_BYTECODE
@@ -96,11 +79,11 @@ _n_hint(u3_noun zep,
low_i = 1;
if ( 0 == (u3R->pro.nox_d % 65536ULL) ) {
if ( c3__spot == zep ) {
- uL(fprintf(uH, "spot %d/%d : %d/%d\r\n",
- u3h(u3h(u3t(hod))),
- u3t(u3h(u3t(hod))),
- u3h(u3t(u3t(hod))),
- u3t(u3t(u3t(hod)))));
+ u3l_log("spot %d/%d : %d/%d\r\n",
+ u3h(u3h(u3t(hod))),
+ u3t(u3h(u3t(hod))),
+ u3h(u3t(u3t(hod))),
+ u3t(u3t(u3t(hod))));
}
}
low_i = 0;
@@ -133,14 +116,6 @@ _n_hint(u3_noun zep,
return _n_nock_on(bus, nex);
}
- case c3__shiv: {
- u3t_off(noc_o);
- u3t_shiv(hod);
- u3t_on(noc_o);
-
- return _n_nock_on(bus, nex);
- }
-
case c3__germ: {
u3_noun pro = _n_nock_on(bus, nex);
diff --git a/pkg/urbit/noun/trace.c b/pkg/urbit/noun/trace.c
index cea64db33..bc4454d6c 100644
--- a/pkg/urbit/noun/trace.c
+++ b/pkg/urbit/noun/trace.c
@@ -40,85 +40,16 @@ u3t_drop(void)
}
}
-extern void
-u3_pier_tank(c3_l tab_l, u3_noun tac);
-
-#ifdef U3_EVENT_TIME_DEBUG
-/* _t_slog_time(): slog timelapse.
-*/
-void
-_t_slog_time(void)
-{
- static int old;
- static struct timeval b4, f2, d0;
- static c3_d b4_d;
- c3_w ms_w;
-
- if ( old ) {
- gettimeofday(&f2, 0);
- timersub(&f2, &b4, &d0);
- ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
- if (ms_w > 1) {
-#if 0
- fprintf(stderr, "%6d.%02dms: %9d ",
- ms_w, (int) (d0.tv_usec % 1000) / 10,
- ((int) (u3R->pro.nox_d - b4_d)));
-#else
- fprintf(stderr, "%6d.%02dms ",
- ms_w, (int) (d0.tv_usec % 1000) / 10);
-#endif
- gettimeofday(&b4, 0);
- b4_d = u3R->pro.nox_d;
- }
- else {
- printf(" ");
- }
- }
- else {
- gettimeofday(&b4, 0);
- b4_d = u3R->pro.nox_d;
- }
- old = 1;
-}
-#endif
-
/* u3t_slog(): print directly.
*/
void
u3t_slog(u3_noun hod)
{
-#ifdef U3_EVENT_TIME_DEBUG
- _t_slog_time();
-#endif
-
- if ( c3y == u3du(hod) ) {
- u3_noun pri = u3h(hod);
-
- switch ( pri ) {
- case 3: fprintf(stderr, ">>> "); break;
- case 2: fprintf(stderr, ">> "); break;
- case 1: fprintf(stderr, "> "); break;
- }
- u3_pier_tank(0, u3k(u3t(hod)));
- }
- u3z(hod);
-}
-
-/* u3t_shiv(): quick print.
-*/
-void
-u3t_shiv(u3_noun hod)
-{
-#ifdef U3_EVENT_TIME_DEBUG
- _t_slog_time();
-#endif
-
- if ( c3n == u3ud(hod) ) {
+ if ( 0 != u3C.slog_f ) {
+ u3C.slog_f(hod);
}
else {
- c3_c *str_c = u3r_string(hod);
- fprintf(stderr, "%s\r\n", str_c);
- free(str_c);
+ u3z(hod);
}
}
@@ -491,46 +422,33 @@ u3t_event_trace(const c3_c* name, c3_c type)
u3_Host.tra_u.con_w++;
}
-extern FILE*
-u3_term_io_hija(void);
-
-extern void
-u3_term_io_loja(int x);
-
-extern void
-u3_term_tape(u3_noun tep);
-
-extern void
-u3_term_wall(u3_noun wol);
-
/* u3t_print_steps: print step counter.
*/
void
u3t_print_steps(c3_c* cap_c, c3_d sep_d)
{
- FILE* fil_f = u3_term_io_hija();
-
c3_w gib_w = (sep_d / 1000000000ULL);
c3_w mib_w = (sep_d % 1000000000ULL) / 1000000ULL;
c3_w kib_w = (sep_d % 1000000ULL) / 1000ULL;
c3_w bib_w = (sep_d % 1000ULL);
+ // XX prints to stderr since it's called on shutdown, daemon may be gone
+ //
if ( sep_d ) {
if ( gib_w ) {
- fprintf(fil_f, "%s: G/%d.%03d.%03d.%03d\r\n",
+ fprintf(stderr, "%s: G/%d.%03d.%03d.%03d\r\n",
cap_c, gib_w, mib_w, kib_w, bib_w);
}
else if ( mib_w ) {
- fprintf(fil_f, "%s: M/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
+ fprintf(stderr, "%s: M/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
}
else if ( kib_w ) {
- fprintf(fil_f, "%s: K/%d.%03d\r\n", cap_c, kib_w, bib_w);
+ fprintf(stderr, "%s: K/%d.%03d\r\n", cap_c, kib_w, bib_w);
}
else if ( bib_w ) {
- fprintf(fil_f, "%s: %d\r\n", cap_c, bib_w);
+ fprintf(stderr, "%s: %d\r\n", cap_c, bib_w);
}
}
- u3_term_io_loja(0);
}
/* u3t_damp(): print and clear profile data.
@@ -541,8 +459,22 @@ u3t_damp(void)
if ( 0 != u3R->pro.day ) {
u3_noun wol = u3do("pi-tell", u3R->pro.day);
- fprintf(stderr, "\r\n");
- u3_term_wall(wol);
+ // XX prints to stderr since it's called on shutdown, daemon may be gone
+ //
+ {
+ u3_noun low = wol;
+
+ while ( u3_nul != low ) {
+ c3_c* str_c = (c3_c*)u3r_tape(u3h(low));
+
+ fprintf(stderr, "%s\r\n", str_c);
+ c3_free(str_c);
+
+ low = u3t(low);
+ }
+
+ u3z(wol);
+ }
/* bunt a +doss
*/
@@ -560,7 +492,6 @@ u3t_damp(void)
*/
void _ct_sigaction(c3_i x_i)
{
- // fprintf(stderr, "itimer!\r\n"); abort();
u3t_samp();
}
diff --git a/pkg/urbit/noun/vortex.c b/pkg/urbit/noun/vortex.c
index 26e332b8a..44fd0205b 100644
--- a/pkg/urbit/noun/vortex.c
+++ b/pkg/urbit/noun/vortex.c
@@ -30,8 +30,6 @@ u3v_boot(u3_noun eve)
// ensure zero-initialized kernel
//
- // So that u3t_slog won't try to print tanks.
- //
u3A->roc = 0;
{
@@ -47,7 +45,7 @@ u3v_boot(u3_noun eve)
u3_noun pro = u3m_soft_run(gul, u3n_nock_on, eve, lyf);
if ( 0 != u3h(pro) ) {
- fprintf(stderr, "boot: failed: invalid boot sequence (from pill)\r\n");
+ u3l_log("boot: failed: invalid boot sequence (from pill)\r\n");
u3z(pro);
return;
}
@@ -79,7 +77,7 @@ u3v_load(u3_noun pil)
{
u3_noun sys = u3ke_cue(pil);
- fprintf(stderr, "load: mug: %x\r\n", u3r_mug(sys));
+ u3l_log("load: mug: %x\r\n", u3r_mug(sys));
{
u3_noun cor = u3v_fire(sys);
u3_noun pro;
@@ -102,9 +100,9 @@ u3v_lite(u3_noun pil)
u3x_trel(arv, &bot, 0, 0);
- fprintf(stderr, "lite: arvo formula %x\r\n", u3r_mug(arv));
+ u3l_log("lite: arvo formula %x\r\n", u3r_mug(arv));
cor = u3n_nock_on(bot, lyf);
- fprintf(stderr, "lite: core %x\r\n", u3r_mug(cor));
+ u3l_log("lite: core %x\r\n", u3r_mug(cor));
pro = u3k(u3r_at(7, cor));
@@ -129,11 +127,11 @@ u3v_boot(c3_c* pas_c)
pru = u3m_soft(0, u3v_load, u3k(u3A->sys));
if ( u3h(pru) != 0 ) {
- fprintf(stderr, "boot failed\r\n");
+ u3l_log("boot failed\r\n");
exit(1);
}
- fprintf(stderr, "boot: final state %x\r\n", u3r_mug(u3t(pru)));
+ u3l_log("boot: final state %x\r\n", u3r_mug(u3t(pru)));
u3A->ken = 0;
u3A->roc = u3k(u3t(pru));
@@ -150,11 +148,11 @@ u3v_boot_lite(u3_atom lit)
u3_noun pru = u3m_soft(0, u3v_lite, lit);
if ( u3h(pru) != 0 ) {
- fprintf(stderr, "boot failed\r\n");
+ u3l_log("boot failed\r\n");
exit(1);
}
- fprintf(stderr, "lite: final state %x\r\n", u3r_mug(u3t(pru)));
+ u3l_log("lite: final state %x\r\n", u3r_mug(u3t(pru)));
u3A->roc = u3k(u3t(pru));
@@ -196,7 +194,7 @@ u3v_start(u3_noun now)
{
c3_c* wen_c = u3r_string(u3A->wen);
- printf("arvo: time: %s\n", wen_c);
+ u3l_log("arvo: time: %s\n", wen_c);
free(wen_c);
}
@@ -281,7 +279,7 @@ _cv_nock_poke(u3_noun ovo)
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
c3_c* tox_c = u3r_string(tox);
- fprintf(stderr, "poke: %%%s (%x) on %s\r\n", ovi_c, u3r_mug(ovo), tox_c);
+ u3l_log("poke: %%%s (%x) on %s\r\n", ovi_c, u3r_mug(ovo), tox_c);
free(tox_c); free(ovi_c); u3z(tox);
}
#endif
@@ -295,9 +293,9 @@ _cv_nock_poke(u3_noun ovo)
c3_c* ovi_c = u3r_string(u3h(u3t(ovo)));
if ( u3_nul == u3h(pro) ) {
- fprintf(stderr, " blank: %s\r\n", ovi_c);
+ u3l_log(" blank: %s\r\n", ovi_c);
} else {
- fprintf(stderr, " happy: %s: %d\r\n", ovi_c, u3kb_lent(u3k(u3h(pro))));
+ u3l_log(" happy: %s: %d\r\n", ovi_c, u3kb_lent(u3k(u3h(pro))));
}
free(ovi_c);
}
@@ -403,9 +401,9 @@ _cv_mole(u3_noun fot,
if ( (c3n == u3r_qual(uco, &p_uco, &q_uco, &r_uco, &s_uco)) ||
(0 != p_uco) ||
(0 != q_uco) ||
- (c3n == u3_sing(fot, r_uco)) )
+ (c3n == u3r_sing(fot, r_uco)) )
{
- uL(fprintf(uH, "strange mole %s\n", u3r_string(san)));
+ u3l_log("strange mole %s\n", u3r_string(san)));
u3z(fot); u3z(uco); return c3n;
}
diff --git a/pkg/urbit/scripts/bootstrap b/pkg/urbit/scripts/bootstrap
deleted file mode 100755
index 3a8a74e56..000000000
--- a/pkg/urbit/scripts/bootstrap
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-
-git submodule init
-git submodule update
diff --git a/pkg/urbit/scripts/build b/pkg/urbit/scripts/build
deleted file mode 100755
index 879618f28..000000000
--- a/pkg/urbit/scripts/build
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-
-mkdir ./build &> /dev/null
-meson . ./build --buildtype=release "$@"
-ninja -C build
diff --git a/pkg/urbit/tests/test.c b/pkg/urbit/tests/test.c
deleted file mode 100644
index 86a75ec03..000000000
--- a/pkg/urbit/tests/test.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* w/test.c
-**
-*/
-#define C3_GLOBAL
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "all.h"
-
-#if 1
-/* u3_walk_load(): load file or bail.
-*/
-static u3_noun
-u3_walk_load(c3_c* pas_c)
-{
- struct stat buf_b;
- c3_i fid_i = open(pas_c, O_RDONLY, 0644);
- c3_w fln_w, red_w;
- c3_y* pad_y;
-
- if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
- fprintf(stderr, "%s: %s\r\n", pas_c, strerror(errno));
- return u3m_bail(c3__fail);
- }
- fln_w = buf_b.st_size;
- pad_y = c3_malloc(buf_b.st_size);
-
- red_w = read(fid_i, pad_y, fln_w);
- close(fid_i);
-
- if ( fln_w != red_w ) {
- free(pad_y);
- return u3m_bail(c3__fail);
- }
- else {
- u3_noun pad = u3i_bytes(fln_w, (c3_y *)pad_y);
- free(pad_y);
-
- return pad;
- }
-}
-#endif
-
-#if 0
-static c3_w*
-_test_walloc(c3_w siz_w)
-{
- c3_w *ptr_w = u3a_walloc(siz_w);
- c3_w i_w;
-
- c3_assert(siz_w >= 1);
- *ptr_w = siz_w;
-
- for ( i_w = 1; i_w < siz_w; i_w++ ) {
- ptr_w[i_w] = u3r_mug((0xffff & (c3_p)(ptr_w)) + i_w);
- }
- return ptr_w;
-}
-
-static void
-_test_free(c3_w* ptr_w)
-{
- c3_w i_w, siz_w = *ptr_w;
-
- for ( i_w = 1; i_w < siz_w; i_w++ ) {
- c3_assert(ptr_w[i_w] == u3r_mug((0xffff & (c3_p)(ptr_w)) + i_w));
- }
- u3a_free(ptr_w);
-}
-
-#define NUM 16384
-
-// Simple allocation test.
-//
-void
-test(void)
-{
- c3_w* one_w[NUM];
- c3_w* two_w[NUM];
- c3_w i_w;
-
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- c3_w siz_w = c3_max(1, u3r_mug(i_w) & 0xff);
-
- one_w[i_w] = _test_walloc(siz_w);
- two_w[i_w] = _test_walloc(siz_w);
- }
- _road_sane();
-
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- _test_free(two_w[NUM - (i_w + 1)]);
- _road_sane();
- }
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- c3_w siz_w = c3_max(1, u3r_mug(i_w + 1) & 0xff);
-
- two_w[i_w] = _test_walloc(siz_w);
- _road_sane();
- }
-
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- _test_free(one_w[NUM - (i_w + 1)]);
- _road_sane();
- }
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- c3_w siz_w = c3_max(1, u3r_mug(i_w + 2) & 0xff);
-
- one_w[i_w] = _test_walloc(siz_w);
- _road_sane();
- }
-
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- _test_free(one_w[NUM - (i_w + 1)]);
- _road_sane();
- }
- for ( i_w = 0; i_w < NUM; i_w++ ) {
- _test_free(two_w[NUM - (i_w + 1)]);
- _road_sane();
- }
-
- printf("allocations %d, iterations %d\n", ALL_w, ITE_w);
-}
-#endif
-
-#if 1
-static void
-_test_hash(void)
-{
- // u3m_dump();
- {
- u3h_root* har_u = u3h_new();
- c3_w i_w;
- c3_w max_w = (1 << 20);
-
- for ( i_w = 0; i_w < max_w; i_w++ ) {
- u3_noun key = u3nc(0, i_w);
-
- u3h_put(har_u, key, (i_w + 1));
- u3z(key);
- }
- for ( i_w = 0; i_w < max_w; i_w++ ) {
- u3_noun key = u3nc(0, i_w);
- u3_noun val = u3h_get(har_u, key);
-
- if ( val != (i_w + 1) ) {
- if ( u3_none == val ) {
- printf("at %d, nothing\n", i_w);
- }
- else printf("at %d, oddly, is %d\n", i_w, val);
- c3_assert(0);
- }
- u3z(key);
- }
- u3h_free(har_u);
- }
- // u3m_dump();
-}
-#endif
-
-#if 1
-static void
-_test_jam(void)
-{
- // u3m_dump();
- {
- u3_noun pil = u3_walk_load("urb/urbit.pill");
- u3_noun cue, jam;
-
- printf("cueing pill - %d bytes\n", u3r_met(3, pil));
- cue = u3ke_cue(pil);
- printf("cued - mug %x\n", u3r_mug(cue));
-
-#if 1
- jam = u3ke_jam(cue);
- printf("jammed - %d bytes\n", u3r_met(3, jam));
- cue = u3ke_cue(jam);
- printf("cued - mug %x\n", u3r_mug(cue));
-#endif
-
- u3z(cue);
- }
- // u3m_dump();
-}
-#endif
-
-static void
-_test_leap(void)
-{
-#if 1
- // u3m_dump();
- {
- u3_noun pil;
- u3_noun cue, jam;
- c3_w gof_w = u3m_golf();
-
- pil = u3_walk_load("urb/urbit.pill");
- u3m_leap(0);
- printf("cueing pill - %d bytes\n", u3r_met(3, pil));
- cue = u3ke_cue(pil);
- printf("cued - %p, mug %x\n", u3a_to_ptr(cue), u3r_mug(cue));
- u3m_fall();
-
- cue = u3a_take(cue);
- printf("taken - %p, mug %x\n", u3a_to_ptr(cue), u3r_mug(cue));
- u3m_flog(gof_w);
- u3z(pil);
-
-#if 1
- jam = u3ke_jam(cue);
- printf("jammed - %d bytes\n", u3r_met(3, jam));
- cue = u3ke_cue(jam);
- printf("cued - mug %x\n", u3r_mug(cue));
-#endif
-
- u3z(cue);
- }
- // u3m_dump();
-#endif
-}
-
-static void
-_test_test(void)
-{
- u3_noun fol = u3ke_cue(u3_walk_load("pill/west.pill"));
- u3_noun val;
-
- printf("test_test: formula mug %x\n", u3r_mug(fol));
- val = u3n_nock_on(u3nc(42, 17), fol);
- printf("val %d\n", val);
- u3z(val);
-}
-
-int FOO;
-
-// A simple memory tester.
-//
-int
-main(int argc, char *argv[])
-{
- printf("hello, world: len %dMB\n", (1 << U3_OS_LoomBits) >> 18);
- // _test_words();
-
- u3m_init();
- u3m_pave(c3y, c3n);
- // u3j_boot();
-
- // u3m_dump();
-
- printf("booted.\n");
-
- {
- _test_leap();
- // _test_hash();
- // _test_jam();
- }
- // u3m_clear();
-
- // u3m_dump();
-}
diff --git a/pkg/urbit/vere/ames.c b/pkg/urbit/vere/ames.c
index f2da94cb6..a7c2540be 100644
--- a/pkg/urbit/vere/ames.c
+++ b/pkg/urbit/vere/ames.c
@@ -36,7 +36,7 @@ _ames_alloc(uv_handle_t* had_u,
static void
_ames_free(void* ptr_v)
{
-// uL(fprintf(uH, "free %p\n", ptr_v));
+// u3l_log("free %p\n", ptr_v);
free(ptr_v);
}
@@ -59,7 +59,7 @@ _ames_send_cb(uv_udp_send_t* req_u, c3_i sas_i)
#if 0
if ( 0 != sas_i ) {
- uL(fprintf(uH, "ames: send_cb: %s\n", uv_strerror(sas_i)));
+ u3l_log("ames: send_cb: %s\n", uv_strerror(sas_i));
}
#endif
@@ -96,7 +96,7 @@ _ames_send(u3_pact* pac_u)
&buf_u, 1,
(const struct sockaddr*)&add_u,
_ames_send_cb)) ) {
- uL(fprintf(uH, "ames: send: %s\n", uv_strerror(sas_i)));
+ u3l_log("ames: send: %s\n", uv_strerror(sas_i));
}
}
@@ -122,7 +122,7 @@ _ames_czar_gone(u3_pact* pac_u, time_t now)
u3_pier* pir_u = u3_pier_stub();
u3_ames* sam_u = pir_u->sam_u;
- uL(fprintf(uH, "ames: czar at %s: not found (b)\n", pac_u->dns_c));
+ u3l_log("ames: czar at %s: not found (b)\n", pac_u->dns_c);
if ( (0 == sam_u->imp_w[pac_u->imp_y]) ||
(0xffffffff == sam_u->imp_w[pac_u->imp_y]) ) {
sam_u->imp_w[pac_u->imp_y] = 0xffffffff;
@@ -168,7 +168,7 @@ _ames_czar_cb(uv_getaddrinfo_t* adr_u,
u3_noun nam = u3dc("scot", c3__if, wad);
c3_c* nam_c = u3r_string(nam);
- uL(fprintf(uH, "ames: czar %s: ip %s\n", pac_u->dns_c, nam_c));
+ u3l_log("ames: czar %s: ip %s\n", pac_u->dns_c, nam_c);
free(nam_c); u3z(nam);
}
@@ -208,7 +208,7 @@ _ames_czar(u3_pact* pac_u, c3_c* bos_c)
if ( 0 == bos_c ) {
u3_noun nam = u3dc("scot", 'p', pac_u->imp_y);
c3_c* nam_c = u3r_string(nam);
- fprintf(stderr, "ames: no galaxy domain for %s, no-op\r\n", nam_c);
+ u3l_log("ames: no galaxy domain for %s, no-op\r\n", nam_c);
free(nam_c);
u3z(nam);
@@ -232,7 +232,7 @@ _ames_czar(u3_pact* pac_u, c3_c* bos_c)
pac_u->dns_c = c3_malloc(1 + strlen(bos_c) + 1 + strlen(nam_c));
snprintf(pac_u->dns_c, 256, "%s.%s", nam_c + 1, bos_c);
- // uL(fprintf(uH, "czar %s, dns %s\n", nam_c, pac_u->dns_c));
+ // u3l_log("czar %s, dns %s\n", nam_c, pac_u->dns_c);
free(nam_c);
u3z(nam);
@@ -246,7 +246,7 @@ _ames_czar(u3_pact* pac_u, c3_c* bos_c)
if ( 0 != (sas_i = uv_getaddrinfo(u3L, adr_u,
_ames_czar_cb,
pac_u->dns_c, 0, 0)) ) {
- uL(fprintf(uH, "ames: %s\n", uv_strerror(sas_i)));
+ u3l_log("ames: %s\n", uv_strerror(sas_i));
_ames_czar_gone(pac_u, now);
return;
}
@@ -351,7 +351,7 @@ _ames_recv_cb(uv_udp_t* wax_u,
const struct sockaddr* adr_u,
unsigned flg_i)
{
- // uL(fprintf(uH, "ames: rx %p\r\n", buf_u.base));
+ // u3l_log("ames: rx %p\r\n", buf_u.base);
if ( 0 == nrd_i ) {
_ames_free(buf_u->base);
@@ -360,7 +360,7 @@ _ames_recv_cb(uv_udp_t* wax_u,
{
u3_noun msg = u3i_bytes((c3_w)nrd_i, (c3_y*)buf_u->base);
- // fprintf(stderr, "ames: plan\r\n");
+ // u3l_log("ames: plan\r\n");
#if 0
u3z(msg);
#else
@@ -397,10 +397,10 @@ _ames_io_start(u3_pier* pir_u)
por_s = _ames_czar_port(num_y);
if ( c3y == u3_Host.ops_u.net ) {
- uL(fprintf(uH, "ames: czar: %s on %d\n", imp_c, por_s));
+ u3l_log("ames: czar: %s on %d\n", imp_c, por_s);
}
else {
- uL(fprintf(uH, "ames: czar: %s on %d (localhost only)\n", imp_c, por_s));
+ u3l_log("ames: czar: %s on %d (localhost only)\n", imp_c, por_s);
}
u3z(imp);
@@ -409,7 +409,7 @@ _ames_io_start(u3_pier* pir_u)
int ret;
if ( 0 != (ret = uv_udp_init(u3L, &sam_u->wax_u)) ) {
- uL(fprintf(uH, "ames: init: %s\n", uv_strerror(ret)));
+ u3l_log("ames: init: %s\n", uv_strerror(ret));
c3_assert(0);
}
@@ -428,11 +428,10 @@ _ames_io_start(u3_pier* pir_u)
int ret;
if ( (ret = uv_udp_bind(&sam_u->wax_u,
(const struct sockaddr*) & add_u, 0)) != 0 ) {
- uL(fprintf(uH, "ames: bind: %s\n",
- uv_strerror(ret)));
+ u3l_log("ames: bind: %s\n",
+ uv_strerror(ret));
if (UV_EADDRINUSE == ret){
- uL(fprintf(uH,
- " ...perhaps you've got two copies of vere running?\n"));
+ u3l_log(" ...perhaps you've got two copies of vere running?\n");
}
u3_pier_exit(pir_u);
}
@@ -443,7 +442,7 @@ _ames_io_start(u3_pier* pir_u)
sam_u->por_s = ntohs(add_u.sin_port);
}
- // uL(fprintf(uH, "ames: on localhost, UDP %d.\n", sam_u->por_s));
+ // u3l_log("ames: on localhost, UDP %d.\n", sam_u->por_s);
uv_udp_recv_start(&sam_u->wax_u, _ames_alloc, _ames_recv_cb);
sam_u->liv = c3y;
@@ -526,7 +525,7 @@ u3_ames_ef_turf(u3_pier* pir_u, u3_noun tuf)
u3z(tuf);
}
else if ( (c3n == pir_u->fak_o) && (0 == sam_u->dns_c) ) {
- uL(fprintf(uH, "ames: turf: no domains\n"));
+ u3l_log("ames: turf: no domains\n");
}
if ( c3n == sam_u->liv ) {
diff --git a/pkg/urbit/vere/cttp.c b/pkg/urbit/vere/cttp.c
index 424892811..36ff32440 100644
--- a/pkg/urbit/vere/cttp.c
+++ b/pkg/urbit/vere/cttp.c
@@ -706,7 +706,7 @@ _cttp_creq_fail(u3_creq* ceq_u, const c3_c* err_c)
// XX anything other than a 504?
c3_w cod_w = 504;
- uL(fprintf(uH, "http: fail (%d, %d): %s\r\n", ceq_u->num_l, cod_w, err_c));
+ u3l_log("http: fail (%d, %d): %s\r\n", ceq_u->num_l, cod_w, err_c);
// XX include err_c as response body?
_cttp_httr(ceq_u->num_l, cod_w, u3_nul, u3_nul);
diff --git a/pkg/urbit/vere/king.c b/pkg/urbit/vere/daemon.c
similarity index 68%
rename from pkg/urbit/vere/king.c
rename to pkg/urbit/vere/daemon.c
index 70dcd7b98..139bda396 100644
--- a/pkg/urbit/vere/king.c
+++ b/pkg/urbit/vere/daemon.c
@@ -1,4 +1,4 @@
-/* vere/king.c
+/* vere/daemon.c
**
** the main loop of the daemon process
*/
@@ -8,15 +8,15 @@
#include "all.h"
#include "vere/vere.h"
-// stash config flags for serf
+// stash config flags for worker
//
static c3_w sag_w;
/*
-:: king/client protocol:
+:: daemon to worker protocol
::
|%
-:: +fate: client to lord
+:: +fate: worker to daemon
::
+$ fate
$% :: authenticate client
@@ -112,7 +112,7 @@ static c3_w sag_w;
:: r: userspace ova
::
[p=@ q=(list ovum) r=(list ovum)]
-:: +cede: lord to client
+:: +cede: daemon to client
::
:: XX not implemented
::
@@ -132,34 +132,34 @@ static c3_w sag_w;
--
*/
-void _king_auth(u3_noun auth);
+void _daemon_auth(u3_noun auth);
-void _king_wyrd(u3_noun ship_wyrd);
- void _king_susp(u3_atom ship, u3_noun susp);
- void _king_vent(u3_atom ship, u3_noun vent);
+void _daemon_wyrd(u3_noun ship_wyrd);
+ void _daemon_susp(u3_atom ship, u3_noun susp);
+ void _daemon_vent(u3_atom ship, u3_noun vent);
-void _king_doom(u3_noun doom);
- void _king_boot(u3_noun boot);
- void _king_come(u3_noun star, u3_noun pill, u3_noun path);
- void _king_dawn(u3_noun seed, u3_noun pill, u3_noun path);
- void _king_fake(u3_noun ship, u3_noun pill, u3_noun path);
- void _king_exit(u3_noun exit);
- void _king_pier(u3_noun pier);
- void _king_root(u3_noun root);
+void _daemon_doom(u3_noun doom);
+ void _daemon_boot(u3_noun boot);
+ void _daemon_come(u3_noun star, u3_noun pill, u3_noun path);
+ void _daemon_dawn(u3_noun seed, u3_noun pill, u3_noun path);
+ void _daemon_fake(u3_noun ship, u3_noun pill, u3_noun path);
+ void _daemon_exit(u3_noun exit);
+ void _daemon_pier(u3_noun pier);
+ void _daemon_root(u3_noun root);
-/* _king_defy_fate(): invalid fate
+/* _daemon_defy_fate(): invalid fate
*/
void
-_king_defy_fate()
+_daemon_defy_fate()
{
exit(1);
}
-/* _king_fate(): top-level fate parser
+/* _daemon_fate(): top-level fate parser
*/
void
-_king_fate(void *vod_p, u3_noun mat)
+_daemon_fate(void *vod_p, u3_noun mat)
{
u3_noun fate = u3ke_cue(u3k(mat));
u3_noun load;
@@ -170,16 +170,16 @@ _king_fate(void *vod_p, u3_noun mat)
switch ( u3h(fate) ) {
case c3__auth:
- next = _king_auth;
+ next = _daemon_auth;
break;
case c3__wyrd:
- next = _king_wyrd;
+ next = _daemon_wyrd;
break;
case c3__doom:
- next = _king_doom;
+ next = _daemon_doom;
break;
default:
- _king_defy_fate();
+ _daemon_defy_fate();
}
load = u3k(u3t(fate));
@@ -187,17 +187,17 @@ _king_fate(void *vod_p, u3_noun mat)
next(load);
}
-/* _king_auth(): auth parser
+/* _daemon_auth(): auth parser
*/
void
-_king_auth(u3_noun auth)
+_daemon_auth(u3_noun auth)
{
}
-/* _king_wyrd(): wyrd parser
+/* _daemon_wyrd(): wyrd parser
*/
void
-_king_wyrd(u3_noun ship_wyrd)
+_daemon_wyrd(u3_noun ship_wyrd)
{
u3_atom ship;
u3_noun wyrd;
@@ -215,13 +215,13 @@ _king_wyrd(u3_noun ship_wyrd)
switch ( u3h(wyrd) ) {
case c3__susp:
- next = _king_susp;
+ next = _daemon_susp;
break;
case c3__vent:
- next = _king_vent;
+ next = _daemon_vent;
break;
default:
- _king_defy_fate();
+ _daemon_defy_fate();
}
load = u3k(u3t(wyrd));
@@ -229,17 +229,17 @@ _king_wyrd(u3_noun ship_wyrd)
next(ship, load);
}
-/* _king_susp(): susp parser
+/* _daemon_susp(): susp parser
*/
void
-_king_susp(u3_atom ship, u3_noun susp)
+_daemon_susp(u3_atom ship, u3_noun susp)
{
}
-/* _king_vent(): vent parser
+/* _daemon_vent(): vent parser
*/
void
-_king_vent(u3_atom ship, u3_noun vent)
+_daemon_vent(u3_atom ship, u3_noun vent)
{
/* stub; have to find pier from ship */
u3z(ship);
@@ -247,10 +247,10 @@ _king_vent(u3_atom ship, u3_noun vent)
u3z(vent);
}
-/* _king_doom(): doom parser
+/* _daemon_doom(): doom parser
*/
void
-_king_doom(u3_noun doom)
+_daemon_doom(u3_noun doom)
{
u3_noun load;
void (*next)(u3_noun);
@@ -260,19 +260,19 @@ _king_doom(u3_noun doom)
switch ( u3h(doom) ) {
case c3__boot:
- next = _king_boot;
+ next = _daemon_boot;
break;
case c3__exit:
- next = _king_exit;
+ next = _daemon_exit;
break;
case c3__pier:
- next = _king_pier;
+ next = _daemon_pier;
break;
case c3__root:
- next = _king_root;
+ next = _daemon_root;
break;
default:
- _king_defy_fate();
+ _daemon_defy_fate();
}
load = u3k(u3t(doom));
@@ -280,10 +280,10 @@ _king_doom(u3_noun doom)
next(load);
}
-/* _king_boot(): boot parser
+/* _daemon_boot(): boot parser
*/
void
-_king_boot(u3_noun bul)
+_daemon_boot(u3_noun bul)
{
u3_noun boot, pill, path;
void (*next)(u3_noun, u3_noun, u3_noun);
@@ -294,66 +294,66 @@ _king_boot(u3_noun bul)
switch ( u3h(boot) ) {
case c3__fake: {
- next = _king_fake;
+ next = _daemon_fake;
break;
}
case c3__come: {
- next = _king_come;
+ next = _daemon_come;
break;
}
case c3__dawn: {
- next = _king_dawn;
+ next = _daemon_dawn;
break;
}
default:
- return _king_defy_fate();
+ return _daemon_defy_fate();
}
next(u3k(u3t(boot)), u3k(pill), u3k(path));
u3z(bul);
}
-/* _king_fake(): boot with fake keys
+/* _daemon_fake(): boot with fake keys
*/
void
-_king_fake(u3_noun ship, u3_noun pill, u3_noun path)
+_daemon_fake(u3_noun ship, u3_noun pill, u3_noun path)
{
u3_pier_boot(sag_w, ship, u3nc(c3__fake, u3k(ship)), pill, path);
}
-/* _king_come(): mine a comet under star (unit)
+/* _daemon_come(): mine a comet under star (unit)
**
** XX revise to exclude star argument
*/
void
-_king_come(u3_noun star, u3_noun pill, u3_noun path)
+_daemon_come(u3_noun star, u3_noun pill, u3_noun path)
{
- _king_dawn(u3_dawn_come(), pill, path);
+ _daemon_dawn(u3_dawn_come(), pill, path);
}
-/* _king_dawn(): boot from keys, validating
+/* _daemon_dawn(): boot from keys, validating
*/
void
-_king_dawn(u3_noun seed, u3_noun pill, u3_noun path)
+_daemon_dawn(u3_noun seed, u3_noun pill, u3_noun path)
{
u3_pier_boot(sag_w, u3k(u3h(seed)), u3_dawn_vent(seed), pill, path);
}
-/* _king_exit(): exit parser
+/* _daemon_exit(): exit parser
*/
void
-_king_exit(u3_noun exit)
+_daemon_exit(u3_noun exit)
{
}
-/* _king_pier(): pier parser
+/* _daemon_pier(): pier parser
*/
void
-_king_pier(u3_noun pier)
+_daemon_pier(u3_noun pier)
{
if ( (c3n == u3du(pier)) ||
(c3n == u3ud(u3t(pier))) ) {
- u3m_p("king: invalid pier", pier);
+ u3m_p("daemon: invalid pier", pier);
exit(1);
}
@@ -361,20 +361,20 @@ _king_pier(u3_noun pier)
u3z(pier);
}
-/* _king_root(): root parser
+/* _daemon_root(): root parser
*/
void
-_king_root(u3_noun root)
+_daemon_root(u3_noun root)
{
}
-/* _king_bail(): bail for command socket newt
+/* _daemon_bail(): bail for command socket newt
*/
void
-_king_bail(u3_moor *vod_p, const c3_c *err_c)
+_daemon_bail(u3_moor *vod_p, const c3_c *err_c)
{
u3_moor *free_p;
- fprintf(stderr, "_king_bail: %s\r\n", err_c);
+ u3l_log("_daemon_bail: %s\r\n", err_c);
if ( vod_p == 0 ) {
free_p = u3K.cli_u;
@@ -388,10 +388,10 @@ _king_bail(u3_moor *vod_p, const c3_c *err_c)
}
}
-/* _king_socket_connect(): callback for new connections
+/* _daemon_socket_connect(): callback for new connections
*/
void
-_king_socket_connect(uv_stream_t *sock, int status)
+_daemon_socket_connect(uv_stream_t *sock, int status)
{
u3_moor *mor_u;
@@ -411,18 +411,18 @@ _king_socket_connect(uv_stream_t *sock, int status)
}
uv_pipe_init(u3L, &mor_u->pyp_u, 0);
- mor_u->pok_f = _king_fate;
- mor_u->bal_f = (u3_bail)_king_bail;
+ mor_u->pok_f = _daemon_fate;
+ mor_u->bal_f = (u3_bail)_daemon_bail;
uv_accept(sock, (uv_stream_t *)&mor_u->pyp_u);
u3_newt_read((u3_moat *)mor_u);
}
-/* _king_curl_alloc(): allocate a response buffer for curl
+/* _daemon_curl_alloc(): allocate a response buffer for curl
** XX deduplicate with dawn.c
*/
static size_t
-_king_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u)
+_daemon_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u)
{
size_t siz_t = uni_t * mem_t;
buf_u->base = c3_realloc(buf_u->base, 1 + siz_t + buf_u->len);
@@ -434,11 +434,11 @@ _king_curl_alloc(void* dat_v, size_t uni_t, size_t mem_t, uv_buf_t* buf_u)
return siz_t;
}
-/* _king_get_atom(): HTTP GET url_c, produce the response body as an atom.
+/* _daemon_get_atom(): HTTP GET url_c, produce the response body as an atom.
** XX deduplicate with dawn.c
*/
static u3_noun
-_king_get_atom(c3_c* url_c)
+_daemon_get_atom(c3_c* url_c)
{
CURL *curl;
CURLcode result;
@@ -447,12 +447,12 @@ _king_get_atom(c3_c* url_c)
uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0);
if ( !(curl = curl_easy_init()) ) {
- fprintf(stderr, "failed to initialize libcurl\n");
+ u3l_log("failed to initialize libcurl\n");
exit(1);
}
curl_easy_setopt(curl, CURLOPT_URL, url_c);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _king_curl_alloc);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _daemon_curl_alloc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&buf_u);
result = curl_easy_perform(curl);
@@ -461,12 +461,12 @@ _king_get_atom(c3_c* url_c)
// XX retry?
//
if ( CURLE_OK != result ) {
- fprintf(stderr, "failed to fetch %s: %s\n",
- url_c, curl_easy_strerror(result));
+ u3l_log("failed to fetch %s: %s\n",
+ url_c, curl_easy_strerror(result));
exit(1);
}
if ( 300 <= cod_l ) {
- fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
+ u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l);
exit(1);
}
@@ -485,12 +485,12 @@ _get_cmd_output(c3_c *cmd_c, c3_c *out_c, c3_w len_c)
{
FILE *fp = popen(cmd_c, "r");
if ( NULL == fp ) {
- fprintf(stderr, "'%s' failed\n", cmd_c);
+ u3l_log("'%s' failed\n", cmd_c);
exit(1);
}
if ( NULL == fgets(out_c, len_c, fp) ) {
- fprintf(stderr, "'%s' produced no output\n", cmd_c);
+ u3l_log("'%s' produced no output\n", cmd_c);
exit(1);
}
@@ -523,7 +523,7 @@ _git_pill_url(c3_c *out_c, c3_c *arv_c)
assert(NULL != arv_c);
if ( 0 != system("which git >> /dev/null") ) {
- fprintf(stderr, "boot: could not find git executable\r\n");
+ u3l_log("boot: could not find git executable\r\n");
exit(1);
}
@@ -540,7 +540,7 @@ _boothack_pill(void)
u3_noun pil;
if ( 0 != u3_Host.ops_u.pil_c ) {
- fprintf(stderr, "boot: loading pill %s\r\n", u3_Host.ops_u.pil_c);
+ u3l_log("boot: loading pill %s\r\n", u3_Host.ops_u.pil_c);
pil = u3m_file(u3_Host.ops_u.pil_c);
}
else {
@@ -556,13 +556,13 @@ _boothack_pill(void)
strcpy(url_c, u3_Host.ops_u.url_c);
}
- fprintf(stderr, "boot: downloading pill %s\r\n", url_c);
- pil = _king_get_atom(url_c);
+ u3l_log("boot: downloading pill %s\r\n", url_c);
+ pil = _daemon_get_atom(url_c);
}
if ( 0 != u3_Host.ops_u.arv_c ) {
- fprintf(stderr, "boot: preparing filesystem from %s\r\n",
- u3_Host.ops_u.arv_c);
+ u3l_log("boot: preparing filesystem from %s\r\n",
+ u3_Host.ops_u.arv_c);
arv = u3nc(u3_nul, u3_unix_initial_into_card(u3_Host.ops_u.arv_c));
}
@@ -581,7 +581,7 @@ _boothack_key(u3_noun kef)
if ( u3_nul == des ) {
c3_c* kef_c = u3r_string(kef);
- fprintf(stderr, "dawn: invalid private keys: %s\r\n", kef_c);
+ u3l_log("dawn: invalid private keys: %s\r\n", kef_c);
free(kef_c);
exit(1);
}
@@ -601,16 +601,16 @@ _boothack_key(u3_noun kef)
u3_noun whu = u3dc("slaw", 'p', u3k(woh));
if ( u3_nul == whu ) {
- fprintf(stderr, "dawn: invalid ship specificed with -w %s\r\n",
- u3_Host.ops_u.who_c);
+ u3l_log("dawn: invalid ship specificed with -w %s\r\n",
+ u3_Host.ops_u.who_c);
exit(1);
}
if ( c3n == u3r_sing(ship, u3t(whu)) ) {
u3_noun how = u3dc("scot", 'p', u3k(ship));
c3_c* how_c = u3r_string(u3k(how));
- fprintf(stderr, "dawn: mismatch between -w %s and -K %s\r\n",
- u3_Host.ops_u.who_c, how_c);
+ u3l_log("dawn: mismatch between -w %s and -K %s\r\n",
+ u3_Host.ops_u.who_c, how_c);
u3z(how);
free(how_c);
@@ -640,7 +640,7 @@ _boothack_doom(void)
u3_noun whu = u3dc("slaw", 'p', u3k(fak));
if ( u3_nul == whu ) {
- fprintf(stderr, "boot: malformed -F ship %s\r\n", u3_Host.ops_u.fak_c);
+ u3l_log("boot: malformed -F ship %s\r\n", u3_Host.ops_u.fak_c);
exit(1);
}
@@ -659,7 +659,7 @@ _boothack_doom(void)
kef = u3i_string(u3_Host.ops_u.gen_c);
}
else {
- fprintf(stderr, "boot: must specify a key with -k or -G\r\n");
+ u3l_log("boot: must specify a key with -k or -G\r\n");
exit(1);
}
@@ -674,6 +674,104 @@ _boothack_doom(void)
return u3nq(c3__boot, bot, _boothack_pill(), pax);
}
+/* _daemon_sign_init(): initialize daemon signal handlers
+*/
+static void
+_daemon_sign_init(void)
+{
+ // gracefully shutdown on SIGTERM
+ //
+ {
+ u3_usig* sig_u;
+
+ sig_u = c3_malloc(sizeof(u3_usig));
+ uv_signal_init(u3L, &sig_u->sil_u);
+
+ sig_u->num_i = SIGTERM;
+ sig_u->nex_u = u3_Host.sig_u;
+ u3_Host.sig_u = sig_u;
+ }
+
+ // forward SIGINT to worker
+ //
+ {
+ u3_usig* sig_u;
+
+ sig_u = c3_malloc(sizeof(u3_usig));
+ uv_signal_init(u3L, &sig_u->sil_u);
+
+ sig_u->num_i = SIGINT;
+ sig_u->nex_u = u3_Host.sig_u;
+ u3_Host.sig_u = sig_u;
+ }
+
+ // inject new dimensions after terminal resize
+ //
+ {
+ u3_usig* sig_u;
+
+ sig_u = c3_malloc(sizeof(u3_usig));
+ uv_signal_init(u3L, &sig_u->sil_u);
+
+ sig_u->num_i = SIGWINCH;
+ sig_u->nex_u = u3_Host.sig_u;
+ u3_Host.sig_u = sig_u;
+ }
+}
+
+/* _daemon_sign_cb: signal callback.
+*/
+static void
+_daemon_sign_cb(uv_signal_t* sil_u, c3_i num_i)
+{
+ switch ( num_i ) {
+ default: {
+ u3l_log("\r\nmysterious signal %d\r\n", num_i);
+ break;
+ }
+
+ case SIGTERM: {
+ u3_pier_exit(u3_pier_stub());
+ break;
+ }
+
+ case SIGINT: {
+ u3l_log("\r\ninterrupt\r\n");
+ u3_term_ef_ctlc();
+ break;
+ }
+
+ case SIGWINCH: {
+ u3_term_ef_winc();
+ break;
+ }
+ }
+}
+
+/* _daemon_sign_move(): enable daemon signal handlers
+*/
+static void
+_daemon_sign_move(void)
+{
+ u3_usig* sig_u;
+
+ for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
+ uv_signal_start(&sig_u->sil_u, _daemon_sign_cb, sig_u->num_i);
+ }
+}
+
+/* _daemon_sign_hold(): disable daemon signal handlers
+*/
+static void
+_daemon_sign_hold(void)
+{
+ u3_usig* sig_u;
+
+ for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
+ uv_signal_stop(&sig_u->sil_u);
+ }
+}
+
/* _boothack_cb(): callback for the boothack self-connection
** (as if we were a client process)
*/
@@ -688,42 +786,13 @@ _boothack_cb(uv_connect_t *conn, int status)
u3_newt_write(moj_u, mat, 0);
}
-/* _king_loop_init(): stuff that comes before the event loop
+/* _daemon_loop_init(): stuff that comes before the event loop
*/
void
-_king_loop_init()
+_daemon_loop_init()
{
- /* move signals out of unix.c */
- {
- u3_usig* sig_u;
-
- sig_u = c3_malloc(sizeof(u3_usig));
- uv_signal_init(u3L, &sig_u->sil_u);
-
- sig_u->num_i = SIGTERM;
- sig_u->nex_u = u3_Host.sig_u;
- u3_Host.sig_u = sig_u;
- }
- {
- u3_usig* sig_u;
-
- sig_u = c3_malloc(sizeof(u3_usig));
- uv_signal_init(u3L, &sig_u->sil_u);
-
- sig_u->num_i = SIGINT;
- sig_u->nex_u = u3_Host.sig_u;
- u3_Host.sig_u = sig_u;
- }
- {
- u3_usig* sig_u;
-
- sig_u = c3_malloc(sizeof(u3_usig));
- uv_signal_init(u3L, &sig_u->sil_u);
-
- sig_u->num_i = SIGWINCH;
- sig_u->nex_u = u3_Host.sig_u;
- u3_Host.sig_u = sig_u;
- }
+ _daemon_sign_init();
+ _daemon_sign_move();
/* boot hack */
{
@@ -735,18 +804,18 @@ _king_loop_init()
}
}
-/* _king_loop_exit(): cleanup after event loop
+/* _daemon_loop_exit(): cleanup after event loop
*/
void
-_king_loop_exit()
+_daemon_loop_exit()
{
unlink(u3K.soc_c);
}
-/* u3_king_commence(): start the daemon
+/* u3_daemon_commence(): start the daemon
*/
void
-u3_king_commence()
+u3_daemon_commence()
{
u3_Host.lup_u = uv_default_loop();
@@ -757,6 +826,14 @@ u3_king_commence()
u3C.wag_w |= u3o_hashless;
u3m_boot_pier();
+
+ // wire up signal controls
+ //
+ u3C.sign_hold_f = _daemon_sign_hold;
+ u3C.sign_move_f = _daemon_sign_move;
+
+ // boot the ivory pill
+ //
{
u3_noun lit;
@@ -786,21 +863,30 @@ u3_king_commence()
uv_pipe_init(u3L, &u3K.cmd_u, 0);
uv_pipe_bind(&u3K.cmd_u, u3K.soc_c);
- uv_listen((uv_stream_t *)&u3K.cmd_u, 128, _king_socket_connect);
- fprintf(stderr, "cmd socket up\r\n");
+ uv_listen((uv_stream_t *)&u3K.cmd_u, 128, _daemon_socket_connect);
- _king_loop_init();
+ _daemon_loop_init();
uv_run(u3L, UV_RUN_DEFAULT);
- _king_loop_exit();
+ _daemon_loop_exit();
exit(0);
}
-/* u3_king_grab(): gc the kingdom
+/* u3_daemon_bail(): immediately shutdown.
*/
void
-u3_king_grab(void* vod_p)
+u3_daemon_bail(void)
+{
+ _daemon_loop_exit();
+ u3_pier_bail();
+ exit(1);
+}
+
+/* u3_daemon_grab(): gc the daemon area
+*/
+void
+u3_daemon_grab(void* vod_p)
{
// XX fix leaks and enable
//
@@ -810,7 +896,7 @@ u3_king_grab(void* vod_p)
c3_assert( u3R == &(u3H->rod_u) );
- fprintf(fil_u, "measuring king:\r\n");
+ fprintf(fil_u, "measuring daemon:\r\n");
man_w = u3m_mark(fil_u);
pir_w = u3_pier_mark(fil_u);
diff --git a/pkg/urbit/vere/dawn.c b/pkg/urbit/vere/dawn.c
index d5854eb3c..1e341699a 100644
--- a/pkg/urbit/vere/dawn.c
+++ b/pkg/urbit/vere/dawn.c
@@ -70,7 +70,7 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u)
uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0);
if ( !(curl = curl_easy_init()) ) {
- fprintf(stderr, "failed to initialize libcurl\n");
+ u3l_log("failed to initialize libcurl\n");
exit(1);
}
@@ -93,12 +93,12 @@ _dawn_post_json(c3_c* url_c, uv_buf_t lod_u)
// XX retry?
if ( CURLE_OK != result ) {
- fprintf(stderr, "failed to fetch %s: %s\n",
- url_c, curl_easy_strerror(result));
+ u3l_log("failed to fetch %s: %s\n",
+ url_c, curl_easy_strerror(result));
exit(1);
}
if ( 300 <= cod_l ) {
- fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
+ u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l);
exit(1);
}
@@ -120,7 +120,7 @@ _dawn_get_jam(c3_c* url_c)
uv_buf_t buf_u = uv_buf_init(c3_malloc(1), 0);
if ( !(curl = curl_easy_init()) ) {
- fprintf(stderr, "failed to initialize libcurl\n");
+ u3l_log("failed to initialize libcurl\n");
exit(1);
}
@@ -135,12 +135,12 @@ _dawn_get_jam(c3_c* url_c)
// XX retry?
if ( CURLE_OK != result ) {
- fprintf(stderr, "failed to fetch %s: %s\n",
- url_c, curl_easy_strerror(result));
+ u3l_log("failed to fetch %s: %s\n",
+ url_c, curl_easy_strerror(result));
exit(1);
}
if ( 300 <= cod_l ) {
- fprintf(stderr, "error fetching %s: HTTP %ld\n", url_c, cod_l);
+ u3l_log("error fetching %s: HTTP %ld\n", url_c, cod_l);
exit(1);
}
@@ -197,7 +197,7 @@ _dawn_fail(u3_noun who, u3_noun rac, u3_noun sas)
}
}
- fprintf(stderr, "dawn: invalid keys for %s '%s'\r\n", rac_c, how_c);
+ u3l_log("dawn: invalid keys for %s '%s'\r\n", rac_c, how_c);
// XX deconstruct sas, print helpful error messages
u3m_p("pre-boot error", u3t(sas));
@@ -213,7 +213,7 @@ static u3_noun
_dawn_need_unit(u3_noun nit, c3_c* msg_c)
{
if ( u3_nul == nit ) {
- fprintf(stderr, "%s\r\n", msg_c);
+ u3l_log("%s\r\n", msg_c);
exit(1);
}
else {
@@ -232,7 +232,7 @@ _dawn_purl(u3_noun rac)
if ( 0 == u3_Host.ops_u.eth_c ) {
if ( c3__czar == rac ) {
- fprintf(stderr, "boot: galaxy requires ethereum gateway via -e\r\n");
+ u3l_log("boot: galaxy requires ethereum gateway via -e\r\n");
exit(1);
}
@@ -247,7 +247,7 @@ _dawn_purl(u3_noun rac)
if ( u3_nul == rul ) {
if ( c3__czar == rac ) {
- fprintf(stderr, "boot: galaxy requires ethereum gateway via -e\r\n");
+ u3l_log("boot: galaxy requires ethereum gateway via -e\r\n");
exit(1);
}
@@ -279,11 +279,11 @@ _dawn_turf(c3_c* dns_c)
u3_noun rul = u3dc("rush", u3k(dns), u3k(par));
if ( (u3_nul == rul) || (c3n == u3h(u3t(rul))) ) {
- fprintf(stderr, "boot: invalid domain specified with -H %s\r\n", dns_c);
+ u3l_log("boot: invalid domain specified with -H %s\r\n", dns_c);
exit(1);
}
else {
- fprintf(stderr, "boot: overriding network domains with %s\r\n", dns_c);
+ u3l_log("boot: overriding network domains with %s\r\n", dns_c);
u3_noun dom = u3t(u3t(rul));
tuf = u3nc(u3k(dom), u3_nul);
}
@@ -306,7 +306,7 @@ u3_dawn_vent(u3_noun seed)
// load snapshot from file
//
if ( 0 != u3_Host.ops_u.ets_c ) {
- fprintf(stderr, "boot: loading ethereum snapshot\r\n");
+ u3l_log("boot: loading ethereum snapshot\r\n");
u3_noun raw_snap = u3ke_cue(u3m_file(u3_Host.ops_u.ets_c));
sap = u3nc(u3_nul, raw_snap);
}
@@ -319,7 +319,7 @@ u3_dawn_vent(u3_noun seed)
// no snapshot
//
else {
- printf("dawn: no ethereum snapshot specified\n");
+ u3l_log("dawn: no ethereum snapshot specified\n");
sap = u3_nul;
}
@@ -334,14 +334,14 @@ u3_dawn_vent(u3_noun seed)
// pin block number
//
if ( c3y == u3_Host.ops_u.etn ) {
- fprintf(stderr, "boot: extracting block from snapshot\r\n");
+ u3l_log("boot: extracting block from snapshot\r\n");
bok = _dawn_need_unit(u3do("bloq:snap:dawn", u3k(u3t(sap))),
"boot: failed to extract "
"block from snapshot");
}
else {
- fprintf(stderr, "boot: retrieving latest block\r\n");
+ u3l_log("boot: retrieving latest block\r\n");
u3_noun oct = u3v_wish("bloq:give:dawn");
u3_noun kob = _dawn_eth_rpc(url_c, u3k(oct));
@@ -357,7 +357,7 @@ u3_dawn_vent(u3_noun seed)
u3_noun pot;
if ( c3y == u3_Host.ops_u.etn ) {
- fprintf(stderr, "boot: extracting public keys from snapshot\r\n");
+ u3l_log("boot: extracting public keys from snapshot\r\n");
pot = _dawn_need_unit(u3dc("point:snap:dawn", u3k(ship), u3k(u3t(sap))),
"boot: failed to extract "
@@ -378,16 +378,16 @@ u3_dawn_vent(u3_noun seed)
u3_noun seg = u3dc("scot", 'p', u3k(who));
c3_c* seg_c = u3r_string(seg);
- fprintf(stderr, "boot: retrieving %s's public keys (for %s)\r\n",
- seg_c, u3_Host.ops_u.who_c);
+ u3l_log("boot: retrieving %s's public keys (for %s)\r\n",
+ seg_c, u3_Host.ops_u.who_c);
free(seg_c);
u3z(seg);
}
}
else {
who = u3k(ship);
- fprintf(stderr, "boot: retrieving %s's public keys\r\n",
- u3_Host.ops_u.who_c);
+ u3l_log("boot: retrieving %s's public keys\r\n",
+ u3_Host.ops_u.who_c);
}
{
@@ -408,7 +408,7 @@ u3_dawn_vent(u3_noun seed)
u3_noun liv = u3_nul;
// u3_noun liv = _dawn_get_json(parent, /some/url)
- fprintf(stderr, "boot: verifying keys\r\n");
+ u3l_log("boot: verifying keys\r\n");
// (each sponsor=ship error=@tas)
//
@@ -432,14 +432,14 @@ u3_dawn_vent(u3_noun seed)
// (map ship [=life =pass]): galaxy table
//
if ( c3y == u3_Host.ops_u.etn ) {
- fprintf(stderr, "boot: extracting galaxy table from snapshot\r\n");
+ u3l_log("boot: extracting galaxy table from snapshot\r\n");
zar = _dawn_need_unit(u3do("czar:snap:dawn", u3k(u3t(sap))),
"boot: failed to extract "
"galaxy table from snapshot");
}
else {
- fprintf(stderr, "boot: retrieving galaxy table\r\n");
+ u3l_log("boot: retrieving galaxy table\r\n");
u3_noun oct = u3do("czar:give:dawn", u3k(bok));
u3_noun raz = _dawn_eth_rpc(url_c, u3k(oct));
@@ -455,14 +455,14 @@ u3_dawn_vent(u3_noun seed)
tuf = _dawn_turf(u3_Host.ops_u.dns_c);
}
else if ( c3y == u3_Host.ops_u.etn ) {
- fprintf(stderr, "boot: extracting network domains from snapshot\r\n");
+ u3l_log("boot: extracting network domains from snapshot\r\n");
tuf = _dawn_need_unit(u3do("turf:snap:dawn", u3k(u3t(sap))),
"boot: failed to extract "
"network domains from snapshot");
}
else {
- fprintf(stderr, "boot: retrieving network domains\r\n");
+ u3l_log("boot: retrieving network domains\r\n");
u3_noun oct = u3do("turf:give:dawn", u3k(bok));
u3_noun fut = _dawn_eth_rpc(url_c, u3k(oct));
@@ -492,8 +492,8 @@ _dawn_come(u3_noun stars)
c3_rand(eny_w);
eny = u3i_words(16, eny_w);
- fprintf(stderr, "boot: mining a comet. May take up to an hour.\r\n");
- fprintf(stderr, "If you want to boot faster, get an Azimuth point.\r\n");
+ u3l_log("boot: mining a comet. May take up to an hour.\r\n");
+ u3l_log("If you want to boot faster, get an Azimuth point.\r\n");
seed = u3dc("come:dawn", u3k(stars), u3k(eny));
u3z(eny);
@@ -503,7 +503,7 @@ _dawn_come(u3_noun stars)
u3_noun who = u3dc("scot", 'p', u3k(u3h(seed)));
c3_c* who_c = u3r_string(who);
- fprintf(stderr, "boot: found comet %s\r\n", who_c);
+ u3l_log("boot: found comet %s\r\n", who_c);
free(who_c);
u3z(who);
}
diff --git a/pkg/urbit/vere/foil.c b/pkg/urbit/vere/foil.c
index b43a84713..591b2783b 100644
--- a/pkg/urbit/vere/foil.c
+++ b/pkg/urbit/vere/foil.c
@@ -54,10 +54,10 @@ static void
_foil_fail(const c3_c* why_c, c3_i err_i)
{
if ( err_i ) {
- fprintf(stderr, "%s: error: %s\r\n", why_c, uv_strerror(err_i));
+ u3l_log("%s: error: %s\r\n", why_c, uv_strerror(err_i));
c3_assert(0);
} else {
- fprintf(stderr, "%s: file error\r\n", why_c);
+ u3l_log("%s: file error\r\n", why_c);
}
exit(1);
}
@@ -561,7 +561,7 @@ u3_foil_reveal(u3_foil* fol_u, // file from
timersub(&aft_u, &req_u->bef_u, &gap_u);
mls_w = (gap_u.tv_sec * 1000) + (gap_u.tv_usec / 1000);
- fprintf(stderr, "invent ms: %d\r\n", mls_w);
+ u3l_log("invent ms: %d\r\n", mls_w);
}
#endif
req_u->fun_f(req_u->vod_p, req_u->fol_u);
diff --git a/pkg/urbit/vere/http.c b/pkg/urbit/vere/http.c
index 1e59c21b4..64ec9eb5d 100644
--- a/pkg/urbit/vere/http.c
+++ b/pkg/urbit/vere/http.c
@@ -355,7 +355,7 @@ _http_req_respond(u3_hreq* req_u, u3_noun sas, u3_noun hed, u3_noun bod)
//c3_assert(u3_rsat_plan == req_u->sat_e);
if ( u3_rsat_plan != req_u->sat_e ) {
- //uL(fprintf(uH, "duplicate response\n"));
+ //u3l_log("duplicate response\n");
return;
}
@@ -442,8 +442,8 @@ _http_rec_accept(h2o_handler_t* han_u, h2o_req_t* rec_u)
if ( u3_none == req ) {
if ( (u3C.wag_w & u3o_verbose) ) {
- uL(fprintf(uH, "strange %.*s request\n", (int)rec_u->method.len,
- rec_u->method.base));
+ u3l_log("strange %.*s request\n", (int)rec_u->method.len,
+ rec_u->method.base);
}
c3_c* msg_c = "bad request";
h2o_send_error_generic(rec_u, 400, msg_c, msg_c, 0);
@@ -545,7 +545,7 @@ _http_conn_free(uv_handle_t* han_t)
noh_u = noh_u->nex_u;
}
- uL(fprintf(uH, "http conn free %d of %u server %d\n", hon_u->coq_l, len_w, htp_u->sev_l));
+ u3l_log("http conn free %d of %u server %d\n", hon_u->coq_l, len_w, htp_u->sev_l);
}
#endif
@@ -562,13 +562,13 @@ _http_conn_free(uv_handle_t* han_t)
noh_u = noh_u->nex_u;
}
- uL(fprintf(uH, "http conn free %u remaining\n", len_w));
+ u3l_log("http conn free %u remaining\n", len_w);
}
#endif
if ( (0 == htp_u->hon_u) && (0 != h2o_u->ctx_u.shutdown_requested) ) {
#if 0
- uL(fprintf(uH, "http conn free %d free server %d\n", hon_u->coq_l, htp_u->sev_l));
+ u3l_log("http conn free %d free server %d\n", hon_u->coq_l, htp_u->sev_l);
#endif
_http_serv_free(htp_u);
}
@@ -592,7 +592,7 @@ _http_conn_new(u3_http* htp_u)
_http_conn_link(htp_u, hon_u);
#if 0
- uL(fprintf(uH, "http conn neww %d server %d\n", hon_u->coq_l, htp_u->sev_l));
+ u3l_log("http conn neww %d server %d\n", hon_u->coq_l, htp_u->sev_l);
#endif
return hon_u;
@@ -758,7 +758,7 @@ static void
_http_serv_free(u3_http* htp_u)
{
#if 0
- uL(fprintf(uH, "http serv free %d\n", htp_u->sev_l));
+ u3l_log("http serv free %d\n", htp_u->sev_l);
#endif
c3_assert( 0 == htp_u->hon_u );
@@ -827,7 +827,7 @@ _http_serv_close(u3_http* htp_u)
h2o_context_request_shutdown(&h2o_u->ctx_u);
#if 0
- uL(fprintf(uH, "http serv close %d %p\n", htp_u->sev_l, &htp_u->wax_u));
+ u3l_log("http serv close %d %p\n", htp_u->sev_l, &htp_u->wax_u);
#endif
uv_close((uv_handle_t*)&htp_u->wax_u, _http_serv_close_cb);
@@ -875,7 +875,7 @@ _http_serv_accept(u3_http* htp_u)
if ( 0 != (sas_i = uv_accept((uv_stream_t*)&htp_u->wax_u,
(uv_stream_t*)&hon_u->wax_u)) ) {
if ( (u3C.wag_w & u3o_verbose) ) {
- uL(fprintf(uH, "http: accept: %s\n", uv_strerror(sas_i)));
+ u3l_log("http: accept: %s\n", uv_strerror(sas_i));
}
uv_close((uv_handle_t*)&hon_u->wax_u, _http_conn_free);
@@ -904,7 +904,7 @@ _http_serv_listen_cb(uv_stream_t* str_u, c3_i sas_i)
u3_http* htp_u = (u3_http*)str_u;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "http: listen_cb: %s\n", uv_strerror(sas_i)));
+ u3l_log("http: listen_cb: %s\n", uv_strerror(sas_i));
}
else {
_http_serv_accept(htp_u);
@@ -1012,7 +1012,7 @@ _http_serv_start(u3_http* htp_u)
continue;
}
- uL(fprintf(uH, "http: listen: %s\n", uv_strerror(sas_i)));
+ u3l_log("http: listen: %s\n", uv_strerror(sas_i));
if ( 0 != htp_u->rox_u ) {
_proxy_serv_free(htp_u->rox_u);
@@ -1027,17 +1027,17 @@ _http_serv_start(u3_http* htp_u)
}
if ( 0 != htp_u->rox_u ) {
- uL(fprintf(uH, "http: live (%s, %s) on %d (proxied on %d)\n",
- (c3y == htp_u->sec) ? "secure" : "insecure",
- (c3y == htp_u->lop) ? "loopback" : "public",
- htp_u->por_s,
- htp_u->rox_u->por_s));
+ u3l_log("http: live (%s, %s) on %d (proxied on %d)\n",
+ (c3y == htp_u->sec) ? "secure" : "insecure",
+ (c3y == htp_u->lop) ? "loopback" : "public",
+ htp_u->por_s,
+ htp_u->rox_u->por_s);
}
else {
- uL(fprintf(uH, "http: live (%s, %s) on %d\n",
- (c3y == htp_u->sec) ? "secure" : "insecure",
- (c3y == htp_u->lop) ? "loopback" : "public",
- htp_u->por_s));
+ u3l_log("http: live (%s, %s) on %d\n",
+ (c3y == htp_u->sec) ? "secure" : "insecure",
+ (c3y == htp_u->lop) ? "loopback" : "public",
+ htp_u->por_s);
}
break;
@@ -1141,9 +1141,9 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u)
BIO_free(bio_u);
if( 0 == sas_i ) {
- uL(fprintf(uH, "http: load private key failed:\n"));
- ERR_print_errors_fp(uH);
- uL(1);
+ u3l_log("http: load private key failed:\n");
+ ERR_print_errors_fp(u3_term_io_hija());
+ u3_term_io_loja(1);
SSL_CTX_free(tls_u);
@@ -1159,9 +1159,9 @@ _http_init_tls(uv_buf_t key_u, uv_buf_t cer_u)
X509_free(xer_u);
if( 0 == sas_i ) {
- uL(fprintf(uH, "http: load certificate failed:\n"));
- ERR_print_errors_fp(uH);
- uL(1);
+ u3l_log("http: load certificate failed:\n");
+ ERR_print_errors_fp(u3_term_io_hija());
+ u3_term_io_loja(1);
BIO_free(bio_u);
SSL_CTX_free(tls_u);
@@ -1341,25 +1341,25 @@ u3_http_ef_thou(c3_l sev_l,
if ( !(htp_u = _http_serv_find(sev_l)) ) {
if ( bug_w ) {
- uL(fprintf(uH, "http: server not found: %x\r\n", sev_l));
+ u3l_log("http: server not found: %x\r\n", sev_l);
}
}
else if ( !(hon_u = _http_conn_find(htp_u, coq_l)) ) {
if ( bug_w ) {
- uL(fprintf(uH, "http: connection not found: %x/%d\r\n", sev_l, coq_l));
+ u3l_log("http: connection not found: %x/%d\r\n", sev_l, coq_l);
}
}
else if ( !(req_u = _http_req_find(hon_u, seq_l)) ) {
if ( bug_w ) {
- uL(fprintf(uH, "http: request not found: %x/%d/%d\r\n",
- sev_l, coq_l, seq_l));
+ u3l_log("http: request not found: %x/%d/%d\r\n",
+ sev_l, coq_l, seq_l);
}
}
else {
u3_noun p_rep, q_rep, r_rep;
if ( c3n == u3r_trel(rep, &p_rep, &q_rep, &r_rep) ) {
- uL(fprintf(uH, "http: strange response\n"));
+ u3l_log("http: strange response\n");
}
else {
_http_req_respond(req_u, u3k(p_rep), u3k(q_rep), u3k(r_rep));
@@ -1455,7 +1455,7 @@ _http_serv_restart(void)
_http_serv_start_all();
}
else {
- uL(fprintf(uH, "http: restarting servers to apply configuration\n"));
+ u3l_log("http: restarting servers to apply configuration\n");
while ( 0 != htp_u ) {
if ( c3y == htp_u->liv ) {
@@ -1507,7 +1507,7 @@ u3_http_ef_form(u3_noun fig)
!( c3y == pro || c3n == pro ) ||
!( c3y == log || c3n == log ) ||
!( c3y == red || c3n == red ) ) {
- uL(fprintf(uH, "http: form: invalid card\n"));
+ u3l_log("http: form: invalid card\n");
u3z(fig);
return;
}
@@ -1832,17 +1832,17 @@ _proxy_write_cb(uv_write_t* wri_u, c3_i sas_i)
proxy_write_ctx* ctx_u = wri_u->data;
if ( ctx_u->str_u == (uv_stream_t*)ctx_u->con_u->upt_u ) {
- uL(fprintf(uH, "proxy: write upstream: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: write upstream: %s\n", uv_strerror(sas_i));
}
else if ( ctx_u->str_u == (uv_stream_t*)&(ctx_u->con_u->don_u) ) {
- uL(fprintf(uH, "proxy: write downstream: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: write downstream: %s\n", uv_strerror(sas_i));
}
else {
- uL(fprintf(uH, "proxy: write: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: write: %s\n", uv_strerror(sas_i));
}
}
else {
- uL(fprintf(uH, "proxy: write: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: write: %s\n", uv_strerror(sas_i));
}
}
@@ -1888,7 +1888,7 @@ _proxy_read_downstream_cb(uv_stream_t* don_u,
if ( 0 > siz_w ) {
if ( UV_EOF != siz_w ) {
- uL(fprintf(uH, "proxy: read downstream: %s\n", uv_strerror(siz_w)));
+ u3l_log("proxy: read downstream: %s\n", uv_strerror(siz_w));
}
_proxy_conn_close(con_u);
}
@@ -1909,7 +1909,7 @@ _proxy_read_upstream_cb(uv_stream_t* upt_u,
if ( 0 > siz_w ) {
if ( UV_EOF != siz_w ) {
- uL(fprintf(uH, "proxy: read upstream: %s\n", uv_strerror(siz_w)));
+ u3l_log("proxy: read upstream: %s\n", uv_strerror(siz_w));
}
_proxy_conn_close(con_u);
}
@@ -1950,7 +1950,7 @@ _proxy_loop_connect_cb(uv_connect_t * upc_u, c3_i sas_i)
u3_pcon* con_u = upc_u->data;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "proxy: connect: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: connect: %s\n", uv_strerror(sas_i));
_proxy_conn_close(con_u);
}
else {
@@ -2010,7 +2010,7 @@ _proxy_loop_connect(u3_pcon* con_u)
if ( 0 != (sas_i = uv_tcp_connect(upc_u, upt_u,
(const struct sockaddr*)&lop_u,
_proxy_loop_connect_cb)) ) {
- uL(fprintf(uH, "proxy: connect: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: connect: %s\n", uv_strerror(sas_i));
free(upc_u);
_proxy_conn_close(con_u);
}
@@ -2192,7 +2192,7 @@ _proxy_wcon_peek_read_cb(uv_stream_t* upt_u,
if ( 0 > siz_w ) {
if ( UV_EOF != siz_w ) {
- uL(fprintf(uH, "proxy: ward peek: %s\n", uv_strerror(siz_w)));
+ u3l_log("proxy: ward peek: %s\n", uv_strerror(siz_w));
}
_proxy_wcon_close(won_u);
}
@@ -2204,7 +2204,7 @@ _proxy_wcon_peek_read_cb(uv_stream_t* upt_u,
if ( ((len_w + 1) != siz_w) ||
(len_w != buf_u->base[0]) ||
(0 != memcmp(rev_u->non_u.base, buf_u->base + 1, len_w)) ) {
- // uL(fprintf(uH, "proxy: ward auth fail\n"));
+ // u3l_log("proxy: ward auth fail\n");
_proxy_wcon_unlink(won_u);
_proxy_wcon_close(won_u);
}
@@ -2243,7 +2243,7 @@ _proxy_ward_accept(u3_ward* rev_u)
if ( 0 != (sas_i = uv_accept((uv_stream_t*)&rev_u->tcp_u,
(uv_stream_t*)&won_u->upt_u)) ) {
- uL(fprintf(uH, "proxy: accept: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: accept: %s\n", uv_strerror(sas_i));
_proxy_wcon_close(won_u);
}
else {
@@ -2259,7 +2259,7 @@ _proxy_ward_listen_cb(uv_stream_t* tcp_u, c3_i sas_i)
u3_ward* rev_u = (u3_ward*)tcp_u;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "proxy: ward: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward: %s\n", uv_strerror(sas_i));
}
else {
_proxy_ward_accept(rev_u);
@@ -2274,7 +2274,7 @@ _proxy_ward_timer_cb(uv_timer_t* tim_u)
u3_ward* rev_u = tim_u->data;
if ( 0 != rev_u ) {
- uL(fprintf(uH, "proxy: ward expired: %d\n", rev_u->por_s));
+ u3l_log("proxy: ward expired: %d\n", rev_u->por_s);
_proxy_ward_close(rev_u);
_proxy_conn_close(rev_u->con_u);
}
@@ -2337,7 +2337,7 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip)
TCP_BACKLOG, _proxy_ward_listen_cb)) ||
0 != (sas_i = uv_tcp_getsockname(&rev_u->tcp_u,
(struct sockaddr*)&add_u, &add_i))) {
- uL(fprintf(uH, "proxy: ward: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward: %s\n", uv_strerror(sas_i));
_proxy_ward_close(rev_u);
_proxy_conn_close(con_u);
}
@@ -2348,7 +2348,7 @@ _proxy_ward_start(u3_pcon* con_u, u3_noun sip)
{
u3_noun who = u3dc("scot", 'p', u3k(sip));
c3_c* who_c = u3r_string(who);
- fprintf(stderr, "\r\nward for %s started on %u\r\n", who_c, rev_u->por_s);
+ u3l_log("\r\nward for %s started on %u\r\n", who_c, rev_u->por_s);
free(who_c);
u3z(who);
}
@@ -2373,7 +2373,7 @@ _proxy_ward_connect_cb(uv_connect_t * upc_u, c3_i sas_i)
u3_pcon* con_u = upc_u->data;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "proxy: ward connect: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward connect: %s\n", uv_strerror(sas_i));
_proxy_conn_close(con_u);
}
else {
@@ -2415,7 +2415,7 @@ _proxy_ward_connect(u3_warc* cli_u)
if ( 0 != (sas_i = uv_tcp_connect(upc_u, &con_u->don_u,
(const struct sockaddr*)&add_u,
_proxy_ward_connect_cb)) ) {
- uL(fprintf(uH, "proxy: ward connect: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward connect: %s\n", uv_strerror(sas_i));
free(upc_u);
_proxy_conn_close(con_u);
}
@@ -2431,7 +2431,7 @@ _proxy_ward_resolve_cb(uv_getaddrinfo_t* adr_u,
u3_warc* cli_u = adr_u->data;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "proxy: ward: resolve: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward: resolve: %s\n", uv_strerror(sas_i));
_proxy_warc_free(cli_u);
}
else {
@@ -2477,7 +2477,7 @@ _proxy_ward_resolve(u3_warc* cli_u)
if ( 0 != (sas_i = uv_getaddrinfo(u3L, adr_u, _proxy_ward_resolve_cb,
cli_u->hot_c, 0, &hin_u)) ) {
- uL(fprintf(uH, "proxy: ward: resolve: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: ward: resolve: %s\n", uv_strerror(sas_i));
_proxy_warc_free(cli_u);
}
}
@@ -2657,13 +2657,13 @@ _proxy_peek(u3_pcon* con_u)
default: c3_assert(0);
case u3_pars_fail: {
- uL(fprintf(uH, "proxy: peek fail\n"));
+ u3l_log("proxy: peek fail\n");
_proxy_conn_close(con_u);
break;
}
case u3_pars_moar: {
- uL(fprintf(uH, "proxy: peek moar\n"));
+ u3l_log("proxy: peek moar\n");
// XX count retries, fail after some n
_proxy_peek_read(con_u);
break;
@@ -2692,7 +2692,7 @@ _proxy_peek_read_cb(uv_stream_t* don_u,
if ( 0 > siz_w ) {
if ( UV_EOF != siz_w ) {
- uL(fprintf(uH, "proxy: peek: %s\n", uv_strerror(siz_w)));
+ u3l_log("proxy: peek: %s\n", uv_strerror(siz_w));
}
_proxy_conn_close(con_u);
}
@@ -2787,7 +2787,7 @@ _proxy_serv_accept(u3_prox* lis_u)
c3_i sas_i;
if ( 0 != (sas_i = uv_accept((uv_stream_t*)&lis_u->sev_u,
(uv_stream_t*)&con_u->don_u)) ) {
- uL(fprintf(uH, "proxy: accept: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: accept: %s\n", uv_strerror(sas_i));
_proxy_conn_close(con_u);
}
else {
@@ -2803,7 +2803,7 @@ _proxy_serv_listen_cb(uv_stream_t* sev_u, c3_i sas_i)
u3_prox* lis_u = (u3_prox*)sev_u;
if ( 0 != sas_i ) {
- uL(fprintf(uH, "proxy: listen_cb: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: listen_cb: %s\n", uv_strerror(sas_i));
}
else {
_proxy_serv_accept(lis_u);
@@ -2848,7 +2848,7 @@ _proxy_serv_start(u3_prox* lis_u)
continue;
}
- uL(fprintf(uH, "proxy: listen: %s\n", uv_strerror(sas_i)));
+ u3l_log("proxy: listen: %s\n", uv_strerror(sas_i));
_proxy_serv_free(lis_u);
return 0;
}
@@ -2869,7 +2869,7 @@ u3_http_ef_that(u3_noun tat)
( c3n == u3a_is_cat(por) ) ||
!( c3y == sec || c3n == sec ) ||
( c3n == u3ud(non) ) ) {
- uL(fprintf(uH, "http: that: invalid card\n"));
+ u3l_log("http: that: invalid card\n");
}
else {
u3_http* htp_u;
@@ -2885,8 +2885,8 @@ u3_http_ef_that(u3_noun tat)
// so this situation can be avoided
//
if ( 0 == htp_u ) {
- uL(fprintf(uH, "http: that: no %s server\n", (c3y == sec) ?
- "secure" : "insecure"));
+ u3l_log("http: that: no %s server\n",
+ (c3y == sec) ? "secure" : "insecure");
}
else {
cli_u = _proxy_warc_new(htp_u, (u3_atom)u3k(sip), (u3_atom)u3k(non),
diff --git a/pkg/urbit/vere/newt.c b/pkg/urbit/vere/newt.c
index 61940b683..67a220daa 100644
--- a/pkg/urbit/vere/newt.c
+++ b/pkg/urbit/vere/newt.c
@@ -31,6 +31,8 @@
#include "all.h"
#include "vere/vere.h"
+#undef NEWT_VERBOSE
+
/* _newt_consume(): advance buffer processing.
*/
static void
@@ -53,16 +55,15 @@ _newt_consume(u3_moat* mot_u)
met_u->len_d = mot_u->len_d;
memcpy(met_u->hun_y, mot_u->rag_y, mot_u->len_d);
-#if 0
- fprintf(stderr,
- "newt: %d: create: msg %p, new block %p, len %"
- PRIu64 ", has %" PRIu64 ", needs %" PRIu64 "\r\n",
- getpid(),
- mot_u->mes_u,
- met_u,
- met_u->len_d,
- mot_u->mes_u->has_d,
- mot_u->mes_u->len_d);
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: create: msg %p, new block %p, len %"
+ PRIu64 ", has %" PRIu64 ", needs %" PRIu64 "\r\n",
+ getpid(),
+ mot_u->mes_u,
+ met_u,
+ met_u->len_d,
+ mot_u->mes_u->has_d,
+ mot_u->mes_u->len_d);
#endif
/* enqueue block
*/
@@ -96,10 +97,11 @@ _newt_consume(u3_moat* mot_u)
nel_d |= ((c3_d) mot_u->rag_y[5]) << 40ULL;
nel_d |= ((c3_d) mot_u->rag_y[6]) << 48ULL;
nel_d |= ((c3_d) mot_u->rag_y[7]) << 56ULL;
-#if 0
- fprintf(stderr, "newt: %d: parsed length %" PRIu64 "\r\n",
- getpid(),
- nel_d);
+
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: parsed length %" PRIu64 "\r\n",
+ getpid(),
+ nel_d);
#endif
mot_u->len_d -= 8ULL;
@@ -225,15 +227,26 @@ _newt_read_cb(uv_stream_t* str_u,
u3_moat* mot_u = (void *)str_u;
if ( UV_EOF == len_i ) {
- // fprintf(stderr, "newt: %d: stream closed\r\n", getpid());
+ // u3l_log("newt: %d: stream closed\r\n", getpid());
uv_read_stop(str_u);
mot_u->bal_f(mot_u->vod_p, "stream closed");
}
else {
-#if 0
- fprintf(stderr, "newt: %d: read %ld\r\n", getpid(), len_i);
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: read %ld\r\n", getpid(), len_i);
#endif
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: ", getpid());
+ for ( int i = 0; i < len_i; i++) {
+ if (0 == (i % 16)) u3l_log("\r\n");
+ u3l_log(" %02x", (unsigned) buf_u->base[i]);
+ }
+ u3l_log("\r\nnewt: %d: \r\n", getpid());
+#endif
+
+ // grow read buffer by `len_d` bytes
+ //
if ( mot_u->rag_y ) {
mot_u->rag_y = c3_realloc(mot_u->rag_y, mot_u->len_d + len_d);
memcpy(mot_u->rag_y + mot_u->len_d, buf_u->base, len_d);
@@ -289,7 +302,7 @@ _newt_write_cb(uv_write_t* wri_u, c3_i sas_i)
free(req_u);
if ( 0 != sas_i ) {
- fprintf(stderr, "newt: bad write %d\r\n", sas_i);
+ u3l_log("newt: bad write %d\r\n", sas_i);
moj_u->bal_f(vod_p, uv_strerror(sas_i));
}
}
@@ -322,9 +335,19 @@ u3_newt_write(u3_mojo* moj_u,
buf_u.base = (c3_c*) buf_y;
buf_u.len = len_w + 8;
-#if 0
- fprintf(stderr, "newt: %d: write %d\n", getpid(), len_w + 8);
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: write %d\n", getpid(), len_w + 8);
#endif
+
+#ifdef NEWT_VERBOSE
+ u3l_log("newt: %d: ", getpid());
+ for ( int i = 0; i < len_w+8; i++) {
+ if (0 == (i % 16)) u3l_log("\r\n");
+ u3l_log(" %02x", (unsigned) buf_u.base[i]);
+ }
+ u3l_log("\r\nnewt: %d: \r\n", getpid());
+#endif
+
if ( 0 != (err_i = uv_write((uv_write_t*)req_u,
(uv_stream_t*)&moj_u->pyp_u,
&buf_u,
diff --git a/pkg/urbit/vere/pier.c b/pkg/urbit/vere/pier.c
index 3f0f613a1..1c2b75372 100644
--- a/pkg/urbit/vere/pier.c
+++ b/pkg/urbit/vere/pier.c
@@ -26,14 +26,14 @@
#undef VERBOSE_EVENTS
/* event handling proceeds on a single path. across both the
- ** child worker process (serf) and parent i/o process (king).
+ ** child worker process (worker) and parent i/o process (daemon).
** state transitions are as follows:
**
** generated (event numbered and queued)
** dispatched (sent to worker)
** computed (completed by worker)
** commit requested (sent to storage subsystem)
- ** commit complete (king notified)
+ ** commit complete (daemon notified)
** released (output actions allowed)
**
** we dispatch one event at a time to the worker. we don't do
@@ -56,7 +56,7 @@
** replace the input event with a different event).
**
** after crash recovery, events committed but not in the snapshot
- ** (the state of the serf) are replayed (re-computed), but their
+ ** (the state of the worker) are replayed (re-computed), but their
** output effects are ignored. it is possible that effects of
** (only the last of ?) these events are not completely released to
** the outside world -- but they should never be released more than once.
@@ -66,9 +66,9 @@
static void _pier_apply(u3_pier* pir_u);
static void _pier_boot_complete(u3_pier* pir_u);
+static void _pier_boot_ready(u3_pier* pir_u);
+static void _pier_boot_set_ship(u3_pier* pir_u, u3_noun who, u3_noun fak);
static void _pier_exit_done(u3_pier* pir_u);
-static void _pier_loop_exit(u3_pier* pir_u);
-static void _pier_work_save(u3_pier* pir_u);
/* _pier_disk_bail(): bail from disk i/o.
*/
@@ -77,65 +77,7 @@ _pier_disk_bail(void* vod_p, const c3_c* err_c)
{
// u3_writ* wit_u = vod_p;
- fprintf(stderr, "disk error: %s\r\n", err_c);
-}
-
-/* _pier_work_bail(): handle subprocess error.
-*/
-static void
-_pier_work_bail(void* vod_p,
- const c3_c* err_c)
-{
- fprintf(stderr, "pier: work error: %s\r\n", err_c);
-}
-
-/* _pier_save_boot_complete(): commit complete.
-*/
-static void
-_pier_save_boot_complete(void* vod_p)
-{
- // no-op, callback required by u3_foil_append()
- //
-}
-
-/* _pier_save_boot(): save boot metadata.
-*/
-static void
-_pier_save_boot(u3_pier* pir_u, u3_atom mat)
-{
- // XX deduplicate with _pier_disk_commit_request
- //
- c3_d len_d = u3r_met(6, mat);
- c3_d* buf_d = c3_malloc(8 * len_d);
-
- u3r_chubs(0, len_d, buf_d, mat);
-
- u3_foil_append(_pier_save_boot_complete,
- (void*)0,
- pir_u->log_u->fol_u,
- buf_d,
- len_d);
-}
-
-/* _pier_work_boot(): prepare serf boot.
-*/
-static void
-_pier_work_boot(u3_pier* pir_u, c3_o sav_o)
-{
- u3_lord* god_u = pir_u->god_u;
-
- c3_assert( 0 != pir_u->lif_d );
-
- u3_noun who = u3i_chubs(2, pir_u->who_d);
- u3_noun len = u3i_chubs(1, &pir_u->lif_d);
- u3_noun msg = u3nq(c3__boot, who, pir_u->fak_o, len);
- u3_atom mat = u3ke_jam(msg);
-
- if ( c3y == sav_o ) {
- _pier_save_boot(pir_u, u3k(mat));
- }
-
- u3_newt_write(&god_u->inn_u, mat, 0);
+ u3l_log("disk error: %s\r\n", err_c);
}
/* _pier_disk_shutdown(): close the log.
@@ -145,60 +87,6 @@ _pier_disk_shutdown(u3_pier* pir_u)
{
}
-/* _pier_work_shutdown(): stop the worker process.
-*/
-static void
-_pier_work_shutdown(u3_pier* pir_u)
-{
- u3_lord* god_u = pir_u->god_u;
-
- u3_newt_write(&god_u->inn_u, u3ke_jam(u3nc(c3__exit, 0)), 0);
-}
-
-/* _pier_insert(): insert raw event.
-*/
-static void
-_pier_insert(u3_pier* pir_u,
- c3_l msc_l,
- u3_noun job)
-{
- u3_writ* wit_u = c3_calloc(sizeof(u3_writ));
- wit_u->pir_u = pir_u;
-
- wit_u->evt_d = pir_u->gen_d;
- pir_u->gen_d++;
-
- wit_u->msc_l = msc_l;
-
- wit_u->job = job;
-
- if ( !pir_u->ent_u ) {
- c3_assert(!pir_u->ext_u);
-
- pir_u->ent_u = pir_u->ext_u = wit_u;
- }
- else {
- pir_u->ent_u->nex_u = wit_u;
- pir_u->ent_u = wit_u;
- }
-}
-
-/* _pier_insert_ovum(): insert raw ovum.
-*/
-static void
-_pier_insert_ovum(u3_pier* pir_u,
- c3_l msc_l,
- u3_noun ovo)
-{
- u3_noun now;
- struct timeval tim_tv;
-
- gettimeofday(&tim_tv, 0);
- now = u3_time_in_tv(&tim_tv);
-
- _pier_insert(pir_u, msc_l, u3nc(now, ovo));
-}
-
/* _pier_disk_commit_complete(): commit complete.
*/
static void
@@ -209,7 +97,7 @@ _pier_disk_commit_complete(void* vod_p)
u3_disk* log_u = pir_u->log_u;
#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): commit: complete\r\n", wit_u->evt_d);
+ u3l_log("pier: (%" PRIu64 "): commit: complete\r\n", wit_u->evt_d);
#endif
/* advance commit counter
@@ -232,7 +120,7 @@ _pier_disk_commit_request(u3_writ* wit_u)
u3_disk* log_u = pir_u->log_u;
#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): commit: request\r\n", wit_u->evt_d);
+ u3l_log("pier: (%" PRIu64 "): commit: request\r\n", wit_u->evt_d);
#endif
/* append to logfile
@@ -257,388 +145,39 @@ _pier_disk_commit_request(u3_writ* wit_u)
}
}
-/* _pier_writ_unlink(): unlink writ from queue.
+/* _pier_disk_write_header_complete(): commit complete.
*/
static void
-_pier_writ_unlink(u3_writ* wit_u)
+_pier_disk_write_header_complete(void* vod_p)
{
- u3_pier* pir_u = wit_u->pir_u;
-
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): delete\r\n", wit_u->evt_d);
-#endif
-
- pir_u->ext_u = wit_u->nex_u;
-
- if ( wit_u == pir_u->ent_u ) {
- c3_assert(pir_u->ext_u == 0);
- pir_u->ent_u = 0;
- }
-}
-
-/* _pier_writ_dispose(): dispose of writ.
-*/
-static void
-_pier_writ_dispose(u3_writ* wit_u)
-{
- /* free contents
- */
- u3z(wit_u->job);
- u3z(wit_u->mat);
- u3z(wit_u->act);
-
- c3_free(wit_u);
-}
-
-/* _pier_work_release(): apply side effects.
-*/
-static void
-_pier_work_release(u3_writ* wit_u)
-{
- u3_pier* pir_u = wit_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
- u3_noun vir = wit_u->act;
-
- if ( u3_psat_pace == pir_u->sat_e ) {
- fputc('.', stderr);
- }
- else {
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): compute: release\r\n", wit_u->evt_d);
-#endif
-
- // advance release counter
- //
- {
- c3_assert(wit_u->evt_d == (1ULL + god_u->rel_d));
- god_u->rel_d += 1ULL;
- }
-
- // apply actions
- //
- while ( u3_nul != vir ) {
- u3_noun ovo, nex;
- u3x_cell(vir, &ovo, &nex);
-
- u3_reck_kick(pir_u, u3k(ovo));
- vir = nex;
- }
- }
-
- // if we have completed the boot sequence, activate system events.
+ // no-op, callback required by u3_foil_append()
//
- if ( wit_u->evt_d == pir_u->but_d ) {
- _pier_boot_complete(pir_u);
- }
+}
- // take snapshot, if requested (and awaiting the commit of this event)
+/* _pier_disk_write_header(): save boot metadata.
+*/
+static void
+_pier_disk_write_header(u3_pier* pir_u, u3_atom mat)
+{
+ // XX deduplicate with _pier_disk_commit_request
//
- {
- u3_save* sav_u = pir_u->sav_u;
-
- if ( (sav_u->req_d > sav_u->dun_d) &&
- (wit_u->evt_d == sav_u->req_d) )
- {
- _pier_work_save(pir_u);
- }
- }
-}
-
-/* _pier_work_build(): build atomic action.
-*/
-static void
-_pier_work_build(u3_writ* wit_u)
-{
- /* marshal into atom
- */
- if ( 0 == wit_u->mat ) {
- c3_assert(0 != wit_u->job);
-
- wit_u->mat = u3ke_jam(u3nq(c3__work,
- u3i_chubs(1, &wit_u->evt_d),
- wit_u->mug_l,
- u3k(wit_u->job)));
- }
-}
-
-/* _pier_work_send(): send to worker.
-*/
-static void
-_pier_work_send(u3_writ* wit_u)
-{
- u3_pier* pir_u = wit_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
-
- c3_assert(0 != wit_u->mat);
-
- u3_newt_write(&god_u->inn_u, u3k(wit_u->mat), wit_u);
-}
-
-/* _pier_work_save(): tell worker to save checkpoint.
-*/
-static void
-_pier_work_save(u3_pier* pir_u)
-{
- u3_lord* god_u = pir_u->god_u;
u3_disk* log_u = pir_u->log_u;
- u3_save* sav_u = pir_u->sav_u;
- c3_assert( god_u->dun_d == sav_u->req_d );
- c3_assert( log_u->com_d >= god_u->dun_d );
+ c3_assert( 0ULL == log_u->fol_u->end_d );
- {
- u3_noun mat = u3ke_jam(u3nc(c3__save, u3i_chubs(1, &god_u->dun_d)));
- u3_newt_write(&god_u->inn_u, mat, 0);
+ c3_d len_d = u3r_met(6, mat);
+ c3_d* buf_d = c3_malloc(8 * len_d);
- // XX wait on some report of success before updating?
- //
- sav_u->dun_d = sav_u->req_d;
- }
+ u3r_chubs(0, len_d, buf_d, mat);
- // if we're gracefully shutting down, do so now
- //
- if ( u3_psat_done == pir_u->sat_e ) {
- _pier_exit_done(pir_u);
- }
-}
-
-/* u3_pier_snap(): request snapshot
-*/
-void
-u3_pier_snap(u3_pier* pir_u)
-{
- u3_lord* god_u = pir_u->god_u;
- u3_disk* log_u = pir_u->log_u;
- u3_save* sav_u = pir_u->sav_u;
-
- c3_d top_d = c3_max(god_u->sen_d, god_u->dun_d);
-
- // no-op if there are no un-snapshot'ed events
- //
- if ( top_d > sav_u->dun_d ) {
- sav_u->req_d = top_d;
-
- // save eagerly if all computed events are already committed
- //
- if ( log_u->com_d >= top_d ) {
- _pier_work_save(pir_u);
- }
- }
- // if we're gracefully shutting down, do so now
- //
- else if ( u3_psat_done == pir_u->sat_e ) {
- _pier_exit_done(pir_u);
- }
-}
-
-/* _pier_work_complete(): worker reported completion.
-*/
-static void
-_pier_work_complete(u3_writ* wit_u,
- c3_l mug_l,
- u3_noun act)
-{
- u3_pier* pir_u = wit_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
-
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): compute: complete\r\n", wit_u->evt_d);
-#endif
-
- god_u->dun_d += 1;
- c3_assert(god_u->dun_d == wit_u->evt_d);
-
- god_u->mug_l = mug_l;
-
- c3_assert(wit_u->act == 0);
- wit_u->act = act;
-}
-
-/* _pier_work_replace(): worker reported replacement.
-*/
-static void
-_pier_work_replace(u3_writ* wit_u,
- u3_noun job,
- u3_noun mat)
-{
- u3_pier* pir_u = wit_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
-
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): compute: replace\r\n", wit_u->evt_d);
-#endif
-
- c3_assert(god_u->sen_d == wit_u->evt_d);
-
- /* move backward in work processing
- */
- {
- u3z(wit_u->job);
- wit_u->job = job;
-
- u3z(wit_u->mat);
- wit_u->mat = mat;
-
- god_u->sen_d -= 1;
- }
-}
-
-/* _pier_work_compute(): dispatch for processing.
-*/
-static void
-_pier_work_compute(u3_writ* wit_u)
-{
- u3_pier* pir_u = wit_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
-
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): compute: request\r\n", wit_u->evt_d);
-#endif
-
- c3_assert(wit_u->evt_d == (1 + god_u->sen_d));
-
- wit_u->mug_l = god_u->mug_l;
-
- _pier_work_build(wit_u);
- _pier_work_send(wit_u);
-
- god_u->sen_d += 1;
-}
-
-/* _pier_apply(): react to i/o, inbound or outbound.
-*/
-static void
-_pier_apply(u3_pier* pir_u)
-{
- u3_disk* log_u = pir_u->log_u;
- u3_lord* god_u = pir_u->god_u;
- u3_save* sav_u = pir_u->sav_u;
-
- if ( (0 == log_u) ||
- (0 == god_u) ||
- (c3n == god_u->liv_o) )
- {
- return;
- }
-
- u3_writ* wit_u;
- c3_o act_o = c3n;
-
-start:
-
- /* iterate from queue exit, advancing any writs that can advance
- */
- wit_u = pir_u->ext_u;
- while ( wit_u ) {
- /* if writ is (a) next in line to compute, (b) worker is inactive,
- ** and (c) a snapshot has not been requested, request computation
- */
- if ( (wit_u->evt_d == (1 + god_u->sen_d)) &&
- (god_u->sen_d == god_u->dun_d) &&
- (sav_u->dun_d == sav_u->req_d) )
- {
- _pier_work_compute(wit_u);
- act_o = c3y;
- }
-
- /* if writ is (a) computed and (b) next in line to commit,
- ** and (c) no commit is in progress and (d) we've booted,
- ** request commit.
- */
- if ( (wit_u->evt_d <= god_u->dun_d) &&
- (wit_u->evt_d == (1 + log_u->moc_d)) &&
- (wit_u->evt_d == (1 + log_u->com_d)) )
- {
- _pier_disk_commit_request(wit_u);
- act_o = c3y;
- }
-
- /* if writ is (a) committed and (b) computed,
- ** release effects and delete from queue
- */
- if ( (wit_u->evt_d <= log_u->com_d) &&
- (wit_u->evt_d <= god_u->dun_d) )
- {
- // effects must be released in order
- //
- c3_assert(wit_u == pir_u->ext_u);
-
- // remove from queue
- //
- // XX must be done before releasing effects
- // which is currently reentrant
- //
- _pier_writ_unlink(wit_u);
-
- // release effects
- //
- _pier_work_release(wit_u);
-
- // free writ
- //
- _pier_writ_dispose(wit_u);
-
- wit_u = pir_u->ext_u;
- act_o = c3y;
- }
- else {
- /* otherwise, continue backward
- */
- wit_u = wit_u->nex_u;
- }
- }
-
- /* if we did anything to the queue, make another pass.
- */
- if ( c3y == act_o ) {
- act_o = c3n;
- goto start;
- }
-}
-
-/* _pier_set_ship():
-*/
-static void
-_pier_set_ship(u3_pier* pir_u, u3_noun who, u3_noun fak)
-{
- c3_assert( c3y == u3ud(who) );
- c3_assert( (c3y == fak) || (c3n == fak) );
-
- c3_o fak_o = fak;
- c3_d who_d[2];
-
- u3r_chubs(0, 2, who_d, who);
-
- c3_assert( ( (0 == pir_u->fak_o) &&
- (0 == pir_u->who_d[0]) &&
- (0 == pir_u->who_d[1]) ) ||
- ( (fak_o == pir_u->fak_o) &&
- (who_d[0] == pir_u->who_d[0]) &&
- (who_d[1] == pir_u->who_d[1]) ) );
-
- pir_u->fak_o = fak_o;
- pir_u->who_d[0] = who_d[0];
- pir_u->who_d[1] = who_d[1];
-
- {
- u3_noun how = u3dc("scot", 'p', u3k(who));
-
- c3_free(pir_u->who_c);
- pir_u->who_c = u3r_string(how);
- u3z(how);
- }
-
- // Disable networking for fake ships
- //
- if ( c3y == pir_u->fak_o ) {
- u3_Host.ops_u.net = c3n;
- }
-
- u3z(who); u3z(fak);
+ u3_foil_append(_pier_disk_write_header_complete,
+ (void*)0,
+ log_u->fol_u,
+ buf_d,
+ len_d);
}
/* _pier_disk_read_header_complete():
-** XX async
*/
static void
_pier_disk_read_header_complete(u3_disk* log_u, u3_noun dat)
@@ -657,7 +196,7 @@ _pier_disk_read_header_complete(u3_disk* log_u, u3_noun dat)
c3_assert( c3y == u3ud(len) );
c3_assert( 1 >= u3r_met(3, len) );
- _pier_set_ship(pir_u, u3k(who), u3k(fak));
+ _pier_boot_set_ship(pir_u, u3k(who), u3k(fak));
pir_u->lif_d = u3r_chub(0, len);
}
@@ -666,18 +205,40 @@ _pier_disk_read_header_complete(u3_disk* log_u, u3_noun dat)
}
/* _pier_disk_read_header():
-** XX async
-** XX very slow
*/
static void
_pier_disk_read_header(u3_disk* log_u)
{
+ // XX disabled
+ //
+ // This is very, very slow.
+ // The one situation in which we currently *need* it -
+ // full log replay - it's unnecessary thanks to the current
+ // _pier_disk_load_commit.
+ // In all other situations, we're covered by
+ // _pier_work_play or u3_pier_boot.
+ // In the long run, it seems best to always get identity
+ // from the log for restart/replay.
+ //
+#if 0
c3_assert( 0 != log_u->fol_u );
c3_d pos_d = log_u->fol_u->end_d;
c3_o got_o = c3n;
- c3_assert( 0ULL != pos_d );
+ // XX requires that writs be unlinked before effects are released
+ //
+ if ( (0 == pir_u->ent_u) &&
+ (wit_u->evt_d < log_u->com_d) )
+ {
+ _pier_disk_load_commit(pir_u, (1ULL + god_u->dun_d), 1000ULL);
+ }
+ }
+ }
+ else {
+#ifdef VERBOSE_EVENTS
+ u3l_log("pier: (%" PRIu64 "): compute: release\r\n", wit_u->evt_d);
+#endif
while ( pos_d ) {
c3_d len_d, evt_d;
@@ -704,425 +265,127 @@ _pier_disk_read_header(u3_disk* log_u)
c3_free(buf_d);
}
+#endif
}
-/* _pier_disk_load_commit(): load all commits >= evt_d; set ent_u, ext_u.
-** XX async
+/* _pier_disk_load_commit(): load len_d commits >= lav_d; enqueue for replay
*/
-static c3_o
+static void
_pier_disk_load_commit(u3_pier* pir_u,
- c3_d lav_d)
-
+ c3_d lav_d,
+ c3_d len_d)
{
u3_disk* log_u = pir_u->log_u;
- if ( !log_u->fol_u ) {
- return c3n;
- }
- else {
- c3_d pos_d = log_u->fol_u->end_d;
- c3_d old_d = 0;
+ c3_d max_d = lav_d + len_d;
+ c3_d pos_d = log_u->fol_u->end_d;
+ c3_d old_d = 0;
+
+ c3_assert ( 0 != log_u->fol_u );
#ifdef VERBOSE_EVENTS
fprintf(stderr, "pier: load: commit: at %" PRIx64 "\r\n", pos_d);
#endif
- while ( pos_d ) {
- c3_d len_d, evt_d;
- c3_d* buf_d;
- u3_noun mat, ovo, job, evt;
+ while ( pos_d ) {
+ c3_d len_d, evt_d;
+ c3_d* buf_d;
+ u3_noun mat, ovo, job, evt;
- buf_d = u3_foil_reveal(log_u->fol_u, &pos_d, &len_d);
- if ( !buf_d ) {
- _pier_disk_bail(0, "load: commit: corrupt");
- return c3n;
- }
+ buf_d = u3_foil_reveal(log_u->fol_u, &pos_d, &len_d);
- mat = u3i_chubs(len_d, buf_d);
- c3_free(buf_d);
+ if ( !buf_d ) {
+ _pier_disk_bail(0, "pier: load: commit: corrupt");
+ return;
+ }
- ovo = u3ke_cue(u3k(mat));
+ mat = u3i_chubs(len_d, buf_d);
+ c3_free(buf_d);
- // reached header
- //
- if ( 0ULL == pos_d ) {
- c3_assert( 1ULL == lav_d );
- c3_assert( c3__boot == u3h(ovo) );
+ ovo = u3ke_cue(u3k(mat));
- _pier_disk_read_header_complete(log_u, u3k(u3t(ovo)));
+ // reached header
+ //
+ if ( 0ULL == pos_d ) {
+ c3_assert( 1ULL == lav_d );
+ c3_assert( c3__boot == u3h(ovo) );
- u3z(ovo); u3z(mat);
- break;
- }
+ _pier_disk_read_header_complete(log_u, u3k(u3t(ovo)));
- c3_assert(c3__work == u3h(ovo));
- evt = u3h(u3t(ovo));
- job = u3k(u3t(u3t(u3t(ovo))));
- evt_d = u3r_chub(0, evt);
- u3z(ovo);
+ u3z(ovo); u3z(mat);
+ break;
+ }
- // confirm event order
- //
- if ( (0 != old_d) &&
- ((old_d - 1ULL) != evt_d) ) {
- fprintf(stderr, "pier: load: event order\r\n");
- return c3n;
- }
- else {
- old_d = evt_d;
- }
+ c3_assert(c3__work == u3h(ovo));
+ evt = u3h(u3t(ovo));
+ job = u3k(u3t(u3t(u3t(ovo))));
+ evt_d = u3r_chub(0, evt);
+ u3z(ovo);
- if ( evt_d < lav_d ) {
- u3z(mat);
- u3z(job);
+ // confirm event order
+ //
+ if ( (0 != old_d) &&
+ ((old_d - 1ULL) != evt_d) ) {
+ _pier_disk_bail(0, "pier: load: commit: event order");
+ return;
+ }
+ else {
+ old_d = evt_d;
+ }
- return c3y;
- }
- else {
- u3_writ* wit_u = c3_calloc(sizeof(u3_writ));
+ // done: read past the first event requested
+ //
+ if ( evt_d < lav_d ) {
+ u3z(mat);
+ u3z(job);
+ return;
+ }
+ // skip: haven't reached the last event requested
+ //
+ else if ( evt_d > max_d ) {
+ u3z(mat);
+ u3z(job);
+ continue;
+ }
+ // enqueue requested event
+ //
+ else {
+ u3_writ* wit_u = c3_calloc(sizeof(u3_writ));
#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: load: commit: %" PRIu64 "\r\n", evt_d);
+ fprintf(stderr, "pier: load: commit: %" PRIu64 "\r\n", evt_d);
#endif
- wit_u->pir_u = pir_u;
- wit_u->evt_d = evt_d;
- wit_u->job = job;
- wit_u->mat = mat;
+ wit_u->pir_u = pir_u;
+ wit_u->evt_d = evt_d;
+ wit_u->job = job;
+ wit_u->mat = mat;
- /* insert at queue exit -- the oldest events run first
- */
- if ( !pir_u->ent_u && !pir_u->ext_u ) {
- pir_u->ent_u = pir_u->ext_u = wit_u;
- }
- else {
- if ( (1ULL + wit_u->evt_d) != pir_u->ext_u->evt_d ) {
- fprintf(stderr, "pier: load: commit: event gap: %" PRIx64 ", %"
- PRIx64 "\r\n",
- wit_u->evt_d,
- pir_u->ext_u->evt_d);
- u3z(mat);
- u3z(job);
- return c3n;
- }
- wit_u->nex_u = pir_u->ext_u;
- pir_u->ext_u = wit_u;
+ /* insert at queue exit -- the oldest events run first
+ */
+ if ( !pir_u->ent_u && !pir_u->ext_u ) {
+ pir_u->ent_u = pir_u->ext_u = wit_u;
+ }
+ else {
+ if ( (1ULL + wit_u->evt_d) != pir_u->ext_u->evt_d ) {
+ fprintf(stderr, "pier: load: commit: event gap: %" PRIx64 ", %"
+ PRIx64 "\r\n",
+ wit_u->evt_d,
+ pir_u->ext_u->evt_d);
+ u3z(mat);
+ u3z(job);
+ _pier_disk_bail(0, "pier: load: comit: event gap");
+ return;
}
+
+ wit_u->nex_u = pir_u->ext_u;
+ pir_u->ext_u = wit_u;
}
}
- return c3y;
- }
-}
-
-/* _pier_boot_vent(): create and enqueue boot sequence
-**
-** per cgy:
-** this new boot sequence is almost, but not quite,
-** the right thing. see new arvo.
-*/
-static void
-_pier_boot_vent(u3_pier* pir_u)
-{
- // bot: boot formulas
- // mod: module ova
- // use: userpace ova
- //
- u3_noun bot, mod, use;
-
- // extract boot formulas and module/userspace ova from pill
- //
- {
- u3_noun pil_p, pil_q, pil_r;
- u3_noun pro;
-
- c3_assert( c3y == u3du(pir_u->pil) );
-
- if ( c3y == u3h(pir_u->pil) ) {
- u3x_trel(pir_u->pil, 0, &pil_p, &pil_q);
- }
- else {
- u3x_qual(pir_u->pil, 0, &pil_p, &pil_q, &pil_r);
- }
-
- pro = u3m_soft(0, u3ke_cue, u3k(pil_p));
-
- if ( 0 != u3h(pro) ) {
- fprintf(stderr, "boot: failed: unable to parse pill\r\n");
- exit(1);
- }
-
- u3x_trel(u3t(pro), &bot, &mod, &use);
- u3k(bot); u3k(mod); u3k(use);
-
- // optionally replace filesystem in userspace
- //
- if ( c3y == u3h(pir_u->pil) ) {
- if ( u3_nul != pil_q ) {
- c3_w len_w = 0;
- u3_noun ova = use;
- u3_noun new = u3_nul;
- u3_noun ovo;
-
- while ( u3_nul != ova ) {
- ovo = u3h(ova);
-
- if ( c3__into == u3h(u3t(ovo)) ) {
- c3_assert( 0 == len_w );
- len_w++;
- ovo = u3k(u3t(pil_q));
- }
-
- new = u3nc(u3k(ovo), new);
- ova = u3t(ova);
- }
-
- c3_assert( 1 == len_w );
-
- u3z(use);
- use = u3kb_flop(new);
- }
- }
- // prepend %lite module and userspace ova
- //
- else {
- mod = u3kb_weld(u3k(pil_q), mod);
- use = u3kb_weld(u3k(pil_r), use);
- }
-
- u3z(pro);
- u3z(pir_u->pil);
- pir_u->pil = u3_nul;
- }
-
- // prepend entropy to the module sequence
- //
- // XX also copy to _pier_loop_wake?
- //
- {
- c3_w eny_w[16];
- c3_rand(eny_w);
-
- u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
- u3_noun car = u3nc(c3__wack, u3i_words(16, eny_w));
-
- mod = u3nc(u3nc(wir, car), mod);
- }
-
- // prepend identity to the module sequence, setting single-home
- //
- {
- u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
- u3_noun car = u3nc(c3__whom, u3i_chubs(2, pir_u->who_d));
-
- mod = u3nc(u3nc(wir, car), mod);
- }
-
- // insert boot sequence directly
- //
- // Note that these are not ovum or (pair @da ovum) events,
- // but raw nock formulas to be directly evaluated as the
- // subject of the lifecycle formula [%2 [%0 3] %0 2].
- // All subsequent events will be (pair @da ovum).
- //
- {
- u3_noun fol = bot;
-
- // initialize the boot barrier
- //
- // And the initial lifecycle boot barrier.
- //
- pir_u->but_d = u3kb_lent(u3k(fol));
- pir_u->lif_d = pir_u->but_d;
-
- while ( u3_nul != fol ) {
- _pier_insert(pir_u, 0, u3k(u3h(fol)));
- fol = u3t(fol);
- }
- }
-
- // prepare serf for boot sequence
- //
- {
- fprintf(stderr, "boot: ship: %s%s\r\n",
- pir_u->who_c,
- (c3y == pir_u->fak_o) ? " (fake)" : "");
-
- _pier_work_boot(pir_u, c3y);
- }
-
- // insert module events
- //
- {
- u3_noun ova = mod;
- // add to the boot barrier
- //
- pir_u->but_d += u3kb_lent(u3k(ova));
-
- while ( u3_nul != ova ) {
- _pier_insert_ovum(pir_u, 0, u3k(u3h(ova)));
- ova = u3t(ova);
- }
- }
-
- // XX moar boot sequence woes
- //
- // some i/o must be initialized before legacy boot
- //
- {
- // partially duplicates _pier_loop_wake()
- //
- c3_l cod_l;
-
- cod_l = u3a_lush(c3__ames);
- {
- // stash domain for fake effect
- //
- // XX this is horrible
- //
- u3_noun tuf = ( c3__fake == u3h(pir_u->bot) ) ? u3_nul :
- u3h(u3t(u3t(u3t(u3t(pir_u->bot)))));
-
-
- // send a fake effect to bring up listeners and configure domains
- //
- // XX horrible hack
- //
- u3_ames_ef_turf(pir_u, u3k(tuf));
- }
-
- u3_ames_ef_bake(pir_u);
- u3a_lop(cod_l);
- }
-
- // insert legacy boot event
- //
- {
- // XX do something about this wire
- // XX route directly to %jael?
- //
- c3_assert( c3y == u3du(pir_u->bot) );
-
- u3_noun wir = u3nq(u3_blip, c3__term, '1', u3_nul);
- u3_noun car = u3nc(c3__boot, pir_u->bot);
- u3_noun ovo = u3nc(wir, car);
-
- _pier_insert_ovum(pir_u, 0, ovo);
-
- pir_u->bot = u3_nul;
- }
-
- // insert userspace events
- //
- // Currently just the initial filesystem
- //
- {
- u3_noun ova = use;
-
- while ( u3_nul != ova ) {
- _pier_insert_ovum(pir_u, 0, u3k(u3h(ova)));
- ova = u3t(ova);
- }
- }
-
- u3z(bot); u3z(mod); u3z(use);
-}
-
-/* _pier_boot_ready():
-*/
-static void
-_pier_boot_ready(u3_pier* pir_u)
-{
- u3_lord* god_u = pir_u->god_u;
- u3_disk* log_u = pir_u->log_u;
-
- c3_assert( c3y == god_u->liv_o );
- c3_assert( c3y == log_u->liv_o );
- c3_assert( u3_psat_init == pir_u->sat_e );
- c3_assert( c3n == pir_u->liv_o );
- pir_u->liv_o = c3y;
-
- // mark all commits as released
- //
- god_u->rel_d = log_u->com_d;
-
- // set next expected event number
- //
- pir_u->gen_d = (1ULL + log_u->com_d);
-
- // boot
- //
- if ( 0 == log_u->com_d ) {
- pir_u->sat_e = u3_psat_boot;
-
- fprintf(stderr, "boot: ship: %s%s\r\n",
- pir_u->who_c,
- (c3y == pir_u->fak_o) ? " (fake)" : "");
-
- // construct/enqueue boot sequence
- //
- _pier_boot_vent(pir_u);
-
- // prepare serf for boot sequence, write log header
- //
- // XX move here from _pier_boot_vent, confirm lif_d is set
- //
- // _pier_work_boot(pir_u, c3y);
- }
- // replay
- //
- else if ( god_u->dun_d < log_u->com_d) {
- pir_u->sat_e = u3_psat_pace;
-
- fprintf(stderr, "---------------- playback starting----------------\r\n");
-
- // set the boot barrier to the last committed event
- //
- pir_u->but_d = log_u->com_d;
-
- if ( 0 == god_u->dun_d ) {
- fprintf(stderr, "pier: replaying events 1 through %" PRIu64 "\r\n",
- log_u->com_d);
-
- // restore pier identity
- //
- // XX currently very slow
- // technically unnecessary due to the current _pier_disk_load_commit
- // could be removed if _pier_disk_load_commit were moved before block
- //
- _pier_disk_read_header(pir_u->log_u);
-
- // prepare serf for replay of boot sequence, don't write log header
- //
- _pier_work_boot(pir_u, c3n);
- }
- else {
- fprintf(stderr, "pier: replaying events %" PRIu64
- " through %" PRIu64 "\r\n",
- god_u->dun_d,
- log_u->com_d);
- }
-
- // begin queuing batches of committed events
- //
- // XX batch, async
- //
- _pier_disk_load_commit(pir_u, (1ULL + god_u->dun_d));
- }
- // resume
- //
- else {
- // set the boot barrier to the last computed event
- //
- pir_u->but_d = god_u->dun_d;
-
- // resume normal operation
- //
- _pier_boot_complete(pir_u);
}
}
/* _pier_disk_init_complete():
-** XX async
*/
static void
_pier_disk_init_complete(u3_disk* log_u, c3_d evt_d)
@@ -1132,20 +395,14 @@ _pier_disk_init_complete(u3_disk* log_u, c3_d evt_d)
log_u->com_d = log_u->moc_d = evt_d;
- {
- u3_pier* pir_u = log_u->pir_u;
- u3_lord* god_u = pir_u->god_u;
+ // restore pier identity (XX currently a no-op, see comment)
+ //
+ _pier_disk_read_header(log_u);
- if ( (0 != god_u) &&
- (c3y == god_u->liv_o) &&
- (c3n == pir_u->liv_o) ) {
- _pier_boot_ready(pir_u);
- }
- }
+ _pier_boot_ready(log_u->pir_u);
}
/* _pier_disk_init():
-** XX async
*/
static c3_o
_pier_disk_init(u3_disk* log_u)
@@ -1276,58 +533,54 @@ _pier_disk_create(u3_pier* pir_u)
return c3y;
}
-/* _pier_work_play(): with active worker, create or load log.
+/* _pier_writ_insert(): insert raw event.
*/
static void
-_pier_work_play(u3_pier* pir_u,
- c3_d lav_d,
- c3_l mug_l)
+_pier_writ_insert(u3_pier* pir_u,
+ c3_l msc_l,
+ u3_noun job)
{
- u3_lord* god_u = pir_u->god_u;
+ u3_writ* wit_u = c3_calloc(sizeof(u3_writ));
+ wit_u->pir_u = pir_u;
-#ifdef VERBOSE_EVENTS
- fprintf(stderr, "pier: (%" PRIu64 "): boot at mug %x\r\n", lav_d, mug_l);
-#endif
+ wit_u->evt_d = pir_u->gen_d;
+ pir_u->gen_d++;
- c3_assert( c3n == god_u->liv_o );
- god_u->liv_o = c3y;
+ wit_u->msc_l = msc_l;
- // all events in the serf are complete
- //
- god_u->rel_d = god_u->dun_d = god_u->sen_d = (lav_d - 1ULL);
+ wit_u->job = job;
- {
- u3_disk* log_u = pir_u->log_u;
+ if ( !pir_u->ent_u ) {
+ c3_assert(!pir_u->ext_u);
- if ( (0 != log_u) &&
- (c3y == log_u->liv_o) &&
- (c3n == pir_u->liv_o) ) {
- _pier_boot_ready(pir_u);
- }
+ pir_u->ent_u = pir_u->ext_u = wit_u;
+ }
+ else {
+ pir_u->ent_u->nex_u = wit_u;
+ pir_u->ent_u = wit_u;
}
}
-/* _pier_work_exit(): handle subprocess exit.
+/* _pier_writ_insert_ovum(): insert raw ovum - for boot sequence.
*/
static void
-_pier_work_exit(uv_process_t* req_u,
- c3_ds sas_i,
- c3_i sig_i)
+_pier_writ_insert_ovum(u3_pier* pir_u,
+ c3_l msc_l,
+ u3_noun ovo)
{
- u3_lord* god_u = (void *) req_u;
- u3_pier* pir_u = god_u->pir_u;
+ u3_noun now;
+ struct timeval tim_tv;
- fprintf(stderr, "pier: exit: status %" PRIu64 ", signal %d\r\n", sas_i, sig_i);
- uv_close((uv_handle_t*) req_u, 0);
+ gettimeofday(&tim_tv, 0);
+ now = u3_time_in_tv(&tim_tv);
- _pier_disk_shutdown(pir_u);
- _pier_work_shutdown(pir_u);
+ _pier_writ_insert(pir_u, msc_l, u3nc(now, ovo));
}
-/* _pier_work_writ(): find writ by event number.
+/* _pier_writ_find(): find writ by event number.
*/
static u3_writ*
-_pier_work_writ(u3_pier* pir_u,
+_pier_writ_find(u3_pier* pir_u,
c3_d evt_d)
{
u3_writ* wit_u;
@@ -1342,6 +595,390 @@ _pier_work_writ(u3_pier* pir_u,
return 0;
}
+/* _pier_writ_unlink(): unlink writ from queue.
+*/
+static void
+_pier_writ_unlink(u3_writ* wit_u)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): delete\r\n", wit_u->evt_d);
+#endif
+
+ pir_u->ext_u = wit_u->nex_u;
+
+ if ( wit_u == pir_u->ent_u ) {
+ c3_assert(pir_u->ext_u == 0);
+ pir_u->ent_u = 0;
+ }
+}
+
+/* _pier_writ_dispose(): dispose of writ.
+*/
+static void
+_pier_writ_dispose(u3_writ* wit_u)
+{
+ /* free contents
+ */
+ u3z(wit_u->job);
+ u3z(wit_u->mat);
+ u3z(wit_u->act);
+
+ c3_free(wit_u);
+}
+
+/* _pier_work_bail(): handle subprocess error.
+*/
+static void
+_pier_work_bail(void* vod_p,
+ const c3_c* err_c)
+{
+ fprintf(stderr, "pier: work error: %s\r\n", err_c);
+}
+
+/* _pier_work_boot(): prepare serf boot.
+*/
+static void
+_pier_work_boot(u3_pier* pir_u, c3_o sav_o)
+{
+ u3_controller* god_u = pir_u->god_u;
+
+ c3_assert( 0 != pir_u->lif_d );
+
+ u3_noun who = u3i_chubs(2, pir_u->who_d);
+ u3_noun len = u3i_chubs(1, &pir_u->lif_d);
+ u3_noun msg = u3nq(c3__boot, who, pir_u->fak_o, len);
+ u3_atom mat = u3ke_jam(msg);
+
+ if ( c3y == sav_o ) {
+ _pier_disk_write_header(pir_u, u3k(mat));
+ }
+
+ u3_newt_write(&god_u->inn_u, mat, 0);
+}
+
+/* _pier_work_shutdown(): stop the worker process.
+*/
+static void
+_pier_work_shutdown(u3_pier* pir_u)
+{
+ u3_controller* god_u = pir_u->god_u;
+
+ u3_newt_write(&god_u->inn_u, u3ke_jam(u3nc(c3__exit, 0)), 0);
+}
+
+/* _pier_work_build(): build atomic action.
+*/
+static void
+_pier_work_build(u3_writ* wit_u)
+{
+ /* marshal into atom
+ */
+ if ( 0 == wit_u->mat ) {
+ c3_assert(0 != wit_u->job);
+
+ wit_u->mat = u3ke_jam(u3nq(c3__work,
+ u3i_chubs(1, &wit_u->evt_d),
+ wit_u->mug_l,
+ u3k(wit_u->job)));
+ }
+}
+
+/* _pier_work_send(): send to worker.
+*/
+static void
+_pier_work_send(u3_writ* wit_u)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+ u3_controller* god_u = pir_u->god_u;
+
+ c3_assert(0 != wit_u->mat);
+
+ u3_newt_write(&god_u->inn_u, u3k(wit_u->mat), wit_u);
+}
+
+/* _pier_work_save(): tell worker to save checkpoint.
+*/
+static void
+_pier_work_save(u3_pier* pir_u)
+{
+ u3_controller* god_u = pir_u->god_u;
+ u3_disk* log_u = pir_u->log_u;
+ u3_save* sav_u = pir_u->sav_u;
+
+ c3_assert( god_u->dun_d == sav_u->req_d );
+ c3_assert( log_u->com_d >= god_u->dun_d );
+
+ {
+ u3_noun mat = u3ke_jam(u3nc(c3__save, u3i_chubs(1, &god_u->dun_d)));
+ u3_newt_write(&god_u->inn_u, mat, 0);
+
+ // XX wait on some report of success before updating?
+ //
+ sav_u->dun_d = sav_u->req_d;
+ }
+
+ // if we're gracefully shutting down, do so now
+ //
+ if ( u3_psat_done == pir_u->sat_e ) {
+ _pier_exit_done(pir_u);
+ }
+}
+
+/* _pier_work_release(): apply side effects.
+*/
+static void
+_pier_work_release(u3_writ* wit_u)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+ u3_controller* god_u = pir_u->god_u;
+ u3_noun vir = wit_u->act;
+
+ if ( u3_psat_pace == pir_u->sat_e ) {
+ fputc('.', stderr);
+
+ // enqueue another batch of events for replay
+ //
+ {
+ u3_disk* log_u = pir_u->log_u;
+
+ // XX requires that writs be unlinked before effects are released
+ //
+ if ( (0 == pir_u->ent_u) &&
+ (wit_u->evt_d < log_u->com_d) )
+ {
+ _pier_disk_load_commit(pir_u, (1ULL + god_u->dun_d), 1000ULL);
+ }
+ }
+ }
+ else {
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): compute: release\r\n", wit_u->evt_d);
+#endif
+
+ // advance release counter
+ //
+ {
+ c3_assert(wit_u->evt_d == (1ULL + god_u->rel_d));
+ god_u->rel_d += 1ULL;
+ }
+
+ // apply actions
+ //
+ while ( u3_nul != vir ) {
+ u3_noun ovo, nex;
+ u3x_cell(vir, &ovo, &nex);
+
+ u3_reck_kick(pir_u, u3k(ovo));
+ vir = nex;
+ }
+ }
+
+ // if we have completed the boot sequence, activate system events.
+ //
+ if ( wit_u->evt_d == pir_u->but_d ) {
+ _pier_boot_complete(pir_u);
+ }
+
+ // take snapshot, if requested (and awaiting the commit of this event)
+ //
+ {
+ u3_save* sav_u = pir_u->sav_u;
+
+ if ( (sav_u->req_d > sav_u->dun_d) &&
+ (wit_u->evt_d == sav_u->req_d) )
+ {
+ _pier_work_save(pir_u);
+ }
+ }
+}
+
+/* _pier_work_complete(): worker reported completion.
+*/
+static void
+_pier_work_complete(u3_writ* wit_u,
+ c3_l mug_l,
+ u3_noun act)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+ u3_controller* god_u = pir_u->god_u;
+
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): compute: complete\r\n", wit_u->evt_d);
+#endif
+
+ god_u->dun_d += 1;
+ c3_assert(god_u->dun_d == wit_u->evt_d);
+
+ god_u->mug_l = mug_l;
+
+ c3_assert(wit_u->act == 0);
+ wit_u->act = act;
+
+ if ( wit_u->evt_d > pir_u->lif_d ) {
+ u3_term_stop_spinner();
+ }
+}
+
+/* _pier_work_replace(): worker reported replacement.
+*/
+static void
+_pier_work_replace(u3_writ* wit_u,
+ u3_noun job,
+ u3_noun mat)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+ u3_controller* god_u = pir_u->god_u;
+
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): compute: replace\r\n", wit_u->evt_d);
+#endif
+
+ c3_assert(god_u->sen_d == wit_u->evt_d);
+
+ /* move backward in work processing
+ */
+ {
+ u3z(wit_u->job);
+ wit_u->job = job;
+
+ u3z(wit_u->mat);
+ wit_u->mat = mat;
+
+ god_u->sen_d -= 1;
+ }
+
+ if ( wit_u->evt_d > pir_u->lif_d ) {
+ u3_term_stop_spinner();
+ }
+}
+
+/* _pier_work_compute(): dispatch for processing.
+*/
+static void
+_pier_work_compute(u3_writ* wit_u)
+{
+ u3_pier* pir_u = wit_u->pir_u;
+ u3_controller* god_u = pir_u->god_u;
+
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): compute: request\r\n", wit_u->evt_d);
+#endif
+
+ c3_assert(wit_u->evt_d == (1 + god_u->sen_d));
+
+ wit_u->mug_l = god_u->mug_l;
+
+ _pier_work_build(wit_u);
+ _pier_work_send(wit_u);
+
+ god_u->sen_d += 1;
+
+ if ( wit_u->evt_d > pir_u->lif_d ) {
+ u3_term_start_spinner(wit_u->job);
+ }
+}
+
+/* _pier_work_play(): with active worker, create or load log.
+*/
+static void
+_pier_work_play(u3_pier* pir_u,
+ c3_d lav_d,
+ c3_l mug_l)
+{
+ u3_controller* god_u = pir_u->god_u;
+
+#ifdef VERBOSE_EVENTS
+ fprintf(stderr, "pier: (%" PRIu64 "): boot at mug %x\r\n", lav_d, mug_l);
+#endif
+
+ c3_assert( c3n == god_u->liv_o );
+ god_u->liv_o = c3y;
+
+ // all events in the serf are complete
+ //
+ god_u->rel_d = god_u->dun_d = god_u->sen_d = (lav_d - 1ULL);
+
+ _pier_boot_ready(pir_u);
+}
+
+/* _pier_work_stdr(): prints an error message to stderr
+ */
+static void
+_pier_work_stdr(u3_writ* wit_u, u3_noun cord)
+{
+ c3_c* str = u3r_string(cord);
+ u3C.stderr_log_f(str);
+ free(str);
+}
+
+/* _pier_work_slog(): print directly.
+*/
+static void
+_pier_work_slog(u3_writ* wit_u, c3_w pri_w, u3_noun tan)
+{
+#ifdef U3_EVENT_TIME_DEBUG
+ {
+ static int old;
+ static struct timeval b4, f2, d0;
+ static c3_d b4_d;
+ c3_w ms_w;
+
+ if ( old ) {
+ gettimeofday(&f2, 0);
+ timersub(&f2, &b4, &d0);
+ ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
+ if (ms_w > 1) {
+ #if 0
+ fprintf(stderr, "%6d.%02dms: %9d ",
+ ms_w, (int) (d0.tv_usec % 1000) / 10,
+ ((int) (u3R->pro.nox_d - b4_d)));
+ #else
+ fprintf(stderr, "%6d.%02dms ",
+ ms_w, (int) (d0.tv_usec % 1000) / 10);
+ #endif
+ gettimeofday(&b4, 0);
+ b4_d = u3R->pro.nox_d;
+ }
+ else {
+ fprintf(stderr, " ");
+ }
+ }
+ else {
+ gettimeofday(&b4, 0);
+ b4_d = u3R->pro.nox_d;
+ }
+ old = 1;
+ }
+#endif
+
+ switch ( pri_w ) {
+ case 3: fprintf(stderr, ">>> "); break;
+ case 2: fprintf(stderr, ">> "); break;
+ case 1: fprintf(stderr, "> "); break;
+ }
+
+ u3_pier_tank(0, tan);
+}
+
+/* _pier_work_exit(): handle subprocess exit.
+*/
+static void
+_pier_work_exit(uv_process_t* req_u,
+ c3_ds sas_i,
+ c3_i sig_i)
+{
+ u3_controller* god_u = (void *) req_u;
+ u3_pier* pir_u = god_u->pir_u;
+
+ u3l_log("pier: exit: status %" PRIu64 ", signal %d\r\n", sas_i, sig_i);
+ uv_close((uv_handle_t*) req_u, 0);
+
+ _pier_disk_shutdown(pir_u);
+ _pier_work_shutdown(pir_u);
+}
+
/* _pier_work_poke(): handle subprocess result. transfer nouns.
*/
static void
@@ -1391,7 +1028,7 @@ _pier_work_poke(void* vod_p,
// single-home
//
- _pier_set_ship(pir_u, u3k(u3h(r_jar)), u3k(u3t(r_jar)));
+ _pier_boot_set_ship(pir_u, u3k(u3h(r_jar)), u3k(u3t(r_jar)));
}
_pier_work_play(pir_u, lav_d, mug_l);
@@ -1410,7 +1047,7 @@ _pier_work_poke(void* vod_p,
else {
c3_d evt_d = u3r_chub(0, p_jar);
c3_l mug_l = u3r_word(0, q_jar);
- u3_writ* wit_u = _pier_work_writ(pir_u, evt_d);
+ u3_writ* wit_u = _pier_writ_find(pir_u, evt_d);
if ( !wit_u || (mug_l && (mug_l != wit_u->mug_l)) ) {
goto error;
@@ -1418,15 +1055,18 @@ _pier_work_poke(void* vod_p,
{
// XX not the right place to print an error!
//
+#if 0
u3m_p("wire", u3h(u3t(r_jar)));
u3m_p("oust", u3h(u3t(u3t(wit_u->job))));
u3m_p("with", u3h(u3t(u3t(r_jar))));
if ( c3__crud == u3h(u3t(u3t(r_jar))) ) {
u3_pier_punt(0, u3k(u3t(u3t(u3t(u3t(r_jar))))));
}
-
+#endif
}
+#ifdef VERBOSE_EVENTS
fprintf(stderr, "pier: replace: %" PRIu64 "\r\n", evt_d);
+#endif
_pier_work_replace(wit_u, u3k(r_jar), u3k(mat));
}
@@ -1445,16 +1085,52 @@ _pier_work_poke(void* vod_p,
else {
c3_d evt_d = u3r_chub(0, p_jar);
c3_l mug_l = u3r_word(0, q_jar);
- u3_writ* wit_u = _pier_work_writ(pir_u, evt_d);
+ u3_writ* wit_u = _pier_writ_find(pir_u, evt_d);
if ( !wit_u ) {
- fprintf(stderr, "poke: no writ: %" PRIu64 "\r\n", evt_d);
+ u3l_log("poke: no writ: %" PRIu64 "\r\n", evt_d);
goto error;
}
_pier_work_complete(wit_u, mug_l, u3k(r_jar));
}
break;
}
+
+ case c3__stdr: {
+ if ( (c3n == u3r_trel(jar, 0, &p_jar, &q_jar)) ||
+ (c3n == u3ud(p_jar)) ||
+ (u3r_met(6, p_jar) > 1) ||
+ (c3n == u3ud(q_jar)) )
+ {
+ goto error;
+ }
+ else {
+ c3_d evt_d = u3r_chub(0, p_jar);
+ u3_writ* wit_u = _pier_writ_find(pir_u, evt_d);
+
+ _pier_work_stdr(wit_u, q_jar);
+ }
+ break;
+ }
+
+ case c3__slog: {
+ if ( (c3n == u3r_qual(jar, 0, &p_jar, &q_jar, &r_jar)) ||
+ (c3n == u3ud(p_jar)) ||
+ (u3r_met(6, p_jar) != 1) ||
+ (c3n == u3ud(q_jar)) ||
+ (u3r_met(3, q_jar) > 1) )
+ {
+ goto error;
+ }
+ else {
+ c3_d evt_d = u3r_chub(0, p_jar);
+ c3_w pri_w = u3r_word(0, q_jar);
+ u3_writ* wit_u = _pier_writ_find(pir_u, evt_d);
+
+ _pier_work_slog(wit_u, pri_w, u3k(r_jar));
+ }
+ break;
+ }
}
u3z(jar); u3z(mat);
@@ -1469,10 +1145,10 @@ _pier_work_poke(void* vod_p,
/* pier_work_create(): instantiate child process.
*/
-u3_lord*
+static u3_controller*
_pier_work_create(u3_pier* pir_u)
{
- u3_lord* god_u = c3_calloc(sizeof *god_u);
+ u3_controller* god_u = c3_calloc(sizeof *god_u);
pir_u->god_u = god_u;
god_u->pir_u = pir_u;
@@ -1524,7 +1200,6 @@ _pier_work_create(u3_pier* pir_u)
god_u->ops_u.file = arg_c[0];
god_u->ops_u.args = arg_c;
- fprintf(stderr, "pier: spawn\r\n");
if ( (err_i = uv_spawn(u3L, &god_u->cub_u, &god_u->ops_u)) ) {
fprintf(stderr, "spawn: %s: %s\r\n", arg_c[0], uv_strerror(err_i));
@@ -1546,146 +1221,6 @@ _pier_work_create(u3_pier* pir_u)
return god_u;
}
-/* u3_pier_create(): create a pier, loading existing.
-*/
-u3_pier*
-u3_pier_create(c3_w wag_w, c3_c* pax_c)
-{
- // create pier
- //
- u3_pier* pir_u = c3_calloc(sizeof *pir_u);
-
- pir_u->pax_c = pax_c;
- pir_u->wag_w = wag_w;
- pir_u->sat_e = u3_psat_init;
- pir_u->liv_o = c3n;
-
- pir_u->sam_u = c3_calloc(sizeof(u3_ames));
- pir_u->teh_u = c3_calloc(sizeof(u3_behn));
- pir_u->unx_u = c3_calloc(sizeof(u3_unix));
- pir_u->sav_u = c3_calloc(sizeof(u3_save));
-
- // initialize persistence
- //
- if ( c3n == _pier_disk_create(pir_u) ) {
- return 0;
- }
-
- // start the serf process
- //
- if ( !(pir_u->god_u = _pier_work_create(pir_u)) ) {
- return 0;
- }
-
- // install in the pier table
- //
- if ( 0 == u3K.all_w ) {
- u3K.all_w = 16;
- u3K.tab_u = c3_malloc(16 * sizeof(u3_pier*));
- }
- if ( u3K.len_w == u3K.all_w ) {
- u3K.all_w = 2 * u3K.all_w;
- u3K.tab_u = c3_realloc(u3K.tab_u, u3K.all_w * sizeof(u3_pier*));
- }
- u3K.tab_u[u3K.len_w++] = pir_u;
-
- return pir_u;
-}
-
-/* u3_pier_interrupt(): interrupt running process.
-*/
-void
-u3_pier_interrupt(u3_pier* pir_u)
-{
- uv_process_kill(&pir_u->god_u->cub_u, SIGINT);
-}
-
-/* u3_pier_discover(): insert task into process controller.
-*/
-void
-u3_pier_discover(u3_pier* pir_u,
- c3_l msc_l,
- u3_noun job)
-{
- _pier_insert(pir_u, msc_l, job);
- _pier_apply(pir_u);
-}
-
-/* _pier_exit_done(): synchronously shutting down
-*/
-static void
-_pier_exit_done(u3_pier* pir_u)
-{
- fprintf(stderr, "pier: exit\r\n");
-
- _pier_work_shutdown(pir_u);
- _pier_loop_exit(pir_u);
-
- // XX uninstall pier from u3K.tab_u, dispose
-
- // XX no can do
- //
- uv_stop(u3L);
-}
-
-/* u3_pier_exit(): trigger a gentle shutdown.
-*/
-void
-u3_pier_exit(u3_pier* pir_u)
-{
- pir_u->sat_e = u3_psat_done;
-
- // XX must wait for callback confirming
- //
- u3_pier_snap(pir_u);
-}
-
-/* u3_pier_send(): modern send with target and path.
-*/
-void
-u3_pier_send(u3_pier* pir_u, u3_noun pax, u3_noun tag, u3_noun fav)
-{
-}
-
-/* u3_pier_work(): send event; real pier pointer.
-**
-** XX: u3_pier_work() is for legacy events sent to a real pier.
-*/
-void
-u3_pier_work(u3_pier* pir_u, u3_noun pax, u3_noun fav)
-{
- u3_noun now;
- struct timeval tim_tv;
-
- gettimeofday(&tim_tv, 0);
- now = u3_time_in_tv(&tim_tv);
-
- u3_pier_discover(pir_u, 0, u3nt(now, pax, fav));
-}
-
-/* u3_pier_plan(): send event; fake pier pointer
-**
-** XX: u3_pier_plan() is maximum legacy, do not use.
-*/
-void
-u3_pier_plan(u3_noun pax, u3_noun fav)
-{
- u3_pier_work(u3_pier_stub(), pax, fav);
-}
-
-/* c3_rand(): fill a 512-bit (16-word) buffer.
-*/
-void
-c3_rand(c3_w* rad_w)
-{
- if ( 0 != ent_getentropy(rad_w, 64) ) {
- uL(fprintf(uH, "c3_rand getentropy: %s\n", strerror(errno)));
- // XX review
- //
- u3_pier_bail();
- }
-}
-
/* _pier_loop_time(): set time.
*/
static void
@@ -1697,6 +1232,14 @@ _pier_loop_time(void)
u3v_time(u3_time_in_tv(&tim_tv));
}
+/* _pier_loop_prepare():
+*/
+static void
+_pier_loop_prepare(uv_prepare_t* pep_u)
+{
+ _pier_loop_time();
+}
+
/* _pier_loop_init_pier(): initialize loop handlers.
*/
static void
@@ -1819,6 +1362,243 @@ _pier_loop_exit(u3_pier* pir_u)
}
}
+/* _pier_boot_set_ship():
+*/
+static void
+_pier_boot_set_ship(u3_pier* pir_u, u3_noun who, u3_noun fak)
+{
+ c3_assert( c3y == u3ud(who) );
+ c3_assert( (c3y == fak) || (c3n == fak) );
+
+ c3_o fak_o = fak;
+ c3_d who_d[2];
+
+ u3r_chubs(0, 2, who_d, who);
+
+ c3_assert( ( (0 == pir_u->fak_o) &&
+ (0 == pir_u->who_d[0]) &&
+ (0 == pir_u->who_d[1]) ) ||
+ ( (fak_o == pir_u->fak_o) &&
+ (who_d[0] == pir_u->who_d[0]) &&
+ (who_d[1] == pir_u->who_d[1]) ) );
+
+ pir_u->fak_o = fak_o;
+ pir_u->who_d[0] = who_d[0];
+ pir_u->who_d[1] = who_d[1];
+
+ {
+ u3_noun how = u3dc("scot", 'p', u3k(who));
+
+ c3_free(pir_u->who_c);
+ pir_u->who_c = u3r_string(how);
+ u3z(how);
+ }
+
+ // Disable networking for fake ships
+ //
+ if ( c3y == pir_u->fak_o ) {
+ u3_Host.ops_u.net = c3n;
+ }
+
+ u3z(who); u3z(fak);
+}
+
+/* _pier_boot_create(): create boot controller
+*/
+static u3_boot*
+_pier_boot_create(u3_pier* pir_u, u3_noun pil, u3_noun ven)
+{
+ u3_boot* bot_u = c3_calloc(sizeof(u3_boot));
+ bot_u->pil = u3k(pil);
+ bot_u->ven = u3k(ven);
+ bot_u->pir_u = pir_u;
+
+ return bot_u;
+}
+
+/* _pier_boot_dispose(): dispose of boot controller
+*/
+static void
+_pier_boot_dispose(u3_boot* bot_u)
+{
+ u3_pier* pir_u = bot_u->pir_u;
+
+ u3z(bot_u->pil);
+ u3z(bot_u->ven);
+ free(bot_u);
+ pir_u->bot_u = 0;
+}
+
+/* _pier_boot_vent(): create and enqueue boot sequence
+**
+** per cgy:
+** this new boot sequence is almost, but not quite,
+** the right thing. see new arvo.
+*/
+static void
+_pier_boot_vent(u3_boot* bot_u)
+{
+ // bot: boot formulas
+ // mod: module ova
+ // use: userpace ova
+ //
+ u3_noun bot, mod, use;
+ u3_pier* pir_u = bot_u->pir_u;
+
+ // extract boot formulas and module/userspace ova from pill
+ //
+ {
+ u3_noun pil_p, pil_q, pil_r;
+ u3_noun pro;
+
+ c3_assert( c3y == u3du(bot_u->pil) );
+
+ if ( c3y == u3h(bot_u->pil) ) {
+ u3x_trel(bot_u->pil, 0, &pil_p, &pil_q);
+ }
+ else {
+ u3x_qual(bot_u->pil, 0, &pil_p, &pil_q, &pil_r);
+ }
+
+ pro = u3m_soft(0, u3ke_cue, u3k(pil_p));
+
+ if ( 0 != u3h(pro) ) {
+ fprintf(stderr, "boot: failed: unable to parse pill\r\n");
+ exit(1);
+ }
+
+ u3x_trel(u3t(pro), &bot, &mod, &use);
+ u3k(bot); u3k(mod); u3k(use);
+
+ // optionally replace filesystem in userspace
+ //
+ if ( c3y == u3h(bot_u->pil) ) {
+ if ( u3_nul != pil_q ) {
+ c3_w len_w = 0;
+ u3_noun ova = use;
+ u3_noun new = u3_nul;
+ u3_noun ovo;
+
+ while ( u3_nul != ova ) {
+ ovo = u3h(ova);
+
+ if ( c3__into == u3h(u3t(ovo)) ) {
+ c3_assert( 0 == len_w );
+ len_w++;
+ ovo = u3k(u3t(pil_q));
+ }
+
+ new = u3nc(u3k(ovo), new);
+ ova = u3t(ova);
+ }
+
+ c3_assert( 1 == len_w );
+
+ u3z(use);
+ use = u3kb_flop(new);
+ }
+ }
+ // prepend %lite module and userspace ova
+ //
+ else {
+ mod = u3kb_weld(u3k(pil_q), mod);
+ use = u3kb_weld(u3k(pil_r), use);
+ }
+
+ u3z(pro);
+ }
+
+ // prepend entropy to the module sequence
+ //
+ // XX also copy to _pier_loop_wake?
+ //
+ {
+ c3_w eny_w[16];
+ c3_rand(eny_w);
+
+ u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
+ u3_noun car = u3nc(c3__wack, u3i_words(16, eny_w));
+
+ mod = u3nc(u3nc(wir, car), mod);
+ }
+
+ // prepend identity to the module sequence, setting single-home
+ //
+ {
+ u3_noun wir = u3nt(u3_blip, c3__arvo, u3_nul);
+ u3_noun car = u3nc(c3__whom, u3i_chubs(2, pir_u->who_d));
+
+ mod = u3nc(u3nc(wir, car), mod);
+ }
+
+ // insert boot sequence directly
+ //
+ // Note that these are not ovum or (pair @da ovum) events,
+ // but raw nock formulas to be directly evaluated as the
+ // subject of the lifecycle formula [%2 [%0 3] %0 2].
+ // All subsequent events will be (pair @da ovum).
+ //
+ {
+ u3_noun fol = bot;
+
+ // initialize the boot barrier
+ //
+ // And the initial lifecycle boot barrier.
+ //
+ pir_u->but_d = u3kb_lent(u3k(fol));
+ pir_u->lif_d = pir_u->but_d;
+
+ while ( u3_nul != fol ) {
+ _pier_writ_insert(pir_u, 0, u3k(u3h(fol)));
+ fol = u3t(fol);
+ }
+ }
+
+ // insert module events
+ //
+ {
+ u3_noun ova = mod;
+ // add to the boot barrier
+ //
+ pir_u->but_d += u3kb_lent(u3k(ova));
+
+ while ( u3_nul != ova ) {
+ _pier_writ_insert_ovum(pir_u, 0, u3k(u3h(ova)));
+ ova = u3t(ova);
+ }
+ }
+
+ // insert legacy boot event
+ //
+ {
+ // XX do something about this wire
+ // XX route directly to %jael?
+ //
+ c3_assert( c3y == u3du(bot_u->ven) );
+
+ u3_noun wir = u3nq(u3_blip, c3__term, '1', u3_nul);
+ u3_noun car = u3nc(c3__boot, u3k(bot_u->ven));
+ u3_noun ovo = u3nc(wir, car);
+
+ _pier_writ_insert_ovum(pir_u, 0, ovo);
+ }
+
+ // insert userspace events
+ //
+ // Currently just the initial filesystem
+ //
+ {
+ u3_noun ova = use;
+
+ while ( u3_nul != ova ) {
+ _pier_writ_insert_ovum(pir_u, 0, u3k(u3h(ova)));
+ ova = u3t(ova);
+ }
+ }
+
+ u3z(bot); u3z(mod); u3z(use);
+}
+
/* _pier_boot_complete(): start organic event flow on boot/reboot.
*/
static void
@@ -1850,22 +1630,371 @@ _pier_boot_complete(u3_pier* pir_u)
}
}
-/* _pier_loop_prepare():
+/* _pier_boot_ready():
*/
static void
-_pier_loop_prepare(uv_prepare_t* pep_u)
+_pier_boot_ready(u3_pier* pir_u)
{
- _pier_loop_time();
+ u3_controller* god_u = pir_u->god_u;
+ u3_disk* log_u = pir_u->log_u;
+
+ c3_assert( u3_psat_init == pir_u->sat_e );
+
+ if ( ( 0 == god_u) ||
+ ( 0 == log_u) ||
+ (c3y != god_u->liv_o) ||
+ (c3y != log_u->liv_o) )
+ {
+ return;
+ }
+
+ // mark all commits as released
+ //
+ god_u->rel_d = log_u->com_d;
+
+ // set next expected event number
+ //
+ pir_u->gen_d = (1ULL + log_u->com_d);
+
+ // boot
+ //
+ if ( 0 != pir_u->bot_u ) {
+ c3_assert( 0 == log_u->com_d );
+ c3_assert( 0 == god_u->dun_d );
+
+ // construct/enqueue boot sequence
+ //
+ _pier_boot_vent(pir_u->bot_u);
+ _pier_boot_dispose(pir_u->bot_u);
+
+ // prepare serf for boot sequence, write log header
+ //
+ _pier_work_boot(pir_u, c3y);
+
+ fprintf(stderr, "boot: ship: %s%s\r\n",
+ pir_u->who_c,
+ (c3y == pir_u->fak_o) ? " (fake)" : "");
+
+ pir_u->sat_e = u3_psat_boot;
+ }
+ // replay
+ //
+ else if ( god_u->dun_d < log_u->com_d ) {
+ c3_assert( 0 != log_u->com_d );
+
+ fprintf(stderr, "---------------- playback starting----------------\r\n");
+
+ // set the boot barrier to the last committed event
+ //
+ pir_u->but_d = log_u->com_d;
+
+ // begin queuing batches of committed events
+ //
+ _pier_disk_load_commit(pir_u, (1ULL + god_u->dun_d), 1000ULL);
+
+ if ( 0 == god_u->dun_d ) {
+ fprintf(stderr, "pier: replaying events 1 through %" PRIu64 "\r\n",
+ log_u->com_d);
+
+ // prepare serf for replay of boot sequence, don't write log header
+ //
+ _pier_work_boot(pir_u, c3n);
+ }
+ else {
+ fprintf(stderr, "pier: replaying events %" PRIu64
+ " through %" PRIu64 "\r\n",
+ god_u->dun_d,
+ log_u->com_d);
+ }
+
+ pir_u->sat_e = u3_psat_pace;
+ }
+ // resume
+ //
+ else {
+ c3_assert( 0 != log_u->com_d );
+ c3_assert( 0 != god_u->dun_d );
+
+ // set the boot barrier to the last computed event
+ //
+ pir_u->but_d = god_u->dun_d;
+
+ // resume normal operation
+ //
+ _pier_boot_complete(pir_u);
+ }
}
-/* u3_pier_bail(): clean up all event state.
+/* _pier_apply(): react to i/o, inbound or outbound.
+*/
+static void
+_pier_apply(u3_pier* pir_u)
+{
+ u3_disk* log_u = pir_u->log_u;
+ u3_controller* god_u = pir_u->god_u;
+ u3_save* sav_u = pir_u->sav_u;
+
+ if ( (0 == log_u) ||
+ (0 == god_u) ||
+ (c3n == god_u->liv_o) ||
+ (u3_psat_init == pir_u->sat_e) )
+ {
+ return;
+ }
+
+ u3_writ* wit_u;
+ c3_o act_o = c3n;
+
+start:
+
+ /* iterate from queue exit, advancing any writs that can advance
+ */
+ wit_u = pir_u->ext_u;
+ while ( wit_u ) {
+ /* if writ is (a) next in line to compute, (b) worker is inactive,
+ ** and (c) a snapshot has not been requested, request computation
+ */
+ if ( (wit_u->evt_d == (1 + god_u->sen_d)) &&
+ (god_u->sen_d == god_u->dun_d) &&
+ (sav_u->dun_d == sav_u->req_d) )
+ {
+ _pier_work_compute(wit_u);
+ act_o = c3y;
+ }
+
+ /* if writ is (a) computed and (b) next in line to commit,
+ ** and (c) no commit is in progress and (d) we've booted,
+ ** request commit.
+ */
+ if ( (wit_u->evt_d <= god_u->dun_d) &&
+ (wit_u->evt_d == (1 + log_u->moc_d)) &&
+ (wit_u->evt_d == (1 + log_u->com_d)) )
+ {
+ _pier_disk_commit_request(wit_u);
+ act_o = c3y;
+ }
+
+ /* if writ is (a) committed and (b) computed,
+ ** release effects and delete from queue
+ */
+ if ( (wit_u->evt_d <= log_u->com_d) &&
+ (wit_u->evt_d <= god_u->dun_d) )
+ {
+ // effects must be released in order
+ //
+ c3_assert(wit_u == pir_u->ext_u);
+
+ // remove from queue
+ //
+ // XX must be done before releasing effects
+ // which is currently reentrant
+ //
+ _pier_writ_unlink(wit_u);
+
+ // release effects
+ //
+ _pier_work_release(wit_u);
+
+ // free writ
+ //
+ _pier_writ_dispose(wit_u);
+
+ wit_u = pir_u->ext_u;
+ act_o = c3y;
+ }
+ else {
+ /* otherwise, continue backward
+ */
+ wit_u = wit_u->nex_u;
+ }
+ }
+
+ /* if we did anything to the queue, make another pass.
+ */
+ if ( c3y == act_o ) {
+ act_o = c3n;
+ goto start;
+ }
+}
+
+/* _pier_create(): create a pier, loading existing.
+*/
+static u3_pier*
+_pier_create(c3_w wag_w, c3_c* pax_c)
+{
+ // create pier
+ //
+ u3_pier* pir_u = c3_calloc(sizeof *pir_u);
+
+ pir_u->pax_c = pax_c;
+ pir_u->wag_w = wag_w;
+ pir_u->sat_e = u3_psat_init;
+
+ pir_u->sam_u = c3_calloc(sizeof(u3_ames));
+ pir_u->teh_u = c3_calloc(sizeof(u3_behn));
+ pir_u->unx_u = c3_calloc(sizeof(u3_unix));
+ pir_u->sav_u = c3_calloc(sizeof(u3_save));
+
+ // initialize persistence
+ //
+ if ( c3n == _pier_disk_create(pir_u) ) {
+ return 0;
+ }
+
+ // start the worker process
+ //
+ if ( !(pir_u->god_u = _pier_work_create(pir_u)) ) {
+ return 0;
+ }
+
+ // install in the pier table
+ //
+ if ( 0 == u3K.all_w ) {
+ u3K.all_w = 16;
+ u3K.tab_u = c3_malloc(16 * sizeof(u3_pier*));
+ }
+ if ( u3K.len_w == u3K.all_w ) {
+ u3K.all_w = 2 * u3K.all_w;
+ u3K.tab_u = c3_realloc(u3K.tab_u, u3K.all_w * sizeof(u3_pier*));
+ }
+ u3K.tab_u[u3K.len_w++] = pir_u;
+
+ return pir_u;
+}
+
+/* u3_pier_interrupt(): interrupt running process.
+*/
+void
+u3_pier_interrupt(u3_pier* pir_u)
+{
+ uv_process_kill(&pir_u->god_u->cub_u, SIGINT);
+}
+
+/* _pier_exit_done(): synchronously shutting down
+*/
+static void
+_pier_exit_done(u3_pier* pir_u)
+{
+ u3l_log("pier: exit\r\n");
+
+ _pier_work_shutdown(pir_u);
+ _pier_loop_exit(pir_u);
+
+ // XX uninstall pier from u3K.tab_u, dispose
+
+ // XX no can do
+ //
+ uv_stop(u3L);
+}
+
+/* u3_pier_exit(): trigger a gentle shutdown.
+*/
+void
+u3_pier_exit(u3_pier* pir_u)
+{
+ pir_u->sat_e = u3_psat_done;
+
+ // XX must wait for callback confirming
+ //
+ u3_pier_snap(pir_u);
+}
+
+/* u3_pier_snap(): request snapshot
+*/
+void
+u3_pier_snap(u3_pier* pir_u)
+{
+ u3_controller* god_u = pir_u->god_u;
+ u3_disk* log_u = pir_u->log_u;
+ u3_save* sav_u = pir_u->sav_u;
+
+ c3_d top_d = c3_max(god_u->sen_d, god_u->dun_d);
+
+ // no-op if there are no un-snapshot'ed events
+ //
+ if ( top_d > sav_u->dun_d ) {
+ sav_u->req_d = top_d;
+
+ // save eagerly if all computed events are already committed
+ //
+ if ( log_u->com_d >= top_d ) {
+ _pier_work_save(pir_u);
+ }
+ }
+ // if we're gracefully shutting down, do so now
+ //
+ else if ( u3_psat_done == pir_u->sat_e ) {
+ _pier_exit_done(pir_u);
+ }
+}
+
+/* u3_pier_discover(): insert task into process controller.
+*/
+void
+u3_pier_discover(u3_pier* pir_u,
+ c3_l msc_l,
+ u3_noun job)
+{
+ _pier_writ_insert(pir_u, msc_l, job);
+ _pier_apply(pir_u);
+}
+
+/* u3_pier_send(): modern send with target and path.
+*/
+void
+u3_pier_send(u3_pier* pir_u, u3_noun pax, u3_noun tag, u3_noun fav)
+{
+}
+
+/* u3_pier_work(): send event; real pier pointer.
+**
+** XX: u3_pier_work() is for legacy events sent to a real pier.
+*/
+void
+u3_pier_work(u3_pier* pir_u, u3_noun pax, u3_noun fav)
+{
+ u3_noun now;
+ struct timeval tim_tv;
+
+ gettimeofday(&tim_tv, 0);
+ now = u3_time_in_tv(&tim_tv);
+
+ u3_pier_discover(pir_u, 0, u3nt(now, pax, fav));
+}
+
+/* u3_pier_plan(): send event; fake pier pointer
+**
+** XX: u3_pier_plan() is maximum legacy, do not use.
+*/
+void
+u3_pier_plan(u3_noun pax, u3_noun fav)
+{
+ u3_pier_work(u3_pier_stub(), pax, fav);
+}
+
+/* c3_rand(): fill a 512-bit (16-word) buffer.
+*/
+void
+c3_rand(c3_w* rad_w)
+{
+ if ( 0 != ent_getentropy(rad_w, 64) ) {
+ u3l_log("c3_rand getentropy: %s\n", strerror(errno));
+ // XX review
+ //
+ u3_pier_bail();
+ }
+}
+
+/* u3_pier_bail(): immediately shutdown.
*/
void
u3_pier_bail(void)
{
- fflush(stdout);
- u3_pier_exit(u3_pier_stub());
+ if ( 0 != u3K.len_w ) {
+ _pier_exit_done(u3_pier_stub());
+ }
+ fflush(stdout);
exit(1);
}
@@ -1897,7 +2026,12 @@ _pier_wall(u3_noun wol)
FILE* fil_u = u3_term_io_hija();
u3_noun wal = wol;
- fil_u = stderr; // XX
+ // XX temporary, for urb.py test runner
+ //
+ if ( c3y == u3_Host.ops_u.dem ) {
+ fil_u = stderr;
+ }
+
while ( u3_nul != wal ) {
_pier_tape(fil_u, u3k(u3h(wal)));
@@ -1936,7 +2070,12 @@ u3_pier_punt(c3_l tab_l, u3_noun tac)
if ( c3__leaf == u3h(act) ) {
FILE* fil_u = u3_term_io_hija();
- fil_u = stderr; // XX
+ // XX temporary, for urb.py test runner
+ //
+ if ( c3y == u3_Host.ops_u.dem ) {
+ fil_u = stderr;
+ }
+
_pier_tape(fil_u, u3k(u3t(act)));
putc(13, fil_u);
putc(10, fil_u);
@@ -1990,16 +2129,14 @@ u3_pier_boot(c3_w wag_w, // config flags
{
// make/load pier
//
- u3_pier* pir_u = u3_pier_create(wag_w, u3r_string(pax));
+ u3_pier* pir_u = _pier_create(wag_w, u3r_string(pax));
// set boot params
//
{
- pir_u->bot = u3k(ven);
- pir_u->pil = u3k(pil);
+ pir_u->bot_u = _pier_boot_create(pir_u, u3k(pil), u3k(ven));
- _pier_set_ship(pir_u, u3k(who),
- ( c3__fake == u3h(pir_u->bot) ) ? c3y : c3n);
+ _pier_boot_set_ship(pir_u, u3k(who), ( c3__fake == u3h(ven) ) ? c3y : c3n);
}
// initialize i/o handlers
@@ -2021,7 +2158,7 @@ u3_pier_stay(c3_w wag_w, u3_noun pax)
{
// make/load pier
//
- u3_pier* pir_u = u3_pier_create(wag_w, u3r_string(pax));
+ u3_pier* pir_u = _pier_create(wag_w, u3r_string(pax));
// initialize i/o handlers
//
@@ -2046,9 +2183,12 @@ u3_pier_mark(FILE* fil_u)
while ( 0 < len_w ) {
pir_u = u3K.tab_u[--len_w];
- fprintf(stderr, "pier: %u\r\n", len_w);
+ u3l_log("pier: %u\r\n", len_w);
- tot_w += u3a_maid(fil_u, " boot event", u3a_mark_noun(pir_u->bot));
+ if ( 0 != pir_u->bot_u ) {
+ tot_w += u3a_maid(fil_u, " boot event", u3a_mark_noun(pir_u->bot_u->ven));
+ tot_w += u3a_maid(fil_u, " pill", u3a_mark_noun(pir_u->bot_u->pil));
+ }
{
u3_writ* wit_u = pir_u->ent_u;
diff --git a/pkg/urbit/vere/reck.c b/pkg/urbit/vere/reck.c
index 7d65d2c62..ba803e36c 100644
--- a/pkg/urbit/vere/reck.c
+++ b/pkg/urbit/vere/reck.c
@@ -26,7 +26,7 @@ _reck_mole(u3_noun fot,
if ( (c3n == u3r_cell(uco, &p_uco, &q_uco)) ||
(u3_nul != p_uco) )
{
- uL(fprintf(uH, "strange mole %s\n", u3r_string(san)));
+ u3l_log("strange mole %s\n", u3r_string(san));
u3z(fot); u3z(uco); return c3n;
}
@@ -108,7 +108,7 @@ _reck_kick_term(u3_pier* pir_u, u3_noun pox, c3_l tid_l, u3_noun fav)
u3_noun lan = u3k(u3h(u3t(fav)));
u3_noun pac = u3k(u3t(u3t(fav)));
- fprintf(stderr, "kick: strange send\r\n");
+ u3l_log("kick: strange send\r\n");
u3_ames_ef_send(pir_u, lan, pac);
u3z(pox); u3z(fav); return c3y;
} break;
@@ -123,9 +123,9 @@ _reck_kick_term(u3_pier* pir_u, u3_noun pox, c3_l tid_l, u3_noun fav)
case c3__init: p_fav = u3t(fav);
{
- // king ignores %init
+ // daemon ignores %init
// u3A->own = u3nc(u3k(p_fav), u3A->own);
- // uL(fprintf(uH, "kick: init: %d\n", p_fav));
+ // u3l_log("kick: init: %d\n", p_fav);
u3z(pox); u3z(fav); return c3y;
} break;
@@ -133,9 +133,9 @@ _reck_kick_term(u3_pier* pir_u, u3_noun pox, c3_l tid_l, u3_noun fav)
{
u3z(pox); u3z(fav);
- // gc the kingdom
+ // gc the daemon area
//
- uv_timer_start(&u3K.tim_u, (uv_timer_cb)u3_king_grab, 0, 0);
+ uv_timer_start(&u3K.tim_u, (uv_timer_cb)u3_daemon_grab, 0, 0);
return c3y;
} break;
}
@@ -286,9 +286,9 @@ _reck_kick_ames(u3_pier* pir_u, u3_noun pox, u3_noun fav)
default: break;
case c3__init: p_fav = u3t(fav);
{
- // king ignores %init
+ // daemon ignores %init
// u3A->own = u3nc(u3k(p_fav), u3A->own);
- // uL(fprintf(uH, "kick: init: %d\n", p_fav));
+ // u3l_log("kick: init: %d\n", p_fav);
u3z(pox); u3z(fav); return c3y;
} break;
}
@@ -377,10 +377,10 @@ _reck_kick_spec(u3_pier* pir_u, u3_noun pox, u3_noun fav)
} break;
case c3__init: {
- // king ignores %init
+ // daemon ignores %init
// p_fav = u3t(fav);
// u3A->own = u3nc(u3k(p_fav), u3A->own);
- // uL(fprintf(uH, "kick: init: %d\n", p_fav));
+ // u3l_log("kick: init: %d\n", p_fav);
u3z(pox); u3z(fav); return c3y;
} break;
@@ -393,7 +393,7 @@ _reck_kick_spec(u3_pier* pir_u, u3_noun pox, u3_noun fav)
(u3_nul != q_pud) ||
(c3n == _reck_orchid(c3__ud, u3k(p_pud), &tid_l)) )
{
- uL(fprintf(uH, "term: bad tire\n"));
+ u3l_log("term: bad tire\n");
u3z(pox); u3z(fav); return c3n;
} else {
return _reck_kick_term(pir_u, pox, tid_l, fav);
@@ -418,7 +418,7 @@ _reck_kick_norm(u3_pier* pir_u, u3_noun pox, u3_noun fav)
case c3__vega:
{
- uL(fprintf(uH, "<<>>\n"));
+ u3l_log("<<>>\n");
u3z(pox); u3z(fav);
// reclaim memory from persistent caches
@@ -429,7 +429,7 @@ _reck_kick_norm(u3_pier* pir_u, u3_noun pox, u3_noun fav)
}
case c3__exit:
{
- uL(fprintf(uH, "<<>>\n"));
+ u3l_log("<<>>\n");
u3_pier_exit(pir_u);
u3z(pox); u3z(fav); return c3y;
@@ -466,9 +466,9 @@ u3_reck_kick(u3_pier* pir_u, u3_noun ovo)
}
else {
u3_noun tox = u3do("spat", u3k(u3h(ovo)));
- uL(fprintf(uH, "kick: lost %%%s on %s\n",
- u3r_string(u3h(u3t(ovo))),
- u3r_string(tox)));
+ u3l_log("kick: lost %%%s on %s\n",
+ u3r_string(u3h(u3t(ovo))),
+ u3r_string(tox));
u3z(tox);
#if 0
if ( c3__hear == u3h(u3t(ovo)) ) {
diff --git a/pkg/urbit/vere/save.c b/pkg/urbit/vere/save.c
index 480e1a5f2..1c62e8442 100644
--- a/pkg/urbit/vere/save.c
+++ b/pkg/urbit/vere/save.c
@@ -31,7 +31,7 @@ u3_save_ef_chld(u3_pier *pir_u)
/* modified for cases with no pid_w
*/
- uL(fprintf(uH, "checkpoint: complete %d\n", sav_u->pid_w));
+ u3l_log("checkpoint: complete %d\n", sav_u->pid_w);
pid_w = wait(&loc_i);
if (0 != sav_u->pid_w) {
c3_assert(pid_w == sav_u->pid_w);
diff --git a/pkg/urbit/vere/term.c b/pkg/urbit/vere/term.c
index 550297bf3..ca4c58d38 100644
--- a/pkg/urbit/vere/term.c
+++ b/pkg/urbit/vere/term.c
@@ -20,6 +20,7 @@ static void _term_read_cb(uv_stream_t* tcp_u,
ssize_t siz_i,
const uv_buf_t * buf_u);
static inline void _term_suck(u3_utty*, const c3_y*, ssize_t);
+static u3_utty* _term_main();
#define _SPIN_COOL_US 500000 // spinner activation delay when cool
#define _SPIN_WARM_US 50000 // spinner activation delay when warm
@@ -265,7 +266,7 @@ u3_term_io_init()
_term_spinner_cb,
uty_u);
if ( 0 != ret_w ) {
- uL(fprintf(uH, "term: spinner start: %s\n", uv_strerror(ret_w)));
+ u3l_log("term: spinner start: %s\n", uv_strerror(ret_w));
free(uty_u->tat_u.sun.sit_u);
uty_u->tat_u.sun.sit_u = NULL;
uv_mutex_unlock(&uty_u->tat_u.mex_u);
@@ -312,7 +313,7 @@ u3_term_io_exit(void)
// XX can block exit waiting for wakeup (max _SPIN_COOL_US)
c3_w ret_w;
if ( 0 != (ret_w = uv_thread_join(sit_u)) ) {
- uL(fprintf(uH, "term: spinner exit: %s\n", uv_strerror(ret_w)));
+ u3l_log("term: spinner exit: %s\n", uv_strerror(ret_w));
}
else {
uv_mutex_destroy(&uty_u->tat_u.mex_u);
@@ -354,7 +355,7 @@ _term_write_cb(uv_write_t* wri_u, c3_i sas_i)
_u3_write_t* ruq_u = (void *)wri_u;
if ( 0 != sas_i ) {
- // uL(fprintf(uH, "term: write: ERROR\n"));
+ // u3l_log("term: write: ERROR\n");
}
free(ruq_u->buf_y);
free(ruq_u);
@@ -375,7 +376,7 @@ _term_it_write_buf(u3_utty* uty_u, uv_buf_t buf_u)
&buf_u, 1,
_term_write_cb)) )
{
- uL(fprintf(uH, "terminal: %s\n", uv_strerror(ret_w)));
+ u3l_log("terminal: %s\n", uv_strerror(ret_w));
}
}
@@ -667,10 +668,10 @@ _term_io_suck_char(u3_utty* uty_u, c3_y cay_y)
u3_noun huv = u3i_bytes(tat_u->fut.wid_w, tat_u->fut.syb_y);
u3_noun wug;
- // uL(fprintf(uH, "muck-utf8 len %d\n", tat_u->fut.len_w));
- // uL(fprintf(uH, "muck-utf8 %x\n", huv));
+ // u3l_log("muck-utf8 len %d\n", tat_u->fut.len_w);
+ // u3l_log("muck-utf8 %x\n", huv);
wug = u3do("taft", huv);
- // uL(fprintf(uH, "muck-utf32 %x\n", tat_u->fut.len_w));
+ // u3l_log("muck-utf32 %x\n", tat_u->fut.len_w);
tat_u->fut.len_w = tat_u->fut.wid_w = 0;
_term_io_belt(uty_u, u3nt(c3__txt, wug, u3_nul));
@@ -738,11 +739,11 @@ _term_suck(u3_utty* uty_u, const c3_y* buf, ssize_t siz_i)
// The process hangs if we do nothing (and ctrl-z
// then corrupts the event log), so we force shutdown.
//
- fprintf(stderr, "term: hangup (EOF)\r\n");
+ u3l_log("term: hangup (EOF)\r\n");
u3_pier_exit(u3_pier_stub());
}
else if ( siz_i < 0 ) {
- uL(fprintf(uH, "term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i)));
+ u3l_log("term %d: read: %s\n", uty_u->tid_l, uv_strerror(siz_i));
}
else {
c3_i i;
@@ -868,6 +869,8 @@ _term_start_spinner(u3_utty* uty_u, u3_noun ovo)
lag_d = _SPIN_COOL_US;
}
+ // second item of the event wire
+ //
u3_noun why = u3h(u3t(u3h(u3t(ovo))));
if ( c3__term == why ) {
u3_noun eve = u3t(u3t(ovo));
@@ -884,7 +887,7 @@ _term_start_spinner(u3_utty* uty_u, u3_noun ovo)
uv_mutex_unlock(&uty_u->tat_u.mex_u);
}
-/* _term_stop_spinner(): reset spinner state and restore input line.
+/* u3_term_stop_spinner(): reset spinner state and restore input line.
*/
static void
_term_stop_spinner(u3_utty* uty_u)
@@ -905,6 +908,26 @@ _term_stop_spinner(u3_utty* uty_u)
uty_u->tat_u.sun.why_c = NULL;
}
+/* u3_term_start_spinner(): prepare spinner state. RETAIN.
+*/
+void
+u3_term_start_spinner(u3_noun ovo)
+{
+ if ( c3n == u3_Host.ops_u.dem ) {
+ _term_start_spinner(_term_main(), ovo);
+ }
+}
+
+/* u3_term_stop_spinner(): reset spinner state and restore input line.
+*/
+void
+u3_term_stop_spinner(void)
+{
+ if ( c3n == u3_Host.ops_u.dem ) {
+ _term_stop_spinner(_term_main());
+ }
+}
+
/* _term_spinner_cb(): manage spinner (off-thread).
*/
static void
@@ -1157,8 +1180,8 @@ u3_term_ef_blit(c3_l tid_l,
u3_utty* uty_u = _term_ef_get(tid_l);
if ( 0 == uty_u ) {
- // uL(fprintf(uH, "no terminal %d\n", tid_l));
- // uL(fprintf(uH, "uty_u %p\n", u3_Host.uty_u));
+ // u3l_log("no terminal %d\n", tid_l);
+ // u3l_log("uty_u %p\n", u3_Host.uty_u);
u3z(bls); return;
}
@@ -1257,6 +1280,15 @@ u3_term_io_loja(int x)
}
}
+/* u3_term_it_log(): writes a log message
+*/
+void
+u3_term_io_log(c3_c* line)
+{
+ FILE* stream = u3_term_io_hija();
+ u3_term_io_loja(fprintf(stream, "%s", line));
+}
+
/* u3_term_tape_to(): dump a tape to a file.
*/
void
diff --git a/pkg/urbit/vere/unix.c b/pkg/urbit/vere/unix.c
index efcbf2000..e3a013293 100644
--- a/pkg/urbit/vere/unix.c
+++ b/pkg/urbit/vere/unix.c
@@ -101,35 +101,35 @@ _unix_rm_r_cb(const c3_c* pax_c,
{
switch ( typeflag ) {
default:
- uL(fprintf(uH, "bad file type in rm_r: %s\r\n", pax_c));
+ u3l_log("bad file type in rm_r: %s\r\n", pax_c);
break;
case FTW_F:
if ( 0 != unlink(pax_c) && ENOENT != errno ) {
- uL(fprintf(uH, "error unlinking (in rm_r) %s: %s\n",
- pax_c, strerror(errno)));
+ u3l_log("error unlinking (in rm_r) %s: %s\n",
+ pax_c, strerror(errno));
c3_assert(0);
}
break;
case FTW_D:
- uL(fprintf(uH, "shouldn't have gotten pure directory: %s\r\n", pax_c));
+ u3l_log("shouldn't have gotten pure directory: %s\r\n", pax_c);
break;
case FTW_DNR:
- uL(fprintf(uH, "couldn't read directory: %s\r\n", pax_c));
+ u3l_log("couldn't read directory: %s\r\n", pax_c);
break;
case FTW_NS:
- uL(fprintf(uH, "couldn't stat path: %s\r\n", pax_c));
+ u3l_log("couldn't stat path: %s\r\n", pax_c);
break;
case FTW_DP:
if ( 0 != rmdir(pax_c) && ENOENT != errno ) {
- uL(fprintf(uH, "error rmdiring %s: %s\n", pax_c, strerror(errno)));
+ u3l_log("error rmdiring %s: %s\n", pax_c, strerror(errno));
c3_assert(0);
}
break;
case FTW_SL:
- uL(fprintf(uH, "got symbolic link: %s\r\n", pax_c));
+ u3l_log("got symbolic link: %s\r\n", pax_c);
break;
case FTW_SLN:
- uL(fprintf(uH, "got nonexistent symbolic link: %s\r\n", pax_c));
+ u3l_log("got nonexistent symbolic link: %s\r\n", pax_c);
break;
}
@@ -143,7 +143,7 @@ _unix_rm_r(c3_c* pax_c)
{
if ( 0 > nftw(pax_c, _unix_rm_r_cb, 100, FTW_DEPTH | FTW_PHYS )
&& ENOENT != errno) {
- uL(fprintf(uH, "rm_r error on %s: %s\r\n", pax_c, strerror(errno)));
+ u3l_log("rm_r error on %s: %s\r\n", pax_c, strerror(errno));
}
}
@@ -153,7 +153,7 @@ static void
_unix_mkdir(c3_c* pax_c)
{
if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno) {
- uL(fprintf(uH, "error mkdiring %s: %s\n", pax_c, strerror(errno)));
+ u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno));
c3_assert(0);
}
}
@@ -170,8 +170,8 @@ _unix_write_file_hard(c3_c* pax_c, u3_noun mim)
u3_noun dat = u3t(u3t(mim));
if ( fid_i < 0 ) {
- uL(fprintf(uH, "error opening %s for writing: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error opening %s for writing: %s\r\n",
+ pax_c, strerror(errno));
u3z(mim);
return 0;
}
@@ -186,8 +186,8 @@ _unix_write_file_hard(c3_c* pax_c, u3_noun mim)
rit_w = write(fid_i, dat_y, siz_w);
if ( rit_w != siz_w ) {
- uL(fprintf(uH, "error writing %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error writing %s: %s\r\n",
+ pax_c, strerror(errno));
mug_w = 0;
}
else {
@@ -216,8 +216,8 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim)
goto _unix_write_file_soft_go;
}
else {
- uL(fprintf(uH, "error opening file (soft) %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error opening file (soft) %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
u3z(mim);
return;
}
@@ -229,18 +229,18 @@ _unix_write_file_soft(u3_ufil* fil_u, u3_noun mim)
red_ws = read(fid_i, old_y, len_ws);
if ( close(fid_i) < 0 ) {
- uL(fprintf(uH, "error closing file (soft) %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error closing file (soft) %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
}
if ( len_ws != red_ws ) {
if ( red_ws < 0 ) {
- uL(fprintf(uH, "error reading file (soft) %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error reading file (soft) %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
}
else {
- uL(fprintf(uH, "wrong # of bytes read in file %s: %d %d\r\n",
- fil_u->pax_c, len_ws, red_ws));
+ u3l_log("wrong # of bytes read in file %s: %d %d\r\n",
+ fil_u->pax_c, len_ws, red_ws);
}
free(old_y);
u3z(mim);
@@ -316,8 +316,8 @@ _unix_scan_mount_point(u3_pier *pir_u, u3_umon* mon_u)
{
DIR* rid_u = opendir(mon_u->dir_u.pax_c);
if ( !rid_u ) {
- uL(fprintf(uH, "error opening pier directory: %s: %s\r\n",
- mon_u->dir_u.pax_c, strerror(errno)));
+ u3l_log("error opening pier directory: %s: %s\r\n",
+ mon_u->dir_u.pax_c, strerror(errno));
return;
}
@@ -329,8 +329,9 @@ _unix_scan_mount_point(u3_pier *pir_u, u3_umon* mon_u)
c3_w err_w;
if ( 0 != (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) ) {
- uL(fprintf(uH, "erroring loading pier directory %s: %s\r\n",
- mon_u->dir_u.pax_c, strerror(errno)));
+ u3l_log("erroring loading pier directory %s: %s\r\n",
+ mon_u->dir_u.pax_c, strerror(errno));
+
c3_assert(0);
}
else if ( !out_u ) {
@@ -348,8 +349,8 @@ _unix_scan_mount_point(u3_pier *pir_u, u3_umon* mon_u)
struct stat buf_u;
if ( 0 != stat(pax_c, &buf_u) ) {
- uL(fprintf(uH, "can't stat pier directory %s: %s\r\n",
- mon_u->dir_u.pax_c, strerror(errno)));
+ u3l_log("can't stat pier directory %s: %s\r\n",
+ mon_u->dir_u.pax_c, strerror(errno));
free(pax_c);
continue;
}
@@ -392,7 +393,7 @@ static void
_unix_free_file(u3_ufil *fil_u)
{
if ( 0 != unlink(fil_u->pax_c) && ENOENT != errno ) {
- uL(fprintf(uH, "error unlinking %s: %s\n", fil_u->pax_c, strerror(errno)));
+ u3l_log("error unlinking %s: %s\n", fil_u->pax_c, strerror(errno));
c3_assert(0);
}
@@ -504,7 +505,7 @@ _unix_delete_mount_point(u3_pier *pir_u, u3_noun mon)
mon_u = pir_u->unx_u->mon_u;
if ( !mon_u ) {
- uL(fprintf(uH, "mount point already gone: %s\r\n", nam_c));
+ u3l_log("mount point already gone: %s\r\n", nam_c);
goto _delete_mount_point_out;
}
if ( 0 == strcmp(nam_c, mon_u->nam_c) ) {
@@ -520,7 +521,7 @@ _unix_delete_mount_point(u3_pier *pir_u, u3_noun mon)
}
if ( !mon_u->nex_u ) {
- uL(fprintf(uH, "mount point already gone: %s\r\n", nam_c));
+ u3l_log("mount point already gone: %s\r\n", nam_c);
goto _delete_mount_point_out;
}
@@ -640,8 +641,8 @@ _unix_update_file(u3_pier *pir_u, u3_ufil* fil_u)
return u3nc(u3nc(_unix_string_to_path(pir_u, fil_u->pax_c), u3_nul), u3_nul);
}
else {
- uL(fprintf(uH, "error opening file %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error opening file %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
return u3_nul;
}
}
@@ -652,18 +653,18 @@ _unix_update_file(u3_pier *pir_u, u3_ufil* fil_u)
red_ws = read(fid_i, dat_y, len_ws);
if ( close(fid_i) < 0 ) {
- uL(fprintf(uH, "error closing file %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error closing file %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
}
if ( len_ws != red_ws ) {
if ( red_ws < 0 ) {
- uL(fprintf(uH, "error reading file %s: %s\r\n",
- fil_u->pax_c, strerror(errno)));
+ u3l_log("error reading file %s: %s\r\n",
+ fil_u->pax_c, strerror(errno));
}
else {
- uL(fprintf(uH, "wrong # of bytes read in file %s: %d %d\r\n",
- fil_u->pax_c, len_ws, red_ws));
+ u3l_log("wrong # of bytes read in file %s: %d %d\r\n",
+ fil_u->pax_c, len_ws, red_ws);
}
free(dat_y);
return u3_nul;
@@ -738,8 +739,8 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
if ( (fid_i < 0) || (fstat(fid_i, &buf_u) < 0) ) {
if ( ENOENT != errno ) {
- uL(fprintf(uH, "_unix_update_dir: error opening file %s: %s\r\n",
- nod_u->pax_c, strerror(errno)));
+ u3l_log("_unix_update_dir: error opening file %s: %s\r\n",
+ nod_u->pax_c, strerror(errno));
}
u3_unod* nex_u = nod_u->nex_u;
@@ -748,8 +749,8 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
}
else {
if ( close(fid_i) < 0 ) {
- uL(fprintf(uH, "_unix_update_dir: error closing file %s: %s\r\n",
- nod_u->pax_c, strerror(errno)));
+ u3l_log("_unix_update_dir: error closing file %s: %s\r\n",
+ nod_u->pax_c, strerror(errno));
}
nod_u = nod_u->nex_u;
@@ -763,8 +764,8 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
DIR* rid_u = opendir(dir_u->pax_c);
if ( !rid_u ) {
- uL(fprintf(uH, "error opening directory %s: %s\r\n",
- dir_u->pax_c, strerror(errno)));
+ u3l_log("error opening directory %s: %s\r\n",
+ dir_u->pax_c, strerror(errno));
c3_assert(0);
}
@@ -773,9 +774,10 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
struct dirent* out_u;
c3_w err_w;
+
if ( (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) != 0 ) {
- uL(fprintf(uH, "error loading directory %s: %s\r\n",
- dir_u->pax_c, strerror(err_w)));
+ u3l_log("error loading directory %s: %s\r\n",
+ dir_u->pax_c, strerror(err_w));
c3_assert(0);
}
else if ( !out_u ) {
@@ -790,7 +792,7 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
struct stat buf_u;
if ( 0 != stat(pax_c, &buf_u) ) {
- uL(fprintf(uH, "can't stat %s: %s\r\n", pax_c, strerror(errno)));
+ u3l_log("can't stat %s: %s\r\n", pax_c, strerror(errno));
free(pax_c);
continue;
}
@@ -800,13 +802,13 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
if ( 0 == strcmp(pax_c, nod_u->pax_c) ) {
if ( S_ISDIR(buf_u.st_mode) ) {
if ( c3n == nod_u->dir ) {
- uL(fprintf(uH, "not a directory: %s\r\n", nod_u->pax_c));
+ u3l_log("not a directory: %s\r\n", nod_u->pax_c);
c3_assert(0);
}
}
else {
if ( c3y == nod_u->dir ) {
- uL(fprintf(uH, "not a file: %s\r\n", nod_u->pax_c));
+ u3l_log("not a file: %s\r\n", nod_u->pax_c);
c3_assert(0);
}
}
@@ -841,8 +843,8 @@ _unix_update_dir(u3_pier *pir_u, u3_udir* dir_u)
}
if ( closedir(rid_u) < 0 ) {
- uL(fprintf(uH, "error closing directory %s: %s\r\n",
- dir_u->pax_c, strerror(errno)));
+ u3l_log("error closing directory %s: %s\r\n",
+ dir_u->pax_c, strerror(errno));
}
if ( !dir_u->kid_u ) {
@@ -905,8 +907,8 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c)
return u3_nul;
}
else {
- uL(fprintf(uH, "error opening initial file %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error opening initial file %s: %s\r\n",
+ pax_c, strerror(errno));
return u3_nul;
}
}
@@ -917,18 +919,18 @@ _unix_initial_update_file(c3_c* pax_c, c3_c* bas_c)
red_ws = read(fid_i, dat_y, len_ws);
if ( close(fid_i) < 0 ) {
- uL(fprintf(uH, "error closing initial file %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error closing initial file %s: %s\r\n",
+ pax_c, strerror(errno));
}
if ( len_ws != red_ws ) {
if ( red_ws < 0 ) {
- uL(fprintf(uH, "error reading initial file %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error reading initial file %s: %s\r\n",
+ pax_c, strerror(errno));
}
else {
- uL(fprintf(uH, "wrong # of bytes read in initial file %s: %d %d\r\n",
- pax_c, len_ws, red_ws));
+ u3l_log("wrong # of bytes read in initial file %s: %d %d\r\n",
+ pax_c, len_ws, red_ws);
}
free(dat_y);
return u3_nul;
@@ -955,8 +957,8 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
DIR* rid_u = opendir(pax_c);
if ( !rid_u ) {
- uL(fprintf(uH, "error opening initial directory: %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error opening initial directory: %s: %s\r\n",
+ pax_c, strerror(errno));
return u3_nul;
}
@@ -966,8 +968,9 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
c3_w err_w;
if ( 0 != (err_w = u3_readdir_r(rid_u, &ent_u, &out_u)) ) {
- uL(fprintf(uH, "error loading initial directory %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error loading initial directory %s: %s\r\n",
+ pax_c, strerror(errno));
+
c3_assert(0);
}
else if ( !out_u ) {
@@ -982,8 +985,8 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
struct stat buf_u;
if ( 0 != stat(pox_c, &buf_u) ) {
- uL(fprintf(uH, "initial can't stat %s: %s\r\n",
- pox_c, strerror(errno)));
+ u3l_log("initial can't stat %s: %s\r\n",
+ pox_c, strerror(errno));
free(pox_c);
continue;
}
@@ -1000,8 +1003,8 @@ _unix_initial_update_dir(c3_c* pax_c, c3_c* bas_c)
}
if ( closedir(rid_u) < 0 ) {
- uL(fprintf(uH, "error closing initial directory %s: %s\r\n",
- pax_c, strerror(errno)));
+ u3l_log("error closing initial directory %s: %s\r\n",
+ pax_c, strerror(errno));
}
return can;
@@ -1018,26 +1021,6 @@ u3_unix_initial_into_card(c3_c* arv_c)
u3nq(c3__into, u3_nul, c3y, can));
}
-/* _unix_sign_cb: signal callback.
-*/
-static void
-_unix_sign_cb(uv_signal_t* sil_u, c3_i num_i)
-{
- {
- switch ( num_i ) {
- default: fprintf(stderr, "\r\nmysterious signal %d\r\n", num_i); break;
- case SIGTERM:
- u3_pier_exit(u3_pier_stub());
- break;
- case SIGINT:
- fprintf(stderr, "\r\ninterrupt\r\n");
- u3_term_ef_ctlc();
- break;
- case SIGWINCH: u3_term_ef_winc(); break;
- }
- }
-}
-
/* _unix_sync_file(): sync file to unix
*/
static void
@@ -1111,16 +1094,16 @@ _unix_sync_change(u3_pier *pir_u, u3_udir* dir_u, u3_noun pax, u3_noun mim)
if ( c3n == u3du(pax) ) {
if ( u3_nul == pax ) {
- uL(fprintf(uH,"can't sync out file as top-level, strange\r\n"));
+ u3l_log("can't sync out file as top-level, strange\r\n");
}
else {
- uL(fprintf(uH,"sync out: bad path\r\n"));
+ u3l_log("sync out: bad path\r\n");
}
u3z(pax); u3z(mim);
return;
}
else if ( c3n == u3du(u3t(pax)) ) {
- uL(fprintf(uH,"can't sync out file as top-level, strangely\r\n"));
+ u3l_log("can't sync out file as top-level, strangely\r\n");
u3z(pax); u3z(mim);
}
else {
@@ -1150,8 +1133,7 @@ _unix_sync_change(u3_pier *pir_u, u3_udir* dir_u, u3_noun pax, u3_noun mim)
}
if ( c3n == nod_u->dir ) {
- uL(fprintf(uH,
- "weird, we got a file when we weren't expecting to\r\n"));
+ u3l_log("weird, we got a file when we weren't expecting to\r\n");
c3_assert(0);
}
@@ -1217,8 +1199,6 @@ u3_unix_ef_hill(u3_pier *pir_u, u3_noun hil)
_unix_scan_mount_point(pir_u, mon_u);
}
u3z(hil);
- pir_u->unx_u->dyr = c3y;
- u3_unix_ef_look(pir_u, c3y);
}
/* u3_unix_io_init(): initialize unix sync.
@@ -1245,7 +1225,7 @@ u3_unix_acquire(c3_c* pax_c)
if ( NULL != (loq_u = fopen(paf_c, "r")) ) {
if ( 1 != fscanf(loq_u, "%" SCNu32, &pid_w) ) {
- uL(fprintf(uH, "lockfile %s is corrupt!\n", paf_c));
+ u3l_log("lockfile %s is corrupt!\n", paf_c);
kill(getpid(), SIGTERM);
sleep(1); c3_assert(0);
}
@@ -1253,8 +1233,8 @@ u3_unix_acquire(c3_c* pax_c)
c3_w i_w;
if ( -1 != kill(pid_w, SIGTERM) ) {
- uL(fprintf(uH, "unix: stopping process %d, live in %s...\n",
- pid_w, pax_c));
+ u3l_log("unix: stopping process %d, live in %s...\n",
+ pid_w, pax_c);
for ( i_w = 0; i_w < 16; i_w++ ) {
sleep(1);
@@ -1271,10 +1251,10 @@ u3_unix_acquire(c3_c* pax_c)
}
}
if ( 16 == i_w ) {
- uL(fprintf(uH, "process %d seems unkillable!\n", pid_w));
+ u3l_log("process %d seems unkillable!\n", pid_w);
c3_assert(0);
}
- uL(fprintf(uH, "unix: stopped old process %u\n", pid_w));
+ u3l_log("unix: stopped old process %u\n", pid_w);
}
}
fclose(loq_u);
@@ -1311,18 +1291,6 @@ u3_unix_release(c3_c* pax_c)
free(paf_c);
}
-/* u3_unix_ef_hold()
-*/
-void
-u3_unix_ef_hold(void)
-{
- u3_usig* sig_u;
-
- for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
- uv_signal_stop(&sig_u->sil_u);
- }
-}
-
/* u3_unix_ef_bake(): initial effects for new process.
*/
void
@@ -1333,18 +1301,6 @@ u3_unix_ef_bake(u3_pier *pir_u)
u3nc(c3__boat, u3_nul));
}
-/* u3_unix_ef_move()
-*/
-void
-u3_unix_ef_move(void)
-{
- u3_usig* sig_u;
-
- for ( sig_u = u3_Host.sig_u; sig_u; sig_u = sig_u->nex_u ) {
- uv_signal_start(&sig_u->sil_u, _unix_sign_cb, sig_u->num_i);
- }
-}
-
/* u3_unix_ef_look(): update the root.
*/
void
@@ -1366,7 +1322,6 @@ void
u3_unix_io_talk(u3_pier *pir_u)
{
u3_unix_acquire(pir_u->pax_c);
- u3_unix_ef_move();
}
/* u3_unix_io_exit(): terminate unix I/O.
diff --git a/pkg/urbit/vere/walk.c b/pkg/urbit/vere/walk.c
index 34b45e39f..e3af728b2 100644
--- a/pkg/urbit/vere/walk.c
+++ b/pkg/urbit/vere/walk.c
@@ -47,7 +47,7 @@ u3_walk_safe(c3_c* pas_c)
c3_y* pad_y;
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
- // uL(fprintf(uH, "%s: %s\n", pas_c, strerror(errno)));
+ // u3l_log("%s: %s\n", pas_c, strerror(errno));
return 0;
}
fln_w = buf_b.st_size;
@@ -79,7 +79,7 @@ u3_walk_load(c3_c* pas_c)
c3_y* pad_y;
if ( (fid_i < 0) || (fstat(fid_i, &buf_b) < 0) ) {
- uL(fprintf(uH, "%s: %s\n", pas_c, strerror(errno)));
+ u3l_log("%s: %s\n", pas_c, strerror(errno));
return u3m_bail(c3__fail);
}
fln_w = buf_b.st_size;
@@ -125,7 +125,7 @@ _walk_mkdirp(c3_c* bas_c, u3_noun pax)
pax_c[len_w] = '\0';
if ( 0 != mkdir(pax_c, 0755) && EEXIST != errno ) {
- uL(fprintf(uH, "error mkdiring %s: %s\n", pax_c, strerror(errno)));
+ u3l_log("error mkdiring %s: %s\n", pax_c, strerror(errno));
u3m_bail(c3__fail);
}
@@ -148,7 +148,7 @@ u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax)
return u3_walk_save(pas_c, tim, pad, 0, u3_nul);
}
- uL(fprintf(uH, "%s: %s\n", pas_c, strerror(errno)));
+ u3l_log("%s: %s\n", pas_c, strerror(errno));
u3m_bail(c3__fail);
}
@@ -163,7 +163,7 @@ u3_walk_save(c3_c* pas_c, u3_noun tim, u3_atom pad, c3_c* bas_c, u3_noun pax)
free(pad_y);
if ( rit_w != fln_w ) {
- uL(fprintf(uH, "%s: %s\n", pas_c, strerror(errno)));
+ u3l_log("%s: %s\n", pas_c, strerror(errno));
u3m_bail(c3__fail);
}
@@ -193,7 +193,7 @@ _walk_in(const c3_c* dir_c, c3_w len_w)
struct dirent* out_n;
if ( u3_readdir_r(dir_d, &ent_n, &out_n) != 0 ) {
- uL(fprintf(uH, "%s: %s\n", dir_c, strerror(errno)));
+ u3l_log("%s: %s\n", dir_c, strerror(errno));
break;
}
else if ( !out_n ) {
@@ -275,7 +275,7 @@ u3_walk(const c3_c* dir_c, u3_noun old)
struct stat buf_b;
if ( 0 != stat(dir_c, &buf_b) ) {
- uL(fprintf(uH, "can't stat %s\n", dir_c));
+ u3l_log("can't stat %s\n", dir_c);
// return u3m_bail(c3__fail);
c3_assert(0);
}
diff --git a/pkg/urbit/serf/main.c b/pkg/urbit/worker/main.c
similarity index 73%
rename from pkg/urbit/serf/main.c
rename to pkg/urbit/worker/main.c
index 4373bab90..b27c25647 100644
--- a/pkg/urbit/serf/main.c
+++ b/pkg/urbit/worker/main.c
@@ -1,4 +1,4 @@
-/* vere/serf.c
+/* worker/main.c
**
** the main loop of a worker process.
*/
@@ -24,7 +24,7 @@
#include "all.h"
#include
- typedef struct _u3_serf {
+ typedef struct _u3_worker {
c3_w len_w; // boot sequence length
c3_d evt_d; // last event processed
c3_l mug_l; // hash of state
@@ -32,14 +32,14 @@
u3_moat inn_u; // message input
u3_mojo out_u; // message output
c3_c* dir_c; // execution directory (pier)
- } u3_serf;
- static u3_serf u3V;
+ } u3_worker;
+ static u3_worker u3V;
/*
-:: serf-lord protocol:
+:: worker to daemon protocol
::
|%
-:: +plea: from serf to lord
+:: +plea: from worker to daemon
::
+$ plea
$% :: status on startup
@@ -72,8 +72,25 @@
:: r: replacement event (at date)
::
[p=@ q=@ r=(pair date ovum)]
+ ==
+ :: sends a line to stderr while computing event
+ ::
+ $: %stdr
+ :: p: event number
+ :: q: output cord
+ ::
+ [p=@ q=cord]
+ ==
+ :: send slog hint while computing event
+ ::
+ $: %slog
+ :: p: event number
+ :: q: priority
+ :: r: output tank
+ ::
+ [p=@ q=@ r=tank]
== ==
-:: +writ: from lord to serf
+:: +writ: from daemon to worker
::
+$ writ
$% :: prepare to boot
@@ -105,20 +122,20 @@
--
*/
-/* _serf_space(): print n spaces.
+/* _worker_space(): print n spaces.
*/
-void _serf_space(FILE* fil_u, c3_w n)
+void _worker_space(FILE* fil_u, c3_w n)
{
for (; n > 0; n--)
(fprintf(fil_u," "));
}
-/* _serf_print_memory(): print memory amount.
+/* _worker_print_memory(): print memory amount.
**
-** Helper for _serf_prof(), just an un-captioned u3a_print_memory().
+** Helper for _worker_prof(), just an un-captioned u3a_print_memory().
*/
void
-_serf_print_memory(FILE* fil_u, c3_w wor_w)
+_worker_print_memory(FILE* fil_u, c3_w wor_w)
{
c3_w byt_w = (wor_w * 4);
c3_w gib_w = (byt_w / 1000000000);
@@ -141,21 +158,21 @@ _serf_print_memory(FILE* fil_u, c3_w wor_w)
}
}
-/* _serf_prof(): print memory profile. RETAIN.
+/* _worker_prof(): print memory profile. RETAIN.
*/
c3_w
-_serf_prof(FILE* fil_u, c3_w den, u3_noun mas)
+_worker_prof(FILE* fil_u, c3_w den, u3_noun mas)
{
c3_w tot_w = 0;
u3_noun h_mas, t_mas;
if ( c3n == u3r_cell(mas, &h_mas, &t_mas) ) {
- _serf_space(fil_u, den);
+ _worker_space(fil_u, den);
fprintf(fil_u, "mistyped mass\r\n");
return tot_w;
}
else if ( _(u3du(h_mas)) ) {
- _serf_space(fil_u, den);
+ _worker_space(fil_u, den);
fprintf(fil_u, "mistyped mass head\r\n");
{
c3_c* lab_c = u3m_pretty(h_mas);
@@ -165,7 +182,7 @@ _serf_prof(FILE* fil_u, c3_w den, u3_noun mas)
return tot_w;
}
else {
- _serf_space(fil_u, den);
+ _worker_space(fil_u, den);
{
c3_c* lab_c = u3m_pretty(h_mas);
@@ -181,7 +198,7 @@ _serf_prof(FILE* fil_u, c3_w den, u3_noun mas)
}
else if ( c3y == it_mas ) {
tot_w += u3a_mark_noun(tt_mas);
- _serf_print_memory(fil_u, tot_w);
+ _worker_print_memory(fil_u, tot_w);
#if 1
/* The basic issue here is that tt_mas is included in
@@ -216,29 +233,29 @@ _serf_prof(FILE* fil_u, c3_w den, u3_noun mas)
fprintf(fil_u, "\r\n");
while ( _(u3du(tt_mas)) ) {
- tot_w += _serf_prof(fil_u, den+2, u3h(tt_mas));
+ tot_w += _worker_prof(fil_u, den+2, u3h(tt_mas));
tt_mas = u3t(tt_mas);
}
- _serf_space(fil_u, den);
+ _worker_space(fil_u, den);
fprintf(fil_u, "--");
- _serf_print_memory(fil_u, tot_w);
+ _worker_print_memory(fil_u, tot_w);
return tot_w;
}
else {
- _serf_space(fil_u, den);
+ _worker_space(fil_u, den);
fprintf(fil_u, "mistyped (strange) mass tail\r\n");
return tot_w;
}
}
}
-/* _serf_grab(): garbage collect, checking for profiling. RETAIN.
+/* _worker_grab(): garbage collect, checking for profiling. RETAIN.
*/
static void
-_serf_grab(u3_noun sac, u3_noun ovo, u3_noun vir)
+_worker_grab(u3_noun sac, u3_noun ovo, u3_noun vir)
{
if ( u3_nul == sac) {
if ( u3C.wag_w & (u3o_debug_ram | u3o_check_corrupt) ) {
@@ -281,7 +298,7 @@ _serf_grab(u3_noun sac, u3_noun ovo, u3_noun vir)
c3_assert( u3R == &(u3H->rod_u) );
fprintf(fil_u, "\r\n");
- usr_w = _serf_prof(fil_u, 0, sac);
+ usr_w = _worker_prof(fil_u, 0, sac);
u3a_print_memory(fil_u, "total userspace", usr_w);
man_w = u3m_mark(fil_u);
@@ -307,64 +324,80 @@ _serf_grab(u3_noun sac, u3_noun ovo, u3_noun vir)
}
}
-/* _serf_fail(): failure stub.
+/* _worker_fail(): failure stub.
*/
static void
-_serf_fail(void* vod_p, const c3_c* wut_c)
+_worker_fail(void* vod_p, const c3_c* wut_c)
{
- fprintf(stderr, "serf: fail: %s\r\n", wut_c);
+ u3l_log("worker: fail: %s\r\n", wut_c);
exit(1);
}
-/* _serf_send(): send result back to lord.
+/* _worker_send(): send result back to daemon.
*/
static void
-_serf_send(u3_noun job)
+_worker_send(u3_noun job)
{
u3_newt_write(&u3V.out_u, u3ke_jam(job), 0);
}
-/* _serf_send_replace(): send replacement job back to lord.
+/* _worker_send_replace(): send replacement job back to daemon.
*/
static void
-_serf_send_replace(c3_d evt_d, u3_noun ovo)
+_worker_send_replace(c3_d evt_d, u3_noun ovo)
{
- fprintf(stderr, "serf_send_replace %" PRIu64 " %s\r\n",
- evt_d,
- u3r_string(u3h(u3t(ovo))));
+ u3l_log("worker_send_replace %" PRIu64 " %s\r\n",
+ evt_d,
+ u3r_string(u3h(u3t(ovo))));
- _serf_send(u3nq(c3__work,
- u3i_chubs(1, &evt_d),
- u3V.mug_l,
- u3nc(u3k(u3A->now), ovo)));
+ _worker_send(u3nq(c3__work,
+ u3i_chubs(1, &evt_d),
+ u3V.mug_l,
+ u3nc(u3k(u3A->now), ovo)));
}
-/* _serf_send_complete(): report completion.
+/* _worker_send_complete(): report completion.
*/
static void
-_serf_send_complete(u3_noun vir)
+_worker_send_complete(u3_noun vir)
{
- _serf_send(u3nq(c3__done,
- u3i_chubs(1, &u3V.evt_d),
- u3r_mug(u3A->roc),
- vir));
+ _worker_send(u3nq(c3__done,
+ u3i_chubs(1, &u3V.evt_d),
+ u3r_mug(u3A->roc),
+ vir));
}
-/* _serf_lame(): event failed, replace with error event.
+/* _worker_send_stdr(): send stderr output
*/
static void
-_serf_lame(c3_d evt_d, u3_noun ovo, u3_noun why, u3_noun tan)
+_worker_send_stdr(c3_c* str_c)
+{
+ _worker_send(u3nt(c3__stdr, u3i_chubs(1, &u3V.evt_d), u3i_string(str_c)));
+}
+
+/* _worker_send_slog(): send hint output (hod is [priority tank]).
+*/
+static void
+_worker_send_slog(u3_noun hod)
+{
+ _worker_send(u3nt(c3__slog, u3i_chubs(1, &u3V.evt_d), hod));
+}
+
+/* _worker_lame(): event failed, replace with error event.
+*/
+static void
+_worker_lame(c3_d evt_d, u3_noun ovo, u3_noun why, u3_noun tan)
{
// %crud will be sent on the original wire.
//
- _serf_send_replace(evt_d, u3nc(u3k(u3h(ovo)), u3nt(c3__crud, why, tan)));
+ _worker_send_replace(evt_d, u3nc(u3k(u3h(ovo)), u3nt(c3__crud, why, tan)));
u3z(ovo);
}
-/* _serf_sure(): event succeeded, report completion.
+/* _worker_sure(): event succeeded, report completion.
*/
static void
-_serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
+_worker_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
{
u3z(u3A->roc);
u3A->roc = cor;
@@ -388,7 +421,7 @@ _serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
sac = u3k(u3t(fec));
// replace the %mass data with ~
//
- // For efficient transmission to king.
+ // For efficient transmission to daemon.
//
riv = u3kb_weld(u3qb_scag(i_w, vir),
u3nc(u3nt(u3k(u3h(u3h(riv))), c3__mass, u3_nul),
@@ -411,18 +444,18 @@ _serf_sure(u3_noun ovo, u3_noun vir, u3_noun cor)
// XX this runs on replay too
//
- _serf_grab(sac, ovo, vir);
- _serf_send_complete(vir);
+ _worker_grab(sac, ovo, vir);
+ _worker_send_complete(vir);
u3z(sac); u3z(ovo);
}
-/* _serf_work_live(): apply event.
+/* _worker_work_live(): apply event.
*/
static void
-_serf_work_live(c3_d evt_d, // event number
- c3_l mug_l, // mug of state
- u3_noun job) // event date
+_worker_work_live(c3_d evt_d, // event number
+ c3_l mug_l, // mug of state
+ u3_noun job) // event date
{
u3_noun now, ovo, gon;
@@ -448,7 +481,7 @@ _serf_work_live(c3_d evt_d, // event number
if ( c3__belt != u3h(u3t(ovo)) ) {
c3_c* txt_c = u3r_string(u3h(u3t(ovo)));
- fprintf(stderr, "serf: %s (%" PRIu64 ") live\r\n", txt_c, evt_d);
+ u3l_log("worker: %s (%" PRIu64 ") live\r\n", txt_c, evt_d);
}
}
#endif
@@ -466,9 +499,9 @@ _serf_work_live(c3_d evt_d, // event number
ms_w = (d0.tv_sec * 1000) + (d0.tv_usec / 1000);
clr_w = ms_w > 1000 ? 1 : ms_w < 100 ? 2 : 3; // red, green, yellow
if (c3__belt != u3h(u3t(ovo)) || clr_w != 2) {
- uL(fprintf(uH, "\x1b[3%dm%%%s (%" PRIu64 ") %4d.%02dms\x1b[0m\n",
- clr_w, txt_c, evt_d, ms_w,
- (int) (d0.tv_usec % 1000) / 10));
+ u3l_log("\x1b[3%dm%%%s (%" PRIu64 ") %4d.%02dms\x1b[0m\n",
+ clr_w, txt_c, evt_d, ms_w,
+ (int) (d0.tv_usec % 1000) / 10);
}
free(txt_c);
}
@@ -483,7 +516,7 @@ _serf_work_live(c3_d evt_d, // event number
u3k(ovo); u3k(why); u3k(tan);
u3z(gon); u3z(job);
- _serf_lame(evt_d, ovo, why, tan);
+ _worker_lame(evt_d, ovo, why, tan);
}
else {
// event accepted
@@ -500,7 +533,7 @@ _serf_work_live(c3_d evt_d, // event number
u3k(ovo); u3k(vir); u3k(cor);
u3z(gon); u3z(job);
- _serf_sure(ovo, vir, cor);
+ _worker_sure(ovo, vir, cor);
// reclaim memory from persistent caches on |reset
//
@@ -510,10 +543,10 @@ _serf_work_live(c3_d evt_d, // event number
}
}
-/* _serf_boot_fire(): execute boot sequence.
+/* _worker_boot_fire(): execute boot sequence.
*/
static u3_noun
-_serf_boot_fire(u3_noun eve)
+_worker_boot_fire(u3_noun eve)
{
// XX virtualize? use u3v_boot?
//
@@ -526,10 +559,10 @@ _serf_boot_fire(u3_noun eve)
return pro;
}
-/* _serf_work_boot(): apply initial-stage event.
+/* _worker_work_boot(): apply initial-stage event.
*/
static void
-_serf_work_boot(c3_d evt_d,
+_worker_work_boot(c3_d evt_d,
c3_l mug_l,
u3_noun job)
{
@@ -538,7 +571,7 @@ _serf_work_boot(c3_d evt_d,
u3A->roe = u3nc(job, u3A->roe);
- fprintf(stderr, "serf: (%" PRIu64 ")| boot\r\n", evt_d);
+ u3l_log("worker: (%" PRIu64 ")| boot\r\n", evt_d);
if ( u3V.len_w == evt_d ) {
u3_noun eve, pru;
@@ -546,34 +579,34 @@ _serf_work_boot(c3_d evt_d,
eve = u3kb_flop(u3A->roe);
u3A->roe = 0;
- fprintf(stderr, "serf: (%" PRIu64 ")| pill: %x\r\n", evt_d, u3r_mug(eve));
+ u3l_log("worker: (%" PRIu64 ")| pill: %x\r\n", evt_d, u3r_mug(eve));
- pru = u3m_soft(0, _serf_boot_fire, eve);
+ pru = u3m_soft(0, _worker_boot_fire, eve);
if ( u3_blip != u3h(pru) ) {
- fprintf(stderr, "boot failed\r\n");
+ u3l_log("boot failed\r\n");
exit(1);
}
u3A->roc = u3k(u3t(pru));
- fprintf(stderr, "serf: (%" PRIu64 ")| core: %x\r\n", evt_d, u3r_mug(u3A->roc));
+ u3l_log("worker: (%" PRIu64 ")| core: %x\r\n", evt_d, u3r_mug(u3A->roc));
// XX set u3A->evt_d ?
//
u3z(pru);
}
- _serf_send(u3nq(c3__done,
- u3i_chubs(1, &evt_d),
- 0,
- u3_nul));
+ _worker_send(u3nq(c3__done,
+ u3i_chubs(1, &evt_d),
+ 0,
+ u3_nul));
}
-/* _serf_poke_work(): apply event.
+/* _worker_poke_work(): apply event.
*/
static void
-_serf_poke_work(c3_d evt_d, // event number
+_worker_poke_work(c3_d evt_d, // event number
c3_l mug_l, // mug of state
u3_noun job) // full event
{
@@ -592,7 +625,7 @@ _serf_poke_work(c3_d evt_d, // event number
snprintf(lab_c, 8, "boot: %" PRIu64 "", evt_d);
u3t_event_trace(lab_c, 'B');
- _serf_work_boot(evt_d, mug_l, job);
+ _worker_work_boot(evt_d, mug_l, job);
u3t_event_trace(lab_c, 'E');
}
else {
@@ -604,23 +637,27 @@ _serf_poke_work(c3_d evt_d, // event number
u3m_pretty_path(wir), u3m_pretty(cad));
u3t_event_trace(lab_c, 'B');
- _serf_work_live(evt_d, mug_l, job);
+ _worker_work_live(evt_d, mug_l, job);
u3t_event_trace(lab_c, 'E');
}
}
-/* _serf_poke_exit(): exit on command.
+/* _worker_poke_exit(): exit on command.
*/
static void
-_serf_poke_exit(c3_w cod_w) // exit code
+_worker_poke_exit(c3_w cod_w) // exit code
{
+ if ( u3C.wag_w & u3o_debug_cpu ) {
+ u3t_damp();
+ }
+
exit(cod_w);
}
-/* _serf_poke_boot(): prepare to boot.
+/* _worker_poke_boot(): prepare to boot.
*/
static void
-_serf_poke_boot(u3_noun who, u3_noun fak, c3_w len_w)
+_worker_poke_boot(u3_noun who, u3_noun fak, c3_w len_w)
{
c3_assert( u3_none == u3A->our );
c3_assert( 0 != len_w );
@@ -630,10 +667,10 @@ _serf_poke_boot(u3_noun who, u3_noun fak, c3_w len_w)
u3V.len_w = len_w;
}
-/* _serf_poke():
+/* _worker_poke():
*/
void
-_serf_poke(void* vod_p, u3_noun mat)
+_worker_poke(void* vod_p, u3_noun mat)
{
u3_noun jar = u3ke_cue(mat);
@@ -666,7 +703,7 @@ _serf_poke(void* vod_p, u3_noun mat)
u3k(fak);
u3z(jar);
- return _serf_poke_boot(who, fak, len_w);
+ return _worker_poke_boot(who, fak, len_w);
}
case c3__work: {
@@ -688,7 +725,7 @@ _serf_poke(void* vod_p, u3_noun mat)
u3k(job);
u3z(jar);
- return _serf_poke_work(evt_d, mug_l, job);
+ return _worker_poke_work(evt_d, mug_l, job);
}
case c3__exit: {
@@ -705,7 +742,7 @@ _serf_poke(void* vod_p, u3_noun mat)
cod_w = u3r_word(0, cod);
u3z(jar);
- return _serf_poke_exit(cod_w);
+ return _worker_poke_exit(cod_w);
}
case c3__save: {
@@ -730,14 +767,14 @@ _serf_poke(void* vod_p, u3_noun mat)
error: {
u3z(jar);
- _serf_fail(0, "bad jar");
+ _worker_fail(0, "bad jar");
}
}
-/* u3_serf_boot(): send startup message to manager.
+/* u3_worker_boot(): send startup message to manager.
*/
void
-u3_serf_boot(void)
+u3_worker_boot(void)
{
c3_d nex_d = 1ULL;
u3_noun dat = u3_nul;
@@ -759,9 +796,9 @@ u3_serf_boot(void)
u3V.len_w = 0;
}
- fprintf(stderr, "serf: play %" PRIu64 "\r\n", nex_d);
+ u3l_log("worker: play %" PRIu64 "\r\n", nex_d);
- _serf_send(u3nc(c3__play, dat));
+ _worker_send(u3nc(c3__play, dat));
}
/* main(): main() when run as urbit-worker
@@ -811,9 +848,11 @@ main(c3_i argc, c3_c* argv[])
*/
{
u3V.evt_d = u3m_boot_new(dir_c);
+ u3C.stderr_log_f = _worker_send_stdr;
+ u3C.slog_f = _worker_send_slog;
}
- /* configure pipe to lord process
+ /* configure pipe to daemon process
*/
{
c3_i err_i;
@@ -829,19 +868,19 @@ main(c3_i argc, c3_c* argv[])
/* set up writing
*/
- u3V.out_u.bal_f = _serf_fail;
+ u3V.out_u.bal_f = _worker_fail;
/* start reading
*/
u3V.inn_u.vod_p = &u3V;
- u3V.inn_u.pok_f = _serf_poke;
- u3V.inn_u.bal_f = _serf_fail;
+ u3V.inn_u.pok_f = _worker_poke;
+ u3V.inn_u.bal_f = _worker_fail;
u3_newt_read(&u3V.inn_u);
/* send start request
*/
- u3_serf_boot();
+ u3_worker_boot();
/* enter loop
*/
diff --git a/sh/load-arvo b/sh/load-arvo
index 2c21aadb4..674f62e59 100755
--- a/sh/load-arvo
+++ b/sh/load-arvo
@@ -10,12 +10,12 @@ ship=$1
test -d $ship/.urb
test -f $ship/.vere.lock
-urb $ship -p hood -d '+hood/autoload |'
+herb $ship -p hood -d '+hood/autoload |'
-urb $ship -p hood -d "+hood/mount %"
+herb $ship -p hood -d "+hood/mount %"
rm -r $ship/home
cp -r pkg/arvo $ship/home
-urb $ship -p hood -d "+hood/commit %home"
+herb $ship -p hood -d "+hood/commit %home"
diff --git a/sh/mk-bootbus b/sh/mk-bootbus
index 2814752da..f69b6250a 100755
--- a/sh/mk-bootbus
+++ b/sh/mk-bootbus
@@ -17,5 +17,5 @@ fi
pkg=$(nix-build nix/ops -A bootbus --no-out-link)
mkdir -p "$(dirname "$target")"
-cp -L -r $pkg/ $target
+cp -r $pkg/ $target
chmod -R u+rw $target
diff --git a/sh/mk-bootzod b/sh/mk-bootzod
index 0b33a72f0..f45ade5a1 100755
--- a/sh/mk-bootzod
+++ b/sh/mk-bootzod
@@ -17,5 +17,5 @@ fi
pkg=$(nix-build nix/ops -A bootzod --no-out-link)
mkdir -p "$(dirname "$target")"
-cp -L -r $pkg/ $target
+cp -r $pkg/ $target
chmod -R u+rw $target
diff --git a/sh/mk-fakezod b/sh/mk-fakezod
index 4dc5d1832..7ae178b9e 100755
--- a/sh/mk-fakezod
+++ b/sh/mk-fakezod
@@ -17,5 +17,5 @@ fi
pkg=$(nix-build nix/ops -A fakezod --no-out-link)
mkdir -p "$(dirname "$target")"
-cp -L -r $pkg/ $target
+cp -r $pkg/ $target
chmod -R u+rw $target
diff --git a/sh/release b/sh/release
index 50900a6df..7945f6e2e 100755
--- a/sh/release
+++ b/sh/release
@@ -22,3 +22,6 @@ res=$(release "$env.$pkg")
mkdir -p ./bin/$env
traced cp -f $res/bin/$pkg ./bin/$env/$pkg
traced cp -f $res/bin/$pkg-worker ./bin/$env/$pkg-worker
+traced cp -r $res/bin/$pkg-terminfo ./bin/$env/$pkg-terminfo
+
+chmod -R u+wr ./bin/$env/$pkg-terminfo