Using boost in WDK build environment for applications? - boost

I am using the Windows Driver Kit (WinDDK 6001.18001) to build my userspace application rather than Visual Studio 2005. I am taking this approach because we also have to build driver components, so I'd prefer to have a single build environment to build everything. Microsoft itself uses this approach for several products.
This was working fine until I started using Boost 1.38.0. I'm not using C++ in the kernel mode components, just the userspace applications. In C++ code, it's natural to use the boost libraries. Unfortunately, the WDK doesn't agree.
The first error I noticed is that "#include <cstddef>" doesn't put ptrdiff_t in the std namespace, as seems required by Annex D. Working around this left several errors in boost\lambda\detail\operator_return_type_traits.hpp about error C2976: 'std::basic_string' : too few template arguments. It appears redundant with iostream.
Has anyone successfully gotten the combination of Boost, iostream, and the WDK to work together?
My sources file:
TARGETNAME=foobar
TARGETTYPE=PROGRAM
USE_MSVCRT = 1
USE_STL = 1
USE_ATL = 1
ATL_VER = 30
STL_VER = 70
USE_NATIVE_EH = 1
USE_IOSTREAM = 1
SUBSYSTEM_VERSION = 5.02
C_DEFINES = \
-D_MT \
-DWIN_32 \
-DWIN32 \
-D_WINDOWS \
-DNT \
-D_WIN32_DCOM \
-DUNICODE \
-D_UNICODE \
-D_ATL_NO_DEBUG_CRT # because we are using USE_MSVCRT=1
SOURCES=service.cpp
INCLUDES=\
$(BOOST_INC_PATH)
TARGETLIBS=\
$(SDK_LIB_PATH)\ole32.lib \
$(SDK_LIB_PATH)\oleaut32.lib \
$(SDK_LIB_PATH)\uuid.lib \
UMTYPE=console
UMBASE=0x400000
service.cpp:
#include <iostream>
#include <cstddef>
namespace std {
typedef ::ptrdiff_t ptrdiff_t; // DDK C++ workaround
}
#include <boost/lambda/lambda.hpp>
int __cdecl main() {
return 0;
}

Interesting question. Using STL as-is was a challenge in itself with the WDK. I have not ventured beyond. I can give this a try. Remember, the WDK has it's own compiler which is not the same as your VS2005/VS2008 complier (check the version numbers). It is highly likely there are a few bugs here and there.
Note, that USE_MSVCRT=1 and USE_STL=1 didn't gel well (at least for WDK 6001).

Boost may already include a work-around for your issues, but isn't applying it because it doesn't recognise the compiler you're using (probably because drivers rarely use boost).
Try examining (and possibly editing) boost/config/select_compiler_config.hpp and boost/config/compiler/visualc.hpp to make sure the compiler workarounds for MSVC are enabled.

I would suggest going different way, i.e compiling driver from VS200.x using this (ddkbuild) nice tool.
Being myself a command line person and using makefiles everywhere possible, i find build utility not useful for complex project.There is tons of limitation within MS build utility and i would recommend using VS environment for compiling your project.
I'm not sure if there is a howto in the ddkbuild, but it's straight forward to integrate ddkbuild.bat into VS custom build option.

Related

Is GNU libraries able to link to dynamic MSVC runtime using autoconf build system when relying on gnulib?

My goal is to understand a GNU libraries autoconf build system. I am aware that libiconv can be build successfully using a crafted MS Visual Studio project with manully added source code files. So the question is more academical rather than practical. I took into account there is no official support of Windows platform for gnulib also.
Following the guide from INSTALL.windows to build libiconv, I faced with next compilation error when built iconv againts dynamic MSVC runtime(cl /MD or cl /MDd).
C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt\corecrt_malloc.h(85): error C2375: 'rpl_free': redefinition; different linkage
D:\work\env\build-env\msvc2019\shared-debug-shared-runtime\iconv\srclib\string.h(599): note: see declaration of 'rpl_free'
Configure invocation:
/cygdrive/d/work/src/libiconv/configure --enable-relocatable --enable-static=no --enable-shared=yes --host=x86_64-w64-mingw32 --prefix=/iconv 'CFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1' 'CXXFLAGS=/MDd /Z7 /Od /D_DEBUG /RTC1'
Compiler invocation:
compile cl /nologo -DHAVE_CONFIG_H -DEXEEXT=\".exe\" -I. -I/cygdrive/d/work/src/libiconv/srclib -I.. -I../lib -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 /DWIN32 /D_WIN64 /D_UNICODE /D_CRT_SECURE_NO_WARNINGS /MDd /Z7 /Od /D_DEBUG /RTC1 /D_DLL -c -o stat.obj `cygpath -w '/cygdrive/d/work/src/libiconv/srclib/stat.c'`
stat.c
Configure generated iconv/srclib/string.h
/* Declare 'free' if needed for _GL_ATTRIBUTE_DEALLOC_FREE. */
_GL_EXTERN_C void free (void *);
#if 1
# if (1 && !defined free \
&& !(defined __cplusplus && defined GNULIB_NAMESPACE))
# define free rpl_free
_GL_EXTERN_C void free (void *);
# endif
#endif
WinSDK/include/ucrt/corecrt_malloc.h
_ACRTIMP _CRT_HYBRIDPATCHABLE
void __cdecl free(
_Pre_maybenull_ _Post_invalid_ void* _Block
);
WinSDK/include/ucrt/corecrt.h defines next
#ifndef _ACRTIMP
#if defined _CRTIMP && !defined _VCRT_DEFINED_CRTIMP
#define _ACRTIMP _CRTIMP
#elif !defined _CORECRT_BUILD && defined _DLL
#define _ACRTIMP __declspec(dllimport)
#else
#define _ACRTIMP
#endif
#endif
After research and investigation I found out that gnulib(as a part of GNU autoconf build system for libiconv) replaces unsatisfying function calls with its own implementation.
rpl_free is a replacement name to replace regular free() function from the C runtime as MSVC free function is not recognized as a POSIX compliant. It seems to me there is no option to tell to configure not to replace suck functions.
An hack with environment variable REPLACE_FREE=0 did the trick and I have turned off function replacement.
However, MSVC compiler still complaints on different linkage. I believe, MSVC runtime exports its API functions with __declspec(dllimport) for consumers when gnulib declares its free() function signature with no extra attributes.
I wonder, is there a 'paved-road' to build libiconv(or other GNU library that leverage gnulib) linked to dynamic MSVC runtime using original autoconf system? Can I achieve that with no gnulib m4 files alteration?
To answer your general question:
Yes, GNU projects with the GNU build system (Autoconf, optionally Automake, Libtool, and Gnulib) can in general be built with the MSVC compiler. The compile script translates compiler options in the traditional Unix style to compiler options for MSVC.
The experience with GNU libiconv, GNU gettext, and other packages, which all have essentially the same INSTALL.windows instructions, shows that this is well possible. But it often requires tweaks in the build system, to cope with dllimport/dllexport, issues related to backslashes, to file names in Cygwin syntax vs. native Windows syntax, and so on. In particular, note that on Windows, it is hairy to export variables from a shared library; exporting functions is much simpler.
You can typically ignore warnings from MSVC regarding the dllimport/dllexport of functions. This warning merely means that the compiler has added one or two extra instructions per function invocation.
Gnulib indeed overrides many libc functions, such as free(), so that the application source code does not get cluttered with workarounds. The precise reason for each override is documented. For the free() function, it is documented here. While Gnulib has ways to disable specific workarounds, in this case I would strongly advise against it: the effects of a wrong errno value can be severe malfunction of any application.
To answer your specific problem about GNU libiconv:
You have encountered a specific build problem; the README of the package tells you where to report bugs.
GNU packages have releases. The latest GNU libiconv release, version 1.16, does not have the problem. In general, before attempting to compile the newest sources from the git repository, it is advisable to use the newest release. This will be simpler, as it has usually been tested before the release.

CUDA error with Boost make_shared.hpp? [duplicate]

I'm trying to integrate CUDA to an existing aplication wich uses boost::spirit.
Isolating the problem, I've found out that the following code does not copile with nvcc:
main.cu:
#include <boost/spirit/include/qi.hpp>
int main(){
exit(0);
}
Compiling with nvcc -o cudaTest main.cu I get a lot of errors that can be seen here.
But if I change the filename to main.cpp, and compile again using nvcc, it works. What is happening here and how can I fix it?
nvcc sometimes has trouble compiling complex template code such as is found in Boost, even if the code is only used in __host__ functions.
When a file's extension is .cpp, nvcc performs no parsing itself and instead forwards the code to the host compiler, which is why you observe different behavior depending on the file extension.
If possible, try to quarantine code which depends on Boost into .cpp files which needn't be parsed by nvcc.
I'd also make sure to try the nvcc which ships with the recent CUDA 4.1. nvcc's template support improves with each release.

Can I use C++11 in the .cu-files (CUDA5.5) in Windows7x64 (MSVC) and Linux64 (GCC4.8.2)?

When I compile the following code containing the design C++11, in Windows7x64 (MSVS2012 + Nsight 2.0 + CUDA5.5), then I do not get errors, and everything compiles and works well:
#include <thrust/device_vector.h>
int main() {
thrust::device_vector<int> dv(10);
auto iter = dv.begin();
return 0;
}
But when I try to compile it under the Linux64 (Debian 7 Wheezey + Nsight Eclipse from CUDA5.5), I get errors:
../src/CudaCpp11.cu(5): error: explicit type is missing ("int"
assumed)
../src/CudaCpp11.cu(5): error: no suitable conversion function from
"thrust::detail::normal_iterator>" to "int"
exists
2 errors detected in the compilation of
"/tmp/tmpxft_00001520_00000000-6_CudaCpp11.cpp1.ii". make: *
[src/CudaCpp11.o] Error 2
When I added line:-stdc++11
in Properties-> Build-> Settings-> Tool Settings-> Build Stages-> Preprocessor options (-Xcompiler)
I get more errors:
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432): error:
identifier "nullptr" is undefined
/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432): error:
expected a ";"
...
/usr/include/c++/4.8/bits/cpp_type_traits.h(314): error: namespace
"std::__gnu_cxx" has no member
"__normal_iterator"
/usr/include/c++/4.8/bits/cpp_type_traits.h(314): error: expected a
">"
nvcc error : 'cudafe' died due to signal 11 (Invalid memory
reference) make: * [src/CudaCpp11.o] Error 11
Only when I use thrust::device_vector<int>::iterator iter = dv.begin(); in Linux-GCC then I do not get an error. But in Windows MSVS2012 all c++11 features works fine!
Can I use C++11 in the .cu-files (CUDA5.5) in Windows7x64 (MSVC) and Linux64 (GCC4.8.2)?
You will probably have to split the main.cpp from your others.cu like this:
others.hpp:
void others();
others.cu:
#include "others.hpp"
#include <boost/typeof/std/utility.hpp>
#include <thrust/device_vector.h>
void others() {
thrust::device_vector<int> dv(10);
BOOST_AUTO(iter, dv.begin()); // regular C++
}
main.cpp:
#include "others.hpp"
int main() {
others();
return 0;
}
This particular answer shows that compiling with an officially supported gcc version (as Robert Crovella stated correctly) should work out at least for c++11 code in the main.cpp file:
g++ -std=c++0x -c main.cpp
nvcc -arch=sm_20 -c others.cu
nvcc -lcudart -o test main.o others.o
(tested on Debian 8 with nvcc 5.5 and gcc 4.7.3).
To answer your underlying question: I am not aware that one can use C++11 in .cu files with CUDA 5.5 in Linux (and I was not aware the shown example with host-side C++11 gets properly de-cluttered under MSVC). I even filed a feature request for constexpr support which is still open.
The CUDA programming guide for CUDA 5.5 states:
For the host code, nvcc supports whatever part of the C++ ISO/IEC
14882:2003 specification the host c++ compiler supports.
For the device code, nvcc supports the features illustrated in Code
Samples with some restrictions described in Restrictions; it does not
support run time type information (RTTI), exception handling, and the
C++ Standard Library.
Anyway, it is possible to use some of the C++11 features like auto in kernels, e.g. with boost::auto.
As an outlook, other C++11 features like threads may be quite unlikely to end up in CUDA and I heard no official plans about them yet (as of supercomputing 2013).
Shameless plug: If you are interested in more of these tweeks, feel free to have a look in our library libPMacc which provides multi-GPU grid and particle abstractions for simulations. We implemented lambda, a STL-like access concept for 1-3D matrices and other useful stuff there.
All the best,
Axel
Update: Since CUDA 7.0 C++11 support in kernels has been added officially. As BenC pointed our correctly, parts of this feature were already silently added in CUDA 6.5.
According to Jared Hoberock (Thrust developer), it seems that C++11 support has been added to CUDA 6.5 (although it is still experimental and undocumented). This may make things easier when starting to use C++11 in very large C++/CUDA projects, since splitting everything can be quite cumbersome for large projects when you use CMake for instance.

Compiling Clang on Windows

I followed instructions at http://clang.llvm.org/get_started.html
I compiled latest trunk of llvm and clang with MSVC 2010. Now I can compile simple programs with Clang but when I tried to compile this program I got a lot of errors.
Here is program:
#include <algorithm>
int main(){ return 0; }
And here are some of errors:
In file included from hello.cpp:1:
In file included from C:\Program Files\Microsoft Visual Studio 10.0\VC\include\algorithm:6:
In file included from C:\Program Files\Microsoft Visual Studio 10.0\VC\include\memory:987:
In file included from C:\Program Files\Microsoft Visual Studio 10.0\VC\include\intrin.h:24:
In file included from H:/LLVM/build/bin/Debug/../lib/clang/3.3/include\immintrin.h:32:
In file included from H:/LLVM/build/bin/Debug/../lib/clang/3.3/include\xmmintrin.h:988:
H:/LLVM/build/bin/Debug/../lib/clang/3.3/include\emmintrin.h:1384:22: error: expected expression
return (__m128)__in;
^
H:/LLVM/build/bin/Debug/../lib/clang/3.3/include\emmintrin.h:1390:23: error: expected expression
return (__m128i)__in;
^
H:/LLVM/build/bin/Debug/../lib/clang/3.3/include\emmintrin.h:1396:23: error: expected expression
return (__m128d)__in;
^
Complete output from Clang: http://pastebin.com/qi87K8qr
Clang tries to use MSVC headers but it doesn't work. Maybe I should use libc++ or libstdc++ instead, but how to do that?
Note I'm not interested in precompiled clang binaries
Yes, clang simply does not support all of Microsoft's extended C++ syntax, and therefore cannot parse Microsoft's C++ headers which use that syntax. Not only that but Clang also doesn't have complete support for Microsoft's C++ ABI, name mangling, etc. I believe Clang on Windows works alright with C, however.
To use a different C++ standard library instead you can make clang ignore the normal header and library directories with, IIRC, -nostdinc++ and -nostdlib++. Then you can tell clang the include and library directories you want to use (using -isystem or -I or whatever). However I'm not sure whether libc++ or libstdc++ work under those circumstances, since they probably depend on things that the Windows C runtime library does not have.
Chandler Carruth mentioned at Going Native 2013 that there are now alpha builds of clang for Windows with Visual Studio integration. Lots of stuff is broken, for example, streams (so good old hello world won't work). However, there is a lot of effort being put into making clang work on Windows, so expect it to get pretty good pretty fast.
Errors were in the header supplied with clang itself. Looks like it can't handle MMX/SSE types properly. Try to add -msse -msse2 switches to the command line.
I'm using libstdc++ and built clang using VS2012Express for desktop. The cmake string was "Visual Studio 11 Win64" and the essential dirs. are specified using -I argument.
My guess you program could work if I used mingw headers for Windows.

PCSC-Lite Codes on Windows

I've successfully built a program that can read Mifare 1K Card using Qt on Linux. So now, I would like it to run on Windows. From what I've gathered, there's no PCSC-Lite port on Windows and I need to use winscard from Windows SDK. I've downloaded it and I got lots of undefined reference errors from my Qt in Windows (with MingW). For example:
release/ReadCard.o:ReadCard.cpp:(.text+0x48e): undefined reference to `pcsc_stringify_error'
release/ReadCard.o:ReadCard.cpp:(.text+0x5e9): undefined reference to `pcsc_stringify_error'
release/ReadCard.o:ReadCard.cpp:(.text+0x7ed): undefined reference to `pcsc_stringify_error'
release/ReadCard.o:ReadCard.cpp:(.text+0x2e56): undefined reference to `SCardListReaderGroups'
release/ReadCard.o:ReadCard.cpp:(.text+0x3adc): undefined reference to `SCardListReaders'
release/ReadCard.o:ReadCard.cpp:(.text+0x3cc6): undefined reference to `SCardListReaders'
release/ReadCard.o:ReadCard.cpp:(.text+0x3f88): undefined reference to `SCardGetStatusChange'
release/ReadCard.o:ReadCard.cpp:(.text+0x4274): undefined reference to `SCardConnect'
release/ReadCard.o:ReadCard.cpp:(.text+0x4d1b): undefined reference to `SCardGetStatusChange
I've also tried specifying these libraries in the project, but still failed.
LIBS += -lwinscard -lpcsclite WinSCard.Lib
Theoretically speaking, pcsc-lite is a port of Windows PC/SC stack to UNIX machines. Windows PC/SC implementation is the "reference implementation" which pcsc-lite mimics. Not all Windows SCard functions are implemented in pcsc-lite and there are even minor differences, documented in pcsc-lite documentation
Don't know about the Qt specifics, but some notes:
pcsc_stringify_error is a pcsc-lite specific function. It does not exist in Windows
there is no pcsclite library on Windows or mingw, so you probably need different build files for Windows.
have a look at OpenSC and how it makes use of PC/SC(-lite) and if you're building with mingw, have a look at the "build" project. internal-winscard.h from OpenSC might be of interest to you as well.
Except for the pcsc_stringify_error, your problems are with generic Windows linking and Qt (qmake?) build system.
It's been a while and I've managed to solve this using headers from the example that comes with my reader. My .pro file looks like this
win32 {
HEADERS += MainWindow.h \
ReadCard.h \
Config.h
INCLUDEPATH += C:/Omnikey/Include
LIBS += C:/Omnikey/Lib/winscardn.lib
}
unix {
HEADERS += MainWindow.h \
wintypes.h \
winscard.h \
reader.h \
pcsclite.h \
ReadCard.h \
Config.h
LIBS += -lpcsclite
}
I'm not sure if this solution can be used with other type of readers, but it sure solved mine.
i ran into the same problem, being unable to use winscard from the Windows SDK together with the minGW compiler.
A quick fix is to use the MSVC++ compiler (if you have access to it offcourse..) instead of minGW (you'll need to build Qt itself using the MSVC++ compiler also).
Probably its also possible to get this working with minGW but i didn't look into it any further..

Resources