Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflict with Boost.Asio on Windows #1663

Closed
gcerretani opened this issue Sep 2, 2020 · 11 comments
Closed

Conflict with Boost.Asio on Windows #1663

gcerretani opened this issue Sep 2, 2020 · 11 comments

Comments

@gcerretani
Copy link

Same as issue #179, marked as fixed in 2016, but reappeared since v1.6.0.

This source code

#include <spdlog/spdlog.h>
#include <boost/asio.hpp>

compiles in v1.5.0, but fails since v1.6.0 with messages like

fatal error C1189: #error: WinSock.h has already been included.

Tested up to v1.8.0 with Boost v1.67 and MSVC 1900 (2015).

@gcerretani gcerretani changed the title Conflict with Boost.Asio Conflict with Boost.Asio on Windows Sep 2, 2020
@tt4g
Copy link
Contributor

tt4g commented Sep 2, 2020

windows.h includes winsock.h.
This is causing Boost.Asio to generate a compile error.
Boost.Asio uses Winsock2, so winsock.h should not be included.

This is the root cause of the windows.h definition, and is not a problem that can be addressed by spdlog alone.

Workaround: #define _WINSOCKAPI_ or #define WIN32_LEAN_AND_MEAN before #include <windows.h.
Another way, #include <boost/asio.hpp> before #include <spdlog/spdlog.h>.

Refer: c - Cannot include both files (WinSock2, Windows.h) - Stack Overflow

@gabime
Copy link
Owner

gabime commented Sep 2, 2020

Strange that it appears in 1.8.0 though.. Are you using the bundled fmt version 7.0.3? There was a fix in that version about it. Please share the compiler error output.

@gcerretani
Copy link
Author

gcerretani commented Sep 3, 2020

I'm using v1.8.0 with bundled fmt. Investigating, I've found that problems arise when compiling with NOMINMAX defined.

Source code:

#include <spdlog/spdlog.h>
#include <boost/asio.hpp>
int main() {}

Preprocessor definitions:

  • NOMINMAX
  • BOOST_ALL_NO_LIB
  • _WIN32_WINNT=0x0601
  • BOOST_ERROR_CODE_HEADER_ONLY
  • BOOST_SYSTEM_NO_DEPRECATED

Compiler output:

1>------ Build started: Project: Playing++, Configuration: Debug x64 ------
1>Build started 9/3/2020 8:52:59 AM.
1>     1>
1>InitializeBuildStatus:
1>         Touching "x64\Debug\Playing++.tlog\unsuccessfulbuild".
1>       ClCompile:
1>         Playing++.cpp
1>     1>
1>e:\external\boost_1_67_0\boost\asio\detail\socket_types.hpp(24): fatal error C1189: #error:  WinSock.h has already been included
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.34
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Removing NOMIXMAX from preprocessors everything works (with only two C4996 warnings). Keeping NOMINMAX, both @tt4g solutions (swapping includes and adding WIN32_LEAN_AND_MEAN) works.

@tt4g
Copy link
Contributor

tt4g commented Sep 3, 2020

Removing NOMIXMAX from preprocessors everything works

It seems that format-inl includes windows.h but does not defined WIN32_LEAN_AND_MEAN when only NOMINMAX macro is defined.

#ifdef _WIN32
# if !defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN)
# define NOMINMAX
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# undef WIN32_LEAN_AND_MEAN
# undef NOMINMAX
# else
# include <windows.h>
# endif
# include <io.h>
#endif

This is a bit tricky.
We need to get all the patterns that branches off by defining WIN32_LEAN_AND_MEAN and NOMINMAX to be addressed.

@tt4g
Copy link
Contributor

tt4g commented Sep 3, 2020

@gcerretani Currently I don't have a machine at hand that can do C++ development.

Can you confirm that the following patch will no longer reproduce the problem?

 #ifdef _WIN32 
 #  if !defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN) 
 #    define NOMINMAX 
 #    define WIN32_LEAN_AND_MEAN 
 #    include <windows.h> 
 #    undef WIN32_LEAN_AND_MEAN 
 #    undef NOMINMAX 
+#  elif defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN) 
+#    define WIN32_LEAN_AND_MEAN 
+#    include <windows.h> 
+#    undef WIN32_LEAN_AND_MEAN 
 #  else
 #    include <windows.h> 
 #  endif 
 #  include <io.h> 
 #endif 

@gabime
Copy link
Owner

gabime commented Sep 3, 2020

@tt4g Good catch. Seems you are right!

@gcerretani
Copy link
Author

That patch resolve the problem.

@gabime
Copy link
Owner

gabime commented Sep 3, 2020

@gcerretani Could you open a PR in the fmt repo to fix this?

@gcerretani
Copy link
Author

I think I've done it.

@gabime
Copy link
Owner

gabime commented Sep 3, 2020

Thanks. Will be updated in spdlog's copy when next official fmt is released

@gabime gabime closed this as completed Sep 3, 2020
@drewhamiltonasdf
Copy link

drewhamiltonasdf commented Nov 20, 2022

I am having this problem with the latest boost release 1.80.0. I used the patch above and I'm back in business, as follows:

#ifdef _WIN32 
#  if !defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN) 
#    define NOMINMAX 
#    define WIN32_LEAN_AND_MEAN 
#    include <windows.h> 
#    undef WIN32_LEAN_AND_MEAN 
#    undef NOMINMAX 
#  elif defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN)
#    define WIN32_LEAN_AND_MEAN
#    include <windows.h>
#    undef WIN32_LEAN_AND_MEAN
#  else
#    include <windows.h> 
#  endif 
#  include <io.h> 
#endif 

#include <boost/asio.hpp>

I will probably disappear and be unresponsive if anyone gets back to me. Just being honest. I'm not on GitHub every day...

bachittle pushed a commit to bachittle/spdlog that referenced this issue Dec 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants