MinGW (Command Line)

From Crypto++ Wiki
Jump to navigation Jump to search

Building Crypto++ with MinGW is a topic that comes up often on the mailing list due to errors encountered during a build. This wiki page will provide instructions for building Crypto++ on the command line for MinGW, and explain some of the issues and their work-arounds.

Broadly speaking there are two sets of problems. First, is MinGW and Cygwin and their intersection with sockets. Sockets can be tricky because Microsoft wants to provide an asynchronous interface using WinSock2 gear, while Unix and Linux provide the standard Posix interface of socket(3).

Second, starting around Crypto++ 5.6.3, we improved C++11 support. For example, the library will use C++11's alignof and alignas when __cplusplus >= 201103L. It works fine for nearly all compilers and runtime libraries, except (1) those that pretend to be C++11 and (2) MinGW layered on top of Windows. We were able to clear most of the pretend C++11 libraries though defines in config.h, but some MinGW/Windows issue remained.

Most of the Windows related C++11 problems can be controlled though three defines: CRYPTOPP_CXX11_DYNAMIC_INIT, CRYPTOPP_CXX11_SYNCHRONIZATION, and CRYPTOPP_CXX11_ATOMICS. We inspect WINVER and _WIN32_WINNT along with a compiler version, and we disable the C++11 defines accordingly. However, the defines are not available through MinGW and Cygwin, so we can't trun them off automatically.

The fixes below are recent, so you will need Crypto++ 6.0 or above. For example, the fix for problems due to std::mutex was checked in at Commit e4cef84883b2. If you are using Crypto++ 5.6.3 through 5.6.5, then you should consider upgrading to Crypto++ 6.0 for the improved support. If you cannot upgrade, then see the referenced commit on how to fix fix things.

Default _WIN32_WINNT

MinGW may not set _WIN32_WINNT or other macros like WINVER. The GNUmakefile will set _WIN32_WINNT if it detects the macro is not set:

ifeq ($(IS_MINGW32),1)
ifeq ($(findstring -D_WIN32_WINNT,$(CXXFLAGS)),)
ifeq ($(findstring -D_WIN32_WINDOWS,$(CXXFLAGS)),)
ifeq ($(findstring -DWINVER,$(CXXFLAGS)),)
ifeq ($(findstring -DNTDDI_VERSION,$(CXXFLAGS)),)
  CXXFLAGS += -D_WIN32_WINNT=0x0501
endif # WINVER
endif # _WIN32_WINDOWS
endif # _WIN32_WINNT
endif # IS_MINGW32

This was added at Commit 404316420529.

std::mutex compile error

Using std::mutex often results in a compile problem out of the box.

g++ -DNDEBUG -g2 -O2 -march=native -pipe -c cryptlib.cpp
In file included from cryptlib.cpp:19:0:
misc.h: In member function 'const T& CryptoPP::Singleton<T, F, instance>::Ref() const':
misc.h:287:14: error: 'mutex' in namespace 'std' does not name a type
  static std::mutex s_mutex;
misc.h:296:18: error: 'mutex' is not a member of 'std'
  std::lock_guard<std::mutex> lock(s_mutex);
misc.h:296:18: error: 'mutex' is not a member of 'std'
misc.h:296:28: error: template argument 1 is invalid
  std::lock_guard<std::mutex> lock(s_mutex);
misc.h:296:35: error: 's_mutex' was not declared in this scope
  std::lock_guard<std::mutex> lock(s_mutex);
make: *** [cryptlib.o] Error 1

If you experience this error, then open config.h, scroll down to around line 65, and uncomment CRYPTOPP_NO_CXX11:

// Define CRYPTOPP_NO_CXX11 to avoid C++11 related features shown at the
// end of this file. Some compilers and standard C++ headers advertise C++11
// but they are really just C++03 with some additional C++11 headers and
// non-conforming classes. You might also consider `-std=c++03` or
// `-std=gnu++03`, but they are required options when building the library
// and all programs. CRYPTOPP_NO_CXX11 is probably easier to manage but it may
// cause -Wterminate warnings under GCC. MSVC++ has a similar warning.
// Also see https://github.com/weidai11/cryptopp/issues/529
// #define CRYPTOPP_NO_CXX11 1

If you want to backport CRYPTOPP_NO_CXX11 to Crypto++ 5.6.5 or earlier, then the fix for this problem was checked in at Commit e4cef84883b2.

wspiapi.h compile error

Another compile error that often occurs wspiapi.h: No such file or directory. It is due to MinGW targeting Windows 2000 by default and not supplying wspiapi.h.

g++ -DNDEBUG -g2 -O3 -pthread -pipe -c socketft.cpp
socketft.cpp:36:23: fatal error: wspiapi.h: No such file or directory
 #  include <wspiapi.h>
compilation terminated.
make: *** [socketft.o] Error 1

We believe the workaround is to set _WINNT_VER accordingly for MinGW in socketft.cpp:

// <wspiapi.h> is a compatibility header and it needs _WIN32_WINNT >= 0x501.
// The work-around should be OK since it won't cross-pollinate into header files.
#if defined(__MINGW32__) && (_WIN32_WINNT < 0x501)
# undef _WIN32_WINNT
# define _WIN32_WINNT 0x501

If you want to backport the header fix to Crypto++ 5.6.5 or earlier, then the fix for this problem was checked in at Commit 379e97cc1c0a .