guix: point to latest upstream master #24300

pull fanquake wants to merge 1 commits into bitcoin:master from fanquake:reenable_win_guix changing 1 files +1 −1
  1. fanquake commented at 3:54 pm on February 9, 2022: member

    Now that Carls fix for binutils and compressed debug sections has been merged into Guix, point our time-machine to the latest commit on Guix master. The Windows builds don’t yet work with this change, but we are now at the point of compiling our own code..

    There must be a difference in the Guix environment, compared to, for example, compiling using GCC 10.3 on Ubuntu Hirsute, which currently works.

    Opening this PR for testing / discussion:

     0Making all in src
     1make[1]: Entering directory '/distsrc-base/distsrc-f6ff8d8604f6-x86_64-w64-mingw32/src'
     2make[2]: Entering directory '/distsrc-base/distsrc-f6ff8d8604f6-x86_64-w64-mingw32/src'
     3  CXX      bitcoind-bitcoind.o
     4  CXX      libbitcoin_node_a-addrdb.o
     5  CXX      libbitcoin_node_a-addrman.o
     6  CXX      libbitcoin_node_a-banman.o
     7  GEN      bitcoind-res.o
     8  CXX      libbitcoin_node_a-blockencodings.o
     9  CXX      libbitcoin_node_a-blockfilter.o
    10  CXX      libbitcoin_node_a-chain.o
    11  CXX      libbitcoin_node_a-dbwrapper.o
    12  CXX      libbitcoin_node_a-deploymentstatus.o
    13  CXX      libbitcoin_node_a-flatfile.o
    14  CXX      libbitcoin_node_a-httprpc.o
    15  CXX      libbitcoin_node_a-httpserver.o
    16  CXX      libbitcoin_node_a-i2p.o
    17  CXX      libbitcoin_node_a-init.o
    18  CXX      libbitcoin_node_a-mapport.o
    19  CXX      libbitcoin_node_a-net.o
    20  CXX      libbitcoin_node_a-net_processing.o
    21  CXX      libbitcoin_node_a-noui.o
    22  CXX      libbitcoin_node_a-pow.o
    23  CXX      libbitcoin_node_a-rest.o
    24  CXX      libbitcoin_node_a-shutdown.o
    25In file included from init.cpp:78:
    26/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream: In instantiation of 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode) [with _Path = fs::path; _Require = fs::path; _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::ios_base::openmode]':
    27init.cpp:143:40:   required from here
    28/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:844:38: error: no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(const value_type*, std::ios_base::openmode&)'
    29  844 |  : basic_ofstream(__s.c_str(), __mode)
    30      |                                      ^
    31/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:850:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(std::basic_ofstream<_CharT, _Traits>&&) [with _CharT = char; _Traits = std::char_traits<char>]'
    32  850 |       basic_ofstream(basic_ofstream&& __rhs)
    33      |       ^~~~~~~~~~~~~~
    34/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:850:7: note:   candidate expects 1 argument, 2 provided
    35/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:842:2: note: candidate: 'template<class _Path, class _Require> std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode) [with _Path = _Path; _Require = _Require; _CharT = char; _Traits = std::char_traits<char>]'
    36  842 |  basic_ofstream(const _Path& __s,
    37      |  ^~~~~~~~~~~~~~
    38/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:842:2: note:   template argument deduction/substitution failed:
    39/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:841:32: error: request for member 'make_preferred' in 'std::declval<const wchar_t*&>()', which is of non-class type 'const wchar_t*'
    40  841 |       template<typename _Path, typename _Require = _If_fs_path<_Path>>
    41      |                                ^~~~~~~~
    42/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:825:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::ios_base::openmode]'
    43  825 |       basic_ofstream(const std::string& __s,
    44      |       ^~~~~~~~~~~~~~
    45/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:825:41: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
    46  825 |       basic_ofstream(const std::string& __s,
    47      |                      ~~~~~~~~~~~~~~~~~~~^~~
    48/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:790:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::ios_base::openmode]'
    49  790 |       basic_ofstream(const char* __s,
    50      |       ^~~~~~~~~~~~~~
    51/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:790:34: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const char*'
    52  790 |       basic_ofstream(const char* __s,
    53      |                      ~~~~~~~~~~~~^~~
    54/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:779:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char; _Traits = std::char_traits<char>]'
    55  779 |       basic_ofstream(): __ostream_type(), _M_filebuf()
    56      |       ^~~~~~~~~~~~~~
    57/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:779:7: note:   candidate expects 0 arguments, 2 provided
    58/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:844:38: error: no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(const value_type*, std::ios_base::openmode&)'
    59  844 |  : basic_ofstream(__s.c_str(), __mode)
    60      |                                      ^
    61/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:850:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(std::basic_ofstream<_CharT, _Traits>&&) [with _CharT = char; _Traits = std::char_traits<char>]'
    62  850 |       basic_ofstream(basic_ofstream&& __rhs)
    63      |       ^~~~~~~~~~~~~~
    64/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:850:7: note:   candidate expects 1 argument, 2 provided
    65/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:842:2: note: candidate: 'template<class _Path, class _Require> std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode) [with _Path = _Path; _Require = _Require; _CharT = char; _Traits = std::char_traits<char>]'
    66  842 |  basic_ofstream(const _Path& __s,
    67      |  ^~~~~~~~~~~~~~
    68/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:842:2: note:   template argument deduction/substitution failed:
    69/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:841:32: error: request for member 'make_preferred' in 'std::declval<const wchar_t*&>()', which is of non-class type 'const wchar_t*'
    70  841 |       template<typename _Path, typename _Require = _If_fs_path<_Path>>
    71      |                                ^~~~~~~~
    72/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:825:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::ios_base::openmode]'
    73  825 |       basic_ofstream(const std::string& __s,
    74      |       ^~~~~~~~~~~~~~
    75/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:825:41: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
    76  825 |       basic_ofstream(const std::string& __s,
    77      |                      ~~~~~~~~~~~~~~~~~~~^~~
    78/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:790:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::ios_base::openmode]'
    79  790 |       basic_ofstream(const char* __s,
    80      |       ^~~~~~~~~~~~~~
    81/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:790:34: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const char*'
    82  790 |       basic_ofstream(const char* __s,
    83      |                      ~~~~~~~~~~~~^~~
    84/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:779:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char; _Traits = std::char_traits<char>]'
    85  779 |       basic_ofstream(): __ostream_type(), _M_filebuf()
    86      |       ^~~~~~~~~~~~~~
    87/gnu/store/k3bs5211ca8hy7hzkj83caiakmj3sh36-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++/fstream:779:7: note:   candidate expects 0 arguments, 2 provided
    88  CXX      libbitcoin_node_a-signet.o
    89  CXX      libbitcoin_node_a-timedata.o
    90  CXX      libbitcoin_node_a-torcontrol.o
    91  CXX      libbitcoin_node_a-txdb.o
    92make[2]: *** [Makefile:9653: libbitcoin_node_a-init.o] Error 1
    93make[2]: *** Waiting for unfinished jobs....
    94make[2]: Leaving directory '/distsrc-base/distsrc-f6ff8d8604f6-x86_64-w64-mingw32/src'
    95make[1]: *** [Makefile:17461: all-recursive] Error 1
    96make[1]: Leaving directory '/distsrc-base/distsrc-f6ff8d8604f6-x86_64-w64-mingw32/src'
    97make: *** [Makefile:816: all-recursive] Error 1
    

    Related to #24055.

  2. guix: point to latest upstream master
    Now that Carls fix for binutils and compressed debug sections when
    targetting windows has been merged into Guix, point our time-machine
    to the latest commit on Guix master.
    
    Related to #24055.
    f6ff8d8604
  3. fanquake added the label Build system on Feb 9, 2022
  4. hebasto commented at 4:41 pm on February 9, 2022: member

    Yesterday I was building against 4be896d6e0d322b3f5b514c8a2811efcd6a31606 Guix commit, and have got the same error.

    The weirdest part of the error message is

    0... error: request for member 'make_preferred' in 'std::declval<const wchar_t*&>()', which is of non-class type 'const wchar_t*'
    

    Friendly ping @dongcarl @ryanofsky

  5. ryanofsky commented at 6:08 pm on February 9, 2022: member

    Fanquake’s error seems to come from this line (based on init.cpp:143:40: required from here)

    https://github.com/bitcoin/bitcoin/blob/f6ff8d8604f65c4cb5392e2259d77439665867e7/src/init.cpp#L143

    Which happens for the reason we are familiar with that std::fstream does not like fs::path objects

    I’m not sure about the other make_preferred error. The place I see us calling that is

    https://github.com/bitcoin/bitcoin/blob/f6ff8d8604f65c4cb5392e2259d77439665867e7/src/test/util/chainstate.h#L40

    which looks ok to me

  6. MarcoFalke commented at 6:27 pm on February 9, 2022: member
    So I guess the solution will be to partially revert fs? That is: std::ofstream -> fs::ofstream.
  7. hebasto commented at 6:34 pm on February 9, 2022: member

    So I guess the solution will be to partially revert fs? That is: std::ofstream -> fs::ofstream.

    FWIW, I’ve tried such approaches in some variants without success..

  8. MarcoFalke commented at 6:40 pm on February 9, 2022: member
    Is there any way to reproduce this outside of guix?
  9. hebasto commented at 7:25 pm on February 10, 2022: member

    I’ve made some investigations. The error does not caused by our fs::path class. A similar error happens when using pure std::filesystem::path.

    I’m not sure about the other make_preferred error.

    It happens during template argument substitution in typename _Require = _If_fs_path<_Path>.

  10. hebasto commented at 8:48 am on February 11, 2022: member
    FWIW, in Guix environment the _GLIBCXX_HAVE__WFOPEN macro is undefined.
  11. hebasto commented at 10:08 am on February 11, 2022: member

    @dongcarl

    Might it be because of: https://salsa.debian.org/mingw-w64-team/gcc-mingw-w64/-/blob/2ee26ff4f275384aa6173ada884929db4d2f1bbf/debian/rules#L228

    I’ve verified this assumption.

    Indeed, in Guix environment the _GLIBCXX_FULLY_DYNAMIC_STRING macro is defined to 0 which differs from non-Guix environment where it is defined to 1.

    The following patch:

     0--- a/contrib/guix/manifest.scm
     1+++ b/contrib/guix/manifest.scm
     2@@ -160,7 +160,7 @@ desirable for building Bitcoin Core release binaries."
     3                         base-gcc))
     4 
     5 (define (make-gcc-with-pthreads gcc)
     6-  (package-with-extra-configure-variable gcc "--enable-threads" "posix"))
     7+  (package-with-extra-configure-variable (package-with-extra-configure-variable gcc "--enable-fully-dynamic-string" "yes") "--enable-threads" "posix"))
     8 
     9 (define (make-mingw-pthreads-cross-toolchain target)
    10   "Create a cross-compilation toolchain package for TARGET"
    

    makes _GLIBCXX_FULLY_DYNAMIC_STRING defined to 1, but the error still exists, unfortunately.

  12. dongcarl commented at 1:08 am on February 12, 2022: member

    Okay leaving a comment here for myself and anyone else who wants to dive in: it seems that _GLIBCXX_FULLY_DYNAMIC_STRING doesn’t really affect this much.

    What does affect it is _GLIBCXX_HAVE__WFOPEN, which is undefined in the Guix environment and defined in the Ubuntu Impish environment. Despite its name it actually affects open and the *fstream constructors, so would match the errors we’re seeing. No --enable-wchar_t=yes does not solve this.

    Additional info:

    How I debug the Guix env:

     0diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh
     1index e06a469338..d7fc617fdd 100755
     2--- a/contrib/guix/libexec/build.sh
     3+++ b/contrib/guix/libexec/build.sh
     4@@ -274,6 +274,8 @@ case "$HOST" in
     5     powerpc64-linux-*|riscv64-linux-*) HOST_LDFLAGS="${HOST_LDFLAGS} -Wl,-z,noexecstack" ;;
     6 esac
     7
     8+bash; exit 1
     9+
    10 # Make $HOST-specific native binaries from depends available in $PATH
    11 export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}"
    12 mkdir -p "$DISTSRC"
    

    Reproducer:

    0#include <filesystem>
    1#include <fstream>
    2
    3namespace fs = std::filesystem;
    4
    5int main() {
    6    fs::path p = "./what";
    7    std::ofstream file{p};
    8    return 0;
    9}
    

    Alt reproducer: (because if (5) works here then we shouldn’t need wchar, so let’s be specific)

    0#include <filesystem>
    1#include <fstream>
    2
    3namespace fs = std::filesystem;
    4
    5int main() {
    6    wchar_t p[] {L"./what"};
    7    std::ofstream file{p};
    8    return 0;
    9}
    

    Compile with:

    0$ x86_64-w64-mingw32-g++ -std=c++17 test.cpp
    

    In impish docker:

    0# x86_64-w64-mingw32-nm -C a.exe | grep stream
    100000000004015d8 T std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(wchar_t const*, std::_Ios_Openmode)
    200000000004015d0 T std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()
    300000000004082d8 I __imp__ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1EPKwSt13_Ios_Openmode
    400000000004082e0 I __imp__ZNSt14basic_ofstreamIcSt11char_traitsIcEED1Ev
    
  13. hebasto commented at 9:50 am on February 12, 2022: member

    FWIW, in Guix environment the _GLIBCXX_HAVE__WFOPEN macro is undefined.

    What does affect it is _GLIBCXX_HAVE__WFOPEN, which is undefined in the Guix environment and defined in the Ubuntu Impish environment. Despite its name it actually affects open and the *fstream constructors, so would match the errors we’re seeing.

    Are mingw headers available at this point https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc++-v3/crossconfig.m4;h=fe1828835368dd5c2c16a20cf4abc52739e52f30;hb=f00b5710a30f22efc3171c393e56aeb335c3cd39#l200:

    0    AC_CHECK_FUNCS(_wfopen)
    

    ?

  14. fanquake deleted a comment on Feb 13, 2022
  15. hebasto commented at 9:37 pm on February 14, 2022: member

    After further investigation, I suspect the following option:

    0                             '("--with-newlib")
    

    I was trying:

     0--- a/contrib/guix/manifest.scm
     1+++ b/contrib/guix/manifest.scm
     2@@ -160,7 +160,7 @@ desirable for building Bitcoin Core release binaries."
     3                         base-gcc))
     4 
     5 (define (make-gcc-with-pthreads gcc)
     6-  (package-with-extra-configure-variable gcc "--enable-threads" "posix"))
     7+  (package-with-extra-configure-variable (package-with-extra-configure-variable gcc "--with-newlib" "no") "--enable-threads" "posix"))
     8 
     9 (define (make-mingw-pthreads-cross-toolchain target)
    10   "Create a cross-compilation toolchain package for TARGET"
    

    but it fails because --with-newlib actually overrides my custom option:

    0configure flags: ("CONFIG_SHELL=/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8/bin/bash" "SHELL=/gnu/store/4y5m9lb8k3qkb1y9m02sw9w9a6hacd16-bash-minimal-5.1.8/bin/bash" "--prefix=/gnu/store/byrh6d5ldyx0i80a39l2q9mns0cd4vp2-gcc-cross-x86_64-w64-mingw32-10.3.0" "--enable-fast-install" "--libdir=/gnu/store/wxjzjz3pajgknmfvj3mg9fvx3l99wmla-gcc-cross-x86_64-w64-mingw32-10.3.0-lib/lib" "--includedir=/gnu/store/wxjzjz3pajgknmfvj3mg9fvx3l99wmla-gcc-cross-x86_64-w64-mingw32-10.3.0-lib/include" "--build=x86_64-unknown-linux-gnu" "--enable-threads=posix" "--with-newlib=no" "--target=x86_64-w64-mingw32" "--disable-libcilkrts" "--with-sysroot=/" "--with-toolexeclibdir=/gnu/store/wxjzjz3pajgknmfvj3mg9fvx3l99wmla-gcc-cross-x86_64-w64-mingw32-10.3.0-lib/x86_64-w64-mingw32/lib" "--with-newlib" "--enable-plugin" "--enable-languages=c,c++" "--disable-multilib" "--with-system-zlib" "--disable-libstdcxx-pch" "--with-local-prefix=/no-gcc-local-prefix" "--with-gxx-include-dir=/gnu/store/byrh6d5ldyx0i80a39l2q9mns0cd4vp2-gcc-cross-x86_64-w64-mingw32-10.3.0/include/c++" "--with-native-system-header-dir=/gnu/store/39m4gjy9dn18r6vcka1iyvl0979zwnv8-mingw-w64-x86_64-winpthreads-8.0.0/include" "CC_FOR_TARGET=x86_64-w64-mingw32-gcc" "CXX_FOR_TARGET=x86_64-w64-mingw32-g++" "LD_FOR_TARGET=x86_64-w64-mingw32-ld" "AR_FOR_TARGET=x86_64-w64-mingw32-ar" "NM_FOR_TARGET=x86_64-w64-mingw32-nm" "OBJDUMP_FOR_TARGET=x86_64-w64-mingw32-objdump" "RANLIB_FOR_TARGET=x86_64-w64-mingw32-ranlib" "STRIP_FOR_TARGET=x86_64-w64-mingw32-strip")
    

    @dongcarl What is the correct way to build with --without-newlib option?

  16. hebasto commented at 11:04 am on February 15, 2022: member

    After further investigation, I suspect the following option:

    0                             '("--with-newlib")
    

    A solution suggested in #24348.

  17. fanquake commented at 12:04 pm on February 15, 2022: member
    Let’s continue discussion in #24348 for now.
  18. fanquake closed this on Feb 15, 2022

  19. fanquake deleted the branch on Feb 15, 2022
  20. fanquake referenced this in commit 97611921be on Feb 17, 2022
  21. sidhujag referenced this in commit 41068c845b on Feb 18, 2022
  22. DrahtBot locked this on Feb 15, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-17 09:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me