Include header that may or may not exist on Windows - c++

So, I am trying to deal with small differences in the various versions of the Windows SDK but am having trouble determining during compilation precisely what version of the Windows SDK I am building against in C++.
As of version 6.1 of the Windows SDK, there is a WinSDKVer.h file that contains some version information that I could use to determine what version of the SDK is being used even though it does not contain a direct version number for the SDK. However, 6.0A does not include this header file, so simply inserting #include and then using something like #ifdef will not work since there is no WinSDKVer.h in the environment.
A colleague of mine had a vague recollection of a way to include a header on Windows if and only if it exists, but could not remember any details and I have so far failed to find any information on doing so either on stackoverflow or the internet.
I've already done what I can to our make process to try to force the use of a 6.1 or greater SDK if installed on the developer's machine, but I'm also interested if others have run into this general kind of issue before and if/how they solved it.
Any ideas?

(ugly) create your own empty version of the header file and place it on a folder. Then add this folder last in your include directories. if the file exists in the SDK it will be included; otherwise your file will be used.

You cannot do it on C++ level. You can do it on build system level — e.g. in SCons see "Checking for the Existence of Header Files". The basic idea is to compile a little program that just includes the file, and see whether compilation succeeds or fails. Then you can set a macro that says if you have the header, or not, and do
#ifdef HAVE_WINSDKVER_H
# include <winsdkver.h>
#endif
or whatever.

Do some spelunking through historic versions of the SDK headers, looking for a header file that has existed in all versions of the SDK but contains subtle variation in its #defines in different SDK versions. You can test these with #ifdef to distinguish the SDKs.
Obviously it'll have to be some file other than WinSDKVer.h, and in some cases you may need a combination of several files.
I did something similar for Palm OS SDKs many years ago.

Related

What should I install to use namespace Windows::Devices in c++?

Now I am going to connect to device using bluetooth, so I have got some source code.
It uses namespace Windows::Devices, but my visual studio gives me compile error.
using namespace Windows::Devices;
I guess I have to install some packages additionally, but I am not sure what I have to install.
If anyone knows, please help me.
Since the question is tagged c++ I'm going to assume that that's the programming language you are using. The most convenient way to consume Windows Runtime types from C++ is through C++/WinRT. It consists of both a base library as well as a code generator. The code generator is responsible for providing the "projected types" (see Consume APIs with C++/WinRT), generated into namespaces such as Windows::Devices.
It's common for a project to generate the headers containing the projected types on the fly, that can then be included like any other header. A project created using the C++/WinRT VSIX extension does that. Those projects have a reference to the Microsoft.Windows.CppWinRT NuGet package that contains the code generator, as well as project properties to drive it during a build.
Previously, the header files containing the projected C++/WinRT types had been delivered through the Windows SDK. They are still part of the SDK, and can be used by client code, even though it's preferable to use the NuGet package instead. You'll find the Windows.Devices.h header file under %WindowsSdkDir%Include<WindowsTargetPlatformVersion>\cppwinrt\winrt, so to use this namespace, that's the file you'll need to include.

Setting up files to compile on any computer in Visual Studio

Question:
Once my code is working how should I prepare my files so that a stranger on a different computer can compile it without difficulty?
Additional Details:
I am sending a code sample to a company as part of an application so obviously an elegant solution would be better (i.e. minimise number of files required etc) and no work should be necessary by the stranger at the other end.
Although I am only using one simple library, even so I need to set include directories, include lib files, images, dll files etc so that it all compiles correctly.
If it matters, I am using Visual Studio 2015 and the simple library is SDL.
Sorry if this is a duplicate, I was sure that this question would have been asked before but if it exists I just don't know the correct terminology to find it amongst the noise.
Apologies if this is overly simplistic, but you might want to bound the scope of your project by deciding which computers you want to support, and build your code yourself on those platforms, in advance, just to be sure.
List the supported platforms in your release notes, including any platform-specific instructions or information (which VC++ versions, which C++ versions, which OS versions, which DLLs, directory structure, etc.).
You may have to stick some "#ifdef"s and such in your code, but only by building on a particular platform/configuration will you really know for sure.
You can use properties/props files in your VS solution which sets the paths to includes and precompiled libs, then reference the build variables in your project files.
To compile on another machine, you just need to change the values in the properties files.

How to create dynamic defines for Visual Studio?

I have a C++ project that builds on several platforms.
On Mac OSX and Linux, I use SConstruct, which allows me to have some "smartness" regarding the different compilation steps. Namely, I could put the program version in a file named VERSION at the root of the repository, whose content is simply:
2.0
In the build SConscript, I just have to open, read and parse that file and I can create dynamic defines based on it. For instance:
env.Append(CXXFLAGS=['-DVERSION_MAJOR=%s' % open('VERSION').read().split('.')[0]])
This is, for obvious reasons, very convenient. It also allows me to put today's date in an environment variable for instance.
Now for Windows, I have a .sln file with different .vcxproj files into which I'd like to do something similar, except I have no idea how.
To summarize, my question is: how can I have "smart" defines like that (reading, parsing a file and putting its content into several environment variables) without having to change the .sln/.vcxproj files manually on every version shift ?
I know I could use SCons on Windows too, but I'd like not to (mainly because it seems less popular on the platform, and I don't want to scare potential contributors that only know Windows-specific tools).
A common way to do this is to define your constants in an include file:
e.g.
// Version.h - Autogenerated, don't edit
#define VERSION_MAJOR 1
Next you write a script or a program (in your favourite language) to obtain version from somewhere and dynamically write Version.h. Possibly parse the old Version.h and increment or get it from some external source.
In visual studio, create a custom build step for Version.h and make it dependent on something that forces it to update on every build.
You could maintain the current solution, and for Windows, integrate it with Visual Studio solution and project files generated by SCons using the MSVSProject() builder or the MSVSSolution() builder.
You can find more info about these SCons builders here.

What is sdkddkver.h?

When I attempt to compile a MFC project I get told I need to include this file. What and where is it? Why do I need it?
It's a rather important Windows SDK header file, the very first one that gets #included in <windows.h>. It declares Windows version numbers, the kind you should use in your program that states what version of Windows you want to be compatible with. The MSDN Library article is here.
If this file is actually missing on your machine (it isn't clear from the question) then you've either got a very old SDK version and are mixing headers (very bad) or you've got some disk damage (very very bad). It is the kind of problem you'd get when you are stuck on an ancient version of Visual Studio and are trying to use modern Windows api functions. Do not mix and match, it won't come to a good end.

Case Sensitivity in C++ Header Files

I'm a complete noob when it comes to C++ and I've been hacking away on Moai trying to add support for an Xbox 360 gamepad via XInput. When I include the header for XInput there are two options:
XInput
and
Xinput
Further, in order to use XInput I need to include windows.h. All the examples I've seen use the following syntax:
#include <windows.h>
But the auto complete in Visual C++ Express 2010 inserts
#include <Windows.h>
In the case of XInput/Xinput it seems that case-sensitivity matters but in the case on Windows.h it does not seem to matter.
Does case-sensitivity matter when including header files? Is there some logic to this?
Is the XInput difference simply a matter of there being a header for something called XInput and another something called Xinput?
Case sensitivity in header names and include directives is implementation defined. Generally it works out to whether the platform you're building on is case sensitive or not.
I'd have to test to make sure, but I suspect that if you type any variety of 'xinput.h' it will find the the one that occurs first in the header search paths, even if the file that occurs later in the search paths is a better match in terms of case. This would be quite unintuitive from the perspective of a developer not familiar with these issues, because it would mean that you could use one of those auto-completions, and VS would then include the file not selected.
It's also possible that VS is smarter than that and will search for the best case match.
It only matters if the underlying file system is case sensitive. The Windows filesystem is not case-sensitive, but the file systems of operating systems like Linux are. Try to use the exact actual name of the real file to ensure that your code works if/when you port it from one OS to another.
On Windows, filenames are not case-sensitive, and this extends to #include. Any case will do.
On some platforms (e.g. Linux), filenames are case-sensitive, so you would need to match the actual filename.
Windows is not case sensetive as others have said. But that's not your problem. Your problem is with include-file settings in Visual Studio. The compiler will look for standard headers (header inclusion using <> syntax), in the order they are setup. Launch Tools->Options, and then lookup Projects and Solutions->VC++ directories and see the sequence of Include Files.