Using boost 1.60 on winxp sp2

boost has dropped winxp support by default. However, it does offer option to allow binary to run on winxp.
We followed the options on http://www.boost.org/users/history/version_1_60_0.html , and the compiled binaries can run on winxp sp3. Sadly, not including winxp sp2.

Let’s take a look at the build instruction:

This release of Boost will by default compile for Windows Vista/Windows Server 2008, if the compiler supports a recent enough Windows SDK, and for Windows XP otherwise. Binaries compiled with default options may not run on the older Windows versions.

It is still possible to explicitly specify target Windows version by defining BOOST_USE_WINAPI_VERSION to a numeric version of Windows API. For example, building Boost for Windows XP can be done with the following command:

b2 release define=BOOST_USE_WINAPI_VERSION=0x0501

But the compiled binaries will get following error when running on winxp sp2.

The procedure entry point GetLogicalProcessorInformation could not be located in the dynamic link library KERNEL32.dll.

Use IDA to disassemble the binary, we can see it’s due to boost::thread::hardware_concurrency()
Here is its implement:

    unsigned thread::physical_concurrency() BOOST_NOEXCEPT
{
// a bit too strict: Windows XP with SP3 would be sufficient
#if BOOST_PLAT_WINDOWS_RUNTIME                                    \
|| ( BOOST_USE_WINAPI_VERSION <= BOOST_WINAPI_VERSION_WINXP ) \
|| ( ( defined(__MINGW32__) && !defined(__MINGW64__) ) && _WIN32_WINNT < 0x0600)
return 0;
#else
unsigned cores = 0;
DWORD size = 0;

GetLogicalProcessorInformation(NULL, &size);
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
return 0;

std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer(size);
if (GetLogicalProcessorInformation(&buffer.front(), &size) == FALSE)
return 0;

const size_t Elements = size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);

for (size_t i = 0; i < Elements; ++i) {
if (buffer[i].Relationship == RelationProcessorCore)
++cores;
}
return cores;
#endif
}

 

if we put #pragma message in front of if-conditional statement, BOOST_USE_WINAPI_VERSION  = 0x0501 while BOOST_WINAPI_VERSION_WINXP is BOOST_WINAPI_VERSION_WINXP, a bit wired.

So the solution is

define=BOOST_USE_WINAPI_VERSION=BOOST_WINAPI_VERSION_WINXP

instead of the suggestion from boost official website:

define=BOOST_USE_WINAPI_VERSION=0x0501

Verified with IDA:

.text$mn:0000106C ; unsigned int __cdecl boost::thread::physical_concurrency()
.text$mn:0000106C                 public ?physical_concurrency@thread@boost@@SAIXZ
.text$mn:0000106C ?physical_concurrency@thread@boost@@SAIXZ proc near
.text$mn:0000106C                 push    ebp
.text$mn:0000106D                 mov     ebp, esp
.text$mn:0000106F                 xor     eax, eax
.text$mn:00001071                 pop     ebp
.text$mn:00001072                 retn
.text$mn:00001072 ?physical_concurrency@thread@boost@@SAIXZ endp

It has become an empty function. The problem has been solved!

Advertisements

One thought on “Using boost 1.60 on winxp sp2

  1. >if we put #pragma message in front of if-conditional statement, BOOST_USE_WINAPI_VERSION = >0x0501 while BOOST_WINAPI_VERSION_WINXP is BOOST_WINAPI_VERSION_WINXP, a bit >wired.

    It’s a bug.

    https://svn.boost.org/trac/boost/ticket/12036

    The variables BOOST_WINAPI_VERSION_WINXP, etc. are not defined either. These are defined in detail/winapi/config.hpp but this file does not appear to be included. Even if the user specified a winapi version via define, there would be no value to compare to.

    Which is fixed in 1.62.0 beta 1.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s