nochowderforyou / clams

Clam Project
MIT License
62 stars 58 forks source link

Updates to peer list and a fix for Content length error in winows .. #205

Closed l0rdicon closed 9 years ago

dooglus commented 9 years ago

I wonder how many other places throughout the code this needs changing.

I see this in debug.log on Windows:

keypool added key 1, size=1u
keypool added key 2, size=2u
keypool added key 3, size=3u

Those us are the same u and shouldn't be there. This is only a log file, but there are many other PRIszu's and similar throughout the code.

Does anyone know which C++ compiler is used to cross-compile for Windows, and which flags are used? I'd like to fix this fully but can't without being able to experiment with the compiler.

l0rdicon commented 9 years ago

It is compiled using g++ and mingw-w64.

The entire compile process, including the packages it installs are all in the descriptor https://github.com/nochowderforyou/clams/blob/master/contrib/gitian-descriptors/gitian-win.yml

I'll echo out the MAKEOPTS and post the response, I can't see exactly where MAKEOPTS is set, I would assume somewhere in the dependency building.

https://github.com/nochowderforyou/clams/tree/master/depends

dooglus commented 9 years ago

I was able to reproduce the problem as follows:

$ cat foo.cpp
#include <iostream>
#include "tinyformat.h"

#if defined(_MSC_VER) || defined(__MSVCRT__)
  #define PRIszx    "Ix"
  #define PRIszu    "Iu"
  #define PRIszd    "Id"
  #define PRIpdx    "Ix"
  #define PRIpdu    "Iu"
  #define PRIpdd    "Id"
#else /* C99 standard */
  #define PRIszx    "zx"
  #define PRIszu    "zu"
  #define PRIszd    "zd"
  #define PRIpdx    "tx"
  #define PRIpdu    "tu"
  #define PRIpdd    "td"
#endif

main() {
    std::cout << strprintf("Content-Length1: %"PRIszu"\r\n", 123);
    std::cout << strprintf("Content-Length2: %" PRIszu "\r\n", 123);
}
$ x86_64-w64-mingw32-g++ foo.cpp
$ wine a
Content-Length1: 123u
Content-Length2: 123u
$ 

Note that whether or not you put spaces around the PRIszu, the u still gets printed.

Compiling and running the same code natively doesn't show the u:

$ g++ foo.cpp
$ ./a.out
Content-Length1: 123
Content-Length2: 123
$ 

It appears to me that we don't want to use the non-ANSI %I stuff when using mingw, and so changing the ifdef in util.h from:

#if defined(_MSC_VER) || defined(__MSVCRT__)

to

#if !defined(__MINGW32__) && (defined(_MSC_VER) || defined(__MSVCRT__))

should fix the problem everywhere.

It turns out that mingw defines these 3 in x86_64:

__MSVCRT__
__MINGW32__
__MINGW64__

and these 2 in i686:

__MSVCRT__
__MINGW32__

so checking for the absense of __MINGW32__ before using the MS turds should be sufficient.

I don't know how to dump a list of defined preprocessor macros, so I wrote code to test for them individially:

#include <iostream>
#include "tinyformat.h"

#if !defined(__MINGW32__) && (defined(_MSC_VER) || defined(__MSVCRT__))
  #define PRIszx    "Ix"
  #define PRIszu    "Iu"
  #define PRIszd    "Id"
  #define PRIpdx    "Ix"
  #define PRIpdu    "Iu"
  #define PRIpdd    "Id"
#else /* C99 standard */
  #define PRIszx    "zx"
  #define PRIszu    "zu"
  #define PRIszd    "zd"
  #define PRIpdx    "tx"
  #define PRIpdu    "tu"
  #define PRIpdd    "td"
#endif

main() {

#if defined(_MSC_VER)
    std::cout << "_MSC_VER" << std::endl;
#endif

#if defined(__MSVCRT__)
    std::cout << "__MSVCRT__" << std::endl;
#endif

#if defined(__MINGW32__)
    std::cout << "__MINGW32__" << std::endl;
#endif

#if defined(__MINGW64__)
    std::cout << "__MINGW64__" << std::endl;
#endif

    std::cout << strprintf("Content-Length1: %"PRIszu"\r\n", 123);
    std::cout << strprintf("Content-Length2: %" PRIszu "\r\n", 123);
}

then tested like this:

$ x86_64-w64-mingw32-g++ foo.cpp
$ wine a
    __MSVCRT__
    __MINGW32__
    __MINGW64__
Content-Length1: 123
Content-Length2: 123
$ cd i686
$ i686-w64-mingw32-g++ foo.cpp
$ wine a
__MSVCRT__
__MINGW32__
Content-Length1: 123
Content-Length2: 123
$